Skip to content

Commit

Permalink
Deployment pipeline.
Browse files Browse the repository at this point in the history
  • Loading branch information
casey-rapnicki-bixal committed Nov 1, 2024
1 parent f62dc5d commit a3b60da
Show file tree
Hide file tree
Showing 141 changed files with 8,148 additions and 0 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/build-and-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Build and deploy

on:
push:
branches:
- develop
- main
- feature/dg-98-build-and-configure-pipeline

permissions:
contents: read
packages: write

jobs:
deploy-infra:
uses: ./.github/workflows/terraform-deploy-infra.yml
secrets: inherit
deploy-app:
uses: ./.github/workflows/cloudgov-deploy-app.yml
secrets: inherit
61 changes: 61 additions & 0 deletions .github/workflows/cloudgov-deploy-app.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Deploy App

on:
workflow_call:

jobs:
updateInfrastructure:
name: Update Infrastructure
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set enviornment
run: |
BRANCH=develop
#BRANCH=$(echo $GITHUB_REF | cut -d'/' -f 3)
COMPOSER_NO_DEV=0
case ${BRANCH} in
develop)
CF_SPACE="dev"
DRUPAL_MEMORY=${{ vars.DEVELOP_CMS_MEMORY }}
DRUPAL_INSTANCES=${{ vars.DEVELOP_INSTANCES }}
;;
main)
CF_SPACE="prod"
COMPOSER_NO_DEV=1
DRUPAL_MEMORY=${{ vars.MAIN_CMS_MEMORY }}
DRUPAL_INSTANCES=${{ vars.MAIN_INSTANCES }}
;;
esac
echo "APP_NAME=drupal" | tee -a $GITHUB_ENV
echo "BRANCH=${BRANCH}" | tee -a $GITHUB_ENV
echo "BUILDPACK_PORT=${{ vars.BUILDPACK_PORT }}" | tee -a $GITHUB_ENV
echo "CF_SPACE=${CF_SPACE}" | tee -a $GITHUB_ENV
echo "COMPOSER_NO_DEV=${COMPOSER_NO_DEV}" | tee -a $GITHUB_ENV
echo "DRUPAL_INSTANCES=${DRUPAL_INSTANCES}" | tee -a $GITHUB_ENV
echo "DRUPAL_MEMORY=${DRUPAL_MEMORY}" | tee -a $GITHUB_ENV
echo "WAF_NAME=waf"| tee -a $GITHUB_ENV
- name: Set repo name
run: echo "REPO_NAME=${{ github.event.repository.name }}" >> $GITHUB_ENV
- name: Install basic dependancies
run: ./scripts/pipeline/deb-basic-deps.sh
- name: Install Cloudfoundry CLI
run: ./scripts/pipeline/deb-cf-install.sh
- name: Cloud.gov login
env:
CF_USER: "${{ secrets.CF_USER }}"
CF_PASSWORD: "${{ secrets.CF_PASSWORD }}"
CF_ORG: "${{ secrets.CF_ORG }}"
PROJECT: "${{ secrets.PROJECT }}"
TF_BASTION: "${{ secrets.TF_BASTION }}"
TF_BACKEND_SPACE: "${{ secrets.TF_BACKEND_SPACE }}"
run: |
source ./scripts/pipeline/cloud-gov-login.sh
cf target -s "${TF_BACKEND_SPACE}" >/dev/null 2>&1
- name: Build theme
run: ./orch/build_node.sh
- name: Deploy App
env:
PROJECT:
133 changes: 133 additions & 0 deletions .github/workflows/terraform-deploy-infra.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
name: Update Infrastructure

on:
workflow_call:

