Last Updated on March 18, 2021
Deploying a continuous integration service such as Jenkins is an important step when kicking off your development project. In this article you’ll discover how to deploy Jenkins into the AWS Elastic Container Service (ECS), meaning you’ll have your own highly available Jenkins instance available to you over the internet.
We’ll be following all the best practices to get Jenkins production-ready, including making sure:
- Jenkins is always available to you even if an entire AWS availability zone goes down
- all Jenkins data is stored on a persistent volume
- Jenkins runs inside a private network with strict security controls to ensure nobody except authenticated users have access
- any changes to the infrastructure can be made easily via AWS CloudFormation templates
This wish list is not difficult to achieve when using services from a cloud provider such as AWS. First though. let’s get an understanding of how Jenkins works before figuring out how to deploy it to AWS.
This is the first article in this three-part series about deploying Jenkins into AWS. Here are details of all three articles:
- in Part 1 Deploy your own production-ready Jenkins in AWS ECS (this article) we’ll explore how to setup a robust Jenkins master in AWS using CloudFormation
- in Part 2 Running Jenkins jobs in AWS ECS with slave agents we’ll get slave jobs running in ECS through a full worked example, doing all the cloud configuration manually for a full understanding of the process
- in Part 3 Using Jenkins Configuration as Code to setup AWS slave agents we’ll improve what we had in part 2 by setting up our Jenkins master’s cloud configuration automatically using Jenkins Configuration as Code
Jenkins architecture overview

This diagram describes a common Jenkins use case, where we need to run jobs that build software whose code is checked out of a version control system such as Git.
Jenkins is designed to run a single master node responsible for serving the web UI, handling configuration, running jobs, and managing interactions with slave nodes. Jenkins slave nodes also run jobs, and they allow for horizontal scalability since you can have many resource intensive jobs running at the same time without affecting the master node.
Also bear in mind that:
- Jenkins stores it’s configuration and data (workspaces, job history etc.) on a filesystem accessed from the master node
- because of this, only a single master node can run at the same time otherwise there is risk of data corruption
- using a single master node without slaves is fine for light Jenkins usage
To keep things focused, for this article we’ll aim to deploy a single master node for running jobs. Executing jobs on slave nodes will be covered in a follow-up article.
Why would you deploy Jenkins into ECS?
AWS ECS is a container orchestration framework much like it’s better-known more fashionable cousin Kubernetes. ECS provides everything you need to deploy services as Docker containers, including handing scaling, failover, networking, and security.
The other nice things about ECS are:
- it’s fairly straightforward to get up and running quickly, especially if you use a templating language like CloudFormation or Terraform
- it integrates very well with other AWS technologies such as Application Load Balancers, Security Groups, and EC2
If you know that AWS is the cloud provider you want to use in the long-term, then for getting a service such as Jenkins deployed ECS is an ideal choice. 👍
AWS & ECS lingo 📚
AWS has a lot of magical acronyms and terms that can sometimes send your head in a spin. Let’s get the relevant ones out in the open before continuing.
- ECS Task – a unit of execution within ECS which equates to a Docker container running a single instance of an application
- ECS Service – an orchestration layer, one for each type of application you want to deploy (e.g. Jenkins). It manages the ECS tasks for you, making sure the desired number are running, and handles security and networking.
- ECS Cluster – a grouping of ECS tasks and services. A cluster can have a group of EC2 instances assigned to it on which it deploys tasks. This is called the EC2 launch type. Another launch type is Fargate, where AWS takes care of provisioning resources on which tasks run. Since you don’t have to provision any EC2 instances yourself, it makes setup a lot simpler. We’ll be using the Fargate launch type in this article.
- AWS Region – a geographical area into which you deploy AWS resources, e.g.
eu-west-1
(Ireland),eu-west-2
(London). We’ll be usingeu-west-1
in this article. - AWS Availability Zone – isolated datacentres within an AWS Region. Each region has multiple availability zones e.g.
eu-west-1
haseu-west-1a
,eu-west-1b
, andeu-west-1c
.
A Jenkins solution in ECS
OK, so we’ve given ECS the thumbs up, but let’s think about what specific features we can use for our Jenkins deployment given the constraints of the Jenkins architecture described earlier. The following points are marked on the diagram below, ‘cos I’m nice like that.
1 Integration with Application Load Balancer (ALB) – the only access point into Jenkins should be via an ALB which serves the Jenkins UI over HTTPS on port 443. An SSL certificate will be provided to the ALB for the domain we want Jenkins to be available on. Registration of ECS tasks into the ALB is handled automatically by ECS.2 Integration with Security Groups – the Jenkins ECS service should be assigned a security group that only allows access on the Jenkins port (8080) from the ALB. We’ll provide full outbound internet access to Jenkins in order that updates and plugins can be installed.
3 Persistent storage – AWS now offers tight integration between ECS tasks and the Elastic File System (EFS) service, meaning our Jenkins data will be safe if the container gets stopped for any reason.
4 Failover – because our Jenkins instance runs as a single master we can’t run multiple instances of it, so it will be deployed into a single availability zone. Although problems with an AWS availability zone are rare, we can provide redundancy by creating an ECS service which spans multiple availability zones. This way, Jenkins will automatically recover if the availability zone it’s running on fails.

