Skip to main content
Service Catalog Version 0.96.9Last updated in version 0.96.2

Jenkins CI Server

View SourceRelease Notes

Overview

This service contains code to deploy Jenkins CI Server on AWS.

Jenkins architectureJenkins architecture

Features

  • Deploy Jenkins CI Server
  • Run Jenkins in an Auto Scaling Group for high availability
  • Store the JENKINS_HOME directory in an EBS Volume
  • Take nightly snapshots of the EBS Volume using the ec2-backup scheduled Lambda function
  • Run an ALB in front of Jenkins so it’s not accessible directly to users
  • Configure DNS in Route 53 and TLS in AWS Certificate Manager (ACM)
  • Send all logs and metrics to CloudWatch
  • Configure alerts in CloudWatch for CPU, memory, and disk space usage
  • Manage SSH access with IAM groups using ssh-grunt
  • Manage deployment permissions for the server using IAM roles
  • OS hardening, including fail2ban, ntp, auto-update, ip-lockdown, and more

Learn

note

This repo is a part of the Gruntwork Service Catalog, a collection of reusable, battle-tested, production ready infrastructure code. If you’ve never used the Service Catalog before, make sure to read How to use the Gruntwork Service Catalog!

  • CI/ CD Core Concepts: An overview of the core concepts you need to understand what a typical CI/CD pipeline entails for application and infrastructure code, including a sample workflow, infrastructure to support CI/CD, an threat models to consider to protect your infrastructure.

  • Jenkins Documentation: The official documentation for Jenkins.

Deploy

Non-production deployment (quick start for learning)

If you just want to try this repo out for experimenting and learning, check out the following resources:

  • examples/for-learning-and-testing folder: The examples/for-learning-and-testing folder contains standalone sample code optimized for learning, experimenting, and testing (but not direct production usage).

Production deployment

If you want to deploy this repo in production, check out the following resources:

Reference

Required

The domain name used for an SSL certificate issued by the Amazon Certificate Manager (ACM).

alb_subnet_idslist(string)required

The IDs of the subnets in which to deploy the ALB that runs in front of Jenkins. Must be subnets in vpc_id.

amistringrequired

The ID of the AMI to run on the Jenkins server. This should be the AMI build from the Packer template jenkins-ubuntu.json. One of ami or ami_filters is required. Set to null if looking up the ami with filters.

ami_filtersobject(…)required

Properties on the AMI that can be used to lookup a prebuilt AMI for use with Jenkins. You can build the AMI using the Packer template jenkins-ubuntu.json. Only used if ami is null. One of ami or ami_filters is required. Set to null if passing the ami ID directly.

object({
# List of owners to limit the search. Set to null if you do not wish to limit the search by AMI owners.
owners = list(string)

# Name/Value pairs to filter the AMI off of. There are several valid keys, for a full reference, check out the
# documentation for describe-images in the AWS CLI reference
# (https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-images.html).
filters = list(object({
name = string
values = list(string)
}))
})
domain_namestringrequired

The domain name for the DNS A record to add for Jenkins (e.g. jenkins.foo.com). Must be in the domain managed by hosted_zone_id.

hosted_zone_idstringrequired

The ID of the Route 53 Hosted Zone in which to create a DNS A record for Jenkins.

instance_typestringrequired

The instance type to use for the Jenkins server (e.g. t2.medium)

jenkins_subnet_idstringrequired

The ID of the subnet in which to deploy Jenkins. Must be a subnet in vpc_id.

memorystringrequired

The amount of memory to give Jenkins (e.g., 1g or 512m). Used for the -Xms and -Xmx settings.

vpc_idstringrequired

The ID of the VPC in which to deploy Jenkins

Optional

alarms_sns_topic_arnlist(string)optional

The ARNs of SNS topics where CloudWatch alarms (e.g., for CPU, memory, and disk space usage) should send notifications. Also used for the alarms if the Jenkins backup job fails.

[]

The IP address ranges in CIDR format from which to allow incoming HTTP requests to Jenkins.

[]

The IDs of security groups from which to allow incoming HTTP requests to Jenkins.

[]
allow_ssh_from_cidr_blockslist(string)optional

The IP address ranges in CIDR format from which to allow incoming SSH requests to Jenkins.

[]

The IDs of security groups from which to allow incoming SSH requests to Jenkins.

