Construido con ❤️ por Valdo usando Windsurf, Gemini y el conocimiento adquirido en el curso de Udemy "Terraform, a popular infrastructure automation tool for DevOps. Terraform with AWS, Packer, Docker, ECS, EKS, Jenkins".
- Agregar ECS a los archivos de terraform
- Separar los archivos tf usando modulos para ambientes STAGE y PROD
- Agregar un job para diferentes ramas STAGE y PROD
- Activar el job de PROD solo en PR de main
This project serves as a Proof of Concept (PoC) demonstrating the deployment of a Node.js (Express) backend application, containerized with Docker, to Amazon Elastic Container Registry (ECR) using Terraform for infrastructure provisioning and GitHub Actions for CI/CD automation.
The primary goal is to showcase an automated workflow where:
- Terraform defines and manages the AWS ECR repository and related resources.
- A local setup script (
setup_tf_backend.sh) configures the Terraform backend using AWS S3 and DynamoDB. - GitHub Actions, upon a push to the
mainbranch, authenticates to AWS using an IAM Role (OIDC), builds the Docker image, and pushes it to the ECR repository provisioned by Terraform.
- Infrastructure as Code (IaC) using Terraform for AWS ECR.
- Automated CI/CD pipeline with GitHub Actions.
- Secure authentication to AWS from GitHub Actions using IAM Roles for Service Accounts (OIDC).
- Docker containerization of a Node.js Express application.
- Automated Terraform backend configuration (S3 bucket and DynamoDB table for state locking).
- Cloud Provider: AWS
- ECR (Elastic Container Registry)
- S3 (for Terraform backend state)
- DynamoDB (for Terraform state locking)
- IAM (Identity and Access Management - OIDC for GitHub Actions)
- IaC: Terraform
- CI/CD: GitHub Actions
- Containerization: Docker
- Application: Node.js (Express.js)
Before you begin, ensure you have the following installed and configured:
- Terraform CLI
- AWS CLI
- Docker
- An AWS Account.
- A GitHub Repository.
Create an IAM Role in your AWS account that GitHub Actions can assume. This role needs permissions to manage ECR, S3 (for Terraform backend), and DynamoDB (for Terraform state lock table).
- Attach necessary permission policies to this role (e.g.,
AmazonEC2ContainerRegistryFullAccess, plus custom policies for S3 backend bucket creation/access and DynamoDB table creation/access if the setup script handles this).
Modify the .env file in the root directory with your values (in case you want to change the default values).
In your GitHub repository, navigate to Settings > Secrets and variables > Actions and add the following secrets:
AWS_REGION: Your AWS region (e.g.,us-east-1).AWS_IAM_ROLE_ARN: The ARN of the IAM role created in the previous step (e.g.,arn:aws:iam::YOUR_AWS_ACCOUNT_ID:role/YOUR_IAM_ROLE_NAME).
And add the following variables:
TERRAFORM_DIR: The path to the directory where the Terraform configuration files are stored (e.g.,./01-tf).
The setup_tf_backend.sh script automates the creation of the S3 bucket and DynamoDB table for the Terraform backend and generates the necessary Terraform configuration files.
In your GitHub repository, navigate to Settings > Secrets and variables > Actions and add the following secrets:
AWS_REGION: Your AWS region (e.g.,us-east-1).AWS_IAM_ROLE_ARN: The ARN of the IAM role created in the previous step (e.g.,arn:aws:iam::YOUR_AWS_ACCOUNT_ID:role/YOUR_IAM_ROLE_NAME).
And add the following variables:
TERRAFORM_DIR: The path to the directory where the Terraform configuration files are stored (e.g.,./01-tf).
The setup_tf_backend.sh script automates the creation of the S3 bucket and DynamoDB table for the Terraform backend and generates the necessary Terraform configuration files.
- The script is expected to create:
terraform/backend.tf: Configures the S3 backend for Terraform state.terraform/variables.tf: May define variables used by the backend setup or main configuration (e.g.,TF_STATE_KEY,TF_BACKEND_REGIONif these are dynamically set or user-provided).
Note: Ensure your Terraform configuration in the terraform/ directory (especially main.tf or a dedicated backend setup file) defines the resources for the S3 bucket and DynamoDB table that the setup_tf_backend.sh script will use or create. The script utilizes outputs like s3_backend_bucket_name and dynamodb_lock_table_name from a preliminary Terraform apply for the backend resources.
-
Clone the repository:
git clone https://github.com/YOUR_GITHUB_USERNAME/YOUR_REPOSITORY_NAME.git cd YOUR_REPOSITORY_NAME -
Make the setup script executable:
chmod +x setup_tf_backend.sh
-
Run the setup script: This script will typically run
terraform initandterraform applyagainst a configuration designed to provision the S3 bucket and DynamoDB table for the state backend. It then uses the outputs to generateterraform/auto_generated_backend.tf(and potentiallyterraform/auto_generated_variables.tf)../setup_tf_backend.sh
Follow any prompts from the script.
-
Commit and Push Changes: After the script successfully generates
terraform/auto_generated_backend.tfandterraform/auto_generated_variables.tf, commit these files and any other changes to your repository:git add terraform/auto_generated_backend.tf terraform/auto_generated_variables.tf git commit -m "Configure Terraform backend" git push origin main -
GitHub Actions Workflow: Pushing to the
mainbranch will trigger the GitHub Actions workflow defined in.github/workflows/deploy-to-ecr.yml. This workflow will:- Configure AWS credentials using the OIDC role.
- Run
terraform initandterraform applyto create/update the ECR repository defined in your main Terraform configuration (e.g.,terraform/main.tf). - Build the Docker image using the
Dockerfile. - Push the Docker image to the ECR repository.
.
├── .github/workflows/ # GitHub Actions workflows
│ └── deploy-to-ecr.yml # Workflow for ECR deployment
├── app/ # Node.js application source code
│ ├── app.js # Express application (e.g., Hello World on port 3011)
│ └── package.json # Node.js dependencies
├── terraform/ # Terraform configuration files
│ ├── main.tf # Main infrastructure (ECR repository, etc.)
│ ├── variables.tf # Terraform input variables
│ ├── outputs.tf # Terraform outputs (ECR URL, region)
│ └── backend.tf # (Generated by setup_tf_backend.sh) Terraform backend config
├── Dockerfile # Dockerfile to build the Node.js application image
├── setup_tf_backend.sh # Script to setup Terraform backend and generate config
└── README.md # This file