Serverless Jenkins on AWS ECS with Fargate and ECR using Terraform.

Sergey Yanover
3 min readAug 19, 2021

--

I’d like to run CI/CD Jenkins pipeline without EC2 instances on AWS ECS and make it available in case of errors inside Jenkins or some problems with the current Availability Zone when it might be not accessible.

I use two AZs for Jenkins, global AWS services ELB(ALB), EFS, ECR and ECS with Fargate. To create services I use Terraform and EC2 instance as a manager and bastion host in the 3rd AZ.

The idea is to have ECS Service which run only one Jenkins Task according Jenkins Task Definition in only one AZ. If something wrong is happening with Jenkins or AZ, according rules of Health check Target Group ALB, ALB triggers ECS Fargate Service to stop current Jenkins Task and at the same time starting another Jenkins Task in another AZ. I use EFS to mount a Jenkins home directory to the network file system and data won’t be lost.

You should have AWS account, generated SSH keys, installed git client and terraform on your local computer.

Use AWS Console with non-root admin account, choose IAM and create user terraform with Access type “Programmatic access”, attach group of policies “AdministratorAccess” directly.

Copy scripts from GitHub to your local computer:

git clone https://github.com/sergeyanover/jenkins-ecs-fargate-terraform.git
cd jenkins-ecs-fargate-terraform/terraform

Generated keys for a user terraform you should put into a file varset.bat and run it in command line. AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and set the region, I use eu-central-1.

Generate SSH public and private keys with puttygen.exe and save them in folder “keys”.

Edit file terraform.tfvars in the folder “terraform” and put your public key like “ssh-rsa …” into it as a value of my_public_key. In addition, you should set your current IP address or your network in ip_admin. You may know your IP address just click https://www.whatismyip.com or other resources.

Also, set the value of “image_jenkins_ecs_master” using your account number.

varset.bat
terraform plan
terraform apply -auto-approve

I receive output in the command line:

alb_hostname = "albdev-49917065.eu-central-1.elb.amazonaws.com"
ec2_public_ip = "3.121.183.6"

Your IP and hostname will be others. Jenkins will be accessable later on address: http://albdev-49917065.eu-central-1.elb.amazonaws.com:8080

You should go to Bastion host via ssh with port 12000 and IP 3.121.183.6

Create Jenkins docker image and put to the ECR using your account number instead of 814177777777:

git clone https://github.com/sergeyanover/jenkins-ecs-fargate-terraform.git
cd jenkins-ecs-fargate-terraform/docker
aws configure
aws ecr get-login-password --region eu-central-1 | docker login --username AWS --password-stdin 814177777777.dkr.ecr.eu-central-1.amazonaws.comdocker build -t jenkins:ecs-master .
docker tag jenkins:ecs-master 814177777777.dkr.ecr.eu-central-1.amazonaws.com/ecr_repo:jenkins-ecs-master_v1
docker push 814177777777.dkr.ecr.eu-central-1.amazonaws.com/ecr_repo:jenkins-ecs-master_v1

Connect to EFS, mount it and create a folder /jenkins-master, address fs-xxxxx you can find in AWS Console EFS :

sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport fs-0de11c4c16e4068e6.efs.eu-central-1.amazonaws.com:/ /mntsudo mkdir /mnt/jenkins-master
chmod a+rwx /mnt/jenkins-master

Click ECS in AWS Console and wait until Task will be created. That can take some time, AWS creates DNS records to resolve EFS and ECR IP addresses.

You can use Jenkins now via Load Balancer in the browser: http://albdev-49917065.eu-central-1.elb.amazonaws.com:8080

Make sure Jenkins works and find out in which Subnet the Task located.

If you stop the Task in ECS Tasks and refresh browser, Jenkins returns Error 502 and you could see in AWS Console as Service starts a new Task. Click on the new Task — that’s another Subnet, another AZ but , as you see in the browser, Jenkins is working well.

References:
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/AWS_Fargate.html
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/fargate-capacity-providers.html
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_cluster
https://www.terraform.io/docs/providers/aws/r/ecs_task_definition.html

--

--