Skip to content

Commit 7884277

Browse files
committed
feat: add Terraform best practices and CI/CD pipeline
1 parent 29734c3 commit 7884277

12 files changed

Lines changed: 1015 additions & 48 deletions

.github/workflows/deploy.yml

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
name: Deploy to AWS
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
environment:
7+
description: 'Deployment environment'
8+
required: true
9+
default: 'dev'
10+
type: choice
11+
options:
12+
- dev
13+
- prod
14+
15+
env:
16+
TF_VERSION: "1.5.0"
17+
AWS_REGION: "us-east-1"
18+
19+
jobs:
20+
deploy:
21+
name: Deploy Infrastructure
22+
runs-on: ubuntu-latest
23+
environment: ${{ github.event.inputs.environment }}
24+
25+
steps:
26+
- name: Checkout code
27+
uses: actions/checkout@v4
28+
29+
- name: Setup Python
30+
uses: actions/setup-python@v5
31+
with:
32+
python-version: "3.9"
33+
34+
- name: Build Lambda Package
35+
run: |
36+
mkdir -p package
37+
pip install -r requirements.txt -t ./package
38+
cp handler.py package/
39+
40+
- name: Configure AWS Credentials
41+
uses: aws-actions/configure-aws-credentials@v4
42+
with:
43+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
44+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
45+
aws-session-token: ${{ secrets.AWS_SESSION_TOKEN }}
46+
aws-region: ${{ env.AWS_REGION }}
47+
48+
- name: Setup Terraform
49+
uses: hashicorp/setup-terraform@v3
50+
with:
51+
terraform_version: ${{ env.TF_VERSION }}
52+
53+
- name: Create terraform.tfvars
54+
run: |
55+
cat > terraform.tfvars <<EOF
56+
telegram_token = "${{ secrets.TELEGRAM_TOKEN }}"
57+
lab_role_arn = "${{ secrets.LAB_ROLE_ARN }}"
58+
environment = "${{ github.event.inputs.environment }}"
59+
log_retention_days = 14
60+
EOF
61+
62+
- name: Terraform Init
63+
run: terraform init
64+
65+
- name: Terraform Plan
66+
run: terraform plan -out=tfplan
67+
68+
- name: Terraform Apply
69+
run: terraform apply -auto-approve tfplan
70+
71+
- name: Get Outputs
72+
id: outputs
73+
run: |
74+
echo "api_url=$(terraform output -raw api_gateway_url)" >> $GITHUB_OUTPUT
75+
echo "lambda_name=$(terraform output -raw lambda_function_name)" >> $GITHUB_OUTPUT
76+
77+
- name: Setup Webhook
78+
run: |
79+
API_URL="${{ steps.outputs.outputs.api_url }}"
80+
curl -s "https://api.telegram.org/bot${{ secrets.TELEGRAM_TOKEN }}/setWebhook?url=${API_URL}"
81+
82+
- name: Deployment Summary
83+
run: |
84+
echo "## Deployment Complete! :rocket:" >> $GITHUB_STEP_SUMMARY
85+
echo "" >> $GITHUB_STEP_SUMMARY
86+
echo "**Environment:** ${{ github.event.inputs.environment }}" >> $GITHUB_STEP_SUMMARY
87+
echo "**API Gateway URL:** ${{ steps.outputs.outputs.api_url }}" >> $GITHUB_STEP_SUMMARY
88+
echo "**Lambda Function:** ${{ steps.outputs.outputs.lambda_name }}" >> $GITHUB_STEP_SUMMARY

