Skip to content

Update CICD in AWS

Update CICD in AWS #19

name: production
on:
pull_request:
branches:
- master
push:
branches:
- master
jobs:
build-test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:13.3
env:
POSTGRES_USER: db_user
POSTGRES_PASSWORD: db_password
POSTGRES_DB: db_test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.9"
cache: "pip"
- name: Install Python dependencies
run: python -m pip install -r requirements.txt
- name: Run isort
run: isort --check-only --profile=black .
- name: Run black
run: black --check .
- name: Run flake8
run: flake8 --ignore=E501,W503,F401 .
- name: Unit Tests and Integration Tests
env:
DATABASE_TEST_URL: postgresql://db_user:db_password@localhost/db_test
run: python -m flask tests
create-config-infrastructure:
runs-on: ubuntu-latest
needs:
- build-test
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Declare variables
shell: bash
run: |
echo "SHA_SHORT=$(git rev-parse --short "$GITHUB_SHA")" >> "$GITHUB_ENV"
echo "BRANCH=$(echo ${GITHUB_REF#refs/heads/})" >> "$GITHUB_ENV"
- name: Configure AWS credentials
id: creds
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Deploy to AWS CloudFormation
uses: aws-actions/aws-cloudformation-github-deploy@v1
with:
name: flask-template-prod-${{ env.SHA_SHORT }}
template: ./.github/workflows/cloudformations/server.yml
parameter-overrides: "file:///${{ github.workspace }}/.github/workflows/cloudformations/server-parameters.json"
tags: ${{ vars.TAGS }}
- name: Get Public DNS Server
run: |
# Create file
backend_public_dns=flask-template-prod-${{ env.SHA_SHORT }}-PublicDNS
# Pull the export value
host=$(aws cloudformation list-exports \
--query "Exports[?Name==\`$backend_public_dns\`].Value" \
--no-paginate --output text)
echo $host
# Append the DNS to the inventory file
echo $host >> $(eval echo "./.github/workflows/ansible/hosts")
cat ./.github/workflows/ansible/hosts
- name: Zip artifact files
uses: montudor/action-zip@v1
with:
args: zip -qq -r artifact.zip .
- name: Create files forlder in ansible
run: mkdir -p ./.github/workflows/ansible/roles/deploy/files
- name: Copy file
uses: canastro/copy-file-action@master
with:
source: "artifact.zip"
target: "./.github/workflows/ansible/roles/deploy/files/artifact.zip"
- name: Run playbook
uses: dawidd6/action-ansible-playbook@v2
with:
playbook: deploy_applications.yml
directory: ./.github/workflows/ansible
key: ${{secrets.SSH_PRIVATE_KEY}}
options: |
--inventory ./hosts
- name: Remove stack on fail
if: failure()
run: |
echo flask-template-prod-${{ env.SHA_SHORT }}
# Get stack id for the delete_stack waiter
stack_info=$(aws cloudformation describe-stacks --stack-name flask-template-prod-${{ env.SHA_SHORT }} --query "Stacks[*] | [0].StackId" 2>&1)
if echo $stack_info | grep 'does not exist' > /dev/null
then
echo "Stack does not exist."
echo $stack_info
exit 0
fi
if echo $stack_info | grep 'ValidationError' > /dev/null
then
echo $stack_info
exit 1
else
aws cloudformation delete-stack --stack-name flask-template-prod-${{ env.SHA_SHORT }}
echo $stack_info
aws cloudformation wait stack-delete-complete --stack-name flask-template-prod-${{ env.SHA_SHORT }}
exit 0
fi
clean-up:
runs-on: ubuntu-latest
needs:
- create-config-infrastructure
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Declare some variables
shell: bash
run: |
echo "SHA_SHORT=$(git rev-parse --short "$GITHUB_SHA")" >> "$GITHUB_ENV"
echo "BRANCH=$(echo ${GITHUB_REF#refs/heads/})" >> "$GITHUB_ENV"
- name: Configure AWS credentials
id: creds
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Fetch stacks and save the old stack name
run: |
# Fetch the stack names
export STACKS=(
$(aws cloudformation list-stacks \
--query "StackSummaries[*].StackName" \
--no-paginate --output text \
--stack-status-filter CREATE_COMPLETE UPDATE_COMPLETE
)
)
for stack in "${STACKS[@]}"; do
if [[ ! "$stack" =~ "${{ env.SHA_SHORT }}" ]] && [[ "$stack" =~ "flask-template-prod" ]]; then
echo "DESTROY_STACK=$stack" >> "$GITHUB_ENV"
fi
done
- name: Remove the search engine infrastructure
run: |
# Check if DESTROY_STACK is not set
if [ -z "${{ env.DESTROY_STACK }}" ]; then
echo "DESTROY_STACK is not set"
exit 0
else
echo "DESTROY_STACK is set to ${{ env.DESTROY_STACK }}"
fi
# Get stack id for the delete_stack waiter
stack_info=$(aws cloudformation describe-stacks --stack-name ${{ env.DESTROY_STACK }} --query "Stacks[*] | [0].StackId" 2>&1)
if echo $stack_info | grep 'does not exist' > /dev/null
then
echo "Stack does not exist."
echo $stack_info
exit 0
fi
if echo $stack_info | grep 'ValidationError' > /dev/null
then
echo $stack_info
exit 1
else
aws cloudformation delete-stack --stack-name ${{ env.DESTROY_STACK }}
echo $stack_info
aws cloudformation wait stack-delete-complete --stack-name ${{ env.DESTROY_STACK }}
exit 0
fi