Leverage on CI/CD to provision infrastructure & do configuration management.

Introduction
This is the 3rd post and my follow up to the previous blog post, https://pohwj.hashnode.dev/ansible-basics. In this blog, I utilise GIthub Actions, one of the CI/CD tools to automate workflow to provision infrastructure and do configuration management.
Folder Structure
Changes are made to folder structure to make use of Github Actions. I include .github\workflows folder. In this folder, 2x yaml files named deploy.yml and ansible.yml are created which contains code to automate the workflow. In addition, following folders are created
infra folder - Contain the terraform files, setup file and .gitignore file to ignore certain terraform files that might contain sensitive data. The terraform state file is stored in an existing S3 bucket specified in backend.tf
ansible folder - Contain inventory file and ansible playbook for configuration management
Include credentials in Github
Credentials for Github Actions to perform infrastructure provisioning in AWS and SSH private key to access the VMs via are added in repository secrets.
The yaml files for Github Actions to deploy infrastructure and do configuration management on our behalf are shown below
name: Terraform to deploy resources on AWS
on:
push:
paths-ignore:
- 'README.md'
jobs:
terraform:
runs-on: ubuntu-latest
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
defaults:
run:
working-directory: ./infra
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
- name: Terraform Init
run: terraform init
- name: Terraform Plan
run: terraform plan
- name: Terraform Apply
run: terraform apply -auto-approve
name: ansible to do configuration management
on:
workflow_dispatch: # manual trigger for a separate workflow
jobs:
ansible:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./ansible
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup SSH Key
run: |
echo "${{ secrets.SSH_PRIVATE_KEY }}" > private_key.pem
chmod 600 private_key.pem
ls -l
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install Ansible
run: pip install ansible
- name: Check Ansible version
run: ansible --version
- name: Run Ansible Playbook
run: ansible-playbook -i inventory playbook.yml --private-key private_key.pem
Save changes, commit and push code to repository via following commands
git add . # include all changes in current repo
git commit -m "added github actions workflow" # insert a message that is meaningful
git push # push code to repo
Click Actions tab of your repository, click on the job. Under Terraform Apply step, a pair of IP addresses for the newly provisioned VMs should be seen
Insert the public IP addresses in inventory file. Commit and push changes.
[targets]
rhel1 ansible_host=13.251.128.22 ansible_user=ec2-user
rhel2 ansible_host=47.129.139.237 ansible_user=ec2-user
Trigger the ansible yml file manually by clicking on Actions tab, and Run workflow.
Changes are made on our target VMs successfully.
Tear down
Tear down the resources via the pipeline upon completion to save cost.
Updates to state lock
At the point of writing, S3 bucket allows state locking, removing need to provision DynamoDB for this feature. More can be read here, https://rafaelmedeiros94.medium.com/goodbye-dynamodb-terraform-s3-backend-now-supports-native-locking-06f74037ad39 & https://developer.hashicorp.com/terraform/language/backend/s3
Conclusion
This concludes the experimentation of Terraform, Ansible and Github Action to provision infrastructure and perform configuration management.
Subscribe to my newsletter
Read articles from Wen Jie Poh directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Wen Jie Poh
Wen Jie Poh
I am exploring the domain of cloud computing.