[]

How often, in seconds, the backup job is expected to run. This is the same as backup_job_schedule_expression, but unfortunately, Terraform offers no way to convert rate expressions to seconds. We add a CloudWatch alarm that triggers if the value of backup_job_metric_name and backup_job_metric_namespace isn't updated within this time period, as that indicates the backup failed to run.

86400

The name for the CloudWatch Metric the AWS lambda backup job will increment every time the job completes successfully.

"jenkins-backup-job"

The namespace for the CloudWatch Metric the AWS lambda backup job will increment every time the job completes successfully.

"Custom/Jenkins"

A cron or rate expression that specifies how often to take a snapshot of the Jenkins server for backup purposes. See https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html for syntax details.

"rate(1 day)"
backup_using_dlmbooloptional

Set to true to backup the Jenkins Server using AWS Data Lifecycle Management Policies.

true

Set to true to backup the Jenkins Server using a Scheduled Lambda Function.

false
build_permission_actionslist(string)optional

The list of IAM actions this Jenkins server should be allowed to do: e.g., ec2:, s3:, etc. This should be the list of IAM permissions Jenkins needs in this AWS account to run builds. These permissions will be added to the server's IAM role for all resources ('*').

[]
cloud_init_partsmap(object(…))optional

Cloud init scripts to run on the Jenkins server when it is booting. See the part blocks in https://www.terraform.io/docs/providers/template/d/cloudinit_config.html for syntax.

map(object({
filename = string
content_type = string
content = string
}))
{}

The ID (ARN, alias ARN, AWS ID) of a customer managed KMS Key to use for encrypting log data.

null

The number of days to retain log events in the log group. Refer to https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group#retention_in_days for all the valid values. When null, the log events are retained forever.

null
cloudwatch_log_group_tagsmap(string)optional

Tags to apply on the CloudWatch Log Group, encoded as a map where the keys are tag keys and values are tag values.

null

Set to true to create a public DNS A record in Route53 for Jenkins.

true
custom_tagsmap(string)optional

A list of custom tags to apply to Jenkins and all other resources.

{}
default_userstringoptional

The default OS user for the Jenkins AMI. For AWS Ubuntu AMIs, which is what the Packer template in jenkins-ubunutu.json uses, the default OS user is 'ubuntu'.

"ubuntu"

How often this lifecycle policy should be evaluated, in hours.

24

The name of the data lifecyle management schedule

"daily-last-two-weeks"

How many snapshots to keep. Must be an integer between 1 and 1000.

15
dlm_backup_job_schedule_timeslist(string)optional

A list of times in 24 hour clock format that sets when the lifecyle policy should be evaluated. Max of 1.

[ "03:00" ]
ebs_kms_key_arnstringoptional

The ARN of the KMS key used for encrypting the Jenkins EBS volume. The module will grant Jenkins permission to use this key.

null

Whether or not the provide EBS KMS key ARN is a key alias. If providing the key ID, leave this set to false.

false

Set to true to enable several basic CloudWatch alarms around CPU usage, memory usage, and disk space usage. If set to true, make sure to specify SNS topics to send notifications to using alarms_sns_topic_arn.

true

Set to true to add AIM permissions to send logs to CloudWatch. This is useful in combination with https://github.com/gruntwork-io/terraform-aws-monitoring/tree/master/modules/logs/cloudwatch-log-aggregation-scripts to do log aggregation in CloudWatch.

true

Set to true to add IAM permissions to send custom metrics to CloudWatch. This is useful in combination with https://github.com/gruntwork-io/terraform-aws-monitoring/tree/master/modules/agents/cloudwatch-agent to get memory and disk metrics in CloudWatch for your Jenkins server.

true
enable_ip_lockdownbooloptional

Enable ip-lockdown to block access to the instance metadata. Defaults to true.

true
enable_ssh_gruntbooloptional

