Skip to content

Commit

Permalink
Merge pull request #483 from qld-gov-au/develop
Browse files Browse the repository at this point in the history
Develop to master - reduce dependence on OpsWorks
  • Loading branch information
ThrawnCA authored Mar 19, 2024
2 parents 4fee003 + 8bf8131 commit 3a3e99d
Show file tree
Hide file tree
Showing 16 changed files with 304 additions and 85 deletions.
7 changes: 4 additions & 3 deletions .ahoy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,10 @@ commands:
ahoy cli "behave -k ${*:-test/features} --tags=-unauthenticated --tags=-smoke --tags=-OpenData --tags=-Publications" \
|| [ "${ALLOW_BDD_FAIL:-0}" -eq 1 ]
else
# run tests with the specified tag
ahoy cli "behave -k ${*:-test/features} --tags=$BEHAVE_TAG --tags=-OpenData --tags=-Publications" \
|| [ "${ALLOW_BDD_FAIL:-0}" -eq 1 ]
# run shared or app-specific tests with the specific tag
(ahoy cli "behave -k ${*:-test/features} --tags=$BEHAVE_TAG --tags=-OpenData --tags=-Publications" \
&& ahoy cli "behave -k ${*:-test/features} --tags=$BEHAVE_TAG --tags=$VARS_TYPE" \
) || [ "${ALLOW_BDD_FAIL:-0}" -eq 1 ]
fi
ahoy stop-mailmock
ahoy stop-ckan-job-workers
Expand Down
2 changes: 1 addition & 1 deletion .docker/test-OpenData.ini
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ ckan.redis.url = redis://redis:6379

## Plugins Settings
ckan.plugins =
stats resource_proxy text_view webpage_view recline_grid_view image_view recline_view recline_graph_view recline_map_view
stats resource_proxy text_view webpage_view image_view
data_qld data_qld_google_analytics
dcat structured_data
validation
Expand Down
2 changes: 1 addition & 1 deletion .docker/test-Publications.ini
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ ckan.redis.url = redis://redis:6379

