The modern software development lifecycle demands rigorous automation to ensure reliability, security, and speed. Continuous Integration and Continuous Delivery (CI/CD) are not merely tools but a culture and set of operating principles that enable development teams to deliver code changes more frequently and reliably. By automating the software build and release process, organizations achieve repeatable builds, rapidly deliver new features, and ensure that each code change is tested to catch and fix bugs before release. This validation process increases the overall security of applications. Two distinct implementation pathways exist for deploying static content: one leveraging the native AWS ecosystem with CDK and CodePipeline, and another utilizing GitHub Actions for direct deployment to EC2.
The AWS CDK and CodePipeline Architecture
The first pathway utilizes the AWS Cloud Development Kit (CDK) to model a robust, reusable CI/CD pipeline. This approach is designed to accelerate the use of CI/CD pipelines while ensuring deployed resources adhere to DevOps best practices. The implementation involves defining a pipeline that includes tests to validate the security of third-party libraries, ensuring expedited and automated releases across desired environments.
AWS CodePipeline serves as the central orchestrator. It allows users to model different stages of the software release process using the AWS Console, AWS CLI, AWS CloudFormation, or AWS SDKs. The service consists of stages that can incorporate various AWS services such as AWS CodeBuild or AWS CodeDeploy. This extensibility allows the pipeline to compile or package application code and deploy the resulting artifact to a fleet of EC2 instances.
Environment Setup and Bootstrapping
To initiate the AWS-based pipeline, one must first clone the reference repository and prepare the local environment. The process begins by removing the local Git history to establish a fresh remote origin via AWS CodeCommit.
bash
git clone --depth 1 https://github.com/aws-samples/aws-codepipeline-cicd.git
cd ./aws-codepipeline-cicd
rm -rf ./.git
Authentication is handled via temporary security tokens or landing zone authentication. Before deployment, it is critical to verify the correct AWS Account and Region configuration.
bash
AWS_REGION="eu-west-1"
ACCOUNT_NUMBER=$(aws sts get-caller-identity --query Account --output text)
echo "${ACCOUNT_NUMBER}"
The CDK toolkit, accessed via the cdk CLI command, is the primary interface for interacting with the CDK application. It converts stacks to CloudFormation templates and deploys them to the specified AWS account. The bootstrapping process prepares the target environment.
bash
npm install
npm run build
npm run cdk bootstrap "aws://${ACCOUNT_NUMBER}/${AWS_REGION}"
Upon successful bootstrapping, the system outputs confirmation such as:
- ⏳ Bootstrapping environment aws://{account#}/eu-west-1...
- ✅ Environment aws://{account#}/eu-west-1 bootstrapped.
Synthesizing and Deploying the Stack
Once the environment is bootstrapped, the next step is to synthesize the CDK application. This process generates the CloudFormation template required for deployment.
bash
npm run cdk synth
The output confirms the synthesis path:
- Successfully synthesized to
To inspect the infrastructure template, supply the stack ID (e.g., CodePipeline, Dev-MainStack). The deployment is then executed using the CDK toolkit, which provisions the necessary AWS resources, including CodeCommit, CodeBuild, and CodeDeploy components.
The Pipeline Workflow and Validation
The implemented pattern defines a reusable CI/CD pipeline written in AWS CDK v2. This pipeline includes a comprehensive validation process to ensure the quality of application or infrastructure code.
After the initial deployment, the pipeline is fully operational with a main branch in the SampleRepository as the source. Any commit to this branch triggers a sequence of automated actions:
- Retrieve code from the AWS CodeCommit repository.
- Build the code using AWS CodeBuild.
- Update the pipeline itself (SelfMutate).
- Execute three parallel jobs for Linting, Security, and UnitTests checks.
- Upon success, deploy the Main stack using Infrastructure as Code.
- Execute post-deployment checks for the deployed resources.
To facilitate local development and testing, a Makefile is provided. It mirrors the steps executed by AWS CodePipeline, allowing developers to run linting and security checks locally before pushing to the remote repository.
Configuring the CodeCommit Remote
To integrate the local codebase with the newly created CodeCommit repository, the remote origin must be configured. First, retrieve the repository name from the CloudFormation stack outputs.
bash
RepoName=$(aws cloudformation describe-stacks --stack-name CodePipeline --query "Stacks[0].Outputs[?OutputKey=='RepositoryName'].OutputValue" --output text)
echo "${RepoName}"
git init
git branch -m master main
git remote add origin codecommit://${RepoName}
git add .
git commit -m "Initial commit"
git push -u origin main
This sequence establishes the connection between the local environment and AWS CodeCommit, triggering the automated pipeline.
Alternative Pathway: GitHub Actions and EC2 Deployment
While the AWS CDK approach provides a comprehensive, infrastructure-as-code solution, an alternative exists for simpler static site deployments. This method uses GitHub Actions to automatically deploy HTML websites to an AWS EC2 instance upon code push.
EC2 Instance Preparation
The foundation of this pathway is a properly configured EC2 instance. The instance should be launched with the following specifications:
- Name: MyStaticSite
- AMI: Amazon Linux 2 or Ubuntu
- Instance Type: t2.micro (eligible for Free Tier)
- Key Pair: Create or use an existing
.pemfile - Security Group: Must allow SSH (port 22) and HTTP (port 80)
After launching the instance, the private key must be secured.
bash
mv ~/Downloads/your-key.pem ~/.ssh/
chmod 400 ~/.ssh/your-key.pem
Access the instance via SSH. The default username depends on the OS: ec2-user for Amazon Linux 2, or ubuntu for Ubuntu.
bash
ssh -i ~/.ssh/your-key.pem ec2-user@your-ec2-public-ip
Once connected, install and configure the web server. For Amazon Linux 2:
bash
sudo yum update -y
sudo yum install -y httpd
sudo systemctl start httpd
sudo systemctl enable httpd
sudo chown ec2-user /var/www/html
For Ubuntu systems:
bash
sudo apt update
sudo apt install -y apache2
sudo systemctl start apache2
sudo systemctl enable apache2
sudo chown ubuntu /var/www/html
Verification involves opening the EC2 public IP in a browser to view the Apache test page.
GitHub Actions Workflow Configuration
The automation logic resides in a GitHub Actions workflow file located at .github/workflows/deploy.yml. The workflow triggers on every push to the main (or master) branch.
yaml
name: Deploy to EC2
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Copy files via SCP
uses: appleboy/[email protected]
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_KEY }}
source: "index.html"
target: "/var/www/html"
This workflow uses the scp-action to securely copy the index.html file to the EC2 instance's web root directory.
Managing Secrets and Deployment
To ensure security, sensitive connection details must be stored as GitHub Secrets. Navigate to the repository Settings → Secrets and variables → Actions. Add the following secrets:
EC2_HOST: The EC2 public IP address.EC2_USER: The system username (ec2-userfor Amazon Linux,ubuntufor Ubuntu).EC2_KEY: The full contents of the private.pemfile.
For production setups, while GitHub Secrets are encrypted, it is recommended to use IAM roles or session-based credentials for enhanced security.
Execution and Verification
After configuring the secrets, commit and push the workflow file to trigger the action.
bash
git add .
git commit -m "Initial CI/CD setup"
git push origin main
Monitor the execution via the GitHub Actions tab. Once the job completes, verify the deployment by accessing http://<your-ec2-public-ip>. The browser should display the content from index.html.
Conclusion
Implementing CI/CD pipelines is essential for modern software delivery, enabling rapid, reliable, and secure code deployment. The AWS CDK approach offers a robust, infrastructure-as-code solution with comprehensive validation, linting, and security checks, ideal for complex application deployments. Conversely, the GitHub Actions pathway provides a streamlined method for static content deployment, leveraging direct SSH/SCP transfers to EC2 instances. Both methods exemplify the core DevOps principle of automating the release process to minimize human error and accelerate feature delivery. The choice between them depends on the complexity of the application and the desired level of infrastructure automation.