Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CloudFormation - always use latest AMI

The blog post Query for the latest Amazon Linux AMI IDs using AWS Systems Manager Parameter Store | AWS Compute Blog describes how to always reference the latest version of an distribution in a CloudFormation template.

# Use public Systems Manager Parameter
Parameters:
  LatestAmiId:
    Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
    Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'

Resources:
 Instance:
    Type: 'AWS::EC2::Instance'
    Properties:
      ImageId: !Ref LatestAmiId

How would that work for other distributions like RedHat and CentOS? What would be the parameter store path to use?

like image 211
benji Avatar asked Apr 02 '19 16:04

benji


People also ask

How often are Amazon AMI updated?

AWS provides updated, fully-patched Windows AMIs within five business days of Microsoft's patch Tuesday (the second Tuesday of each month). For more information, see Details about AWS Windows AMI versions. The AWS Windows AMIs contain the latest security updates available at the time they were created.

How do I force CloudFormation to update?

To force a rolling update, change the logical ID of the launch configuration resource, and then update the stack and any references pointing to the original logic ID (such as the associated Auto Scaling group). CloudFormation triggers a rolling update on the Auto Scaling group, replacing all instances.

How do you use AMI in CloudFormation?

To submit your product, you need to prepare and validate your AMIs, create your AWS CloudFormation templates, create an architectural diagram, complete the product load form, and submit the materials to AWS Marketplace.


2 Answers

As @John Rotenstein said, SSM seems to only have Amazon Linux AMIs. But you can still get others with DescribeImages. You can then create a custom resource to query it for you and use the result as the AMI value.

Resources:
  DescribeImagesRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies:
        - PolicyName: DescribeImages
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Action: ec2:DescribeImages
                Effect: Allow
                Resource: "*"
  GetLatestAMI:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: python3.6
      Handler: index.handler
      Role: !Sub ${DescribeImagesRole.Arn}
      Timeout: 60
      Code:
        ZipFile: |
          import boto3
          import cfnresponse
          import json
          import traceback

          def handler(event, context):
            try:
              response = boto3.client('ec2').describe_images(
                  Owners=[event['ResourceProperties']['Owner']],
                  Filters=[
                    {'Name': 'name', 'Values': [event['ResourceProperties']['Name']]},
                    {'Name': 'architecture', 'Values': [event['ResourceProperties']['Architecture']]},
                    {'Name': 'root-device-type', 'Values': ['ebs']},
                  ],
              )

              amis = sorted(response['Images'],
                            key=lambda x: x['CreationDate'],
                            reverse=True)
              id = amis[0]['ImageId']

              cfnresponse.send(event, context, cfnresponse.SUCCESS, {}, id)
            except:
              traceback.print_last()
              cfnresponse.send(event, context, cfnresponse.FAIL, {}, "ok")
  CentOSAmi:
    Type: Custom::FindAMI
    Properties:
      ServiceToken: !Sub ${GetLatestAMI.Arn}
      Owner: "679593333241"
      Name: "CentOS Linux 7 x86_64 HVM EBS *"
      Architecture: "x86_64"

You would update the values in CentOSAmi so you can find the right AMI and then use the output with:

ImageId: !Ref CentOSAmi
like image 112
kichik Avatar answered Oct 18 '22 23:10

kichik


Those parameter store AMI values appear to be hand-managed by AWS. I've only found references to:

  • Amazon Linux
  • Windows
  • ECS

Update: There are now more services available:

enter image description here

like image 2
John Rotenstein Avatar answered Oct 18 '22 23:10

John Rotenstein