Infrastructure as Code (IaC) with Jenkins and AWS CloudFormation

Infrastructure as code, more commonly referred to as IaC, involves infrastructure being provisioned through code or templates. This facilitates versioning, easy replication, collaboration, and rollbacks as well as integration with DevOps protocols for fast development and secure execution.

Jenkins and AWS CloudFormation are widely used in IaC models:

  • Jenkins performs continuous integration and continuous deployment (CI/CD) and is responsible for the building, testing, and deploying of projects.
  • CloudFormation supplements Jenkins, offering declarative templates for provisioning and modifying AWS infrastructure with a focus on idempotent and versioned operations.

Together, Jenkins and AWS CloudFormation improve the performance and reliability of IaC processes in complex and dynamic cloud architectures. This allows you to smoothly integrate infrastructure changes into a continuous deployment process.

This article provides insights into both Jenkins and CloudFormation, highlighting their relevance today in efforts to redesign IT functions and adopt cloud-first architectures.

Core principles of IaC

Infrastructure as code automates the configuration and management of your infrastructure, in contrast to traditional methods that rely on physical hardware or graphical interfaces.

IaC’s automation completely changes the performance of traditional IT processes and procedures, as it coordinates and unifies them across different systems. IaC achieves this via the following characteristics.

Declarative definition

IaC focuses on the goals to be met, not how to achieve them. It enables imperative architectural definitions, stating what the infrastructure should be like.

Automation

As already noted, IaC is based on the automated provisioning and management of all infrastructure resources. This results in less manual work, which in turn leads to a lower risk of human error and faster deployment.

Version control

IaC registers and stores different infrastructure settings within a version control system such as Git. This practice helps monitor changes, revert back to the previous state if necessary, and share changes among team members.

Consistency and repeatability

Infrastructure configurations will always be the same across your environments—development, testing, and production. This helps eliminate configuration drift and makes deployments more reliable and replicable.

Scalability

With the help of IaC, infrastructure resources can be scaled on the fly. Code or templates will allow you to increase or decrease resources without human intervention in response to demand fluctuations.

Benefits of IaC

There are numerous advantages to implementing infrastructure as code.

Speed and efficiency

IaC facilitates provisioning and updates, while the time taken to deploy is drastically reduced; this allows for rapid adaptation to market needs.

Reduced risk and improved stability

IaC enables standardization, which enhances system stability, reliability, and performance. Standard configurations also help avoid conventional errors.

Cost savings

IaC contributes to the improvement of infrastructure management. It can decrease resource utilization, as well as overall operating costs, and frees up resources for strategic initiatives.

Collaboration

IaC promotes collaboration between the DevOps and security teams. They must work together to define and implement best practices in building templates with version control for infrastructure provision across the organization.

Agility and innovation

IaC enables swift responses to market changes, supports continuous integration and deployment, and promotes innovation through faster software development cycles and iterative improvements.

Given the above characteristics, IaC represents a paradigm shift in IT operations, leveraging automation, version control, and codified configurations to achieve greater efficiency, reliability, and scalability. Embracing IaC empowers organizations to streamline operations, reduce risks, and accelerate delivery to customers, ultimately driving business success in a competitive digital landscape.

AWS CloudFormation basics

AWS CloudFormation enables the declarative definition and provisioning of resources via templates. This approach facilitates AWS infrastructure management, makes version control possible, and ensures that provisioning is consistent across all environments.

Core components of CloudFormation

CloudFormation involves several elements working together to enable infrastructure as code capabilities.

Templates

JSON- or YAML-formatted templates serve as a sort of map, clarifying everything required to provision and configure AWS resources and their interdependencies.

Stacks

Templates are executed as stacks, separate bundles of AWS resources. Stacks can be easily created, updated, or deleted; they also ensure consistency and simplify the instance deployment.

Resources

Each AWS resource, such as an EC2 instance, S3 bucket, or VPC, is created and declared in a CloudFormation template. These resources can also define properties, dependencies, and other settings.

Parameters and outputs

Templates can also contain properties that define values of the resources at creation time (e.g., instances type and IP ranges), along with references that dictate what outputs of the stack should be propagated to the client (e.g., endpoints and resource IDs).

Declarative syntax and templates

CloudFormation templates use a declarative syntax. This contrasts with imperative programming, as it focuses on what resources should exist and how they should be configured rather than the sequence of commands needed to create them.

Example templates for common resources

Below, we present simplified examples of CloudFormation templates for commonly used AWS resources.

EC2 instance:

# cat ec2_instance.yaml
Resources:
MyEC2Instance
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: ami-0d5eff06f840b45e9
KeyName: my-key-pair
SecurityGroupIds:
- sg-12345678

S3 bucket:

# cat s3_bucket.yaml
Resources:
MyS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: sample-zoho-s3-bucket

Virtual private cloud (VPC):

# cat virtual_private_cloud.yaml
Resources:
MyVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: MyVPC

Along with defining resources, these templates also define their properties such as instance types, bucket names, CIDR blocks, and tags. They illustrate the simplicity and power of CloudFormation in orchestrating complex infrastructure deployments with just a few lines of code.