EBS vs. EFS
Traditionally the Elastic Block Store (EBS) is the storage type to use when attaching a volume to an EC2 instance. This won’t work for our use case, because:
- we’re running in ECS Fargate, which doesn’t support EBS
- an EBS volume can only exist in a single availability zone, making things difficult for our high availability requirement
Fortunately though, the Elastic File System (EFS) can run in Fargate (as of April 2020) and its volumes can exist in multiple availability zones, which is why it’s our choice for this article.
Attaching EFS to Fargate containers: 1,000 foot view
To keep this article on-point, I’ll explain just enough information about attaching EFS to Fargate so that you can understand the main concepts. Sound fair?
EFS is an Network File System (NFS) type file system. It can be attached to one or many devices at the same time, each of which can read and write data. In the case of Fargate, you can attach an EFS file system to multiple ECS tasks.
The way this works with Fargate is using another resource that you have to create called a mount target. A mount target has its own network interface and therefore IP address, and it’s via the mount target that an EFS resource is attached to a Fargate container.

You can see from the diagram above that each availability zone has its own mount target. EFS itself stores data across multiple availability zones. This means that if an availability zone fails, whatever Fargate containers are in the other availability zone keep running uninterrupted via the corresponding mount target.
As already mentioned we’ll only have one Jenkins master running at once. But, these EFS features are very helpful to ensure Jenkins can come back automatically with the same data should an availability zone fail.
Deploying Jenkins into ECS with CloudFormation
Let’s get this show on the road by deploying all the AWS resources required to implement the solution above, using the AWS templating engine CloudFormation.
I recommend first reading through the descriptions that follow so you know what AWS resources you’re deploying. But, if you’re a super-keen eager beaver, jump right in by hitting Launch Stack below. This will create the CloudFormation stack in your own AWS account, resulting in a running Jenkins instance deployed in a new VPC and ECS cluster, available over the internet.
Full details of what to do when you click the Launch Stack button are given in the section Launching the CloudFormation stack in your AWS account.

