diff --git a/composer.json b/composer.json index deb2414de..2a6b73e5d 100644 --- a/composer.json +++ b/composer.json @@ -12,6 +12,7 @@ "minimum-stability": "dev", "require": {}, "bin": [ - "d" + "d", + "scripts/ansible-galaxy-install.sh" ] } diff --git a/roles/app/defaults/main.yml b/roles/app/defaults/main.yml index 38617cc86..8e96abfb6 100644 --- a/roles/app/defaults/main.yml +++ b/roles/app/defaults/main.yml @@ -38,6 +38,9 @@ devshop_app_git_root: "{{ devshop_host_apps_root }}/apps/{{ inventory_hostname } devshop_app_git_document_root: web devshop_app_git_document_root_path: "{{ devshop_app_git_root }}/{{ devshop_app_git_document_root }}" +# The file to write environment variables to. Make sure to include this file in your app. +devshop_app_env_file_path: "{{ devshop_app_git_root }}/.env" + # Passed to ansible.builtin.git recursive option. # Set to false to stop git from cloning the repo with the "recursive" option. devshop_app_git_recursive: true diff --git a/roles/app/tasks/drupal.post-deploy.yml b/roles/app/tasks/drupal.post-deploy.yml new file mode 100644 index 000000000..6580dd916 --- /dev/null +++ b/roles/app/tasks/drupal.post-deploy.yml @@ -0,0 +1,6 @@ +--- +# +#- name: Login link +# command: +# cmd: "drush uli" +# chdir: "{{ devshop_app_git_root }}" diff --git a/roles/app/tasks/drupal.post-git.yml b/roles/app/tasks/drupal.post-git.yml index 3718c8a48..b2db97ac5 100644 --- a/roles/app/tasks/drupal.post-git.yml +++ b/roles/app/tasks/drupal.post-git.yml @@ -1,4 +1,28 @@ --- +- name: Prepare .env file. + file: + path: "{{ devshop_app_env_file_path }}" + state: touch + +- name: Write service variables to .env file. + blockinfile: + path: "{{ devshop_app_env_file_path }}" + block: | + ## + ## Written by opendevshop/devshop.platform:roles/app/tasks/drupal.post-git.yml + ## + ## + MYSQL_DATABASE="{{ devshop_service_db_name }}" + MYSQL_USER="{{ devshop_service_db_user }}" + MYSQL_PASSWORD="{{ devshop_service_db_password }}" + MYSQL_HOSTNAME="{{ devshop_service_db_host }}" + MYSQL_PORT="{{ devshop_service_db_port }}" + DRUSH_OPTIONS_URI="{{ ansible_host }}" + ## END ansible_managed. + + when: + - devshop_service_db_name | default(false) + # #- name: Make sure settings folder exists # file: diff --git a/roles/app/tasks/drupal.yml b/roles/app/tasks/drupal.yml index a648be2bd..a916a4d9f 100644 --- a/roles/app/tasks/drupal.yml +++ b/roles/app/tasks/drupal.yml @@ -6,7 +6,7 @@ - name: Check if site is already installed. command: - cmd: "drush status --root={{ devshop_app_git_document_root_path }} status bootstrap" + cmd: "drush --root={{ devshop_app_git_document_root_path }} status bootstrap" chdir: "{{ devshop_app_git_document_root_path }}" register: drupal_status_register failed_when: "drupal_status_register.stdout is undefined" diff --git a/roles/app/tasks/git-handler.yml b/roles/app/tasks/git-handler.yml index cf641943e..a6a3a193b 100644 --- a/roles/app/tasks/git-handler.yml +++ b/roles/app/tasks/git-handler.yml @@ -28,6 +28,7 @@ debug: msg: | ================={{ inventory_hostname }}================= + http://{{ ansible_host }} User: {{ devshop_app_user }} Directory: {{ devshop_app_git_root }} Log File: {{ devshop_app_commands_log_file }} diff --git a/roles/app/tasks/main.yml b/roles/app/tasks/main.yml index 9646d917d..5331a6267 100644 --- a/roles/app/tasks/main.yml +++ b/roles/app/tasks/main.yml @@ -76,6 +76,14 @@ - name: Deploy code from Git + # Slow things down. SSH Hosts can throttle you if you clone too fast. + throttle: 1 + + # Retry git checkout. Git servers might block us for cloning so fast. + retries: 10 + delay: 4 + until: "git_results is not failed" + # On idempotent test runs, any changes to the working copy cause failure. # This can happen when build scripts are run. # To allow molecule idempotency to pass, this tag is added. @@ -94,11 +102,11 @@ track_submodules: "{{ devshop_app_git_track_submodules }}" register: git_results -#- name: Run Post-Git Tasks. -# include_role: -# name: "{{ devshop_app_role }}" -# defaults_from: "{{ devshop_app_role_defaults_from }}" -# tasks_from: "{{ devshop_app_type }}.post-git.yml" +- name: Run Post-Git Tasks. + include_role: + name: "{{ devshop_app_role }}" + defaults_from: "{{ devshop_app_role_defaults_from }}" + tasks_from: "{{ devshop_app_type }}.post-git.yml" # Launch Logic: # Task will RUN if: @@ -115,7 +123,7 @@ Launching App Commands for {{ inventory_hostname }}... {{ devshop_app_git_repository }} {{ devshop_app_git_reference }} - + {% if git_results.changed: %} Reason: Git changes detected. {% endif %} @@ -136,3 +144,9 @@ msg: "Command stages were skipped because there were no changes to git. To force the App Commands to run, use the option --extra-vars=force_commands=true" - meta: flush_handlers + +- name: Run Post-Deploy Tasks. + include_role: + name: "{{ devshop_app_role }}" + defaults_from: "{{ devshop_app_role_defaults_from }}" + tasks_from: "{{ devshop_app_type }}.post-deploy.yml" diff --git a/roles/host/vars/Debian.yml b/roles/host/vars/Debian.yml index ca8146b4d..0064c179d 100644 --- a/roles/host/vars/Debian.yml +++ b/roles/host/vars/Debian.yml @@ -8,3 +8,4 @@ __devshop_host_common_packages: - curl - unzip - sendmail + - acl diff --git a/roles/service/tasks/db.yml b/roles/service/tasks/db.yml index aa1bacc60..d6ab85224 100644 --- a/roles/service/tasks/db.yml +++ b/roles/service/tasks/db.yml @@ -1,11 +1,11 @@ --- -- name: App Hosts Config +- name: "Preparing DevShop App Service: db" when: - '"apps" in group_names' - 'devshop_app_server_db is defined' - - '"devshop_app_server_db" in hostvars' + - 'devshop_app_server_db in hostvars' - '"ansible_fqdn" in hostvars[devshop_app_server_db]' block: @@ -53,13 +53,13 @@ - '"db" in group_names' block: - - name: "Preparing DevShop Service: db" + - name: "Preparing DevShop Host Service: db" debug: msg: | - Current Host: {{ inventory_hostname }} + ansible_hostname: {{ ansible_hostname }} + inventory_hostname: {{ inventory_hostname }} mysql_user_home: {{ mysql_user_home }} - - name: "Prepare Databases." with_items: "{{ groups['apps'] }}" when: diff --git a/roles/service/tasks/http.yml b/roles/service/tasks/http.yml index 866e8fda0..cb6ca9e56 100644 --- a/roles/service/tasks/http.yml +++ b/roles/service/tasks/http.yml @@ -6,7 +6,7 @@ - '"http" in group_names' block: - - name: "Preparing DevShop Service: http" + - name: "Preparing DevShop Host Service: http" debug: msg: | Current Host: {{ inventory_hostname }} @@ -14,25 +14,29 @@ - name: "All app hosts that use this server:" debug: msg: | - {{ hostvars[item] }} + inventory_hostname: {{ item }} + ansible_host: {{ hostvars[item]['ansible_host'] }} + HTTP Server: {{ hostvars[item]['devshop_app_server_http'] }} with_items: "{{ groups['apps'] }}" when: - - '"devshop_app_server_http" in hostvars[item]' - - hostvars[item]['devshop_app_server_http'] == inventory_hostname + - 'item in hostvars' + - '"devshop_app_server_http" in hostvars[item]' + - 'hostvars[item]["devshop_app_server_http"] == inventory_hostname' # @TODO: Move lookup of apps using this server to server_vars.py - name: "Prepare Apache VHosts." with_items: "{{ groups['apps'] }}" when: + - 'item in hostvars' - '"devshop_app_server_http" in hostvars[item]' - - hostvars[item]['devshop_app_server_http'] == inventory_hostname + - 'hostvars[item]["devshop_app_server_http"] == inventory_hostname' register: apache_vhost_register set_fact: devshop_app_apache_vhost: # See https://github.com/geerlingguy/ansible-role-apache - servername: "{{ item }}" + servername: "{{ hostvars[item]['ansible_host'] }}" # NOTE: hostvars are from inventory. They do NOT include app role defaults. documentroot: "{{ hostvars[item]['devshop_app_git_root'] }}/{{ hostvars[item]['devshop_app_git_document_root'] | default(devshop_app_git_document_root) }}" @@ -50,8 +54,9 @@ - name: "Prepare Certbot Variables" with_items: "{{ groups['apps'] }}" when: + - 'item in hostvars' - '"devshop_app_server_http" in hostvars[item]' - - hostvars[item]['devshop_app_server_http'] == inventory_hostname + - 'hostvars[item]["devshop_app_server_http"] == inventory_hostname' register: certbot_certs_register set_fact: @@ -84,14 +89,14 @@ # @TODO: Figure out why we can't move these to inventory/defaults vars files. # Generating certs during server playbook run isn't great. Too many and LE will lock you out. certbot_create_if_missing: yes - + certbot_create_standalone_stop_services: [] certbot_auto_renew_user: "{{ devshop_platform_user }}" certbot_auto_renew_hour: "3" certbot_auto_renew_minute: "30" certbot_create_method: "webroot" - # @TODO: replace with php fpm role. + # @TODO: replace with php fpm role. - name: "Set Facts for Debian hosts." set_fact: php_packages_extra: diff --git a/roles/services/defaults/main.yml b/roles/services/defaults/main.yml index f368cdd30..f3b8843cb 100644 --- a/roles/services/defaults/main.yml +++ b/roles/services/defaults/main.yml @@ -2,10 +2,7 @@ devshop_host_users: - platform - control - - jonpugh -devshop_host_admins: - - jonpugh +devshop_host_admins: [] -devshop_host_github_users: - - jonpugh +devshop_host_github_users: "{{ devshop_host_admins }}" diff --git a/scripts/devshop-ansible-playbook.sh b/scripts/devshop-ansible-playbook.sh index 60b8a7212..b1cbc4d89 100755 --- a/scripts/devshop-ansible-playbook.sh +++ b/scripts/devshop-ansible-playbook.sh @@ -1,12 +1,15 @@ #!/usr/bin/env bash set -e +if [[ -z "$COMPOSER_RUNTIME_BIN_DIR" ]]; then + BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +else + BIN_DIR="$COMPOSER_RUNTIME_BIN_DIR" +fi -SCRIPT_FOLDER_PATH="$( cd "$(dirname "$0")" ; pwd -P )" - -#TODO: Look for /vendor and set dynamically. -PLATFORM_FOLDER_PATH="$(cd "$(dirname $(dirname $(dirname "$SCRIPT_FOLDER_PATH")))" && pwd)" +PLATFORM_FOLDER_PATH="$( cd "$(dirname "$0")" ; pwd -P )" +PROJECT_FOLDER_PATH=$(dirname $BIN_DIR) -ANSIBLE_PLAYBOOK=${ANSIBLE_PLAYBOOK:-"playbook.yml"} +ANSIBLE_PLAYBOOK=${ANSIBLE_PLAYBOOK:-"${PLATFORM_FOLDER_PATH}/playbook.yml"} ANSIBLE_TAGS=${ANSIBLE_TAGS:-""} ANSIBLE_SKIP_TAGS=${ANSIBLE_SKIP_TAGS:-""} ANSIBLE_EXTRA_VARS=${ANSIBLE_EXTRA_VARS:-""} @@ -14,8 +17,8 @@ ANSIBLE_PLAYBOOK_COMMAND_OPTIONS=${ANSIBLE_PLAYBOOK_COMMAND_OPTIONS:-""} ANSIBLE_VERBOSITY=${ANSIBLE_VERBOSITY:-"0"} # If the including repo has an inventory.yml file at the root, load it. -if [[ -f "$PLATFORM_FOLDER_PATH/inventory.yml" ]]; then - ANSIBLE_PLAYBOOK_COMMAND_OPTIONS="$ANSIBLE_PLAYBOOK_COMMAND_OPTIONS --inventory=$PLATFORM_FOLDER_PATH/inventory.yml" +if [[ -f "$PROJECT_FOLDER_PATH/inventory.yml" ]]; then + ANSIBLE_PLAYBOOK_COMMAND_OPTIONS="$ANSIBLE_PLAYBOOK_COMMAND_OPTIONS --inventory=$PROJECT_FOLDER_PATH/inventory.yml" fi # Build options string if ENV vars exist. @@ -30,20 +33,26 @@ if [[ -n "${ANSIBLE_EXTRA_VARS}" ]]; then fi -ANSIBLE_PLAYBOOK_COMMAND_OPTIONS="$ANSIBLE_PLAYBOOK_COMMAND_OPTIONS --inventory=$SCRIPT_FOLDER_PATH/services" +ANSIBLE_PLAYBOOK_COMMAND_OPTIONS="$ANSIBLE_PLAYBOOK_COMMAND_OPTIONS --inventory=$PLATFORM_FOLDER_PATH/services" ON_FAIL=${ON_FAIL:-"systemctl status --no-pager"} # TODO: Goat Scripts LINE="------------------------" echo $LINE echo "Welcome to the Platform." +echo "Current Dir: ${pwd}" +# Detect dependencies +if [[ ! `command -v ansible` ]]; then + echo "This script requires ansible. Install it and try again." + exit 1 +fi if [ -n "$DEBUG" ]; then echo $LINE echo "devshop-ansible-playbook.sh Environment Vars:" echo - echo "SCRIPT_FOLDER_PATH: $SCRIPT_FOLDER_PATH" echo "PLATFORM_FOLDER_PATH: $PLATFORM_FOLDER_PATH" + echo "PROJECT_FOLDER_PATH: $PROJECT_FOLDER_PATH" echo "PWD: $PWD" echo "ANSIBLE_PLAYBOOK: $ANSIBLE_PLAYBOOK" echo "ANSIBLE_TAGS: $ANSIBLE_TAGS" @@ -66,16 +75,16 @@ echo $LINE # @TODO: detect missing roles using ansible instead. This is tricky due to paths & ansible config. We don't want this to run unless called. ## Detect missing roles and install. -#if [ ! -d ${PLATFORM_FOLDER_PATH}/roles/contrib ]; then -# echo "No ansible roles found at ${PLATFORM_FOLDER_PATH}/roles/contrib." +#if [ ! -d ${PROJECT_FOLDER_PATH}/roles/contrib ]; then +# echo "No ansible roles found at ${PROJECT_FOLDER_PATH}/roles/contrib." # echo "Running ./scripts/ansible-galaxy-install.sh..." -# cd ${PLATFORM_FOLDER_PATH} +# cd ${PROJECT_FOLDER_PATH} # ./scripts/ansible-galaxy-install.sh # cd - #fi -cd $SCRIPT_FOLDER_PATH -echo "Changed director to $SCRIPT_FOLDER_PATH" +cd $PROJECT_FOLDER_PATH +echo "Changed directory to $PROJECT_FOLDER_PATH" echo "Running Ansible Playbook --list-hosts Command: " echo "> $ANSIBLE_PLAYBOOK_INVENTORY_COMMAND" $ANSIBLE_PLAYBOOK_INVENTORY_COMMAND diff --git a/services/drupal.yml b/services/drupal.yml index d56c5a74b..2eb41793c 100644 --- a/services/drupal.yml +++ b/services/drupal.yml @@ -26,8 +26,6 @@ apps: devshop_app_command_install: > drush site-install {{ drupal_install_profile | default('standard') }} -y - --root={{ devshop_app_git_document_root_path }} - --db-url={{ devshop_service_db_backend | default('mysql') }}://{{ devshop_service_db_user | default('drupal') }}:{{ devshop_service_db_password | default('drupal') }}@{{ devshop_service_db_host | default('localhost') }}/{{ devshop_service_db_name | default('drupal') }} {{ drupal_site_install_extra_args | join(" ") }} # The new "drush deploy" command includes all of these steps. @@ -36,7 +34,6 @@ apps: drush cache:rebuild drush config:import --preview -y drush cache:rebuild - drush deploy:hook devshop_app_command_test: | drush status