Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions .github/workflows/build-push.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Build and Push Container

on:
push:
branches: [ main ]
paths:
- 'webserver/**'
- '.github/workflows/build-push.yml'
workflow_dispatch: # Allow manual triggering

env:
AWS_REGION: ca-central-1
ECR_REPOSITORY: iac-exercise-app

jobs:
build-and-push:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}

- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2

- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}
run: |
# Build Docker image
cd webserver
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:latest

# Push both tags to ECR
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest

echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT
echo "✅ Image pushed: $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
echo "✅ Latest tag updated: $ECR_REGISTRY/$ECR_REPOSITORY:latest"

- name: Update ECS service (force new deployment)
run: |
aws ecs update-service \
--cluster iac-exercise-cluster \
--service iac-exercise-service \
--force-new-deployment \
--region ${{ env.AWS_REGION }}
echo "✅ ECS service deployment triggered"

- name: Deployment summary
run: |
echo "🚀 Container build and push completed!"
echo "📦 Image: ${{ steps.build-image.outputs.image }}"
echo "🔄 ECS service will pull new image and redeploy"
84 changes: 84 additions & 0 deletions .github/workflows/terraform-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: Terraform CI

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
workflow_dispatch: # Allow manual triggering

env:
TERRAFORM_VERSION: '1.6.0'

jobs:
terraform-validate:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ env.TERRAFORM_VERSION }}

- name: Terraform Format Check
run: terraform fmt -check -recursive
working-directory: ./infra

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ca-central-1

- name: Terraform Init
run: terraform init
working-directory: ./infra

- name: Terraform Validate
run: terraform validate
working-directory: ./infra

- name: Terraform Plan
run: terraform plan -out=tfplan
working-directory: ./infra

- name: Upload Terraform Plan
uses: actions/upload-artifact@v4
with:
name: terraform-plan
path: infra/tfplan
retention-days: 30

security-scan:
runs-on: ubuntu-latest
needs: terraform-validate
if: github.event_name == 'pull_request'

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ env.TERRAFORM_VERSION }}

- name: Run Checkov (Terraform security scanner)
uses: bridgecrewio/checkov-action@master
with:
directory: ./infra
framework: terraform
output_format: sarif
output_file_path: checkov-report.sarif
continue-on-error: true

- name: Upload Checkov results
uses: github/codeql-action/upload-sarif@v2
if: always()
with:
sarif_file: checkov-report.sarif
continue-on-error: true
70 changes: 70 additions & 0 deletions .github/workflows/terraform-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Terraform Deploy to Dev

on:
push:
branches: [ main ]
workflow_dispatch: # Allow manual triggering

env:
TERRAFORM_VERSION: '1.6.0'

jobs:
deploy-dev:
runs-on: ubuntu-latest
environment: development

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ env.TERRAFORM_VERSION }}

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ vars.AWS_REGION || 'ca-central-1' }}

- name: Terraform Init
run: terraform init
working-directory: ./infra

- name: Terraform Plan
run: terraform plan -out=tfplan
working-directory: ./infra

- name: Terraform Apply
run: terraform apply -auto-approve tfplan
working-directory: ./infra

- name: Get Infrastructure Outputs
id: terraform-output
run: |
VPC_ID=$(terraform output -raw vpc_id)
PUBLIC_SUBNETS=$(terraform output -json public_subnet_ids)
PRIVATE_SUBNETS=$(terraform output -json private_subnet_ids)
ECR_URL=$(terraform output -raw ecr_repository_url)
ECS_CLUSTER=$(terraform output -raw ecs_cluster_name)
ECS_SERVICE=$(terraform output -raw ecs_service_name)
echo "vpc_id=$VPC_ID" >> $GITHUB_OUTPUT
echo "public_subnets=$PUBLIC_SUBNETS" >> $GITHUB_OUTPUT
echo "private_subnets=$PRIVATE_SUBNETS" >> $GITHUB_OUTPUT
echo "ecr_url=$ECR_URL" >> $GITHUB_OUTPUT
echo "ecs_cluster=$ECS_CLUSTER" >> $GITHUB_OUTPUT
echo "ecs_service=$ECS_SERVICE" >> $GITHUB_OUTPUT
working-directory: ./infra

- name: Post-deployment summary
run: |
echo "✅ Development deployment completed successfully!"
echo "🌐 VPC ID: ${{ steps.terraform-output.outputs.vpc_id }}"
echo "🔗 Public Subnets: ${{ steps.terraform-output.outputs.public_subnets }}"
echo "🔒 Private Subnets: ${{ steps.terraform-output.outputs.private_subnets }}"
echo "📦 ECR Repository: ${{ steps.terraform-output.outputs.ecr_url }}"
echo "🚀 ECS Cluster: ${{ steps.terraform-output.outputs.ecs_cluster }}"
echo "⚙️ ECS Service: ${{ steps.terraform-output.outputs.ecs_service }}"
echo "📊 Infrastructure ready! Build and push your container to deploy the application."
56 changes: 48 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,48 @@
*.js
!jest.config.js
*.d.ts
node_modules

# CDK asset staging directory
.cdk.staging
cdk.out
# Terraform
*.tfstate
*.tfstate.*
*.tfvars.json
.terraform/
.terraform.lock.hcl
terraform.tfplan
tfplan

# Crash log files
crash.log
crash.*.log

# Exclude all .tfvars files, which are likely to contain sensitive data
# Comment out the line below if you want to include dev.tfvars in version control
# *.tfvars

# Ignore override files as they are usually used to override resources locally
override.tf
override.tf.json
*_override.tf
*_override.tf.json

# Include override files you do wish to add to version control using negated pattern
# !example_override.tf

# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*

# Ignore CLI configuration files
.terraformrc
terraform.rc

# macOS
.DS_Store

# IDEs
.vscode/
.idea/
*.swp
*.swo
*~

# Logs
*.log

# AWS
.aws/
6 changes: 0 additions & 6 deletions .npmignore

This file was deleted.

Loading