Infrastructure as Code
Modern DevOps Strategy
Manual server configuration is prone to error. By defining infrastructure as code (IaC), we can provision, configure, and deploy environments identically every time.
🏗️ Terraform:
Provisions the hardware (EC2, VPC, S3).
⚙️ Ansible:
Configures the software (Nginx, Docker, Users).
🚀 CI/CD:
Automates the testing and deployment pipeline.
Step 1: Terraform (Provisioning)
Instead of clicking buttons in the AWS Console, I use Terraform to define the entire cloud environment declaratively.
provider "aws" {
region = "us-east-1"
}
# 1. Create a Virtual Private Cloud (VPC)
resource "aws_vpc" "main_vpc" {
cidr_block = "10.0.0.0/16"
}
# 2. Launch an EC2 Instance (Server)
resource "aws_instance" "web_server" {
ami = "ami-0c55b159cbfafe1f0" # Ubuntu 20.04
instance_type = "t2.micro"
tags = {
Name = "Portfolio-WebServer"
}
}
# 3. Output the Public IP
output "server_ip" {
value = aws_instance.web_server.public_ip
}Key Benefits:
- State Management: Terraform remembers what is already deployed (`terraform.tfstate`).
- Idempotency: Running the script twice won't create two servers; it ensures the state matches the code.
Step 2: Ansible (Configuration)
Once the server exists, Ansible installs the software. It uses SSH to connect and run "Playbooks."
---
- name: Configure Web Server
hosts: webservers
become: true
tasks:
- name: Update apt cache
apt:
update_cache: yes
- name: Install Nginx and Docker
apt:
name:
- nginx
- docker.io
state: present
- name: Start Docker Service
service:
name: docker
state: started
enabled: yes
- name: Copy Website Files
copy:
src: ./index.html
dest: /var/www/html/index.htmlStep 3: CI/CD Pipeline
I use GitHub Actions to automatically test and deploy code whenever I push to the repository.
🔄 The Workflow
- 1
Push Code
Developer commits change to GitHub.
- 2
Test & Build
GitHub Actions runs unit tests and builds Docker image.
- 3
Deploy
If tests pass, SSH into server and update container.
name: CI/CD Pipeline
on:
push:
branches: [ "main" ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Build Docker Image
run: docker build -t my-app .
- name: Deploy via SSH
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
docker pull my-user/my-app:latest
docker stop web-app || true
docker rm web-app || true
docker run -d -p 80:80 --name web-app my-user/my-app:latest