.github/workflows/pr-check.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: PR Check
2+
3+
on:
4+
pull_request:
5+
branches: [main, master]
6+
types: [opened, synchronize, reopened]
7+
8+
jobs:
9+
check:
10+
name: PR Validation
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout code
15+
uses: actions/checkout@v4
16+
17+
- name: Check branch name
18+
run: |
19+
BRANCH_NAME="${{ github.head_ref }}"
20+
if [[ ! "$BRANCH_NAME" =~ ^(dev|feature/|bugfix/|hotfix/) ]]; then
21+
echo "::warning::Branch name should follow convention: dev, feature/*, bugfix/*, or hotfix/*"
22+
fi
23+
24+
- name: Check for terraform.tfvars in PR
25+
run: |
26+
if git diff --name-only origin/${{ github.base_ref }}...${{ github.head_ref }} | grep -q "terraform.tfvars$"; then
27+
echo "::error::terraform.tfvars should not be committed! Add it to .gitignore"
28+
exit 1
29+
fi
30+
31+
- name: Check for sensitive data
32+
run: |
33+
# Check for potential secrets in files
34+
if grep -rE "(aws_access_key_id|aws_secret_access_key|AKIA[0-9A-Z]{16})" --include="*.tf" --include="*.py" --include="*.sh" .; then
35+
echo "::error::Potential sensitive data found in files!"
36+
exit 1
37+
fi
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
name: Terraform Validate
2+
3+
on:
4+
push:
5+
branches: [dev, main, master]
6+
pull_request:
7+
branches: [main, master]
8+
9+
env:
10+
TF_VERSION: "1.5.0"
11+
12+
jobs:
13+
validate:
14+
name: Validate Terraform
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
21+
- name: Setup Terraform
22+
uses: hashicorp/setup-terraform@v3
23+
with:
24+
terraform_version: ${{ env.TF_VERSION }}
25+
26+
- name: Terraform Format Check
27+
id: fmt
28+
run: terraform fmt -check -recursive
29+
continue-on-error: true
30+
31+
- name: Create dummy tfvars for validation
32+
run: |
33+
cat > terraform.tfvars <<EOF
34+
telegram_token = "dummy-token-for-validation"
35+
lab_role_arn = "arn:aws:iam::123456789012:role/LabRole"
36+
environment = "dev"
37+
EOF
38+
39+
- name: Create dummy package directory
40+
run: |
41+
mkdir -p package
42+
cp handler.py package/
43+
touch package/__init__.py
44+
45+
- name: Terraform Init
46+
id: init
47+
run: terraform init -backend=false
48+
49+
- name: Terraform Validate
50+
id: validate
51+
run: terraform validate
52+
53+
- name: Post Validation Status
54+
if: github.event_name == 'pull_request'
55+
uses: actions/github-script@v7
56+
with:
57+
script: |
58+
const output = `#### Terraform Format 🖌 \`${{ steps.fmt.outcome }}\`
59+
#### Terraform Init ⚙️ \`${{ steps.init.outcome }}\`
60+
#### Terraform Validate 🤖 \`${{ steps.validate.outcome }}\`
61+
62+
*Pushed by: @${{ github.actor }}, Action: \`${{ github.event_name }}\`*`;
63+
64+
github.rest.issues.createComment({
65+
issue_number: context.issue.number,
66+
owner: context.repo.owner,
67+
repo: context.repo.repo,
68+
body: output
69+
})
70+
71+
lint:
72+
name: Lint Python
73+
runs-on: ubuntu-latest
74+
75+
steps:
76+
- name: Checkout code
77+
uses: actions/checkout@v4
78+
79+
- name: Setup Python
80+
uses: actions/setup-python@v5
81+
with:
82+
python-version: "3.9"
83+
84+
- name: Install dependencies
85+
run: |
86+
python -m pip install --upgrade pip
87+
pip install flake8
88+
89+
- name: Lint with flake8
90+
run: |
91+
# Stop build if there are Python syntax errors or undefined names
92+
flake8 handler.py --count --select=E9,F63,F7,F82 --show-source --statistics
93+
# Exit-zero treats all errors as warnings
94+
flake8 handler.py --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
95+
96+
security:
97+
name: Security Scan
98+
runs-on: ubuntu-latest
99+
100+
steps:
101+
- name: Checkout code
102+
uses: actions/checkout@v4
103+
104+
- name: Run Checkov (Terraform Security)
105+
uses: bridgecrewio/checkov-action@v12
106+
with:
107+
directory: .
108+
framework: terraform
109+
soft_fail: true
110+
output_format: cli

0 commit comments

Comments
 (0)