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

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()

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.


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.