First though, let’s run through the two template files that make up this infrastructure deployment.
Stack one: VPC and networking
This nested stack (default-vpc.yml) contains all the resources to create a standard VPC setup:
- VPC – a new network in the AWS cloud, where we’ll be deploying all resources. Note that for us to attach an EFS volume to a Fargate container in this VPC, it must have DNS hostnames enabled.
- public subnets x 2 (in different availability zones) – here we’ll deploy our ALB, so it’s accessible to the internet
- private subnets x 2 (in different availability zones) – here we’ll deploy our Jenkins service, so it’s not directly accessible to the internet
- an internet gateway – attached to the public subnets, this is the network’s route to the internet
- NAT gateway x 2 – these allow traffic from any services deployed in the private subnets to reach the internet via the internet gateway
- route tables, elastic IP, etc. – see the CloudFormation template for full details of miscellaneous resources
To learn more about these AWS resources, see my guide VPCs, subnets, and gateways – fundamentals for working with containers in AWS.
Nested stacks
A nested stack is a reusable CloudFormation template. Because we’re using a standard setup for the VPC/networking this has been extracted out into a separate nested stack, which can also be reused in future articles.
Stack two: ECS cluster, Jenkins ECS task, & ECS service
This main stack (jenkins-for-ecs.yml) references the nested stack created above, then it defines all the ECS resources required to get a Jenkins ECS service running, and hooks it into a load balancer.
ECS cluster
Our ECS cluster will be given the name default-cluster. Imaginative, I know!
ECSCluster: Type: AWS::ECS::Cluster Properties: ClusterName: default-cluster
ECS task definition
The Jenkins ECS task definition references the official Jenkins Docker image, and configures:
PortMappings
provides access to the container on port 8080MountPoints
defines a mount point for a volume called jenkins-home inside the container at/var/jenkins_home
(where Jenkins writes its data)- the
LogConfiguration
sets up logging to CloudWatch using theCloudwatchLogsGroup
resource, which keeps logs for 14 days - the
Volumes
section contains a jenkins-home volume which uses theEFSVolumeConfiguration
type to reference an EFS volume defined later on. Note thatTransitEncryption
is set toENABLED
so that Jenkins storage data is encrypted as it passes between the ECS task and EFS.
JenkinsTaskDefinition: Type: AWS::ECS::TaskDefinition Properties: Family: !Sub jenkins-task Cpu: 512 Memory: 1024 NetworkMode: awsvpc TaskRoleArn: !Ref JenkinsRole ExecutionRoleArn: !Ref JenkinsExecutionRole RequiresCompatibilities: - FARGATE - EC2 ContainerDefinitions: - Name: jenkins Image: jenkins/jenkins:lts PortMappings: - ContainerPort: 8080 MountPoints: - SourceVolume: jenkins-home ContainerPath: /var/jenkins_home LogConfiguration: LogDriver: awslogs Options: awslogs-group: !Ref CloudwatchLogsGroup awslogs-region: !Ref AWS::Region awslogs-stream-prefix: jenkins Volumes: - Name: jenkins-home EFSVolumeConfiguration: FilesystemId: !Ref FileSystemResource TransitEncryption: ENABLED AuthorizationConfig: AccessPointId: !Ref AccessPointResource IAM: ENABLED CloudwatchLogsGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Join ['-', [ECSLogGroup, !Ref 'AWS::StackName']] RetentionInDays: 14
ECS service
The Jenkins ECS service will be responsible for making sure the task (i.e. the container) is running, and it also manages networking:
- the
DesiredCount
of 1 means we’ll get a single Jenkins instance - the
LaunchType
ofFARGATE
means that AWS will be provisioning any underlying resources for us - the
PlatformVersion
must be1.4.0
otherwise the functionality to mount EFS volumes inside our Fargate container won’t work - the
DeploymentConfiguration
controls how ECS handles deployments when tasks need to be recreated. In our case we want at most one Jenkins instance to be running at once - the provided
NetworkConfiguration
means the service can create ECS tasks in any of the given subnets. It also says the tasks should have network access restricted as described in theJenkinsSecurityGroup
, which gives inbound access from the ALB on port 8080 (see template for details). - the
LoadBalancers
section says the service should automatically register itself with the provided target group, defined in the next section
JenkinsService: Type: AWS::ECS::Service DependsOn: LoadBalancerListener Properties: Cluster: !Ref ECSCluster TaskDefinition: !Ref JenkinsTaskDefinition DesiredCount: 1 HealthCheckGracePeriodSeconds: 300 LaunchType: FARGATE PlatformVersion: 1.4.0 DeploymentConfiguration: MinimumHealthyPercent: 0 MaximumPercent: 100 NetworkConfiguration: AwsvpcConfiguration: AssignPublicIp: ENABLED Subnets: - !GetAtt VPCStack.Outputs.PrivateSubnet1 - !GetAtt VPCStack.Outputs.PrivateSubnet2 SecurityGroups: - !GetAtt JenkinsSecurityGroup.GroupId LoadBalancers: - ContainerName: jenkins ContainerPort: 8080 TargetGroupArn: !Ref JenkinsTargetGroup
Load balancer and related resources
To expose Jenkins to the internet over SSL we’ll create a load balancer and a load balancer listener to receive incoming HTTPS traffic.
- the
LoadBalancer
spans two public subnets - it’s assigned a
LoadBalancerSecurityGroup
which allows inbound traffic from the internet on the SSL port 443, and outbound traffic to our Jenkins instance only - the
LoadBalancerListener
:- listens for HTTPS traffic on port 443
- is assigned a certificate id which must be passed into the CloudFormation template as a parameter (see Certificate & DNS setup below)
- by default forwards traffic to the Jenkins target group
- the
JenkinsTargetGroup
is where the ECS service will register the Jenkins task IP address- the
HealthCheckpath
is/login
which returns a 200 - the
Protocol
at this point isHTTP
since by this point traffic has been decrypted by the ALB deregistration_delay
is how long the target group will wait for requests to drain from a target when it’s being deregistered. Reducing this from the default of 5 minutes to 10 seconds means that changes to the Jenkins task will happen quicker.
- the
LoadBalancer: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Subnets: - !GetAtt VPCStack.Outputs.PublicSubnet1 - !GetAtt VPCStack.Outputs.PublicSubnet2 SecurityGroups: - !Ref LoadBalancerSecurityGroup LoadBalancerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: LoadBalancerSecurityGroup GroupDescription: Security group for load balancer VpcId: !GetAtt VPCStack.Outputs.VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 0.0.0.0/0 SecurityGroupEgress: - IpProtocol: tcp FromPort: 8080 ToPort: 8080 DestinationSecurityGroupId: !Ref JenkinsSecurityGroup LoadBalancerListener: Type: AWS::ElasticLoadBalancingV2::Listener Properties: Certificates: - CertificateArn: !Ref CertificateArn DefaultActions: - Type: forward ForwardConfig: TargetGroups: - TargetGroupArn: !Ref JenkinsTargetGroup LoadBalancerArn: !Ref LoadBalancer Port: 443 Protocol: HTTPS JenkinsTargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: HealthCheckPath: /login Name: JenkinsTargetGroup Port: 8080 Protocol: HTTP TargetType: ip VpcId: !GetAtt VPCStack.Outputs.VPC TargetGroupAttributes: - Key: deregistration_delay.timeout_seconds Value: 10
Certificate & DNS setup
You can use an existing certificate or create one through Services > Certificate Manager. Create the certificate for whatever domain you want Jenkins to be available on. In my case I wanted to serve Jenkins on jenkins.tomgregory.com
so created a wildcard certificate for *.tomgregory.com
.
Once your domain has been validated and the certificate has been created, the certificate ARN should be passed as a parameter when launching the CloudFormation stack (see Launching the CloudFormation stack in your AWS account below).
After the stack has been created, on the stack details page select the Outputs tab and copy the value from LoadBalancerDNSName. This is the DNS name of the load balancer created by CloudFormation.


