/terraform-jenkins-aws-fargate

Terraform stack to deploy Jenkins on ECS Fargate with Jenkins configuration stored in EFS and agents on ECS fargate

Primary LanguageHCL

Terraform Jenkins AWS ECS Fargate

Terraform stack to deploy Jenkins on ECS Fargate with Jenkins configuration stored in EFS and agents on Fargate too. Since the recent support for EFS in Fargate, we can now run a fully Serverless Jenkins on AWS.

This stack can be used as a starting point to build a production ready Jenkins on AWS.

More details can be found on my blog post (in french).

How it works

This stack will deploy Jenkins Master on ECS Fargate. It uses a docker image based on the official Jenkins. See docker/ folder.

The following main resources will be created:

  • An application load balancer in front of Jenkins.
  • A network load balancer for Agent -> Master communication. For more information about how Master <-> Agents communication works, see this page.
  • An EFS to store Jenkins configuration.
  • An S3 bucket used by the Jenkins Configuration as code plugin to get the configuration generated by Terraform.
  • Two log groups for the Master and agents logs

Architecture

Prerequisites

  • A VPC with public and private subnets configured properly (route table, nat gateways...)
  • An IAM user with the proper policies to run Terraform on the following services: EC2, ECS, IAM, S3, Cloudwatch, EFS, Route53 et ACM.
  • A recent version of Terraform ( > 0.12.20)

The only required Terraform variables are:

  • vpc_id : the VPC ID
  • public_subnets : public subnets IDs
  • private_subnets : private subnets IDs

See variables.tf for all the possible variables to override.

AWS authentication:

export AWS_PROFILE=...
# or
export AWS_SECRET_ACCESS_KEY=""
export AWS_ACCESS_KEY_ID=""

Deployment:

export TF_VAR_vpc_id="vpc-123456789"
export TF_VAR_private_subnets='["private-subnet-a", "private-subnet-b", "private-subnet-c"]'
export TF_VAR_public_subnets='["public-subnet-a", "public--subnet-b", "public-subnet-c"]'
terraform init
terraform apply

Variables

Name Description Type Default Required
private_subnets Private subnets to deploy Jenkins and the internal NLB set(string) n/a yes
public_subnets Public subnets to deploy the load balancer set(string) n/a yes
vpc_id The VPC id string n/a yes
agent_docker_image Docker image to use for the default agent. See: https://hub.docker.com/r/jenkins/inbound-agent/ string "elmhaidara/jenkins-alpine-agent-aws:latest" no
agents_log_retention_days Retention days for Agents log group number 5 no
aws_region The AWS region in which deploy the resources string "eu-west-1" no
default_tags Default tags to apply to the resources map(string)
{
"Application": "Jenkins",
"Environment": "test",
"Terraform": "True"
}
no
efs_burst_credit_balance_threshold Threshold below which the metric BurstCreditBalance associated alarm will be triggered. Expressed in bytes number 1154487209164 no
efs_performance_mode EFS performance mode. Valid values: generalPurpose or maxIO string "generalPurpose" no
efs_provisioned_throughput_in_mibps The throughput, measured in MiB/s, that you want to provision for the file system. Only applicable with throughput_mode set to provisioned. number null no
efs_throughput_mode Throughput mode for the file system. Valid values: bursting, provisioned. When using provisioned, also set provisioned_throughput_in_mibps string "bursting" no
fargate_platform_version Fargate platform version to use. Must be >= 1.4.0 to be able to use Fargate string "1.4.0" no
master_cpu_memory CPU and memory for Jenkins master. Note that all combinations are not supported with Fargate
object({
memory = number
cpu = number
})
{
"cpu": 1024,
"memory": 2048
}
no
master_deployment_percentages The Min and Max percentages of Master instance to keep when updating the service. See https://docs.aws.amazon.com/AmazonECS/latest/developerguide/update-service.html
object({
min = number
max = number
})
{
"max": 100,
"min": 0
}
no
master_docker_image Jenkins Master docker image to use string "elmhaidara/jenkins-aws-fargate:latest" no
master_docker_user_uid_gid Jenkins User/Group ID inside the container. One should consider using access point. number 0 no
master_java_opts JAVA_OPTS to pass to the JVM string "" no
master_jnlp_port JNLP port used by Jenkins agent to communicate with the master number 50000 no
master_listening_port Jenkins container listening port number 8080 no
master_log_retention_days Retention days for Master log group number 14 no
master_num_executors Set this to a number > 0 to be able to build on master (NOT RECOMMENDED) number 0 no
route53_subdomain The subdomain to use for Jenkins Master. Used when var.route53_zone_name is not empty string "jenkins" no
route53_zone_name A Route53 zone name to use to create a DNS record for the Jenkins Master. Required for HTTPs. string "" no

References: