GenTel
GenTel

Reputation: 1558

How To Specify AMI in CloudFormation?

My task is basic - I want to use CloudFormation to set up an EC2 instance with some arbitrary AMI that I like. However, for some reason this isn't as simple as just putting in the ID number of the image that I want.

As we see in their tutorial CloudFormation template, for the ImageId section they have:

Properties:
    ImageId: !FindInMap [ AWSRegionArch2AMI, !Ref 'AWS::Region' , !FindInMap [ AWSInstanceType2Arch, !Ref InstanceType, Arch ] ]

When searching among the available EC2 images, I don't see anything called "AWSRegionArch2AMI", so I have no idea why this keyword is able to specify their desired AMI and allow this template to function.

So for example say I want to have my CloudFormation template create an instance with this popular, publicly available AMI:

Red Hat Enterprise Linux 8 (HVM), SSD Volume Type - ami-08949fb6466dd2cf3

What should I specify in the ImageId field to get CloudFormation to use this AMI?

Additionally, why is it standard to use these complex programmatic arguments instead of just a UID indicating the image I want?

Upvotes: 2

Views: 6335

Answers (2)

Hasitha Palihena
Hasitha Palihena

Reputation: 1

Incase if someone need to do similar using YAML, here is the code below.

AWSTemplateFormatVersion: "2010-09-09"

Description: AWS CloudFormation Testing.

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: Amazon EC2 Configuration
        Parameters:
          - InstanceType
          - AmiID
    ParameterLabels:
      InstanceType:
        default: Type of EC2 Instance
      AmiID:
        default: Amazon Machine Image ID
        

Parameters:
  InstanceType:
    Description: Enter t2.micro or t2.small. Default is t2.micro.
    Type: String
    AllowedValues:
      - t2.micro
      - t2.small
    Default: t2.micro

  AmiID:
    Description: The ID of the AMI.
    Type: AWS::EC2::Image::Id
    Default: ami-02396cdd13e9a1257

Resources:
  WebServerInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref AmiID
      InstanceType: !Ref InstanceType
      Tags:
        - Key: Name
          Value: !Join ['-', [!Ref InstanceType, webserver]]
        - Key: InstanceType
          Value: !Sub ${InstanceType}

Upvotes: 0

guest
guest

Reputation: 901

Short answer: it isn't necessary to go through this lookup process. If you plan to run in a single region, using a single AMI, then it's perfectly reasonable to specify that AMI as a parameter and use it directly.

The AWS example, however, must be able to run in multiple regions because AWS has customers that use these different regions. To do this it defines mappings (in the Mappings section of the example template that can be used to translate from instance type to AMI.


Edit: here's an excerpt from a template that I'm currently using that passes the AMI as a parameter (with default). It's in JSON, and leaves out a lot of stuff, but should give you the gist of what's happening:

"Parameters" : {
    "AmiId" : {
        "Description" : "The ID of the AMI to use for the EC2 instance",
        "Default": "ami-059f4aad319ff1bc3",
        "Type": "String"
    }


"Resources" : {

    "EC2Instance" : {
        "Type" : "AWS::EC2::Instance",
        "Properties" : {
            "ImageId" : { "Ref" : "AmiId" },

Upvotes: 5

Related Questions