Unsere Reise durch die DevOps-Welt
Name: Matthias Alt
email: alt@solutiondrive.de
twitter: @sd_alt
20x
5x
~250MB
vorher ca. 5std
Ziel < 1std
2x
Ansible
- hosts: all
become: true
gather_facts: false
vars_files:
- vars/default_bestellabwicklung.yml
- vars/default_timezone.yml
- vars/default_php71-fpm.yml
- vars/default_deployment.yml
pre_tasks:
- name: ensure python2.7 is installed
raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal)
register: output
changed_when: output.stdout != "" and output.stdout != "\r\n"
- setup: # aka gather_facts
roles:
- role: geerlingguy.ntp
- role: geerlingguy.nginx
nginx_extra_http_options: |
gzip on;
gzip_proxied any;
gzip_types text/plain text/css text/javascript application/javascript image/png image/jpeg image/jpg;
gzip_vary on;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
- role: geerlingguy.php-versions
- role: geerlingguy.php
- role: geerlingguy.composer
- role: geerlingguy.certbot
certbot_install_from_source: yes
- role: solutiondrive.deployment
- role: solutiondrive.server-access
sd_access_user: "ubuntu"
sd_access_authorized_keys:
- "matthias.pub"
- "wojtylak.pub"
- "toby.pub"
- role: sdoit.bestellabwicklung
- hosts: sponge
become: yes
roles:
- {
role: solutiondrive.s3_deployment,
project_name: sponge,
installation_path: /var/www/,
s3_bucket: sd-applications-releases,
s3_object: /project-releases/sponge/release-master-php7.2.tar.gz
}
post_tasks:
- name: Create nginx configuration
template:
src: "files/nginx-conf.j2"
dest: "/etc/nginx/sites-available/{{ item.project_name }}.conf"
with_items:
- project_name: sponge
installation_path: /var/www/
- name: Activate nginx configuration
file:
src: "/etc/nginx/sites-available/{{ item.project_name }}.conf"
dest: "/etc/nginx/sites-enabled/{{ item.project_name }}.conf"
state: link
with_items:
- project_name: sponge
- name: reload nginx
service:
name: nginx
state: reloaded
global
Applikation
workspace:
base: /workspace
path: morpheus
pipeline:
setup:composer:
image: solutiondrive/php-composer:${PHP_VERSION}
commands:
- composer install -n --no-progress
volumes:
- /var/cache/composer:/composer/cache
secrets: [ composer_auth ]
validate:yaml:
group: validate
image: solutiondrive/php-xdebug:${PHP_VERSION}
commands:
- php bin/console lint:yaml app/config --parse-tags
- php bin/console lint:yaml src --parse-tags
validate:twig:
group: validate
image: solutiondrive/php-xdebug:${PHP_VERSION}
commands:
- php bin/console lint:twig src
test:codingstandards:
group: standardsandlint
image: solutiondrive/php-composer:${PHP_VERSION}
commands:
- bin/ecs check --no-progress-bar ./src ./tests ./spec
test:stylelint:
group: standardsandlint
image: docker.solutiondrive.de/library/stylelint
path: "app/themes/*/Resources/**/*.{css,scss}"
template: ".stylelintconfig.json"
quiet: true
test:eslint:
group: standardsandlint
image: docker.solutiondrive.de/library/eslint
path: "app/themes/**/*.{.html,.twig,js}"
ignore: ".eslintignore"
template: ".eslintconfig.json"
quiet: true
test:spec:
group: specandbehat
image: solutiondrive/php-xdebug:${PHP_VERSION}
commands:
- bin/phpspec run --no-code-generation --format=dot
test:behat:
group: specandbehat
image: solutiondrive/php-xdebug:${PHP_VERSION}
commands:
- sleep 15
- bin/console doctrine:schema:update --env=test --force
- bin/console server:run --env=test --quiet &
- bin/behat features/ -n --strict -vvv --format=progress --tags="~@javascript && ~@todo"
phpserver:
image: solutiondrive/php-xdebug:${PHP_VERSION}
commands:
- cd /workspace/morpheus
- bin/console doctrine:schema:update --env=test --force
- bin/console server:run --env=test --quiet 0.0.0.0:8080
detach: true
general:restore_cache:
image: drillster/drone-volume-cache
restore: true
mount:
- ./node_modules
volumes:
- /tmp/cache:/cache
general:generate:assets:
image: node:9.5
commands:
- ./etc/scripts/publish/generateAssets.sh
test:behat:javascript:
image: solutiondrive/php-xdebug:${PHP_VERSION}
commands:
- bin/behat features/ --config=behat.selenium.drone.yml.dist -n --strict -vvv --format=progress --tags="@javascript && ~@todo"
general:rebuild_cache:
image: drillster/drone-volume-cache
rebuild: true
mount:
- ./node_modules
volumes:
- /tmp/cache:/cache
publish:cleanup:composer:
image: solutiondrive/php-composer:${PHP_VERSION}
commands:
- ./etc/scripts/publish/cleanupComposer.sh
volumes:
- /var/cache/composer:/composer/cache
secrets: [ composer_auth ]
when:
ref: [ refs/heads/master, refs/heads/release/*, refs/tags/* ]
event: [push, tag]
publish:pre:cleanup:files:
image: alpine:3.7
commands:
- ./etc/scripts/publish/preCleanupFiles.sh
when:
ref: [ refs/heads/master, refs/heads/release/*, refs/tags/* ]
event: [push, tag]
publish:setup:generate:assets:
image: node:9.5
commands:
- ./etc/scripts/publish/generateAssets.sh
when:
ref: [ refs/heads/master, refs/heads/release/*, refs/tags/* ]
event: [push, tag]
publish:setup:install:assets:
image: solutiondrive/php-composer:${PHP_VERSION}
commands:
- ./etc/scripts/publish/setupInstallAssets.sh
when:
ref: [ refs/heads/master, refs/heads/release/*, refs/tags/* ]
event: [push, tag]
publish:post:cleanup:files:
image: alpine:3.7
commands:
- ./etc/scripts/publish/postCleanupFiles.sh
when:
ref: [ refs/heads/master, refs/heads/release/*, refs/tags/* ]
event: [push, tag]
publish:create:master_archive:
image: alpine:3.7
commands:
- ./etc/scripts/publish/writeVersions.sh
- tar --exclude='./etc' -czf release-${DRONE_COMMIT_BRANCH}-${PHP_VERSION}.tar.gz ./
when:
ref: [ refs/heads/master, refs/heads/release/*, refs/tags/* ]
event: [push]
publish:create:release_archive:
image: alpine:3.7
commands:
- ./etc/scripts/publish/writeVersions.sh
- tar --exclude='./etc' -czf release-${DRONE_TAG}-${PHP_VERSION}.tar.gz ./
- cp release-${DRONE_TAG}-${PHP_VERSION}.tar.gz release-latest-${PHP_VERSION}.tar.gz
when:
ref: [
"refs/tags/v[0-9].[0-9].[0-9]",
"refs/tags/v[0-9].[0-9].[0-9][0-9]",
"refs/tags/v[0-9].[0-9][0-9].[0-9]",
"refs/tags/v[0-9][0-9].[0-9].[0-9]",
"refs/tags/v[0-9].[0-9][0-9].[0-9][0-9]",
"refs/tags/v[0-9][0-9].[0-9].[0-9][0-9]",
"refs/tags/v[0-9][0-9].[0-9][0-9].[0-9]",
"refs/tags/v[0-9][0-9].[0-9][0-9].[0-9][0-9]"
]
event: [tag]
publish:s3:release:
image: plugins/s3
bucket: application-configs-385280725562
acl: private
region: eu-central-1
source: release-*.tar.gz
target: /releases/morpheus/releases
when:
ref: [ refs/heads/master, refs/heads/release/*, refs/tags/* ]
event: [push, tag]
publish:s3:screenshots:
image: plugins/s3
bucket: application-configs-385280725562
acl: private
region: eu-central-1
source: etc/screenshots/*
target: /build/morpheus/screenshots/${DRONE_BRANCH}
when:
ref: [ refs/heads/master, refs/heads/release/*, refs/tags/* ]
event: [push]
publish:s3:screenshots:tag:
image: plugins/s3
bucket: application-configs-385280725562
acl: private
region: eu-central-1
source: etc/screenshots/*
target: /build/morpheus/screenshots/${DRONE_TAG}
when:
ref: [
"refs/tags/v[0-9].[0-9].[0-9]",
"refs/tags/v[0-9].[0-9].[0-9][0-9]",
"refs/tags/v[0-9].[0-9][0-9].[0-9]",
"refs/tags/v[0-9][0-9].[0-9].[0-9]",
"refs/tags/v[0-9].[0-9][0-9].[0-9][0-9]",
"refs/tags/v[0-9][0-9].[0-9].[0-9][0-9]",
"refs/tags/v[0-9][0-9].[0-9][0-9].[0-9]",
"refs/tags/v[0-9][0-9].[0-9][0-9].[0-9][0-9]"
]
event: [tag]
infrastructure:packer:
image: solutiondrive/docker-aws-packer-ansible
aws_account_id: 385280725562
aws_role: PackerRole
target: packer/morpheus-appserver.json
working_directory: etc/infrastructure
ansible_run_galaxy_install: true
ansible_ansible_requirements_path: ansible/requirements.yml
environment:
USER: ci
AMI_IMAGE_NAME: morpheus-appserver-${DRONE_BUILD_NUMBER}-${DRONE_COMMIT_BRANCH}
when:
ref: [ refs/heads/master, refs/heads/release/*, refs/tags/* ]
event: [push, tag]
matrix:
PHP_VERSION: php7.2
infrastructure:terraform:reference:
group: infrastructure_terraform
image: jmccann/drone-terraform
plan: false
root_dir: etc/infrastructure/terraform
targets:
- module.application_cluster.aws_launch_configuration.application_cluster_appserver_launch_configuration
- module.application_cluster.aws_autoscaling_group.application_cluster_appserver_auto_scaling_group
init_options:
backend-config:
- "role_arn=arn:aws:iam::385280725562:role/TerraformRole"
- "bucket=sd-infrastructure-up-and-running-state-385280725562"
- "key=morpheus/terraform.tfstate"
- "dynamodb_table=sd_internal_infrastructure"
var_files:
- reference.tfvars
vars:
solutiondrive_internal_role_arn: "arn:aws:iam::385280725562:role/TerraformRole"
appserver_image_name: "morpheus-appserver-${DRONE_BUILD_NUMBER}-${DRONE_COMMIT_BRANCH}"
appserver_image_use_most_recent: "false"
when:
ref: [ refs/heads/master, refs/heads/release/*, refs/tags/*-rc* ]
event: [push, tag]
matrix:
PHP_VERSION: php7.2
infrastructure:ec2:rescale:reference:
group: infrastructure_rescale
image: solutiondrive/docker-aws-packer-ansible
environment:
USER: ci
AUTOSCALING_GROUP_NAME: "morpheus-refe-asg"
AWS_REGION: "eu-central-1"
PLUGIN_AWS_ACCOUNT_ID: "385280725562"
PLUGIN_AWS_ROLE: "AutoscalingRole"
commands:
- echo "Acquire session token..."
- iam_creds=$(aws sts assume-role --role-arn "arn:aws:iam::$PLUGIN_AWS_ACCOUNT_ID:role/$PLUGIN_AWS_ROLE" --role-session-name "docker-$DRONE_COMMIT_SHA-$DRONE_BUILD_NUMBER" --region $AWS_REGION | python -m json.tool)
- export AWS_ACCESS_KEY_ID=$(echo "$iam_creds" | grep AccessKeyId | tr -d '" ,' | cut -d ':' -f2)
- export AWS_SECRET_ACCESS_KEY=$(echo "$iam_creds" | grep SecretAccessKey | tr -d '" ,' | cut -d ':' -f2)
- export AWS_SESSION_TOKEN=$(echo "$iam_creds" | grep SessionToken | tr -d '" ,' | cut -d ':' -f2)
- echo -e "\n"
- echo "First scale up to 2 machines in $AUTOSCALING_GROUP_NAME ..."
- aws autoscaling update-auto-scaling-group --desired-capacity 2 --auto-scaling-group-name "$AUTOSCALING_GROUP_NAME" --region $AWS_REGION
- echo "... Then wait some seconds ..."
- sleep 30
- echo "... And now scale down again ..."
- aws autoscaling update-auto-scaling-group --desired-capacity 1 --auto-scaling-group-name "$AUTOSCALING_GROUP_NAME" --region $AWS_REGION
- echo "... Done! Now it can take some minutes for EC2 to fully start and stop the desired machines."
when:
ref: [ refs/heads/master, refs/heads/release/*, refs/tags/*-rc* ]
event: [push, tag]
matrix:
PHP_VERSION: php7.2
infrastructure:terraform:staging_neo:
group: infrastructure_terraform
image: jmccann/drone-terraform
plan: false
root_dir: etc/infrastructure/terraform
targets:
- module.application_cluster.aws_launch_configuration.application_cluster_appserver_launch_configuration
- module.application_cluster.aws_autoscaling_group.application_cluster_appserver_auto_scaling_group
init_options:
backend-config:
- "role_arn=arn:aws:iam::186561619776:role/TerraformRole"
- "bucket=sd-infrastructure-up-and-running-state-186561619776"
- "key=staging_neo/terraform.tfstate"
- "dynamodb_table=outfitter_infrastructure"
var_files:
- staging.neo.tfvars
vars:
solutiondrive_internal_role_arn: "arn:aws:iam::186561619776:role/TerraformRole"
appserver_image_name: "morpheus-appserver-${DRONE_BUILD_NUMBER}-${DRONE_COMMIT_BRANCH}"
appserver_image_use_most_recent: "false"
when:
ref: [
"refs/tags/v[0-9].[0-9].[0-9]",
"refs/tags/v[0-9].[0-9].[0-9][0-9]",
"refs/tags/v[0-9].[0-9][0-9].[0-9]",
"refs/tags/v[0-9][0-9].[0-9].[0-9]",
"refs/tags/v[0-9].[0-9][0-9].[0-9][0-9]",
"refs/tags/v[0-9][0-9].[0-9].[0-9][0-9]",
"refs/tags/v[0-9][0-9].[0-9][0-9].[0-9]",
"refs/tags/v[0-9][0-9].[0-9][0-9].[0-9][0-9]"
]
event: [push, tag]
matrix:
PHP_VERSION: php7.2
infrastructure:ec2:rescale:staging_neo:
group: infrastructure_rescale
image: solutiondrive/docker-aws-packer-ansible
environment:
USER: ci
AUTOSCALING_GROUP_NAME: "neo-stag-asg"
AWS_REGION: "eu-central-1"
PLUGIN_AWS_ACCOUNT_ID: "186561619776"
PLUGIN_AWS_ROLE: "AutoscalingRole"
commands:
- echo "Acquire session token..."
- iam_creds=$(aws sts assume-role --role-arn "arn:aws:iam::$PLUGIN_AWS_ACCOUNT_ID:role/$PLUGIN_AWS_ROLE" --role-session-name "docker-$DRONE_COMMIT_SHA-$DRONE_BUILD_NUMBER" --region $AWS_REGION | python -m json.tool)
- export AWS_ACCESS_KEY_ID=$(echo "$iam_creds" | grep AccessKeyId | tr -d '" ,' | cut -d ':' -f2)
- export AWS_SECRET_ACCESS_KEY=$(echo "$iam_creds" | grep SecretAccessKey | tr -d '" ,' | cut -d ':' -f2)
- export AWS_SESSION_TOKEN=$(echo "$iam_creds" | grep SessionToken | tr -d '" ,' | cut -d ':' -f2)
- echo -e "\n"
- echo "First scale up to 2 machines in $AUTOSCALING_GROUP_NAME ..."
- aws autoscaling update-auto-scaling-group --desired-capacity 2 --auto-scaling-group-name "$AUTOSCALING_GROUP_NAME" --region $AWS_REGION
- echo "... Then wait some seconds ..."
- sleep 30
- echo "... And now scale down again ..."
- aws autoscaling update-auto-scaling-group --desired-capacity 1 --auto-scaling-group-name "$AUTOSCALING_GROUP_NAME" --region $AWS_REGION
- echo "... Done! Now it can take some minutes for EC2 to fully start and stop the desired machines."
when:
ref: [
"refs/tags/v[0-9].[0-9].[0-9]",
"refs/tags/v[0-9].[0-9].[0-9][0-9]",
"refs/tags/v[0-9].[0-9][0-9].[0-9]",
"refs/tags/v[0-9][0-9].[0-9].[0-9]",
"refs/tags/v[0-9].[0-9][0-9].[0-9][0-9]",
"refs/tags/v[0-9][0-9].[0-9].[0-9][0-9]",
"refs/tags/v[0-9][0-9].[0-9][0-9].[0-9]",
"refs/tags/v[0-9][0-9].[0-9][0-9].[0-9][0-9]"
]
event: [push, tag]
matrix:
PHP_VERSION: php7.2
infrastructure:terraform:staging_trinity:
group: infrastructure_terraform
image: jmccann/drone-terraform
plan: false
root_dir: etc/infrastructure/terraform
targets:
- module.application_cluster.aws_launch_configuration.application_cluster_appserver_launch_configuration
- module.application_cluster.aws_autoscaling_group.application_cluster_appserver_auto_scaling_group
init_options:
backend-config:
- "role_arn=arn:aws:iam::186561619776:role/TerraformRole"
- "bucket=sd-infrastructure-up-and-running-state-186561619776"
- "key=staging_trinity/terraform.tfstate"
- "dynamodb_table=outfitter_infrastructure"
var_files:
- staging.trinity.tfvars
vars:
solutiondrive_internal_role_arn: "arn:aws:iam::186561619776:role/TerraformRole"
appserver_image_name: "morpheus-appserver-${DRONE_BUILD_NUMBER}-${DRONE_COMMIT_BRANCH}"
appserver_image_use_most_recent: "false"
when:
ref: [
"refs/tags/v[0-9].[0-9].[0-9]",
"refs/tags/v[0-9].[0-9].[0-9][0-9]",
"refs/tags/v[0-9].[0-9][0-9].[0-9]",
"refs/tags/v[0-9][0-9].[0-9].[0-9]",
"refs/tags/v[0-9].[0-9][0-9].[0-9][0-9]",
"refs/tags/v[0-9][0-9].[0-9].[0-9][0-9]",
"refs/tags/v[0-9][0-9].[0-9][0-9].[0-9]",
"refs/tags/v[0-9][0-9].[0-9][0-9].[0-9][0-9]"
]
event: [push, tag]
matrix:
PHP_VERSION: php7.2
infrastructure:ec2:rescale:staging_trinity:
group: infrastructure_rescale
image: solutiondrive/docker-aws-packer-ansible
environment:
USER: ci
AUTOSCALING_GROUP_NAME: "trinity-stag-asg"
AWS_REGION: "eu-central-1"
PLUGIN_AWS_ACCOUNT_ID: "186561619776"
PLUGIN_AWS_ROLE: "AutoscalingRole"
commands:
- echo "Acquire session token..."
- iam_creds=$(aws sts assume-role --role-arn "arn:aws:iam::$PLUGIN_AWS_ACCOUNT_ID:role/$PLUGIN_AWS_ROLE" --role-session-name "docker-$DRONE_COMMIT_SHA-$DRONE_BUILD_NUMBER" --region $AWS_REGION | python -m json.tool)
- export AWS_ACCESS_KEY_ID=$(echo "$iam_creds" | grep AccessKeyId | tr -d '" ,' | cut -d ':' -f2)
- export AWS_SECRET_ACCESS_KEY=$(echo "$iam_creds" | grep SecretAccessKey | tr -d '" ,' | cut -d ':' -f2)
- export AWS_SESSION_TOKEN=$(echo "$iam_creds" | grep SessionToken | tr -d '" ,' | cut -d ':' -f2)
- echo -e "\n"
- echo "First scale up to 2 machines in $AUTOSCALING_GROUP_NAME ..."
- aws autoscaling update-auto-scaling-group --desired-capacity 2 --auto-scaling-group-name "$AUTOSCALING_GROUP_NAME" --region $AWS_REGION
- echo "... Then wait some seconds ..."
- sleep 30
- echo "... And now scale down again ..."
- aws autoscaling update-auto-scaling-group --desired-capacity 1 --auto-scaling-group-name "$AUTOSCALING_GROUP_NAME" --region $AWS_REGION
- echo "... Done! Now it can take some minutes for EC2 to fully start and stop the desired machines."
when:
ref: [
"refs/tags/v[0-9].[0-9].[0-9]",
"refs/tags/v[0-9].[0-9].[0-9][0-9]",
"refs/tags/v[0-9].[0-9][0-9].[0-9]",
"refs/tags/v[0-9][0-9].[0-9].[0-9]",
"refs/tags/v[0-9].[0-9][0-9].[0-9][0-9]",
"refs/tags/v[0-9][0-9].[0-9].[0-9][0-9]",
"refs/tags/v[0-9][0-9].[0-9][0-9].[0-9]",
"refs/tags/v[0-9][0-9].[0-9][0-9].[0-9][0-9]"
]
event: [push, tag]
matrix:
PHP_VERSION: php7.2
publish:s3:errors:
image: plugins/s3
bucket: application-configs-385280725562
acl: private
region: eu-central-1
source: etc/build/*
target: /build/morpheus/failures
when:
event: push
status: [failure]
notify:mail:
image: docker.solutiondrive.de/drone/plugin-email
from: ci@solutiondrive.de
host: sslout.df.eu
when:
event: push
status: [changed, failure]
secrets:
- source: ci_email_user
target: plugin_username
- source: ci_email_password
target: plugin_password
services:
database:
# @TODO Check newer version (use 5.7.20 for the moment because newer versions have problems with certificates)
image: mysql:5.7.20
environment:
- MYSQL_DATABASE=projectmorpheus_test
- MYSQL_USER=agent
- MYSQL_PASSWORD=smith
- MYSQL_ROOT_PASSWORD=root
detach: true
chrome:
# @TODO Have a look at https://gitlab.com/DMore/chrome-mink-driver
image: selenium/standalone-chrome
volumes:
- /dev/shm:/dev/shm
matrix:
PHP_VERSION:
- php7.2
Fertiges Image
Fertiges Image
BaseImage
Packer
{
"variables": {
"imagename": "{{env `AMI_IMAGE_NAME`}}",
"DRONE_COMMIT_BRANCH": "{{env `DRONE_COMMIT_BRANCH`}}",
"DRONE_BUILD_NUMBER": "{{env `DRONE_BUILD_NUMBER`}}",
"CI": "{{env `CI`}}"
},
"builders": [
{
"type": "amazon-ebs",
"profile": "packer_internalinfrastructure",
"region": "eu-central-1",
"source_ami_filter": {
"filters": {
"name": "webserver-php7.2-nginx-appserver-image*"
},
"owners": ["385280725562"],
"most_recent": true
},
"iam_instance_profile": "GeneralInstanceProfile",
"instance_type": "t2.micro",
"spot_price": "auto",
"spot_price_auto_product": "Linux/UNIX",
"ssh_username": "ubuntu",
"ami_name": "{{user `imagename`}}",
"ssh_keypair_name": "internalinfrastructure_insecure_packer_key",
"ssh_private_key_file": "insecure_packer_key",
"run_tags": {
"Name": "Packer solutionMonitoring Appserver Image",
"Branch": "{{user `DRONE_COMMIT_BRANCH`}}",
"BuildNumber": "{{user `DRONE_BUILD_NUMBER`}}",
"BuiltByCI": "{{user `CI`}}"
},
"tags": {
"Name": "sponge-appserver-image",
"autocleanup": "true"
},
"ami_description": "image for sponge appserver",
"ami_users": [
"385280725562"
]
}
],
"provisioners": [
{
"type": "shell",
"scripts": [
"./scripts/packer/helper/waitloop-for-unattended-upgrades.sh"
]
},
{
"type": "ansible",
"playbook_file": "ansible/playbook.yml",
"inventory_directory": "ansible/inventory",
"host_alias": "packer.sponge",
"groups": [
"sponge"
],
"ansible_env_vars": [ "ANSIBLE_HOST_KEY_CHECKING=False", "ANSIBLE_SSH_ARGS='-o ForwardAgent=yes -o ControlMaster=auto -o ControlPersist=30m -o IdentitiesOnly=Yes'" ]
},
{
"type": "shell",
"inline": [
"echo 'ebs-ip' && curl -s http://169.254.169.254/latest/meta-data/public-ipv4"
]
},
{
"type": "shell",
"inline": [
"sed -i '/internalinfrastructure_insecure_packer_key/d' ~/.ssh/authorized_keys"
]
}
]
}
Icons by:
Freepik from www.flaticon.com
Wichai.wi from www.flaticon.com
Smashicons from www.flaticon.com
Danke für eure Aufmerksamkeit!