Introduction to Jenkins

Jenkins is a tool that orchestrates and manages CI/CD processes aimed at automating and streamlining the software delivery lifecycle.

To make sure that new code contributions do not conflict with pre-existing code, continuous integration focuses on automating the merging of code changes from numerous contributors into a common repository. Continuous deployment helps by automating the deployment of code changes to production or other environments following multiple testing and validation steps.

Jenkins facilitates both CI and CD. An open-source automation server, it is widely used due to its flexibility and extensibility for building, testing, and deploying software applications. It also integrates with numerous plugins, enriching applications with a range of tools and platforms.

Jenkins’ key features

Three primary attributes make Jenkins such a robust automation server:

  • Automation: Jenkins leverages automation for faster development, testing, and deployment.
  • Integration: Jenkins integrates with version control systems, build tools, and deployment platforms, creating a unified environment for teams.
  • Plugins: Jenkins supports over 1,500 plugins for diverse needs ranging from automating infrastructure deployment to managing complex CI/CD pipelines.

Installing and configuring Jenkins for IaC

To install Jenkins for infrastructure as code, you will need to download Jenkins and install it via the official installer or Docker. You will also need a Java Development Kit (JDK) that supports Jenkins’ runtime and is suitable for your OS.

After installation, access the Jenkins web interface, log in to Jenkins using the initial default password, and configure the admin settings.

Jenkins initial admin password wizard Fig 1: Jenkins initial admin password wizard

Click on "Manage Jenkins" to install Git and the AWS CLI plugins for automation. Next, define a “Jenkinsfile” in version control for building code, testing it, and deploying CloudFormation templates.

Manage Jenkins plugins Fig 2: Manage Jenkins plugins

Now you are ready to integrate Jenkins with GitLab/GitHub for automated Pipeline executions on commits/pull requests. Make sure to verify your settings for a smooth CI/CD process.

Jenkins Pipeline creation Fig 3: Jenkins Pipeline creation Enabling GitHub for Jenkins Pipeline Fig 4: Enabling GitHub for Jenkins Pipeline Integrating GitHub for Jenkins Pipeline Fig 5: Integrating GitHub for Jenkins Pipeline

Jenkins’ simple setup optimizes IaC workflows, facilitating efficient infrastructure provisioning, deployment, and testing. Once Jenkins is installed and configured for IaC, the next step involves automating IaC deployment through Jenkins Pipeline.

Automating IaC deployment with Jenkins Pipeline

First off, you will have to create and configure Pipeline to trigger your CloudFormation deployments.

From the Jenkins home page, navigate to "Manage Jenkins" > "Manage Plugins" to install the AWS CloudFormation plugin.

Integrating Jenkins with AWS CloudFormation plugin Fig 6: Integrating Jenkins with AWS CloudFormation plugin

You will next have to configure Jenkins to integrate with your AWS account, setting up credentials securely for API access. Define a Jenkins Pipeline that includes stages for initializing CloudFormation stacks, updating stacks with changes, and managing deployments across environments.

Example Jenkins Pipeline for CloudFormation

Below is an example Jenkins Pipeline (a Jenkinsfile) for deploying infrastructure using AWS CloudFormation:

pipeline {
agent any
environment {
AWS_REGION = 'us-east-1'
CF_STACK_NAME = 'my-cloudformation-stack'
}
stages {
stage('Initialize') {
steps {
script {
sh 'aws cloudformation create-stack --stack-name $CF_STACK_NAME --template-body $(pwd)template.yml --capabilities CAPABILITY_IAM'
}
}
}

stage('Deploy') {
steps {
script {
sh 'aws cloudformation deploy --stack-name $CF_STACK_NAME --template-file $(pwd)/template.yml --capabilities CAPABILITY_IAM'
}
}
}

stage('Cleanup') {
steps {
script {
sh 'aws cloudformation delete-stack --stack-name $CF_STACK_NAME'
}
}
}
}
}

This Jenkins Pipeline script leverages AWS CloudFormation for automating infrastructure deployment. It begins by setting up the execution environment, specifying the AWS region (us-east-1) and CloudFormation stack name (my-cloudformation-stack) variables.

The Pipeline consists of three stages: Initialize, Deploy, and Cleanup.

In the Initialize stage, the script uses AWS CLI commands to create a new CloudFormation stack named my-cloudformation-stack. It deploys a CloudFormation template (template.yml) located in the current directory $(pwd), granting the necessary IAM permissions (CAPABILITY_IAM) for resources. Also, we can provide the absolute path by replacing the “pwd” command.

The Deploy stage handles CloudFormation stack updates. It deploys changes by executing the aws cloudformation deploy command with the updated template file.

Finally, the Cleanup stage deletes the CloudFormation stack to remove resources and reduce costs after the deployment is complete. The aws cloudformation delete-stack command in this stage ensures proper cleanup of all resources provisioned by the stack.

This Pipeline ensures consistent and reliable deployment processes within Jenkins by streamlining infrastructure provisioning and maintenance using AWS CloudFormation.

Using IaC to deploy monitoring agents

