In AWS CloudFormation is it possible to create a number of EC2 instances with the values from Mappings without AutoScaling group?

12,596

Solution 1

No it is not possible, there is no iteration you can specify in a template. You can, however, create an instance resource for each instance type. It's a matter of copy and paste. To make it easy to tell CloudFormation which instances to run on stack creation, you can specify functions and conditions in a template. For example, you could create a parameter or parameters that indicate which instance types to start, and use conditions to start only the ones you specify.

Solution 2

It sounds like you want to loop through each instance type, creating one of each. This is not possible in a CloudFormation template.

You could programmatically generate a template. The troposphere Python library provides a nice abstraction to generate templates. For example:

import json
from troposphere import Template, ec2


types = [
    "t1.micro",
    "m1.small",
    "m1.medium",
    "m1.large",
    "m1.xlarge",
    "m3.xlarge",
    "m3.2xlarge",
    "m2.xlarge",
    "m2.2xlarge",
    "m2.4xlarge",
    "c1.medium",
    "c1.xlarge",
    "cc1.4xlarge",
    "cc2.8xlarge",
    "cg1.4xlarge",
    "hi1.4xlarge",
    "hs1.8xlarge"]
ami = "ami-12345678"
t = Template()

for type in types:
    t.add_resource(ec2.Instance(
        type.replace('.', ''), #resource names must be alphanumeric
        ImageId=ami,
        InstanceType=type,
        ))

print t.to_json()

Solution 3

We also encountered same challenger after working with a few cloudformation templates for client. Essentially, we'd like to loop over a list instances type to generate spotfleet launch configuration, but we don't want to manually duplicate those code in our template.

We have tried troposphere as @Ben Whaley mentioned, but it wasn't too suitable to our scenario as we need to rewrite existing cloudformation template with python.

After some investigation, we decided to use EJS template with ejs-cli to generate programmatic cloudformation template, which allows us interpolate variables and include different fragment into target CFT.

  • Fragment management

    Resources: <% include ./partials/resources.yml %> ...

  • Variable interpolation

    apiTaskDefinition: Type: AWS::ECS::TaskDefinition DependsOn: ECSTaskRole Properties: ContainerDefinitions: - Name: api Essential: true Image: <%= container_path %>/api Memory: <%= container.api.memory %>

  • Loop over list

    Properties: SpotFleetRequestConfigData: IamFleetRole: !GetAtt iamFleetRole.Arn SpotPrice: !Ref 'ECSSpotPrice' TargetCapacity: !Ref 'DesiredCapacity' TerminateInstancesWithExpiration: false AllocationStrategy: lowestPrice LaunchSpecifications: <% for(var i in instancesTypes) {%> <% include ./partials/instance-launch-specification.yml %> <% } %>

You can find demo source code here and our blog post.

Share:
12,596
user1249170
Author by

user1249170

Updated on June 26, 2022

Comments

  • user1249170
    user1249170 almost 2 years

    Let's say I want to create EC2 instances one per each InstanceType and otherwise they are the same.

    So I would create a Mapping like this:

    "Mappings" : {
        "MyAWSInstanceTypes" : [
          "t1.micro",
          "m1.small",
          "m1.medium",
          "m1.large",
          "m1.xlarge",
          "m3.xlarge",
          "m3.2xlarge",
          "m2.xlarge",
          "m2.2xlarge",
          "m2.4xlarge",
          "c1.medium",
          "c1.xlarge",
          "cc1.4xlarge",
          "cc2.8xlarge",
          "cg1.4xlarge",
          "hi1.4xlarge",
          "hs1.8xlarge"
        ],
    

    and later on I would like to have

     "Resources" : {  
        "MyEc2Instances" : {    
                 "Type" :
                     "AWS::EC2::Instance",
    

    where I would magically get all my instance types created as per mapping.

    Is that possible without AutoScaling?

  • user1249170
    user1249170 about 10 years
    Thanks for the tip. Functions and conditions are definitely good features which I wasn't aware of, but unfortunately wouldn't eliminate copy-pasting in my case.
  • Gert van den Berg
    Gert van den Berg over 4 years
    docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/… is the link you should have included ;)
  • Miguel Conde
    Miguel Conde over 4 years
    Right now is possible using macros with lambda functions