Skip to content

Feature/issue 77 dockerize daily fetch #14

Feature/issue 77 dockerize daily fetch

Feature/issue 77 dockerize daily fetch #14

Workflow file for this run

name: AtomikLabs IAC CI/CD Workflow
on:
pull_request:
branches:
- dev
- stage
- main
paths:
- "infra/**"
push:
branches:
- dev
- stage
- main
paths:
- "infra/**"
env:
AWS_REGION: ${{ secrets.AWS_REGION }}
jobs:
setup-environment:
runs-on: ubuntu-latest
outputs:
env-file: ${{ steps.set-env.outputs.env-file }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Determine environment
id: set-env
run: |
if [ "${{ github.event_name }}" == "pull_request" ]; then
echo "Base branch of the PR: ${{ github.base_ref }}"
BRANCH_NAME="${{ github.base_ref }}"
else
echo "Push to branch: ${GITHUB_REF#refs/heads/}"
BRANCH_NAME="${GITHUB_REF#refs/heads/}"
fi
if [[ $BRANCH_NAME == 'dev' ]]; then
echo "Development environment selected"
echo "env-file=infra/aws/environments/env.dev.json" >> $GITHUB_ENV
elif [[ $BRANCH_NAME == 'stage' ]]; then
echo "Staging environment selected"
echo "env-file=infra/aws/environments/env.stage.json" >> $GITHUB_ENV
elif [[ $BRANCH_NAME == 'main' ]]; then
echo "Production environment selected"
echo "env-file=infra/aws/environments/env.prod.json" >> $GITHUB_ENV
else
echo "No matching environment for branch $BRANCH_NAME"
fi
- name: Echo environment file path
run: |
echo "Environment file path: ${{ env.env-file }}"
if [[ -z "${{ env.env-file }}" ]]; then
echo "Environment file path is empty"
else
echo "Environment file path is set"
fi
- name: Set environment variables from file
if: env.env-file != ''
run: |
jq -r 'to_entries | .[] | "\(.key)=\(.value)"' "${{ env.env-file }}" >> $GITHUB_ENV
lint-and-validate:
needs: setup-environment
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Validate CloudFormation templates
run: |
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: ${{ secrets.AWS_REGION }}
test-deploy:
needs: lint-and-validate
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Determine environment and set variables
run: |
echo "env-file=infra/aws/environments/env.test.json" >> $GITHUB_ENV
- name: Set environment variables from file
run: |
if [ -f ${{ env.env-file }} ]; then
jq -r 'to_entries | .[] | "\(.key)=\(.value)"' "${{ env.env-file }}" >> $GITHUB_ENV
else
echo "${{ env.env-file }} does not exist"
fi
- name: Set AWS Credentials for Test Environment
run: |
echo "AWS_ACCESS_KEY_ID=${{ secrets.TEST_AWS_ACCESS_KEY_ID }}" >> $GITHUB_ENV
echo "AWS_SECRET_ACCESS_KEY=${{ secrets.TEST_AWS_SECRET_ACCESS_KEY }}" >> $GITHUB_ENV
- name: Upload Substack Template to S3
run: |
CONTAINERIZATION_SUBSTACK_TEMPLATE_FILE="infra/aws/templates/containerization-substack.yaml"
echo "Uploading substack template: $CONTAINERIZATION_SUBSTACK_TEMPLATE_FILE"
NETWORKING_SUBSTACK_TEMPLATE_FILE="infra/aws/templates/networking-substack.yaml"
echo "Uploading substack template: $NETWORKING_SUBSTACK_TEMPLATE_FILE"
DATA_LAYER_SUBSTACK_TEMPLATE_FILE="infra/aws/templates/data-layer-substack.yaml"
echo "Uploading substack template: $DATA_LAYER_SUBSTACK_TEMPLATE_FILE"
DATA_INGESTION_SUBSTACK_TEMPLATE_FILE="infra/aws/templates/data-ingestion-substack.yaml"
echo "Uploading substack template: $DATA_INGESTION_SUBSTACK_TEMPLATE_FILE"
DATA_PERSISTENCE_SUBSTACK_TEMPLATE_FILE="infra/aws/templates/data-persistence-substack.yaml"
echo "Uploading substack template: $DATA_PERSISTENCE_SUBSTACK_TEMPLATE_FILE"
aws s3 cp $CONTAINERIZATION_SUBSTACK_TEMPLATE_FILE s3://atomiklabs-iac/cloudformation/test/containerization-substack.yaml
aws s3 cp $NETWORKING_SUBSTACK_TEMPLATE_FILE s3://atomiklabs-iac/cloudformation/test/networking-substack.yaml
aws s3 cp $DATA_LAYER_SUBSTACK_TEMPLATE_FILE s3://atomiklabs-iac/cloudformation/test/data-layer-substack.yaml
aws s3 cp $DATA_INGESTION_SUBSTACK_TEMPLATE_FILE s3://atomiklabs-iac/cloudformation/test/data-ingestion-substack.yaml
aws s3 cp $DATA_PERSISTENCE_SUBSTACK_TEMPLATE_FILE s3://atomiklabs-iac/cloudformation/test/data-persistence-substack.yaml
- name: Deploy to Test Stack
run: |
MAIN_TEMPLATE_FILE="infra/aws/templates/template.yaml"
STACK_NAME="atomiklabs-test-stack-${{ github.run_number }}"
CONTAINERIZATION_SUBSTACK_URL="https://atomiklabs-iac.s3.${{ secrets.AWS_REGION }}.amazonaws.com/cloudformation/test/containerization-substack.yaml"
NETWORKING_SUBSTACK_URL="https://atomiklabs-iac.s3.${{ secrets.AWS_REGION }}.amazonaws.com/cloudformation/test/networking-substack.yaml"
DATA_LAYER_SUBSTACK_URL="https://atomiklabs-iac.s3.${{ secrets.AWS_REGION }}.amazonaws.com/cloudformation/test/data-layer-substack.yaml"
DATA_INGESTION_SUBSTACK_URL="https://atomiklabs-iac.s3.${{ secrets.AWS_REGION }}.amazonaws.com/cloudformation/test/data-ingestion-substack.yaml"
DATA_PERSISTENCE_SUBSTACK_TEMPLATE_URL="https://atomiklabs-iac.s3.${{ secrets.AWS_REGION }}.amazonaws.com/cloudformation/test/data-persistence-substack.yaml"
BASTION_ACCESS_CIDR=${{ secrets.BASTION_ACCESS_CIDR }}
echo "Deploying main template: $MAIN_TEMPLATE_FILE"
echo "Containerization Substack URL: $CONTAINERIZATION_SUBSTACK_URL"
echo "Networking Substack URL: $NETWORKING_SUBSTACK_URL"
echo "Data Layer Substack URL: $DATA_LAYER_SUBSTACK_URL"
echo "Data Ingestion Substack URL: $DATA_INGESTION_SUBSTACK_URL"
echo "Data Persistence Substack URL: $DATA_PERSISTENCE_SUBSTACK_TEMPLATE_URL"
aws cloudformation deploy \
--template-file $MAIN_TEMPLATE_FILE \
--stack-name $STACK_NAME \
--region ${{ secrets.AWS_REGION }} \
--no-fail-on-empty-changeset \
--capabilities CAPABILITY_NAMED_IAM \
--parameter-overrides \
ContainerizationSubstackTemplateURL=$CONTAINERIZATION_SUBSTACK_URL \
NetworkingSubstackTemplateURL=$NETWORKING_SUBSTACK_URL \
DataLayerSubstackTemplateURL=$DATA_LAYER_SUBSTACK_URL \
DataIngestionSubstackTemplateURL=$DATA_INGESTION_SUBSTACK_URL \
DataPersistenceSubstackTemplateURL=$DATA_PERSISTENCE_SUBSTACK_TEMPLATE_URL \
EnvironmentName=test \
VpcCidr=$TEST_VPC_CIDR \
PublicSubnet1Cidr=$TEST_PUBLIC_SUBNET_1_CIDR \
PublicSubnet2Cidr=$TEST_PUBLIC_SUBNET_2_CIDR \
PrivateSubnet1Cidr=$TEST_PRIVATE_SUBNET_1_CIDR \
PrivateSubnet2Cidr=$TEST_PRIVATE_SUBNET_2_CIDR \
BastionAccessCidr=$BASTION_ACCESS_CIDR
- name: Capture Events on Failure
if: failure()
run: |
STACK_NAME="atomiklabs-test-stack-${{ github.run_number }}"
echo "Fetching stack events for $STACK_NAME"
aws cloudformation describe-stack-events --stack-name $STACK_NAME
- name: Confirm Stack Creation
run: |
STACK_NAME="atomiklabs-test-stack-${{ github.run_number }}"
aws cloudformation describe-stacks --stack-name $STACK_NAME
echo "Stack $STACK_NAME has been confirmed to exist."
- name: Delete Test Stack
if: always()
run: |
STACK_NAME="atomiklabs-test-stack-${{ github.run_number }}"
echo "Deleting stack: $STACK_NAME"
aws cloudformation delete-stack --stack-name $STACK_NAME
echo "Waiting for the stack to be deleted..."
aws cloudformation wait stack-delete-complete --stack-name $STACK_NAME
if ! aws cloudformation describe-stacks --stack-name $STACK_NAME; then
echo "Stack $STACK_NAME has been deleted successfully."
else
echo "Stack $STACK_NAME deletion failed."
fi
deploy:
needs: [setup-environment, lint-and-validate]
if: github.event_name == 'push' && (contains(github.ref, 'refs/heads/dev') || contains(github.ref, 'refs/heads/stage') || contains(github.ref, 'refs/heads/main'))
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set AWS Credentials and Parameter File
run: |
if [[ $GITHUB_REF == 'refs/heads/dev' ]]; then
echo "AWS_ACCESS_KEY_ID=${{ secrets.DEV_AWS_ACCESS_KEY_ID }}" >> $GITHUB_ENV
echo "AWS_SECRET_ACCESS_KEY=${{ secrets.DEV_AWS_SECRET_ACCESS_KEY }}" >> $GITHUB_ENV
elif [[ $GITHUB_REF == 'refs/heads/stage' ]]; then
echo "AWS_ACCESS_KEY_ID=${{ secrets.STAGE_AWS_ACCESS_KEY_ID }}" >> $GITHUB_ENV
echo "AWS_SECRET_ACCESS_KEY=${{ secrets.STAGE_AWS_SECRET_ACCESS_KEY }}" >> $GITHUB_ENV
elif [[ $GITHUB_REF == 'refs/heads/main' ]]; then
echo "AWS_ACCESS_KEY_ID=${{ secrets.PROD_AWS_ACCESS_KEY_ID }}" >> $GITHUB_ENV
echo "AWS_SECRET_ACCESS_KEY=${{ secrets.PROD_AWS_SECRET_ACCESS_KEY }}" >> $GITHUB_ENV
fi
- name: Determine environment
run: |
if [ "${{ github.event_name }}" == "pull_request" ]; then
echo "Base branch of the PR: ${{ github.base_ref }}"
BRANCH_NAME="${{ github.base_ref }}"
else
echo "Push to branch: ${GITHUB_REF#refs/heads/}"
BRANCH_NAME="${GITHUB_REF#refs/heads/}"
fi
if [[ $BRANCH_NAME == 'dev' ]]; then
echo "Development environment selected"
echo "env-file=infra/aws/environments/env.dev.json" >> $GITHUB_ENV
elif [[ $BRANCH_NAME == 'stage' ]]; then
echo "Staging environment selected"
echo "env-file=infra/aws/environments/env.stage.json" >> $GITHUB_ENV
elif [[ $BRANCH_NAME == 'main' ]]; then
echo "Production environment selected"
echo "env-file=infra/aws/environments/env.prod.json" >> $GITHUB_ENV
else
echo "No matching environment for branch $BRANCH_NAME"
fi
- name: Echo environment file path
run: |
echo "Environment file path: ${{ env.env-file }}"
if [[ -z "${{ env.env-file }}" ]]; then
echo "Environment file path is empty"
else
echo "Environment file path is set"
fi
- name: Set environment variables from file
if: env.env-file != ''
run: |
jq -r 'to_entries | .[] | "\(.key)=\(.value)"' "${{ env.env-file }}" >> $GITHUB_ENV
- name: Upload Template to S3
run: |
aws s3 cp infra/aws/templates/containerization-substack.yaml s3://atomiklabs-iac/cloudformation/$ENVIRONMENT_NAME/containerization-substack.yaml
aws s3 cp infra/aws/templates/networking-substack.yaml s3://atomiklabs-iac/cloudformation/$ENVIRONMENT_NAME/networking-substack.yaml
aws s3 cp infra/aws/templates/data-layer-substack.yaml s3://atomiklabs-iac/cloudformation/$ENVIRONMENT_NAME/data-layer-substack.yaml
aws s3 cp infra/aws/templates/data-ingestion-substack.yaml s3://atomiklabs-iac/cloudformation/$ENVIRONMENT_NAME/data-ingestion-substack.yaml
aws s3 cp infra/aws/templates/data-persistence-substack.yaml s3://atomiklabs-iac/cloudformation/$ENVIRONMENT_NAME/data-persistence-substack.yaml
- name: Deploy CloudFormation stack
run: |
TEMPLATE_FILE="infra/aws/templates/template.yaml"
STACK_NAME="atomiklabs-${ENVIRONMENT_NAME}-stack"
CONTAINERIZATION_SUBSTACK_URL="https://atomiklabs-iac.s3.${{ secrets.AWS_REGION }}.amazonaws.com/cloudformation/${ENVIRONMENT_NAME}/containerization-substack.yaml"
NETWORKING_SUBSTACK_URL="https://atomiklabs-iac.s3.${{ secrets.AWS_REGION }}.amazonaws.com/cloudformation/${ENVIRONMENT_NAME}/networking-substack.yaml"
DATA_LAYER_SUBSTACK_URL="https://atomiklabs-iac.s3.${{ secrets.AWS_REGION }}.amazonaws.com/cloudformation/${ENVIRONMENT_NAME}/data-layer-substack.yaml"
DATA_INGESTION_SUBSTACK_URL="https://atomiklabs-iac.s3.${{ secrets.AWS_REGION }}.amazonaws.com/cloudformation/${ENVIRONMENT_NAME}/data-ingestion-substack.yaml"
DATA_PERSISTENCE_SUBSTACK_TEMPLATE_URL="https://atomiklabs-iac.s3.${{ secrets.AWS_REGION }}.amazonaws.com/cloudformation/${ENVIRONMENT_NAME}/data-persistence-substack.yaml"
BASTION_ACCESS_CIDR=${{ secrets.BASTION_ACCESS_CIDR }}
echo "Deploying template: $TEMPLATE_FILE"
echo "Containerization Substack URL: $CONTAINERIZATION_SUBSTACK_URL"
echo "Networking Substack URL: $NETWORKING_SUBSTACK_URL"
echo "Data Layer Substack URL: $DATA_LAYER_SUBSTACK_URL"
echo "Data Ingestion Substack URL: $DATA_INGESTION_SUBSTACK_URL"
echo "Data Persistence Substack URL: $DATA_PERSISTENCE_SUBSTACK_TEMPLATE_URL"
aws cloudformation deploy \
--template-file $TEMPLATE_FILE \
--stack-name $STACK_NAME \
--region ${{ secrets.AWS_REGION }} \
--capabilities CAPABILITY_NAMED_IAM \
--no-fail-on-empty-changeset \
--parameter-overrides \
ContainerizationSubstackTemplateURL=$CONTAINERIZATION_SUBSTACK_URL \
NetworkingSubstackTemplateURL=$NETWORKING_SUBSTACK_URL \
DataLayerSubstackTemplateURL=$DATA_LAYER_SUBSTACK_URL \
DataIngestionSubstackTemplateURL=$DATA_INGESTION_SUBSTACK_URL \
DataPersistenceSubstackTemplateURL=$DATA_PERSISTENCE_SUBSTACK_TEMPLATE_URL \
EnvironmentName=$ENVIRONMENT_NAME \
VpcCidr=$VPC_CIDR \
PublicSubnet1Cidr=$PUBLIC_SUBNET_1_CIDR \
PublicSubnet2Cidr=$PUBLIC_SUBNET_2_CIDR \
PrivateSubnet1Cidr=$PRIVATE_SUBNET_1_CIDR \
PrivateSubnet2Cidr=$PRIVATE_SUBNET_2_CIDR \
BastionAccessCidr=$BASTION_ACCESS_CIDR
- name: Capture Events on Failure
if: failure()
run: |
STACK_NAME="atomiklabs-${ENVIRONMENT_NAME}-stack"
echo "Fetching stack events for $STACK_NAME"
aws cloudformation describe-stack-events --stack-name $STACK_NAME
- name: Confirm Stack Creation
run: |
STACK_NAME="atomiklabs-${ENVIRONMENT_NAME}-stack"
aws cloudformation describe-stacks --stack-name $STACK_NAME
echo "Stack $STACK_NAME has been confirmed to exist."