packer‐pipeline - robjcook/sync GitHub Wiki
To create a Jenkins pipeline that runs Packer to maintain a baseline AWS AMI, you can follow these steps. This pipeline will automate the process of building, validating, and deploying AWS AMIs using Packer.
Prerequisites:
- Jenkins is installed and running.
- Packer is installed on the Jenkins server or the build agent.
- AWS CLI is installed and configured with the appropriate IAM permissions.
- A Packer template (JSON or HCL) is created for building your AMI.
Step 1: Install Required Plugins
Ensure the following plugins are installed in Jenkins:
- Pipeline: for creating pipeline jobs.
- AWS Credentials: to manage AWS credentials.
Step 2: Create a Jenkins Pipeline Job
-
Open Jenkins Dashboard:
- Navigate to
New Item
. - Enter a name for your job (e.g., "Packer-AMI-Pipeline").
- Select
Pipeline
and clickOK
.
- Navigate to
-
Configure Pipeline:
- Scroll down to the
Pipeline
section. - Choose
Pipeline script
and add the following Groovy script.
- Scroll down to the
Step 3: Jenkins Pipeline Script
Here's a sample Jenkins pipeline script:
pipeline {
agent any
environment {
AWS_REGION = 'us-east-1' // Replace with your AWS region
PACKER_TEMPLATE = 'packer-template.json' // Replace with your Packer template file name
AWS_CREDENTIALS_ID = 'aws-credentials-id' // Replace with your AWS credentials ID from Jenkins
}
stages {
stage('Checkout') {
steps {
// Checkout code from version control
git branch: 'main', url: 'https://github.com/your-repo/packer-ami-repo.git' // Replace with your repository
}
}
stage('Validate Packer Template') {
steps {
script {
// Validate the Packer template
sh 'packer validate ${PACKER_TEMPLATE}'
}
}
}
stage('Build AMI') {
steps {
script {
withAWS(credentials: "${AWS_CREDENTIALS_ID}", region: "${AWS_REGION}") {
// Build the AMI using Packer
sh 'packer build ${PACKER_TEMPLATE}'
}
}
}
}
stage('Post-Build Actions') {
steps {
script {
// Add any post-build steps like notifications, tagging, or cleanup
echo "Packer build completed. AMI created."
}
}
}
}
post {
always {
// Archive Packer logs or other files if needed
archiveArtifacts artifacts: '**/packer-log.txt', allowEmptyArchive: true
}
success {
echo "Pipeline completed successfully!"
}
failure {
echo "Pipeline failed. Check the logs for more details."
}
}
}
Explanation of the Pipeline Script:
environment {}
: This block sets environment variables like AWS region, Packer template file, and AWS credentials ID.stages {}
: Defines the different stages of the pipeline.Checkout
: Checks out your Packer template and related files from the version control repository.Validate Packer Template
: Runspacker validate
to ensure the template is valid.Build AMI
: Runspacker build
to create the AMI. It uses the AWS credentials defined in Jenkins.Post-Build Actions
: Any actions you want to perform after the build, such as tagging the AMI or sending notifications.
post {}
: Handles post-pipeline tasks like archiving artifacts and handling success or failure messages.
Step 4: Run the Pipeline
-
Save and Run the Job:
- Save the pipeline configuration.
- Click
Build Now
to trigger the pipeline.
-
Monitor the Job:
- Check the console output to monitor the stages of the pipeline as it progresses.
Step 5: Post-Build Activities
- You may want to add additional steps to handle AMI tagging, deregistering old AMIs, or sending notifications based on your specific requirements.
To modify the Packer template so that it references Ansible playbooks stored in a Git repository, you'll need to include steps to clone the repository and run the playbooks from the cloned directory. Below is an updated version of the Packer template that accomplishes this.
packer-template.json
)
Updated Packer Template ({
"variables": {
"aws_region": "us-east-1",
"source_ami": "ami-0c55b159cbfafe1f0", // Replace with the appropriate base AMI ID
"instance_type": "t2.micro",
"ssh_username": "ec2-user",
"ami_name": "my-custom-ami-{{timestamp}}",
"ansible_repo_url": "https://github.com/your-organization/your-ansible-repo.git", // Replace with your Git repository URL
"ansible_repo_branch": "main" // Replace with the branch you want to use
},
"builders": [
{
"type": "amazon-ebs",
"region": "{{user `aws_region`}}",
"source_ami": "{{user `source_ami`}}",
"instance_type": "{{user `instance_type`}}",
"ssh_username": "{{user `ssh_username`}}",
"ami_name": "{{user `ami_name`}}",
"ami_description": "An AMI built with Packer and configured with Ansible",
"associate_public_ip_address": true,
"tags": {
"Name": "Packer-Ansible-AMI",
"Environment": "Dev"
}
}
],
"provisioners": [
{
"type": "shell",
"inline": [
"sudo amazon-linux-extras install ansible2 git -y",
"ansible --version"
]
},
{
"type": "shell",
"inline": [
"git clone --branch {{user `ansible_repo_branch`}} {{user `ansible_repo_url`}} /tmp/ansible",
"cd /tmp/ansible",
"ansible-playbook -i 'localhost,' -c local playbook.yml" // Replace 'playbook.yml' with your main playbook if different
]
},
{
"type": "shell",
"inline": [
"echo 'Cleaning up...'",
"sudo yum clean all",
"sudo rm -rf /tmp/* /var/tmp/*"
]
}
]
}
Explanation of Changes
-
New Variables:
ansible_repo_url
: The URL of the Git repository containing your Ansible playbooks.ansible_repo_branch
: The branch of the repository you want to clone (e.g.,main
ormaster
).
-
Provisioners:
- First Shell Step:
- Installs both Ansible and Git on the instance.
- Second Shell Step:
- Clones the specified Git repository and branch into the
/tmp/ansible
directory. - Navigates to the cloned repository directory.
- Runs the Ansible playbook using
ansible-playbook
command. The playbook is executed locally (-c local
) with the inventory specified aslocalhost
.
- Clones the specified Git repository and branch into the
- Third Shell Step:
- Cleans up the system before creating the AMI.
- First Shell Step:
Integration with Jenkins
To use this updated Packer template in your Jenkins pipeline:
-
Store the Packer Template in Your Repository:
- Ensure the
packer-template.json
file is stored in the same repository as your Jenkins pipeline or another accessible location.
- Ensure the
-
Jenkins Pipeline Configuration:
- Use the existing pipeline script from earlier, ensuring that the environment variables and template file paths match.
Example Ansible Playbook in Git Repo
Assume your Git repository has the following structure:
your-ansible-repo/
├── playbook.yml
└── roles/
├── common/
│ └── tasks/
│ └── main.yml
└── webserver/
└── tasks/
└── main.yml
The playbook.yml
might look like this:
---
- hosts: localhost
become: true
roles:
- role: common
- role: webserver
This structure allows Packer to clone the repository and run the playbook.yml
, which can include roles and tasks to configure the instance.
Running the Pipeline
- Run the Jenkins Pipeline:
- Trigger the Jenkins pipeline to build the AMI.
- The pipeline will use Packer to launch an EC2 instance, clone the Ansible repository, run the Ansible playbook, and create an AMI with the configured environment.
By using this approach, you maintain your Ansible code in a version-controlled repository and dynamically apply the configurations during the Packer build process. This also allows for easy updates to the configurations without needing to modify the Packer template itself—simply update the Ansible repository.
Step 6: Automate the Pipeline
- Schedule the Jenkins job to run periodically (e.g., daily, weekly) or trigger it based on code changes in your repository.
This pipeline provides a foundation for automating the creation and maintenance of AWS AMIs using Packer. You can extend and customize it based on your infrastructure needs.