## Plugins Settings
ckan.plugins =
stats text_view image_view recline_view
stats text_view image_view
publications_qld_theme
resource_type_validation
qgovext
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
*.pyc
*.retry
templates/chef.json
templates/chef-source.json
templates/cloudfront.cfn.yml
templates/security_groups.cfn.yml
templates/Datashades-OpsWorks-CKAN-Extensions.cfn.yml
templates/Datashades-OpsWorks-CKAN-Instances.cfn.yml
templates/Datashades-OpsWorks-CKAN-Stack.cfn.yml
templates/*.sql
.idea
*.log
Expand Down
34 changes: 18 additions & 16 deletions build-CKAN.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,14 @@ run-shared-resource-playbooks () {
}

run-deployment () {
PARALLEL=1 ./opsworks-deploy.sh update_custom_cookbooks $STACK_NAME
./opsworks-deploy.sh setup $STACK_NAME ${INSTANCE_SHORTNAME}-web & WEB_PID=$!
PARALLEL=1 ./opsworks-deploy.sh setup $STACK_NAME ${INSTANCE_SHORTNAME}-batch & BATCH_PID=$!
run-playbook "chef-json"
./chef-deploy.sh datashades::ckanweb-setup,datashades::ckanweb-deploy $INSTANCE_NAME $ENVIRONMENT web & WEB_PID=$!
PARALLEL=1 ./chef-deploy.sh datashades::ckanbatch-setup,datashades::ckanbatch-deploy,datashades::ckanbatch-configure $INSTANCE_NAME $ENVIRONMENT batch & BATCH_PID=$!
wait $WEB_PID
PARALLEL=1 ./chef-deploy.sh datashades::ckanweb-configure $INSTANCE_NAME $ENVIRONMENT web
wait $BATCH_PID
STOPPED_INSTANCES=$(./opsworks-deploy.sh get_stopped_instances $STACK_NAME ${INSTANCE_SHORTNAME}-solr)
if [ "$STOPPED_INSTANCES" = "" ]; then
./opsworks-deploy.sh execute_recipes $STACK_NAME ${INSTANCE_SHORTNAME}-solr datashades::solr-deploy || exit 1
else
./opsworks-deploy.sh start $STACK_NAME ${INSTANCE_SHORTNAME}-solr
./opsworks-deploy.sh setup $STACK_NAME ${INSTANCE_SHORTNAME}-solr
./opsworks-deploy.sh stop $STACK_NAME ${INSTANCE_SHORTNAME}-solr "$STOPPED_INSTANCES"
fi
PARALLEL=1 ./opsworks-deploy.sh configure $STACK_NAME
./chef-deploy.sh datashades::solr-setup,datashades::solr-deploy $INSTANCE_NAME $ENVIRONMENT solr || exit 1
PARALLEL=1 ./chef-deploy.sh datashades::solr-configure $INSTANCE_NAME $ENVIRONMENT solr
}

run-all-playbooks () {
Expand All @@ -60,7 +54,6 @@ run-all-playbooks () {
fi
run-playbook "CloudFormation" "vars/s3_buckets.var.yml"
run-playbook "CKAN-Stack"
run-playbook "CKAN-extensions"
run-playbook "CloudFormation" "vars/instances-${INSTANCE_NAME}.var.yml"
run-playbook "CloudFormation" "vars/cloudfront-lambda-at-edge.var.yml"
run-playbook "cloudfront"
Expand All @@ -71,10 +64,19 @@ if [ $# -ge 3 ]; then
if [ "$3" = "deploy" ]; then
run-deployment
elif [ "$3" = "setup" ]; then
PARALLEL=1 ./opsworks-deploy.sh setup $STACK_NAME
run-playbook "chef-json"
PARALLEL=1 ./chef-deploy.sh datashades::ckanweb-setup,datashades::ckanweb-deploy,datashades::ckanweb-configure $INSTANCE_NAME $ENVIRONMENT web & WEB_PID=$!
PARALLEL=1 ./chef-deploy.sh datashades::ckanbatch-setup,datashades::ckanbatch-deploy,datashades::ckanbatch-configure $INSTANCE_NAME $ENVIRONMENT batch & BATCH_PID=$!
PARALLEL=1 ./chef-deploy.sh datashades::solr-setup,datashades::solr-deploy,datashades::solr-configure $INSTANCE_NAME $ENVIRONMENT solr
wait $WEB_PID
wait $BATCH_PID
elif [ "$3" = "configure" ]; then
PARALLEL=1 ./opsworks-deploy.sh update_custom_cookbooks $STACK_NAME
PARALLEL=1 ./opsworks-deploy.sh configure $STACK_NAME
run-playbook "chef-json"
PARALLEL=1 ./chef-deploy.sh datashades::ckanweb-configure $INSTANCE_NAME $ENVIRONMENT web & WEB_PID=$!
PARALLEL=1 ./chef-deploy.sh datashades::ckanbatch-configure $INSTANCE_NAME $ENVIRONMENT batch & BATCH_PID=$!
PARALLEL=1 ./chef-deploy.sh datashades::solr-configure $INSTANCE_NAME $ENVIRONMENT solr
wait $WEB_PID
wait $BATCH_PID
else
# run custom playbook
run-playbook "$3" "$4"
Expand Down
104 changes: 104 additions & 0 deletions chef-deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#!/bin/sh

set -e

debug () {
echo "$1" >&2
}

if [ "$#" -lt 3 ]; then
debug "Usage: [PARALLEL=true] $0 <command eg setup> <service eg OpenData> [environment eg DEV] [layer eg web] [recipe name eg datashades::ckanweb-deploy]"
debug "When PARALLEL is true, deployments will run on all servers in the stack/layer simultaneously. This is suitable for low-impact commands like 'configure'."
debug "When PARALLEL is false or not set, deployments will run on each server sequentially. This is slower, but safer, avoiding race conditions and allowing disruptive commands like 'setup' without downtime."
exit 1
fi

COMMAND="$1"
SERVICE="$2"
ENVIRONMENT="$3"
LAYER_NAME="$4"
RUN_LIST="recipe[$(echo $COMMAND | sed 's/,/],recipe[/g')]"

# Retrieve generated custom JSON
CHEF_SOURCE=$(cat templates/chef-source.json | tr -d '\n')
CUSTOM_JSON=$(cat templates/chef.json | tr -d '\n' | sed 's/"/\\"/g')

REGION_SNIPPET="--region ap-southeast-2"
MESSAGE="[$COMMAND on $SERVICE $ENVIRONMENT $LAYER_NAME]"
debug "$MESSAGE: commencing..."

wait_for_deployment () {
DEPLOYMENT_ID=$1
debug "$MESSAGE: waiting for deployment $DEPLOYMENT_ID..."
STATUS=$(aws ssm list-commands $REGION_SNIPPET --command-id $DEPLOYMENT_ID --query "Commands|[0].Status" --output text) || exit 1
for retry in `seq 1 180`; do
if [ "$STATUS" = "Pending" ] || [ "$STATUS" = "InProgress" ]; then
sleep 10
STATUS=$(aws ssm list-commands $REGION_SNIPPET --command-id $DEPLOYMENT_ID --query "Commands|[0].Status" --output text) || exit 1
debug "Deployment $DEPLOYMENT_ID: $STATUS"
else
break
fi
done
if [ "$STATUS" != "Success" ]; then
debug "Failed to deploy $DEPLOYMENT_ID, status $STATUS - aborting"
exit 1
fi
}

find_load_balancer () {
# Finds the first load balancer whose tags all match the deployment,
# and outputs its identifying name
for lb_name in `aws elb describe-load-balancers --query "LoadBalancerDescriptions[].LoadBalancerName" --output text`; do
LB_TAGS=$(aws elb describe-tags --load-balancer-name $lb_name --query "TagDescriptions[].Tags[].{Key: Key, Value: Value}[?Key=='Environment' || Key=='Service' || Key == 'Layer']" --output text)
if (echo $LB_TAGS | grep -E "(\s|^)Environment\s+$ENVIRONMENT(\s|$)" >/dev/null 2>&1) \
&& (echo $LB_TAGS | grep -E "(\s|^)Service\s+$SERVICE(\s|$)" >/dev/null 2>&1) \
&& (echo $LB_TAGS | grep -E "(\s|^)Layer\s+$LAYER_NAME(\s|$)" >/dev/null 2>&1); then
echo "$lb_name"
fi
done
}

deploy () {
for truthy in `echo "y t true T 1" |xargs echo`; do
if [ "$PARALLEL" = "$truthy" ]; then
debug "$MESSAGE: Parallel enabled, will deploy to all target instances simultaneously"
PARALLEL=true
fi
done

INSTANCE_IDENTIFIER_SNIPPET="--filters Name=tag:Environment,Values=$ENVIRONMENT Name=tag:Service,Values=$SERVICE Name=instance-state-name,Values=running"
if [ "$LAYER_NAME" != "" ]; then
INSTANCE_IDENTIFIER_SNIPPET="${INSTANCE_IDENTIFIER_SNIPPET} Name=tag:Layer,Values=$LAYER_NAME"
fi
INSTANCE_IDS=$(aws ec2 describe-instances $REGION_SNIPPET $INSTANCE_IDENTIFIER_SNIPPET --query "Reservations[].Instances[].InstanceId" --output text) || exit 1
if [ "$INSTANCE_IDS" = "" ]; then
debug "No eligible instance(s) in $SERVICE $ENVIRONMENT $LAYER_NAME"
exit 1
else
debug "Target instance(s) in $SERVICE $ENVIRONMENT $LAYER_NAME: $INSTANCE_IDS"
fi
if [ "$PARALLEL" = "true" ]; then
DEPLOYMENT_ID=$(aws ssm send-command --document-name "AWS-ApplyChefRecipes" --document-version "\$DEFAULT" --instance-ids $INSTANCE_IDS --parameters '{'"$CHEF_SOURCE"',"RunList":["'"$RUN_LIST"'"],"JsonAttributesSources":[""],"JsonAttributesContent":["'"$CUSTOM_JSON"'"],"ChefClientVersion":["14"],"ChefClientArguments":[""],"WhyRun":["False"],"ComplianceSeverity":["None"],"ComplianceType":["Custom:Chef"],"ComplianceReportBucket":[""]}' --timeout-seconds 3600 --max-concurrency "50" --max-errors "0" --output-s3-bucket-name "osssio-ckan-web-logs" --output-s3-key-prefix "run_command" --region ap-southeast-2 --query "Command.CommandId" --output text)
wait_for_deployment $DEPLOYMENT_ID || exit 1
else
ELB_NAME=$(find_load_balancer)
for instance in $INSTANCE_IDS; do
if [ "$ELB_NAME" != "" ]; then
OUTPUT=$(aws elb deregister-instances-from-load-balancer --load-balancer-name "$ELB_NAME" --instances "$instance" --query "Instances[].InstanceId" --output text)
debug "Deregistered instance $instance from load balancer $ELB_NAME, resulting registered instances: $OUTPUT"
fi
DEPLOYMENT_ID=$(aws ssm send-command --document-name "AWS-ApplyChefRecipes" --document-version "\$DEFAULT" --instance-ids $instance --parameters '{'"$CHEF_SOURCE"',"RunList":["'"$RUN_LIST"'"],"JsonAttributesSources":[""],"JsonAttributesContent":["'"$CUSTOM_JSON"'"],"ChefClientVersion":["14"],"ChefClientArguments":[""],"WhyRun":["False"],"ComplianceSeverity":["None"],"ComplianceType":["Custom:Chef"],"ComplianceReportBucket":[""]}' --timeout-seconds 3600 --max-concurrency "50" --max-errors "0" --output-s3-bucket-name "osssio-ckan-web-logs" --output-s3-key-prefix "run_command" --region ap-southeast-2 --query "Command.CommandId" --output text)
wait_for_deployment $DEPLOYMENT_ID
DEPLOYMENT_SUCCESS=$?
if [ "$ELB_NAME" != "" ]; then
OUTPUT=$(aws elb register-instances-with-load-balancer --load-balancer-name "$ELB_NAME" --instances "$instance" --query "Instances[].InstanceId" --output text)
debug "Registered instance with load balancer $ELB_NAME, resulting registered instances: $OUTPUT"
fi
if [ "$DEPLOYMENT_SUCCESS" != "0" ]; then exit 1; fi
done
debug "$MESSAGE: success"
fi
}

deploy
64 changes: 64 additions & 0 deletions chef-json.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
- name: Generate Chef custom JSON
hosts: localhost
connection: local
vars_files:
- vars/CKAN-Stack.var.yml
pre_tasks:

- name: get basic_facts
set_fact:
basic_fact={{ item }}
when: item.Environment == Environment
with_items: "{{ basic_facts }}"

- name: set facts to environment from basic_fact
set_fact: "{{ item.key }}={{ item.value }}"
with_dict: "{{ basic_fact }}"
when: basic_fact is defined

- name: Identify cloudformation stack
set_fact:
Stack_Name: "{{ item.name }}"
state: "{{ item.state }}"
template_parameters: "{{ item.template_parameters }}"
when: item.template_parameters.Environment == Environment
with_items: "{{ cloudformation_stacks }}"

- name: Describe cloudformation stack
cloudformation_facts:
region: "{{ region }}"
stack_name: "{{ Stack_Name }}"
stack_resources: true
register: stack

- name: set facts to environment from stack parameters
set_fact: "{{ item.key }}={{ item.value }}"
with_dict: "{{ stack.ansible_facts.cloudformation[Stack_Name].stack_parameters }}"

- name: Identify hosted zone cloudformation stack
set_fact:
Zone_Stack_Name: "CKAN-{{ Environment }}-hosted-zone"

- name: Describe hosted zone cloudformation stack
cloudformation_facts:
region: "{{ region }}"
stack_name: "{{ Zone_Stack_Name }}"
stack_resources: true
register: hosted_zone

- name: set internal TLD from hosted zone
set_fact:
InternalHostedZoneTLD: "{{ hosted_zone.ansible_facts.cloudformation[Zone_Stack_Name].stack_outputs.ZoneTLD }}"

tasks:

- name: Prepare chef source JSON
template:
src: chef-source.json.j2
dest: templates/chef-source.json

- name: Prepare custom JSON
template:
src: chef.json.j2
dest: templates/chef.json
4 changes: 2 additions & 2 deletions library/ec2_vpc_peer_describe.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ def main():
client = boto3_conn(module, conn_type='client', resource='ec2', region=region, endpoint=ec2_url, **aws_connect_kwargs)
except botocore.exceptions.NoCredentialsError as e:
module.fail_json(msg="Can't authorize connection - "+str(e))
except Exception, e:
except Exception as e:
module.fail_json(msg='Failed to connect to VPC: %s' % str(e))

if peer_vpc_id is None:
Expand All @@ -232,4 +232,4 @@ def main():
from ansible.module_utils.basic import *
from ansible.module_utils.ec2 import *

main()
main()
Loading

0 comments on commit 3a3e99d

Please sign in to comment.