jobs:
updateInfrastructure:
name: Update Infrastructure
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set env.BRANCH
run: |
BRANCH=develop
#BRANCH=$(echo $GITHUB_REF | cut -d'/' -f 3)
case ${BRANCH} in
develop)
CF_SPACE="dev"
;;
main)
CF_SPACE="prod"
;;
esac
echo "BRANCH=${BRANCH}" >> $GITHUB_ENV
echo "CF_SPACE=${CF_SPACE}" >> $GITHUB_ENV
- name: Set repo name
run: echo "REPO_NAME=${{ github.event.repository.name }}" >> $GITHUB_ENV
- name: Install basic dependancies
run: ./scripts/pipeline/deb-basic-deps.sh
- name: Install Cloudfoundry CLI
run: ./scripts/pipeline/deb-cf-install.sh
- name: Cloud.gov login
env:
CF_USER: "${{ secrets.CF_USER }}"
CF_PASSWORD: "${{ secrets.CF_PASSWORD }}"
CF_ORG: "${{ secrets.CF_ORG }}"
PROJECT: "${{ secrets.PROJECT }}"
TF_BASTION: "${{ secrets.TF_BASTION }}"
TF_BACKEND_SPACE: "${{ secrets.TF_BACKEND_SPACE }}"
run: |
source ./scripts/pipeline/cloud-gov-login.sh
cf target -s "${TF_BACKEND_SPACE}" >/dev/null 2>&1
- name: Start Bastion
env:
TF_BASTION: "${{ secrets.TF_BASTION }}"
run: |
cf start "${TF_BASTION}" >/dev/null 2>&1
./scripts/pipeline/cloud-gov-wait-for-app-start.sh "${TF_BASTION}"
- name: Cloud.gov bastion git checkout
env:
TF_BASTION: "${{ secrets.TF_BASTION }}"
run: |
#declare -a commands=("rm -rf ${REPO_NAME}" "git clone https://github.com/${GITHUB_REPOSITORY_OWNER}/${REPO_NAME}.git" "cd ${REPO_NAME}" "git checkout ${BRANCH}")
declare -a commands=("rm -rf ${REPO_NAME}" "git clone -b "feature/dg-98-build-and-configure-pipeline" https://github.com/${GITHUB_REPOSITORY_OWNER}/${REPO_NAME}.git")
for command in "${commands[@]}"; do
./scripts/pipeline/cloud-gov-remote-command.sh "${TF_BASTION}" "${command}" 1
done
- name: Build nginx WAF Plugin
env:
ubuntu_version: "${{ vars.UBUNTU_VERSION }}"
modsecurity_nginx_version: "${{ vars.MODSECURITY_NGINX_VERSION }}"
TF_BASTION: "${{ secrets.TF_BASTION }}"
run: |
source ./scripts/pipeline/cloud-gov-waf-version.sh
source ./scripts/pipeline/terraform-build-waf-plugin.sh
- name: Configure Terraform
env:
CF_USER: "${{ secrets.CF_USER }}"
CF_PASSWORD: "${{ secrets.CF_PASSWORD }}"
CF_ORG: "${{ secrets.CF_ORG }}"
PROJECT: "${{ secrets.PROJECT }}"
TF_BASTION: "${{ secrets.TF_BASTION }}"
run: |
CWD=$(pwd)
cd terraform/infra
envsubst < terraform.tfvars.tmpl > terraform.tfvars
${CWD}/scripts/pipeline/cloud-gov-scp-file.sh "${TF_BASTION}" "terraform.tfvars" "${REPO_NAME}/terraform/infra/"
cd "${CWD}"
- name: Terraform Init
env:
TF_BASTION: "${{ secrets.TF_BASTION }}"
id: init
run: |
./scripts/pipeline/cloud-gov-remote-command.sh "${TF_BASTION}" "tofu -chdir=${REPO_NAME}/terraform/infra init" 1
./scripts/pipeline/cloud-gov-remote-command.sh "${TF_BASTION}" "tofu -chdir=${REPO_NAME}/terraform/infra workspace new ${CF_SPACE} || exit 0" 1
- name: Terraform Validate
env:
TF_BASTION: "${{ secrets.TF_BASTION }}"
id: validate
run: |
./scripts/pipeline/cloud-gov-remote-command.sh ${TF_BASTION} "TF_WORKSPACE=${CF_SPACE} tofu -chdir=${REPO_NAME}/terraform/infra validate -no-color" 1
- name: Terraform Plan
env:
TF_BASTION: "${{ secrets.TF_BASTION }}"
id: plan
run: |
./scripts/pipeline/cloud-gov-remote-command.sh "${TF_BASTION}" "TF_WORKSPACE=${CF_SPACE} tofu -chdir=${REPO_NAME}/terraform/infra plan -no-color" 1
- name: Terraform Apply
env:
TF_BASTION: "${{ secrets.TF_BASTION }}"
id: apply
run: |
./scripts/pipeline/cloud-gov-remote-command.sh "${TF_BASTION}" "TF_WORKSPACE=${CF_SPACE} tofu -chdir=${REPO_NAME}/terraform/infra apply -auto-approve" 1
stopBastion:
name: Stop Bastion
runs-on: ubuntu-latest
needs: updateInfrastructure
if: ${{ always() }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set env.BRANCH
run: echo "BRANCH=dev" >> $GITHUB_ENV
- name: Install basic dependancies
run: ./scripts/pipeline/deb-basic-deps.sh
- name: Install Cloudfoundry CLI
run: ./scripts/pipeline/deb-cf-install.sh
- name: Cloud.gov login
env:
CF_USER: "${{ secrets.CF_USER }}"
CF_PASSWORD: "${{ secrets.CF_PASSWORD }}"
CF_ORG: "${{ secrets.CF_ORG }}"
PROJECT: "${{ secrets.PROJECT }}"
TF_BASTION: "${{ secrets.TF_BASTION }}"
TF_BACKEND_SPACE: "${{ secrets.TF_BACKEND_SPACE }}"
run: |
source ./scripts/pipeline/cloud-gov-login.sh
cf target -s "${TF_BACKEND_SPACE}" >/dev/null 2>&1
- name: Stop Bastion
env:
TF_BASTION: "${{ secrets.TF_BASTION }}"
run: cf stop "${TF_BASTION}" >/dev/null 2>&1
62 changes: 62 additions & 0 deletions .phpcs.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?xml version="1.0"?>
<!--
To override this file, copy it to phpcs.xml and then modify.
@see https://github.com/squizlabs/PHP_CodeSniffer/wiki/Annotated-ruleset.xml#the-annotated-sample-file
-->
<ruleset name="mobomo">
<description>PHP_CodeSniffer standards overrides.</description>

<!-- Create .phpcs.xml to override anything in this file
<?xml version="1.0"?>
<ruleset name="devloper">
<description>My Developer overrides.</description>
<rule ref="./.phpcs.xml.dist"/>
</ruleset>
-->
<!-- By default, warnings and errors cause an exception. -->
<config name="ignore_warnings_on_exit" value="1" />
<config name="ignore_errors_on_exit" value="0" />

<!-- Set ignore extensions. -->
<!-- @see https://www.drupal.org/node/2867601#comment-12075633 -->
<!-- This can probably be removed by setting a dependency on Coder 8.3.7 -->
<arg name="ignore" value="*.css,*.md,*.txt,*.png,*.gif,*.jpeg,*.jpg,*.svg"/>

<!-- Set extensions to scan (taken from Coder 8.3.6). -->
<!-- @see https://git.drupalcode.org/project/coder/blob/8.3.6/coder_sniffer/Drupal/ruleset.xml#L8 -->
<arg name="extensions" value="php,module,inc,install,test,profile,theme,info,yml"/>

<!-- Use colors in output. -->
<arg name="colors"/>
<!-- Show progress. -->
<arg value="p"/>

<rule ref="Drupal.Files.LineLength">
<properties>
<property name="lineLimit" value="100"/>
<property name="absoluteLineLimit" value="0"/>
</properties>
</rule>

<!-- Include existing standards. -->
<rule ref="Drupal">
<!-- Ignore specific sniffs. -->
<exclude name="Drupal.Commenting.InlineComment"/>
<exclude name="Drupal.InfoFiles.AutoAddedKeys.Version"/>
<exclude name="Drupal.Commenting"/>
</rule>
<rule ref="DrupalPractice">
<!-- Ignore specific sniffs. -->
</rule>

<!-- Default directories to sniff if no commandline instructions -->
<file>web/modules/custom</file>
<file>web/themes/custom</file>

<exclude-pattern>*/vendor/*</exclude-pattern>
<exclude-pattern>*/node_modules/*</exclude-pattern>
<exclude-pattern>.github/</exclude-pattern>
<exclude-pattern>web/modules/custom/tome</exclude-pattern>
<exclude-pattern>web/modules/custom/samlauth</exclude-pattern>

</ruleset>
39 changes: 39 additions & 0 deletions scripts/bash_exports.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#! /bin/bash

export SECRETS=$(echo $VCAP_SERVICES | jq -r '.["user-provided"][] | select(.name == "secrets") | .credentials')
export SECAUTHSECRETS=$(echo $VCAP_SERVICES | jq -r '.["user-provided"][] | select(.name == "secauthsecrets") | .credentials')

export APP_NAME=$(echo $VCAP_APPLICATION | jq -r '.name')
export APP_ROOT=$(dirname "$0")
export APP_ID=$(echo "$VCAP_APPLICATION" | jq -r '.application_id')

export DB_NAME=$(echo $VCAP_SERVICES | jq -r '.["aws-rds"][] | .credentials.db_name')
export DB_USER=$(echo $VCAP_SERVICES | jq -r '.["aws-rds"][] | .credentials.username')
export DB_PW=$(echo $VCAP_SERVICES | jq -r '.["aws-rds"][] | .credentials.password')
export DB_HOST=$(echo $VCAP_SERVICES | jq -r '.["aws-rds"][] | .credentials.host')
export DB_PORT=$(echo $VCAP_SERVICES | jq -r '.["aws-rds"][] | .credentials.port')

export ADMIN_EMAIL=$(echo $SECRETS | jq -r '.ADMIN_EMAIL')

export ENV=$(echo "$VCAP_APPLICATION" | jq -r '.space_name' | rev | cut -d- -f1 | rev)

export S3_BUCKET=$(echo "$VCAP_SERVICES" | jq -r '.["s3"][]? | select(.name == "storage") | .credentials.bucket')
export S3_ENDPOINT=$(echo "$VCAP_SERVICES" | jq -r '.["s3"][]? | select(.name == "storage") | .credentials.fips_endpoint')

export SPACE=$(echo $VCAP_APPLICATION | jq -r '.["space_name"]')
export WWW_HOST=${WWW_HOST:-$(echo $VCAP_APPLICATION | jq -r '.["application_uris"][]' | grep 'beta\|www' | tr '\n' ' ')}
export CMS_HOST=${CMS_HOST:-$(echo $VCAP_APPLICATION | jq -r '.["application_uris"][]' | grep cms | tr '\n' ' ')}
if [ -z "$WWW_HOST" ]; then
export WWW_HOST="*.app.cloud.gov"
elif [ -z "$CMS_HOST" ]; then
export CMS_HOST=$(echo $VCAP_APPLICATION | jq -r '.["application_uris"][]' | head -n 1)
fi

export S3_ROOT_WEB=${S3_ROOT_WEB:-/web}
export S3_ROOT_CMS=${S3_ROOT_CMS:-/cms/public}
export S3_HOST=${S3_HOST:-$S3_BUCKET.$S3_ENDPOINT}
export S3_PROXY_WEB=${S3_PROXY_WEB:-$S3_HOST$S3_ROOT_WEB}
export S3_PROXY_CMS=${S3_PROXY_CMS:-$S3_HOST$S3_ROOT_CMS}
export S3_PROXY_PATH_CMS=${S3_PROXY_PATH_CMS:-/s3/files}

export DNS_SERVER=${DNS_SERVER:-$(grep -i '^nameserver' /etc/resolv.conf|head -n1|cut -d ' ' -f2)}
76 changes: 76 additions & 0 deletions scripts/bootstrap.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/bin/bash
set -uo pipefail

## Export proxy servers.
export http_proxy=$(echo ${VCAP_SERVICES} | jq -r '."user-provided"[].credentials.proxy_uri')
export https_proxy=$(echo ${VCAP_SERVICES} | jq -r '."user-provided"[].credentials.proxy_uri')

export home="/home/vcap"
export app_path="${home}/app"
export apt_path="${home}/deps/0/apt"

echo $VCAP_SERVICES | jq -r '."user-provided"[].credentials.ca_certificate' | base64 -d > ${app_path}/ca_certificate.pem
echo $VCAP_SERVICES | jq -r '."user-provided"[].credentials.ca_key' | base64 -d > ${app_path}/ca_key.pem

chmod 600 ${app_path}/ca_certificate.pem
chmod 600 ${app_path}/ca_key.pem

if [ -z "${VCAP_SERVICES:-}" ]; then
echo "VCAP_SERVICES must a be set in the environment: aborting bootstrap";
exit 1;
fi

## NewRelic configuration
export newrelic_apt="${apt_path}/usr/lib/newrelic-php5"
export newrelic_app="${app_path}/newrelic/"

rm -rf ${newrelic_app}/agent
ln -s ${newrelic_apt}/agent ${newrelic_app}/agent

rm -f ${newrelic_app}/daemon/newrelic-daemon.x64
ln -s ${apt_path}/usr/bin/newrelic-daemon ${newrelic_app}/daemon/newrelic-daemon.x64

rm -f ${app_path}/newrelic/scripts/newrelic-iutil.x64
ln -s ${newrelic_apt}/scripts/newrelic-iutil.x64 ${newrelic_app}/scripts/newrelic-iutil.x64

echo 'newrelic.daemon.collector_host=gov-collector.newrelic.com' >> ${app_path}/php/etc/php.ini

source ${app_path}/scripts/bash_exports.sh

if [ ! -f ./container_start_timestamp ]; then
touch ./container_start_timestamp
chmod a+r ./container_start_timestamp
echo "$(date +'%s')" > ./container_start_timestamp
fi

dirs=( "${HOME}/private" "${HOME}/web/sites/default/files" )

for dir in $dirs; do
if [ ! -d $dir ]; then
echo "Creating ${dir} directory ... "
mkdir $dir
chown vcap. $dir
fi
done

## Updated ~/.bashrc to update $PATH when someone logs in.
[ -z $(cat ${home}/.bashrc | grep PATH) ] && \
touch ${home}/.bashrc && \
echo "export http_proxy=${http_proxy}" >> ${home}/.bashrc && \
echo "export https_proxy=${https_proxy}" >> ${home}/.bashrc && \
echo "alias nano=\"${home}/deps/0/apt/bin/nano\"" >> ${home}/.bashrc && \
echo "PATH=$PATH:/home/vcap/app/php/bin:/home/vcap/app/vendor/drush/drush" >> /home/vcap/.bashrc

source ${home}/.bashrc

echo "Installing awscli..."
{
curl -S "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "/tmp/awscliv2.zip"
unzip -qq /tmp/awscliv2.zip -d /tmp/
/tmp/aws/install --bin-dir ${home}/deps/0/bin --install-dir ${home}/deps/0/usr/local/aws-cli
rm -rf /tmp/awscliv2.zip /tmp/aws
} >/dev/null 2>&1

# if [ "${CF_INSTANCE_INDEX:-''}" == "0" ]; then
# ${app_path}/scripts/post-deploy
# fi
Loading

0 comments on commit a3b60da

Please sign in to comment.