This project demonstrates the use of GitOps with Argo CD to automate the deployment of a React web app to a Kubernetes cluster, using AWS Elastic Container Registry (ECR) for storing Docker images and integrating AWS CloudTrail for monitoring and security logging.
The project consists of several key components:
AWS ECR for securely storing Docker images.
GitHub Actions for automating the build, tag, and push process of Docker images to ECR whenever changes are made to the repository.
Argo CD for continuous deployment, syncing the desired state from the GitHub repository to the Kubernetes cluster.
AWS CloudTrail to log and monitor API activities for security and auditing purposes.
This approach streamlines the CI/CD pipeline, enhances deployment security, and provides continuous visibility into system activity, allowing for a robust and automated application deployment process.
Prerequisites
Before you begin, make sure you have the following set up:
AWS Account with permissions to manage ECR, EC2, and CloudTrail.
Kubernetes Cluster with Argo CD installed (either on AWS EKS or a self-managed Kubernetes cluster). https://kubernetes.io/docs/setup/
GitHub repository where your React web app’s code is stored.
Docker installed on your local machine for building container images. https://docs.docker.com/engine/install/
AWS CLI installed and configured on your machine. https://docs.aws.amazon.com/cli/v1/userguide/cli-chap-install.html
Kubectl to interact with your Kubernetes cluster.
GitHub Actions configured to automate the CI/CD pipeline.
NOTE: Anywhere you see LEEMAH-STORE Replace with your app name
STAGE 1: Creating an ECR repo, building docker image from your app and pushing the image to ECR
Methods:
Using bash Terminal
Automating with GitHub Actions
Step 1: Create a New ECR Repository
Log in to the AWS Management Console.
Navigate to Amazon ECR under the Services section.
Click on Create repository.
Provide a repository name (e.g.,
leemah-store-repo
).Choose Private as the repository type (though you can choose public if needed).
Click Create repository.
Using Bash
Step 2: Authenticate Docker to ECR
To push images to ECR, authenticate Docker using the AWS CLI:
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <aws_account_id>.
dkr.ecr.us-east-1.amazonaws.com
Replace <aws_account_id>
with your AWS account ID and adjust the region (us-east-1
) accordingly.
Step 3: Build and Tag the Docker Image
Build the Docker image for your app:
docker build -t app-name .
docker build -t leemah-store .
docker tag app-name:latest <aws_account_id>.
dkr.ecr.us-east-1.amazonaws.com/leemah-store-repo:latest
Step 4: Push the Docker Image to ECR
Push the tagged image to the ECR repository:
docker push <aws_account_id>.
dkr.ecr.us-east-1.amazonaws.com/leemah-store-repo:latest
Automating with GitHub Actions.
To automate the process of building, tagging, and pushing the Docker image to AWS ECR, we'll use GitHub Actions. This will trigger on every push to the main
branch of your repository.
Step 1: Set Up AWS Credentials in GitHub Secrets
To allow GitHub Actions to interact with AWS ECR, configure your AWS credentials in GitHub Secrets:
In your GitHub repository, go to Settings > Secrets.
Add the following secrets:
AWS_ACCESS_KEY_ID: Your AWS access key.
AWS_SECRET_ACCESS_KEY: Your AWS secret key.
AWS_REGION: The AWS region where your ECR repository is located (e.g.,
us-east-1
).
These credentials will be automatically used by the GitHub Actions workflow to log in to AWS ECR.
Step 2: Create the GitHub Actions Workflow File
In your GitHub repository, create the
.github/workflows
directory if it doesn’t already exist.Inside this directory, create a file named
ci-cd.yml
.
Step 2: Define the GitHub Actions Workflow
Here’s the content for your ci-cd.yml
file:
name: CI/CD Pipeline
on: push: branches: - main
jobs: build: runs-on: ubuntu-latest
steps: - name: Checkout code uses: actions/checkout@v3
- name: Set up Docker Buildx uses: docker/setup-buildx-action@v2
- name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v1
- name: Build Docker image run: | docker build -t leemah-store .
- name: Tag Docker image run: | docker tag leemah-store:latest <aws_account_id>.
dkr.ecr.us-east-1.amazonaws.com/leemah-store-repo:latest
- name: Push Docker image to ECR run: | docker push <aws_account_id>.
dkr.ecr.us-east-1.amazonaws.com/leemah-store-repo:latest
Replace <aws_account_id>
with your AWS account ID and us-east-1
with the appropriate region.
- Push this file to your GitHub repository.
STAGE 2: Setting Up Argo CD for GitOps
Argo CD allows us to automate the deployment process by syncing the desired state from our Git repository to the Kubernetes cluster. It will automatically deploy our containerized application using the image stored in AWS ECR.
Step 1: Install Argo CD
If you don't have Argo CD installed on your Kubernetes cluster, you can use the following commands to install it:
kubectl create namespace argocd kubectl apply -n argocd -f
https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Step 2: Create the Deployment Configuration in GitHub
Create a deployment configuration in your GitHub repository. This configuration will tell Argo CD how to deploy your app from the Docker image stored in AWS ECR.
- Create a file named
argocd-deployment.yaml
in your repository with the following contents:
apiVersion: apps/v1
kind: Deployment
metadata:
name: leemah-store
spec:
replicas: 1
selector:
matchLabels:
app: leemah-store
template:
metadata:
labels:
app: leemah-store
spec:
containers:
- name: leemah-store
image: <aws_account_id>.
dkr.ecr.us-east-1.amazonaws.com/leemah-store-repo:latest
ports:
- containerPort: 80
Replace <aws_account_id>
with your AWS account ID and us-east-1
with the appropriate region.
- Push this file to your GitHub repository.
STAGE 3: Create an Argo CD Application
In the Argo CD UI, create an application that will reference your GitHub repository to sync the configuration:
Log in to the Argo CD UI (e.g.,
https://<argocd-server>/
).Navigate to Applications and click New App.
Fill in the details:
Application Name:
leemah-store
Project:
default
Repository URL: URL of your GitHub repository.
Path: Path to the
argocd-deployment.yaml
file in your repo.Cluster URL: URL of your Kubernetes cluster.
Namespace: The namespace where you want to deploy the app.
Click Create to finish the setup.
Argo CD will now automatically monitor your GitHub repository, pull the Docker image from ECR, and deploy it to your Kubernetes cluster.
STAGE 4:Implementing AWS CloudTrail for Monitoring and Logging
AWS CloudTrail provides visibility into API activity, making it an essential tool for tracking deployments and ensuring security.
Step 1: Enable CloudTrail in AWS
Go to the AWS CloudTrail Console.
Click Create trail and provide a trail name (e.g.,
leemah-store-trail
).Choose Apply trail to all regions.
Enable logging to a new S3 bucket to store logs.
Enable CloudWatch Logs for real-time monitoring.
Click Create to set up the trail.
Step 2: Monitor ECR and Kubernetes Events
CloudTrail will log various AWS service activities, including those related to ECR and Kubernetes.
ECR Events: Events like
PutImage
andGetAuthorizationToken
will be captured.Kubernetes Events: If you're using AWS EKS, CloudTrail will capture logs for all Kubernetes API server interactions.
Step 3: Analyze Logs in CloudWatch
You can use CloudWatch Logs to monitor and filter specific events, such as unauthorized access attempts or changes to your ECR repositories.
Example CloudWatch log filter for ECR events:
filter @message /PutImage
Conclusion
By integrating AWS ECR and CloudTrail into your GitOps pipeline, you can enhance the security and manageability of your deployments. This setup not only stores your Docker images in a secure, AWS-native service but also provides robust monitoring and logging capabilities for all your AWS activities, including ECR and Kubernetes actions.
With this setup, you can confidently automate your deployment processes with Argo CD, ensuring both operational efficiency and security.