This is a simple Spring Boot application that demonstrates a complete CI/CD pipeline using AWS services, Docker, and GitHub.
- GitHub
- IAM (Identity and Access Management)
- AWS CodeBuild
- AWS CodePipeline
- AWS CodeDeploy
- Elastic Container Registry (ECR)
- Elastic Container Service (ECS)
- Elastic Load Balancer (ALB)
- AWS Systems Manager Parameter Store
mvn clean packagejava -jar target/spring-boot-app-0.0.1-SNAPSHOT.jar- GitHub: https://github.com/Umarsatti1/simple-springboot-app
- Clone:
git clone https://github.com/Umarsatti1/simple-springboot-app.git- Create a GitHub repository
- Store Spring Boot application files
- Visibility: Private
- Name Format:
<account-id>.dkr.ecr.us-east-1.amazonaws.com/<REPO NAME> - Settings: Mutable, AES-256 Encryption
- Leave other settings default
version: 0.2 env: parameter-store: DOCKERHUB_USERNAME: "/app/docker/docker_username" DOCKERHUB_PASSWORD: "/app/docker/docker_password" phases: install: runtime-versions: java: corretto17 pre_build: commands: - echo "Building Spring Boot application..." - mvn clean package - echo "Logging in to Amazon ECR..." - aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT.dkr.ecr.$AWS_REGION.amazonaws.com - echo "Trying Docker Hub login (optional)..." - echo $DOCKERHUB_PASSWORD | docker login -u $DOCKERHUB_USERNAME --password-stdin || echo "Docker Hub login failed, continuing..." build: commands: - echo "Building Docker image..." - sed -i 's|FROM eclipse-temurin:17-jre-alpine|FROM public.ecr.aws/docker/library/eclipse-temurin:17-jre-alpine|g' Dockerfile || echo "No change needed" - docker build -t $ECR_REPO_NAME:latest . - docker tag $ECR_REPO_NAME:latest $AWS_ACCOUNT.dkr.ecr.$AWS_REGION.amazonaws.com/$ECR_REPO_NAME:latest post_build: commands: - echo "Pushing Docker image..." - docker push $AWS_ACCOUNT.dkr.ecr.$AWS_REGION.amazonaws.com/$ECR_REPO_NAME:latest - echo "Creating image definition file..." - echo '[{"name":"springboot-app-container","imageUri":"'$AWS_ACCOUNT.dkr.ecr.$AWS_REGION.amazonaws.com/$ECR_REPO_NAME:latest'"}]' > imageDefinitions.json artifacts: files: - imageDefinitions.json - appspec.yml - taskdef.json - '**/*' discard-paths: noNote: Enable CloudWatch Logs
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ecr:GetAuthorizationToken", "ecr:BatchCheckLayerAvailability", "ecr:PutImage", "ecr:InitiateLayerUpload", "ecr:UploadLayerPart", "ecr:CompleteLayerUpload" ], "Resource": "*" } ] }AmazonS3FullAccessAmazonSSMFullAccess
- Trigger the build in CodeBuild
- Check the Docker image in ECR
- Build a custom pipeline
- Execution mode: Queued
- Skip Deploy stage for now
- Complete: Source, Build, Test
- Review and create
/app/docker/docker_username→ DockerHub Username/app/docker/docker_password→ DockerHub Password
Ensure it has:
- AmazonS3FullAccess
- AmazonSSMFullAccess
Create and attach necessary policies that allow CodePipeline to:
- Pull from GitHub
- Interact with CodeBuild, ECS, ECR, and CodeDeploy
- VPC: Default
- Subnets: All
- Security Group: Allow HTTP (Port 80) & Port 8080
- Listener: Port 80
- Port: 8080
- Protocol: HTTP
- Select during Load Balancer setup
- Create Cluster → Type: AWS Fargate
- Create Task Definition
- Container port: 8080
- Platform: Fargate
- Launch Type: Fargate
- Service Type: Replica (2 desired tasks)
- Deployment: Rolling Update
- Load Balancer: Select the ALB & target group created earlier
- VPC/Subnets/Security Group: same as ALB
Access your app via the ALB DNS (example):
http://simple-springboot-app-alb-1193977350.us-east-1.elb.amazonaws.com/- Add Deploy stage
- Action Provider: Amazon ECS
- Input Artifacts:
BuildArtifact - Cluster:
springboot-app - Service:
codepipeline-service - Image Definitions File:
imageDefinitions.json
- Make a change to your app
- Commit & push to GitHub
- Confirm pipeline runs automatically
- Validate via ALB that the update deployed successfully
- ECS Service is running 2 tasks
- Target Groups are healthy
- ALB is routing correctly
- CodePipeline deploys on Git push
- Docker image pushed to ECR