An Amazon Machine Image (AMI) is the starting point for an EC2 virtual machine. It bundles an operating system, preinstalled software, and configuration in a read-only image. When you launch an EC2 instance, you choose an AMI to determine what the machine starts with. section 3.1.1
To choose an AMI for a new instance:
- In the EC2 launch wizard, select an operating system image; Amazon Linux 2 AMI (HVM) is one example. section 3.1.1
- Check that the image meets your application's requirements, fits an operating system you can manage, and comes from a publisher you trust. Images are available from AWS, third parties, the community, and AWS Marketplace. section 3.1.1
A custom AMI can hold an application that is already installed. This supports an immutable-server approach: build a new image for each change, then replace servers launched from the old image rather than modifying them in place. Automating image creation matters because every change calls for another build. section 15.3
Build and deploy an Etherpad image
A Packer template selects a source AMI, launches a temporary EC2 instance, connects through Systems Manager, and runs a shell provisioner to install Etherpad. Packer stops the instance, creates an AMI, and terminates the temporary instance. Run `packer init chapter15/` followed by `packer build chapter15/etherpad.pkr.hcl`. Pass the resulting AMI ID to a CloudFormation stack; its launch template uses that ID when an Auto Scaling group replaces instances during a rolling update. section 15.3
Listing 15.7 The Packer template to build an Etherpad AMI, part 2
source "amazon-ebs" "etherpad" {
ami_name = "awsinaction-etherpad-{{timestamp}}" #1
tags = {
Name = "awsinaction-etherpad"
}
instance_type = "t2.micro" #2
region = "us-east-1" #3
source_ami_filter { #4
filters = {
name = "amzn2-ami-hvm-2.0.*-x86_64-gp2" #5
root-device-type = "ebs"
virtualization-type = "hvm"
}
most_recent = true #6
owners = ["137112412989"] #7
}
ssh_username = "ec2-user"
ssh_interface = "session_manager" #8
communicator = "ssh"
iam_instance_profile = "ec2-ssm-core" #9
ami_groups = ["all"]
ami_regions = ["us-east-1"] #10
}
The Packer source configuration shows how a base Amazon Linux 2 AMI, build-instance settings, Systems Manager connection, and IAM instance profile fit together. section 15.3
Listing 15.9 Handing over the AMI ID to the CloudFormation template
# [...] Parameters: AMI: #1 Type: 'AWS::EC2::Image::Id' Description: 'The AMI ID' Resources: # [...] LaunchTemplate: Type: 'AWS::EC2::LaunchTemplate' Properties: # [...] LaunchTemplateData: ImageId: !Ref AMI #2 UserData: #3 'Fn::Base64': !Sub | #!/bin/bash -ex trap '/opt/aws/bin/cfn-signal -e 1 --stack ${AWS::StackName} \ --resource AutoScalingGroup --region ${AWS::Region}' ERR cd /opt/etherpad-lite/ echo " { \"title\": \"Etherpad\", \"dbType\": \"mysql\", \"dbSettings\": { \"host\": \"${Database.Endpoint.Address}\", \"port\": \"3306\", \"database\": \"etherpad\", \"user\": \"etherpad\", \"password\": \"etherpad\" }, \"exposeVersion\": true } " > settings.json #4 /opt/etherpad-lite/src/bin/fastRun.sh & #5 /opt/aws/bin/cfn-signal -e 0 --stack ${AWS::StackName} \ --resource AutoScalingGroup --region ${AWS::Region} # [...] #1 The parameter to set the AMI #2 The launch template references the AMI parameter. #3 Wait what? We are still using user data to inject a script into the boot process of the EC2 instance? #4 Yes, but only to create a settings file, which requires the database host name; this is not known when creating the AMI ... #5 ... and to start the Etherpad application.
The CloudFormation template accepts an AMI ID as a parameter and assigns it to the launch template's ImageId. section 15.3
