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

StackOverflow https://stackoverflow.com/questions/21978641

문제

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?

도움이 되었습니까?

해결책 3

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.

다른 팁

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.

In september 6, 2018 was launched AWS CloudFormation Macros, was explained in AWS Reinvent:2018. Now you can add lambda functions to the deploy of your template.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top