Integrating monitoring agents into infrastructure-as-code deployments is vital for maintaining cloud system health, performance, and security. By embedding monitoring configurations into IaC templates such as AWS CloudFormation or Terraform, teams ensure consistent monitoring across environments.

Deploying a Monitoring Agent with CloudFormation: A Practical Example

Let's quickly look at an example that demonstrates how to use AWS CloudFormation to deploy an EC2 instance with the AWS CloudWatch agent, which collects key performance metrics for system monitoring:

AWSTemplateFormatVersion: '2024-11-11'
Resources:
CloudWatchAgentRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: '2024-11-11'
Statement:
- Effect: 'Allow'
Action: 'sts:AssumeRole'
Principal:
Service: 'ec2.amazonaws.com'
Policies:
- PolicyName: 'CloudWatchAgentPolicy'
PolicyDocument:
Version: '2024-11-11'
Statement:
- Effect: 'Allow'
Action:
- 'cloudwatch:PutMetricData'
- 'cloudwatch:PutDashboard'
- 'logs:PutLogEvents'
- 'logs:CreateLogStream'
- 'logs:CreateLogGroup'
Resource: '*'

EC2Instance:
Type: 'AWS::EC2::Instance'
Properties:
InstanceType: 't2.micro'
ImageId: 'ami-0abcdef1234567890'
KeyName: 'replace-with-key-pair'
IamInstanceProfile:
Ref: 'CloudWatchAgentProfile'
SecurityGroups:
- Ref: EC2SecurityGroup
UserData:
Fn::Base64: |
#!/bin/bash
# Install CloudWatch Agent
sudo yum install -y amazon-cloudwatch-agent

# Create CloudWatch Agent configuration file
cat <<EOT > /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
{
"agent": {
"metrics_collection_interval": 60,
"run_as_user": "root"
},
"metrics": {
"append_dimensions": {
"InstanceId": "${!aws:InstanceId}"
},
"metrics_collected": {
"CPU": {
"measurement": [
"usage_idle",
"usage_user",
"usage_system"
],
"metrics_collection_interval": 60
},
"Mem": {
"measurement": [
"mem_used",
"mem_free",
"mem_cached"
],
"metrics_collection_interval": 60
}
}
}
}
EOT

# Start CloudWatch Agent
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a start -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json -s
EC2SecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: Enable SSH access
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: '0.0.0.0/0' # Adjust for your security needs
CloudWatchAgentProfile:
Type: 'AWS::IAM::InstanceProfile'
Properties:
Roles:
- Ref: 'CloudWatchAgentRole'

In the above code, the CloudFormation template creates an EC2 instance with an associated IAM role that allows metrics to be sent to CloudWatch. A UserData script installs the CloudWatch agent and configures it to collect system metrics such as CPU and memory usage. The script then starts the agent, ensuring it sends data to CloudWatch. Meanwhile, a security group allows SSH access, and an instance profile links the IAM role to the instance for necessary permissions.

This template automates the entire process of provisioning the EC2 instance and setting up CloudWatch monitoring. Such a proactive approach detects issues early, aids in troubleshooting, supports capacity planning, and enhances system reliability. It further empowers teams to shift left and seamlessly integrate continuous monitoring into their DevOps workflows, promoting collaboration, continuous improvement, and resilience in dynamic cloud environments.

Shifting left for observability

The shift left strategy advocates for the early integration of monitoring into the CI/CD pipeline. Embedding monitoring agents in IaC templates empowers developers to detect and address performance issues and security vulnerabilities early on, fostering rapid feedback loops and iterative improvements.

Implementing DevOps for continuous monitoring

To establish a DevOps pipeline with continuous monitoring via IaC, organizations must define their monitoring needs, choose the right tools for these needs, and integrate them with their IaC templates.

Automation tools such as Jenkins or GitLab automate template deployment, ensuring consistent deployments and updates of both applications and monitoring agents. Furthermore, configuring monitoring dashboards and alerts based on predefined rules ensures timely notifications of critical events, fostering proactive responses.

Conclusion

Mastering IaC principles lays a solid foundation for efficient cloud management. AWS CloudFormation simplifies provisioning with declarative templates, ensuring consistency and scalability.

Jenkins automates IaC deployments via Pipeline, optimizing workflows and reducing manual effort. Lastly, integrating infrastructure as code for deploying monitoring agents enhances visibility and proactive management of cloud resources.

This holistic approach not only accelerates deployment cycles but also strengthens system reliability and security.

By embracing these tools and practices, organizations empower teams to achieve agile, scalable infrastructure operations, delivering continuous improvement in today’s competitive cloud landscape.

Stay ahead of the competition by mastering infrastructure as code with Jenkins and AWS CloudFormation. It will empower your team to automate deployments, achieve consistency, and enhance visibility across your cloud infrastructure.

Begin your journey towards scalable, reliable, and secure cloud management today.

Was this article helpful?

Related Articles

Write For Us

Write for Site24x7 is a special writing program that supports writers who create content for Site24x7 "Learn" portal. Get paid for your writing.

Write For Us

Write for Site24x7 is a special writing program that supports writers who create content for Site24x7 “Learn” portal. Get paid for your writing.

Apply Now
Write For Us