Set to true to add IAM permissions for ssh-grunt (https://github.com/gruntwork-io/terraform-aws-security/tree/master/modules/ssh-grunt), which will allow you to manage SSH access via IAM groups.

true

A list of IAM role ARNs in other AWS accounts that Jenkins will be able to assume to do automated deployment in those accounts.

[]

If you are using ssh-grunt and your IAM users / groups are defined in a separate AWS account, you can use this variable to specify the ARN of an IAM role that ssh-grunt can assume to retrieve IAM group and public SSH key info from that account. To omit this variable, set it to an empty string (do NOT use null, or Terraform will complain).

""

The period, in seconds, over which to measure the CPU utilization percentage for the ASG.

60

Trigger an alarm if the ASG has an average cluster CPU utilization percentage above this threshold.

90

Sets how this alarm should handle entering the INSUFFICIENT_DATA state. Based on https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-and-missing-data. Must be one of: 'missing', 'ignore', 'breaching' or 'notBreaching'.

"missing"

The period, in seconds, over which to measure the root disk utilization percentage for the ASG.

60

Trigger an alarm if the ASG has an average cluster root disk utilization percentage above this threshold.

90

Sets how this alarm should handle entering the INSUFFICIENT_DATA state. Based on https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-and-missing-data. Must be one of: 'missing', 'ignore', 'breaching' or 'notBreaching'.

"missing"

The period, in seconds, over which to measure the Memory utilization percentage for the ASG.

60

Trigger an alarm if the ASG has an average cluster Memory utilization percentage above this threshold.

90

Sets how this alarm should handle entering the INSUFFICIENT_DATA state. Based on https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-and-missing-data. Must be one of: 'missing', 'ignore', 'breaching' or 'notBreaching'.

"missing"
is_internal_albbooloptional

Set to true to make the Jenkins ALB an internal ALB that cannot be accessed from the public Internet. We strongly recommend setting this to true to keep Jenkins more secure.

true
jenkins_device_namestringoptional

The OS device name where the Jenkins EBS volume should be attached

"xvdh"
jenkins_mount_pointstringoptional

The OS path where the Jenkins EBS volume should be mounted

"/jenkins"
jenkins_userstringoptional

The OS user that should be used to run Jenkins

"jenkins"

Sets how the backup job alarm should handle entering the INSUFFICIENT_DATA state. Based on https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-and-missing-data. Must be one of: 'missing', 'ignore', 'breaching' or 'notBreaching'.

"missing"

Set to true to encrypt the Jenkins EBS volume.

true
jenkins_volume_sizenumberoptional

The amount of disk space, in GB, to allocate for the EBS volume used by the Jenkins server.

200
jenkins_volume_typestringoptional

The type of volume to use for the EBS volume used by the Jenkins server. Must be one of: standard, gp2, io1, sc1, or st1.

"gp2"
keypair_namestringoptional

The name of a Key Pair that can be used to SSH to the Jenkins server. Leave blank if you don't want to enable Key Pair auth.

null
namestringoptional

Enter the name of the Jenkins server

"jenkins"

The type of volume to use for the root disk for Jenkins. Must be one of: standard, gp2, io1, sc1, or st1.

"gp2"
root_volume_sizenumberoptional

The amount of disk space, in GB, to allocate for the root volume of this server. Note that all of Jenkins' data is stored on a separate EBS Volume (see jenkins_volume_size), so this root volume is primarily used for the OS, temp folders, apps, etc.

100

When true, precreate the CloudWatch Log Group to use for log aggregation from the EC2 instances. This is useful if you wish to customize the CloudWatch Log Group with various settings such as retention periods and KMS encryption. When false, the CloudWatch agent will automatically create a basic log group to use.

true
skip_health_checkbooloptional

If set to true, skip the health check, and start a rolling deployment of Jenkins without waiting for it to initially be in a healthy state. This is primarily useful if the server group is in a broken state and you want to force a deployment anyway.

false
ssh_grunt_iam_groupstringoptional

If you are using ssh-grunt, this is the name of the IAM group from which users will be allowed to SSH to this Jenkins server. This value is only used if enable_ssh_grunt=true.

"ssh-grunt-users"

If you are using ssh-grunt, this is the name of the IAM group from which users will be allowed to SSH to this Jenkins server with sudo permissions. This value is only used if enable_ssh_grunt=true.

"ssh-grunt-sudo-users"
tenancystringoptional

The tenancy of this server. Must be one of: default, dedicated, or host.

"default"

When true, all IAM policies will be managed as dedicated policies rather than inline policies attached to the IAM roles. Dedicated managed policies are friendlier to automated policy checkers, which may scan a single resource for findings. As such, it is important to avoid inline policies when targeting compliance with various security standards.

true