Then add the copied value into your DNS through whatever tool you use (AWS or otherwise) as a CNAME record.


EFS File System
- the
EFSSecurityGroup
provides access from the Jenkins security group on port 2049, the default EFS port - the
FileSystemResource
is the volume itself, which we provide a name ofjenkins-home
Encrypted
is set to true to enable encryption at rest- two mount targets
MountTargetResource1
andMountTargetResource2
provide access from ECS tasks to the file system. We create a mount target in each of our private subnets, so depending on which availability zone our Jenkins ECS task gets placed, it will always have access to the file system.
EFSSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: !GetAtt VPCStack.Outputs.VPC GroupDescription: Enable EFS access via port 2049 SecurityGroupIngress: - IpProtocol: tcp FromPort: 2049 ToPort: 2049 SourceSecurityGroupId: !Ref JenkinsSecurityGroup FileSystemResource: Type: AWS::EFS::FileSystem Properties: Encrypted: true FileSystemTags: - Key: Name Value: jenkins-home MountTargetResource1: Type: AWS::EFS::MountTarget Properties: FileSystemId: !Ref FileSystemResource SubnetId: !GetAtt VPCStack.Outputs.PrivateSubnet1 SecurityGroups: - !GetAtt EFSSecurityGroup.GroupId MountTargetResource2: Type: AWS::EFS::MountTarget Properties: FileSystemId: !Ref FileSystemResource SubnetId: !GetAtt VPCStack.Outputs.PrivateSubnet2 SecurityGroups: - !GetAtt EFSSecurityGroup.GroupId AccessPointResource: Type: AWS::EFS::AccessPoint Properties: FileSystemId: !Ref FileSystemResource PosixUser: Uid: '1000' Gid: '1000' RootDirectory: CreationInfo: OwnerGid: '1000' OwnerUid: '1000' Permissions: '755' Path: '/jenkins-home'
Launching the CloudFormation stack in your AWS account
Now you know what resources are created in the CloudFormation templates you can go ahead and deploy the example using the Launch Stack button below:




When you click this button you’ll be taken to the Quick create stack page in your own AWS account.
- provide a CertificateArn. This is the ARN of the certificate you want to attach to your ALB for HTTPS access (see the Certificates & DNS setup section for more details).
- accept that this stack may create IAM resources and needs the
CAPABILITY_AUTO_EXPAND
capability
Click Create stack.


AWS will now go off and do its business, the infrastructure type business that is.
Go to Services > CloudFormation and you’ll see your CloudFormation stacks in the process of being created. After about 5 minutes all the stacks should be in the UPDATE_COMPLETE
state.


Prod ready? Yes, but…
The CloudFormation I’ve supplied here deploys an example of a production ready Jenkins service into a new VPC. In applying this to your own production infrastructure, I suggest:
- making a copy of any CloudFormation templates provided here and hosting them in your own S3 bucket
- adjusting as necessary to integrate with your own VPC and subnets
- setting up log retention and automated EFS backups based on your own requirements
- limiting access to your Jenkins instance by IP if you can. This can be achieved by updating the
LoadBalancerSecurityGroup
ingress rule.
Getting started with the Jenkins instance
If you’ve applied the CloudFormation stack described above you’ll now have a shiny new Jenkins instance running. Be patient as even when the stack has applied Jenkins still takes a couple of minutes to start up. ⏰
You can access Jenkins using the ALB DNS name described in the Certificates & DNS setup section above, although you’ll have to accept the “Your connection is not private” warning about an insecure certificate. If you’ve setup your certificate and DNS correctly though, you’ll be able to access Jenkins with a valid certificate for the domain, which will look like this:


Grab the admin password by navigating to the ECS Task and clicking on the Logs tab. The password will be printed in the logs the first time Jenkins starts up. Look for the log line “Please use the following password to proceed to installation”.
Copy the password, paste it into Jenkins, and you’ll be off and away with the Jenkins setup wizard:


Once you’ve followed this through, you’ll have a Jenkins instance ready to start running some jobs!
Disaster recovery scenarios
Since the intention of this article is to create a production-ready Jenkins deployment, let’s put our money where our mouth is and test some disaster recovery scenarios.
1. ECS task failure
Scenario: the Jenkins ECS Task gets stopped for some reason
Requirement: the ECS task should restart automatically restoring service quickly
Test: go to the list of tasks in the cluster, select the Jenkins task, then click Stop


Observation: ECS restarts the task and Jenkins is available again in 2m00s. ✅
2. Availability zone failure
This is a real “squeaky bum time” scenario where an entire AWS availability zone datacentre goes down.
You can identify which availability zone your ECS task is running in by going to the task details page and clicking on the ENI Id under Network:


This opens up details of the Elastic Network Interface (ENI) which our ECS task uses to connect to the network and internet. Under Zone it tells us which availability zone this ENI and associated ECS task are in.


In my case I know then that I need to simulate a failure of eu-west-1a.
Sadly AWS won’t be very helpful in bringing down a whole availability zone for our testing. 😢 But, the next best thing we can do is to modify our Jenkins ECS service to force it to deploy into a different subnet and therefore a different availability zone.
In the main CloudFormation template jenkins-for-ecs.yml it passes a list of subnet ids through in the NetworkConfiguration
section of the JenkinsService
resource:
NetworkConfiguration: AwsvpcConfiguration: AssignPublicIp: ENABLED Subnets: - !GetAtt VPCStack.Outputs.PrivateSubnet1 - !GetAtt VPCStack.Outputs.PrivateSubnet2 SecurityGroups: - !GetAtt JenkinsSecurityGroup.GroupId
All we need to do is tweak this list so that it only contains PrivateSubnet2, which lives in the second availability zone in your region (in my case eu-west-1b).
NetworkConfiguration: AwsvpcConfiguration: AssignPublicIp: ENABLED Subnets: - !GetAtt VPCStack.Outputs.PrivateSubnet2 SecurityGroups: - !GetAtt JenkinsSecurityGroup.GroupId
Once this change is applied the ECS service creates the ECS task in the remaining subnet, and the Jenkins instance is available again in 2m28s. ✅
Making these changes yourself
Download the original jenkins-for-ecs.yml template and make the above code change. To apply it, go to Services > CloudFormation, then select the stack and click Update. You can then select Replace current template and upload the file. Keep clicking Next then on the final screen click to say you accept the additional capabilities, then click Update stack.


Next steps
Even though now you have created a production-ready Jenkins instance which is secure and highly available, there’s still some way to go before you have a full continuous integration solution in place. Check out the next article in this series Running Jenkins jobs in AWS ECS with slave agents where we’ll learn how to horizontally scale Jenkins workloads by running jobs on slave agents.
As a final point, if you followed the example in this tutorial don’t forget to delete the CloudFormation stack once you’re finished with it, to avoid incurring unnecessary charges.
Discover more Jenkins CloudFormation templates


Liked the example from this article?
Check out my premium one-click Jenkins CloudFormation templates covering many different use cases.
✅ Run Jenkins securely in your own AWS account
✅ Try out different scenarios for running Jenkins in AWS
✅ Take the bits you like and incorporate them into your own templates
Resources
CloudFormation
The CloudFormation stack can be applied directly to your AWS account by clicking below:




There were two templates used in this article:
- jenkins-for-ecs.yml (main template)
- default-vpc.yml (nested)
AWS
- for more detailed info on how EFS connects with Fargate, check out AWS’s in-depth Developers guide to using Amazon EFS with Amazon ECS and AWS Fargate
- to learn more about VPC setup and related resources, read the AWS article What is Amazon VPC?
Jenkins
The Docker image used in this article was jenkins/jenkins, available on Docker Hub
Video
Check out the accompanying video over on my YouTube channel
Hello,
Thanks for your tutorial, I’ve tried this in a staging environment and this seems to work wonders. I’ve adapted the cloudformation stack so I can easily add the relevant parts to an existing App load balancer. It was a bit tricky to reuse the existing infra directly via cloudformation, so I left the creation of a target group + adding the target group to the load balancer listeners as a manual operation, but the rest seems to work fine.
However I have some speed issues sometimes, I have some suspicions that it is maybe caused by with AWS EFS (Ive seen some posts of people complaining about EFS speed in some cases), have you also observed something similar? Do you use this in production ? Do you sometimes have slow rendering speed of some jenkins page or slow API calls ?
Hi Cryil. I haven’t seen this issue, but I also haven’t used this setup in any heavy-load scenarios yet. I’m wondering if you’re hitting a throughput limit on your EFS volume though.
EFS has a base throughput and a burst throughput which you can use for short periods. Both of these are related to the current size of your volume. You can see if you have any burst credits available by checking the
BurstCreditBalance
metric in CloudWatch. I suggest reading through the documentation to see if it’s relevant to you. You could always try provisioned throughput mode to rule out this issue.Some other questions & ideas:
If you can provide more details about your scenario I can run some more detailed tests, as I think others could benefit from the findings. Thanks for sharing your concerns.
Tom,
Just wanted to let you know that I found this EXTREMELY helpful in setting up our serverless Jenkins implementation. This article was very well written, easy to follow and was a real catalyst to my project.
Keep up the good work and thank you for taking the time to share your information!
Cheers!
Hey Jason. Glad to hear the article helped you out. All the best, Tom
Hi Tom,
Good article! My question is, are you doing an EFS backup? If so, what approach are you using? For example, you made destructive changes to Jenkins master and want to restore the previous state.
Hi Anton. Good question. I’ve looked into this and couldn’t find an ideal solution. I see three main options though:
Let me know what you think of these options, or if you have any other ideas.
Hi Tom,
I spent some time investigating the best approach to deploy Jenkins HA for my goals, I use the following approach:
– Using Terraform I deploy an ECS cluster with two EC2 instances in different zones.
– Jenkins master is working as Replica with one replica with EFS volume for Jenkins data.
– Additional container with a backup script is working as Replica too and uses the same EFS volume. The script creates backup via rsync, first iteration – full sync, and then rsync in a loop with excluding logs till source folder(Jenkins home) and destination folder are not identities, on my test environment it takes about 5 iterations in the loop. Then script creates an archive and pushes it to S3.
Hi Tom,
Thank you very much, it was very helpful for me, as I’m installing for the first time jenkins on AWS.
I want to know if there’s something I have to add to get docker working in a pipeline other than adding plugins.
I’ve done everything I found on the net, and the best working from them gave me this error : Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
the solution for that I think was to add this “unix:///var/run/docker.sock” as volume, if you think that this is the solution can you give me how to add it.
Thank you.
Hi Bassem. The part of your Jenkins pipeline which needs access to Docker won’t be able to run in Fargate. That’s because you can’t mount
/var/run/docker.sock
into a Fargate container.I suggest looking into using ECS on EC2 instances or AWS CodeBuild. You can run a specific stage of your pipeline using one of these alternatives.
Hi Tom,
This series of articles is really helpful but I am working on a slightly different scenario which is about having Jenkins agents making use of codebuild as aws cloud agents based on this plugin – https://plugins.jenkins.io/codebuilder-cloud/#documentation. Is this something you have seen and worth considering it hosting Jenkins master as a docker container on EC2 instance? If so, can you please write an article or video demonstrating this? I tried this and it doesn’t work as expected, maybe I am missing something, I think plugin instructions aren’t clear and fails at handshake of sending a communication from codebuild back to Jenkins after initiating Jenkins agents communication from Jenkins to codebuild but fails other way and hence doesn’t work. Please check and let me know your thoughts on this.
Many thanks in advance.
Hi. I haven’t seen this plugin before but it definitely looks like an interesting option. Are you able to share your use case as to why you’ve picked this option? I think it would be interesting for readers of this article.
Regarding your specific problem, what URL is CodeBuild using to communicate back to the Jenkins master? I don’t see any mention of that in the plugin instructions. Consider whether CodeBuild has access to the VPC in which Jenkins master is running, and if it does are the security groups setup correctly? Here’s an article about access from CodeBuild to a VPC.
Hi Tom,
Thanks for checking and replying to this https://plugins.jenkins.io/codebuilder-cloud/#documentation plugin query. We got an existing Jenkins master agent as a docker containers concept in existing on-prem and while I was exploring Jenkins hosting on AWS cloud I came across the above-mentioned plugin and as we make use of AWS native DevOps tools like codebuild to build images & codedeploy, codepipeline as CI/CD pipeline tools, I thought of having Jenkins agents built making use of codebuild projects as agents.
Coming to Jenkins master > codebuild as Jenkins agents, yes I am making use of codebuild with VPC enabled options with right subnets and security groups where Jenkins on EC2 instance is hosted and I opened all ports from all both source (Jenkins > codebuild > Jenkins) and destination for testing purposes on this, but it still doesn’t establish a connection from codebuild to Jenkins and it doesn’t give much information on this, still exploring on this bits. Meanwhile, if you got this plugin method option working please do let me know.
thx
Hi Tom,
This is a great Article, thank you for sharing. I think the limitation of this setup where you are unable to run docker commands/build docker images inside of your agents is pretty big! I wish that was more prominently mentioned before I went ahead and deployed the stack. Hope you have a good day!
Sincerely,
Eric
Hi Eric. Thanks for bringing this to my attention, and apologies if you were lead in the wrong direction. I’ve added a clarification to the article Running Jenkins jobs in AWS ECS with slave agents.
If you’re using slave agents to run your jobs, then running the Jenkins master in Fargate is still a valid option.
Hi Tom,
I tried similar setup and followed your blog. every thing went well and jenkins is up and running. but the very next day when i come back and open the jenkins page i get 504 gateway time out. this is repeating all the time. first time it runs properly after a day or say prolonged ideal state the r53 url[jenkins rul] is giving 504 error.
Hi Ram. Thanks for letting me know about the issue you’re having. Can you confirm you’re deploying the CloudFormation template with no modifications?
Two more things to check:
Looking forward to hearing what you find out.
Hi Tom,
Thanks for sharing, this is exactly what I need. I am currently migrating my Jenkins running in ECS EC2 instance to FARGATE, this tutorial helped a lot. I just have an issue right now where I am getting the following error when I have more than one container running:
“HTTP ERROR 403 No valid crumb was included in the request”
I am just wondering if you have seen this error before? Your help is much appreciated. Thank you!
Sincerely,
Renz
Hi wyseman. Good to hear you’re moving your Jenkins over to the Fargate launch type.
Are you saying you’re running multiple Jenkins masters? This approach isn’t recommended in the article. It proposes scaling horizontally by running multiple Jenkins agents.
Hi Tom,
Thanks for sharing the video and the article. This is detailed and amazing.
I have done this setup and ecs containers are deployed and build is getting completed.
I have tried to store the completed builds to my S3 bucket using ‘S3 Publisher’ Jenkins plugin. However, once the build is complete, containers are deprovisioned before the s3upload in post section is initiated. Are these plugin not compatible with each other.
Jenkinsfile: https://github.com/pavansp729/easyio/blob/master/Jenkinsfile
Hello Thanks for the wonderful article. I have question related to aws cli.
How do I execute aws cli commands on pipeline (groovy) steps?
Hi. One way is just to use
sh
directly. e.g.sh 'aws s3 ls'
.Hi,
What’s the difference os installing Jenkins on EC2 or ECS?
When using ECS it runs Jenkins as a Docker container. This is the most straightforward approach, without having to worry about setting up the environment, which you would have to do with EC2.
Can you run Jenkins on your local machine and make Jenkins run jobs in your ECS cluster in Fargate mode?
I haven’t tried this but I don’t see why not. You will have to figure out how to set the AWS credentials within the local Jenkins.
Very much focused and clear way to get hands dirty.. 🙂
Thank you Tom!!!
Hi Tom, thanks a lot for this guide.
I got stuck on the second screen, for plugin installations, and I don’t see any errors in the logs.
I stumbled on this old open bug: https://issues.jenkins.io/browse/JENKINS-46776, but seeing all the comments above, it seems that most people do manage to pass this phase.
Any ideas?
Thanks again,
Erez
Hi Erez. Thanks for sharing your issue. Are you using the provided CloudFormation template to run Jenkins in AWS? Or are you running it some other way?