This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Using CloudFormation

This topic describes the Eucalyptus implementation of the AWS CloudFormation web service, how CloudFormation works, and some details and examples of how to add CloudFormation to your Eucalyptus deployment.

Why use CloudFormation?

Cloud computing allows for application repeatability and redundancy. This means that you can spin up as many virtual machines as you need, but the application configuration only needs to happen when the images are created. CloudFormation takes this concept to the next level: it allows you to configure an entire set of resources (instances, security groups, user roles and policies, and more) in a single template. Then you can create a stack of all those resources from the template using a single command. So, you don’t just get machine repeatability, you get environment repeatability. CloudFormation allows you to clone environments in different cloud setups, as well as giving applications the ability to be set up and torn down in a repeatable manner.

How does CloudFormation Work?

CloudFormation manages a set of resources, called a stack, in batch operations (create, update, or delete). Stacks are described in templates, which can be simple, as the following example:

Resources:
  MyInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: emi-371ada125a928669e

This stack creates a single instance, based on the image with ID emi-371ada125a928669e. However, this stack is not portable because different clouds might have different image IDs.

CloudFormation allows stack customization through user parameters that are passed in at stack creation time. The following is an example of the template above with a user parameter called MyImageId.

Parameters:
  MyImageId:
    Description: Image id
    Type: String
Resources:
  MyInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref MyImageId

This stack creates a single instance, but the image ID will be required to be passed in using the command line. For example, the following example uses the euform-create-stack command in Euca2ools:

euform-create-stack --template-file template.yaml -p MyImageId=emi-371ada125a928669e MyStack

or using the AWS CLI:

aws cloudformation create-stack --template-body file://template.yaml --parameters ParameterKey=MyImageId,ParameterValue=emi-371ada125a928669e --stack-name MyStack

These example commands pass the parameter MyImageId with value emi-371ada125a928669e into the stack creation process.

You can also use templates to create multiple resources and associate them with each other. For example, the following template creates an instance with its own security group and ingress rule.

Parameters:
  MyImageId:
    Description: Image id
    Type: String
Resources:
  MySecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security Group with Ingress Rule for MyInstance
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: '0.0.0.0/0'
  MyInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref 'MyImageId'
      SecurityGroups:
        - !Ref 'MySecurityGroup'

Templates can be more complicated than the ones shown above, but CloudFormation allows many resources to be deployed in one operation. Resources from most Eucalyptus services are supported.

CloudFormation Requirements

To run CloudFormation on Eucalyptus, you need the following:

  • A running Eucalyptus cloud, version 4.0 or later, with at least one Cloud Controller, Node Controller, and Cluster Controller up, running and registered
  • At least one active running service of each of the following: CloudWatch, AutoScaling, Load Balancing, Compute, and IAM
  • A registered active CloudFormation service

Supported Resources

The following resources are supported by CloudFormation in Eucalyptus.

ResourceDescription
AWS::AutoScaling::AutoScalingGroupAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported except: HealthCheckType.
AWS::AutoScaling::LaunchConfigurationAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported except AssociatePublicIpAddress.
AWS::AutoScaling::ScalingPolicyAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::CloudFormation::StackAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::CloudFormation::WaitConditionAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::CloudFormation::WaitConditionHandle.All properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::CloudWatch::AlarmAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::CustomerGatewayAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::DHCPOptionsAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::EIPAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::EIPAssociationAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported except: PrivateIpAddress.
AWS::EC2::InstanceAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported except: SourceDestCheck, Tags, and Tenancy.
AWS::EC2::InternetGatewayAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::LaunchTemplateAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::NatGatewayAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::NetworkAclAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::NetworkAclEntryAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::NetworkInterfaceAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::NetworkInterfaceAttachmentAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::RouteAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::RouteTableAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::SecurityGroupAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::SecurityGroupEgressAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::SecurityGroupIngressAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported except SourceSecurityGroupId.
AWS::EC2::SubnetAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::SubnetNetworkAclAssociationAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::SubnetRouteTableAssociationAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::VolumeAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported except: HealthCheckType and Tags.
AWS::EC2::VolumeAttachmentAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::VPCAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::VPCDHCPOptionsAssociationAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::EC2::VPCGatewayAttachmentAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::ElasticLoadBalancing::LoadBalancerAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported except: AccessLoggingPolicy, ConnectionDrainingPolicy, CrossZone, Policies.InstancePorts, and Policies.LoadBalanerPorts. All other properties are passed through to the LoadBalancing service internally but some features are not implemented so properties may be ignored there.
AWS::IAM::AccessKeyAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported except Serial.
AWS::IAM::GroupAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::IAM::InstanceProfileAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::IAM::ManagedPolicyAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::IAM::PolicyAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::IAM::RoleAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::IAM::UserAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::IAM::UserToGroupAdditionAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::Route53::HostedZoneAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::Route53::RecordSetAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::Route53::RecordSetGroupAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::S3::BucketAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::S3::BucketPolicyAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::SQS::QueueAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.
AWS::SQS::QueuePolicyAll properties in the Template Reference section of the AWS CloudFormation User Guide are supported.

CloudFormation Endpoint

The service endpoint for CloudFormation is of the form:

http://cloudformation.mycloud.example.com:8773/

If DNS is not availble for your cloud, then an endpoint with a service path can be used:

http://<host-ip>:8773/services/CloudFormation

CloudFormation follows the same convention as the other user facing services.

1 - CloudFormation Use Case

This topic describes a use case for creating a stack, checking the stack progress, and deleting the stack. For this use case, we will use the following template:

Parameters:
  MyImageId:
    Description: Image id
    Type: String
  MyKeyPair:
    Description: Key Pair
    Type: String
Resources:
  MySecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security Group with Ingress Rule for MyInstance
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: '0.0.0.0/0'
  MyInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref 'MyImageId'
      SecurityGroups:
        - !Ref 'MySecurityGroup'
      KeyName: !Ref 'MyKeyPair'

This template creates an instance with a security group that allows global SSH access (port 22), but uses a keypair to log in. It requires two parameters, MyImageId , which is the image ID of the instance to create, and MyKeyPair , which is the name of the keypair to use to log in with. You could use both values with the euca-run-instances or aws ec2 run-instances commands to create an instance manually (for example, euca-run-instances -k mykey emi-371ada125a928669e ) so the arguments needed here are standard instance arguments.

The steps to run this template through the system are explained in the following steps.

Verify connectivity to the CloudFormation service.

euform-describe-stacks 
# Or
aws cloudformation describe-stacks

You should not see anything returned, including any errors. Create a file called ex_template.yaml that contains the YAML template content shown in the introduction above.

Create a keypair.

euca-create-keypair myKey > myKey.pem
# Or
aws ec2 create-key-pair --key-name myKey > myKey.pem

Set the permissions on the keypair.

chmod 0600 myKey.pem

Find what resources have been created., run the command and the euca-describe-groups commands. Make note of the output for later. Run:

euca-describe-images -a
# Or
aws ec2 describe-images

Note the output for later use.

Create the stack referencing the existing resources.

# euform-create-stack --template-file ex_template.yaml -p MyImageId=<image_id> -p MyKeyPair=myKey MyStack
arn:aws:cloudformation::000575948401:stack/MyStack/26daf046-3776-4b97-9444-5edae2f2eceb

of with the AWS CLI:

# aws cloudformation create-stack --template-body file://ex_template.yaml --parameters ParameterKey=MyImageId,ParameterValue=emi-371ada125a928669e ParameterKey=MyKeyPair,ParameterValue=myKey --stack-name MyStack
arn:aws:cloudformation::000575948401:stack/MyStack/26daf046-3776-4b97-9444-5edae2f2eceb

Run the checks you want on your stack. Check the status of the stack.

# euform-describe-stacks
STACK	MyStack	CREATE_COMPLETE			2020-10-20T18:31:15.662Z
PARAMETER	MyImageId		emi-371ada125a928669e
PARAMETER	MyKeyPair		myKey
#
# aws cloudformation describe-stacks
STACKS	2020-10-20T18:31:15.662Z	False	2020-10-20T18:31:51.316Z	arn:aws:cloudformation::000575948401:stack/MyStack/26daf046-3776-4b97-9444-5edae2f2eceb	MyStack	CREATE_COMPLETE	
PARAMETERS	MyImageId	emi-371ada125a928669e
PARAMETERS	MyKeyPair	myKey

Check the stack at any time to see all the events that have occurred during the stack lifecycle.

# euform-describe-stack-events MyStack
EVENT	MyStack	d87c4381-b765-4d44-a5ba-a952855ffd79	AWS::CloudFormation::Stack	MyStack	arn:aws:cloudformation::000575948401:stack/MyStack/26daf046-3776-4b97-9444-5edae2f2eceb	2020-10-20T18:31:51.310Z	CREATE_COMPLETE	
EVENT	MyStack	MyInstance-CREATE_COMPLETE-1603218711063	AWS::EC2::Instance	MyInstance	i-687f112f4c99e9a98	2020-10-20T18:31:51.063Z	CREATE_COMPLETE	
EVENT	MyStack	MyInstance-CREATE_IN_PROGRESS-1603218676951	AWS::EC2::Instance	MyInstance	i-687f112f4c99e9a98	2020-10-20T18:31:16.951Z	CREATE_IN_PROGRESS	Resource creation Initiated
EVENT	MyStack	MyInstance-CREATE_IN_PROGRESS-1603218676783	AWS::EC2::Instance	MyInstance		2020-10-20T18:31:16.783Z	CREATE_IN_PROGRESS	
EVENT	MyStack	MySecurityGroup-CREATE_COMPLETE-1603218676599	AWS::EC2::SecurityGroup	MySecurityGroup	MyStack-MySecurityGroup-SWUBTU8TQ9MBV	2020-10-20T18:31:16.599Z	CREATE_COMPLETE	
EVENT	MyStack	MySecurityGroup-CREATE_IN_PROGRESS-1603218676174	AWS::EC2::SecurityGroup	MySecurityGroup	MyStack-MySecurityGroup-SWUBTU8TQ9MBV	2020-10-20T18:31:16.174Z	CREATE_IN_PROGRESS	Resource creation Initiated
EVENT	MyStack	MySecurityGroup-CREATE_IN_PROGRESS-1603218676038	AWS::EC2::SecurityGroup	MySecurityGroup		2020-10-20T18:31:16.038Z	CREATE_IN_PROGRESS	
EVENT	MyStack	9212e1ff-6c7a-4710-96a2-d83606a3c34f	AWS::CloudFormation::Stack	MyStack	arn:aws:cloudformation::000575948401:stack/MyStack/26daf046-3776-4b97-9444-5edae2f2eceb	2020-10-20T18:31:15.780Z	CREATE_IN_PROGRESS	User Initiated

Run euca-describe-instances and euca-describe-groups to see the newly created resources:

# euca-describe-instances i-687f112f4c99e9a98
RESERVATION	r-2381c3e652dd942f2	000575948401	MyStack-MySecurityGroup-SWUBTU8TQ9MBV
INSTANCE	i-687f112f4c99e9a98	emi-371ada125a928669e	euca-192-168-134-181.eucalyptus.mycloud.example.com	euca-172-31-15-210.eucalyptus.internal	running	myKey	0		t2.micro	2020-10-20T18:31:16.920Z	cloud-1a				monitoring-disabled	192.168.134.181	172.31.15.210	vpc-837bc081de161f8c0	subnet-1503566df094fe78a	instance-store					hvm			sg-98da12246d91375e3				x86_64
NETWORKINTERFACE	eni-42a4a3bf7d1075735	subnet-1503566df094fe78a	vpc-837bc081de161f8c0	000575948401	in-use	172.31.15.210	euca-172-31-15-210.eucalyptus.internal	true
ATTACHMENT		eni-attach-cc38f4f4ef78a6469	0	attached	2020-10-20T18:31:16.923Z	true
ASSOCIATION	192.168.134.181		172.31.15.210
GROUP	sg-98da12246d91375e3	MyStack-MySecurityGroup-SWUBTU8TQ9MBV
PRIVATEIPADDRESS	172.31.15.210	euca-172-31-15-210.eucalyptus.internal	primary
TAG	instance	i-687f112f4c99e9a98	aws:cloudformation:logical-id	MyInstance
TAG	instance	i-687f112f4c99e9a98	aws:cloudformation:stack-id	arn:aws:cloudformation::000575948401:stack/MyStack/26daf046-3776-4b97-9444-5edae2f2eceb
TAG	instance	i-687f112f4c99e9a98	aws:cloudformation:stack-name	MyStack
TAG	instance	i-687f112f4c99e9a98	euca:node	10.117.111.18
#
# euca-describe-groups sg-98da12246d91375e3
GROUP	sg-98da12246d91375e3	000575948401	MyStack-MySecurityGroup-SWUBTU8TQ9MBV	Security Group with Ingress Rule for MyInstance	vpc-837bc081de161f8c0
PERMISSION	000575948401	MyStack-MySecurityGroup-SWUBTU8TQ9MBV	ALLOWS	tcp	22	22	FROM	CIDR	0.0.0.0/0	ingress
PERMISSION	000575948401	MyStack-MySecurityGroup-SWUBTU8TQ9MBV	ALLOWS	-1			TO	CIDR	0.0.0.0/0	egress
TAG	security-group	sg-98da12246d91375e3	aws:cloudformation:logical-id	MySecurityGroup
TAG	security-group	sg-98da12246d91375e3	aws:cloudformation:stack-id	arn:aws:cloudformation::000575948401:stack/MyStack/26daf046-3776-4b97-9444-5edae2f2eceb
TAG	security-group	sg-98da12246d91375e3	aws:cloudformation:stack-name	MyStack

To SSH into the instance:

ssh -i myKey.pem root@192.168.134.181

Delete the stack.

euform-delete-stack MyStack
# Or
aws cloudformation delete-stack --stack-name MyStack

You can run euform-describe-stacks and all the other describe commands to check the progress until the delete is complete.

2 - CloudFormation Templates

This topic details templates that have been tested with Eucalyptus.

AccessKeys.template

{
  "AWSTemplateFormatVersion":"2010-09-09",
  "Parameters":{
    "Username":{
      "Description":"Username",
      "Type":"String"
    }
  },
  "Resources":{
    "Key1":{
      "Type":"AWS::IAM::AccessKey",
      "Properties":{
        "UserName":{"Ref":"Username"},
        "Serial":"1",
        "Status":"Active"
      }
    },
    "Key2":{
      "Type":"AWS::IAM::AccessKey",
      "Properties":{
        "UserName":{"Ref":"Username"},
       "Serial":"1",
       "Status":"Inactive"
      }
    }
  },
  "Outputs":{
    "Key1AK":{
      "Value":{"Ref":"Key1"}
    },
    "Key1SK":{
      "Value":{"Fn::GetAtt":["Key1","SecretAccessKey"]}
    },
    "Key2AK":{
      "Value":{"Ref":"Key2"}
    },
    "Key2SK":{
      "Value":{"Fn::GetAtt":["Key2","SecretAccessKey"]}
    }
  }
}

AutoscalingGroupsAndCloudWatchAlarm.template

{
  "AWSTemplateFormatVersion":"2010-09-09",
  "Parameters":{
    "ImageId":{
      "Description":"Image id",
      "Type":"String"
    }
  },
  "Resources":{
    "LaunchConfig":{
      "Type":"AWS::AutoScaling::LaunchConfiguration",
      "Properties":{
        "ImageId":{"Ref":"ImageId"},
        "InstanceType":"m1.small",
        "BlockDeviceMappings":[
          {"DeviceName":"/dev/sdc","VirtualName":"ephemeral0"},
          {"DeviceName":"/dev/sdc","Ebs":{"VolumeSize":"10"}}
        ],
        "SecurityGroups":[{"Ref":"InstanceSecurityGroup"}]}
      },
      "ASG1":{
        "UpdatePolicy":{
          "AutoScalingRollingUpdate":{
            "MinInstancesInService":"1",
            "MaxBatchSize":"1",
            "PauseTime":"PT12M5S"
          }
        },
        "Type":"AWS::AutoScaling::AutoScalingGroup",
        "Properties":{
          "AvailabilityZones":{"Fn::GetAZs":{"Ref":"AWS::Region"}
        },
        "LaunchConfigurationName":{"Ref":"LaunchConfig"},
        "MaxSize":"3",
        "MinSize":"1"
      }
    },
    "ScaleUpPolicy":{
      "Type":"AWS::AutoScaling::ScalingPolicy",
        "Properties":{
          "AdjustmentType":"ChangeInCapacity",
          "AutoScalingGroupName":{"Ref":"ASG1"},
          "Cooldown":"1",
          "ScalingAdjustment":"1"
        }
      },
      "CPUAlarmHigh":{
        "Type":"AWS::CloudWatch::Alarm",
        "Properties":{
          "EvaluationPeriods":"1",
          "Statistic":"Average",
          "Threshold":"10",
          "AlarmDescription":"Alarm if CPU too high or metric disappears indicating instance is down",
          "Period":"60",
          "AlarmActions":[{"Ref":"ScaleUpPolicy"}],
          "Namespace":"AWS/EC2",
          "Dimensions":[{
            "Name":"AutoScalingGroupName",
            "Value":{"Ref":"ASG1"}
          }],
          "ComparisonOperator":"GreaterThanThreshold",
          "MetricName":"CPUUtilization"
        }
      },
      "InstanceSecurityGroup":{
        "Type":"AWS::EC2::SecurityGroup",
        "Properties":{
          "GroupDescription":"Cloudformation Group",
          "SecurityGroupIngress":[{
            "IpProtocol":"tcp",
            "FromPort":"22",
            "ToPort":"22",
             "CidrIp":"0.0.0.0/0"
          }]
        }
      },
      "IngressRule":{
        "Type":"AWS::EC2::SecurityGroupIngress",
        "Properties":{
          "GroupName":{"Ref":"InstanceSecurityGroup"},
          "FromPort":"80",
          "ToPort":"80",
          "IpProtocol":"tcp",
          "SourceSecurityGroupName":{"Ref":"InstanceSecurityGroup"}
      }
    }
  }
}

BlockDeviceMappings.template

{
  "AWSTemplateFormatVersion":"2010-09-09",
  "Description":"Create an EC2 instance running a specified EMI with block device mappings.",
  "Parameters":{
    "ImageId":{
      "Description":"Image id",
      "Type":"String"
    },
    "KeyName":{
      "Description":"KeyName",
      "Type":"String"
    },
    "SnapshotId":{
      "Type":"String"
    }
  },
  "Resources":{
    "Ec2Instance1":{
      "Type":"AWS::EC2::Instance",
      "Properties":{
        "ImageId":{"Ref":"ImageId"},
        "BlockDeviceMappings":[{"DeviceName":"/dev/sdc","VirtualName":"ephemeral0"}]
      }
    },
    "Ec2Instance2":{
      "Type":"AWS::EC2::Instance",
      "Properties":{
        "ImageId":{"Ref":"ImageId"},
        "KeyName":{"Ref":"KeyName"},
        "BlockDeviceMappings":[{
          "DeviceName":"/dev/sdc",
          "Ebs":{"SnapshotId":{"Ref":"SnapshotId"},"DeleteOnTermination":"false"}
        }]
      }
    },
    "Ec2Instance3":{
      "Type":"AWS::EC2::Instance",
      "Properties":{
        "ImageId":{"Ref":"ImageId"},
        "KeyName":{"Ref":"KeyName"},
        "BlockDeviceMappings":[{
          "DeviceName":"/dev/sdc",
          "Ebs":{"VolumeSize":"10","DeleteOnTermination":"true"}
        }]
      }
    }
  }
}

ConditionsAndFunctions.template

{
  "Mappings":{
    "Mapping01":{
      "Key01":{"Value":["1","2"]},
      "Key02":{"Value":"3"},
      "Key03":{"Value":"4"}
    }
  },
  "AWSTemplateFormatVersion":"2010-09-09",
  "Description":"Create an EC2 instance running a specified EMI, also test functions and conditions.",
  "Parameters":{
    "ImageId":{
      "Description":"Image id",
      "Type":"String",
      "NoEcho":"True"
    },
    "Split":{
      "Default":"1,2,3",
      "Type":"CommaDelimitedList"
    }
  },
  "Resources":{
    "Ec2Instance1":{
      "Type":"AWS::EC2::Instance",
        "Properties":{
          "ImageId":{"Ref":"ImageId"}
        },
      "Condition":"True"
    },
    "Ec2Instance2":{
      "Type":"AWS::EC2::Instance",
      "Properties":{
        "ImageId":{"Ref":"ImageId"}
      },
      "Condition":"False"
    }
  },
  "Conditions":{
    "True":{"Fn::Equals":["x","x"]},
    "False":{"Fn::Not":[{"Condition":"True"}]},
    "NotTrue":{"Fn::Not":[{"Condition":"True"}]},
    "NotFalse":{"Fn::Not":[{"Condition":"False"}]},
    "TrueAndTrue":{"Fn::And":[{"Condition":"True"},{"Condition":"True"}]},
    "TrueAndFalse":{"Fn::And":[{"Condition":"True"},{"Condition":"False"}]},
    "FalseAndTrue":{"Fn::And":[{"Condition":"False"},{"Condition":"True"}]},
    "FalseAndFalse":{"Fn::And":[{"Condition":"False"},{"Condition":"False"}]},
    "TrueOrTrue":{"Fn::Or":[{"Condition":"True"},{"Condition":"True"}]},
    "TrueOrFalse":{"Fn::Or":[{"Condition":"True"},{"Condition":"False"}]},
    "FalseOrTrue":{"Fn::Or":[{"Condition":"False"},{"Condition":"True"}]},
    "FalseOrFalse":{"Fn::Or":[{"Condition":"False"},{"Condition":"False"}]}
  },
  "Outputs":{
    "Region":{
      "Value":{"Ref":"AWS::Region"}
    },
    "JoinAndAZ":{
      "Value":{"Fn::Join":[",",{"Fn::GetAZs":""}]}
    },
    "FindInMap1AndSelect":{
      "Value":{"Fn::Select":["0",{"Fn::FindInMap":["Mapping01","Key01","Value"]}]}
    },
    "FindInMap2AndSelect":{
     "Value":{"Fn::Select":["1","Fn::FindInMap":["Mapping01","Key01","Value"]}]}
    },
    "FindInMap3AndSelect":{
      "Value":{"Fn::FindInMap":["Mapping01","Key02","Value"]}
    },
    "FindInMap4AndSelect":{
      "Value":{"Fn::FindInMap":["Mapping01","Key03","Value"]}
    },
    "GetAtt":{
      "Value":{"Fn::GetAtt":["Ec2Instance1","PrivateIp"]}
    },
    "StackId":{
      "Value":{"Ref":"AWS::StackId"}
    },
    "StackName":{
      "Value":{"Ref":"AWS::StackName"}
    },
    "AccountId":{
      "Value":{"Ref":"AWS::AccountId"}
    },
    "True":{
      "Value":{"Fn::Join" : [",",[{"Fn::If": ["True","True","False"]}]]}},
    },
    "False":{
      "Value":{"Fn::Join" : [",",[{"Fn::If": ["False","True","False"]}]]}},
    },
    "NotTrue":{
      "Value":{"Fn::Join" : [",",[{"Fn::If": ["NotTrue","True","False"]}]]}},
    },
    "NotFalse":{
      "Value":{"Fn::Join" : [",",[{"Fn::If": ["NotFalse","True","False"]}]]}},
    },
    "TrueAndTrue":{
      "Value":{"Fn::Join" : [",",[{"Fn::If": ["TrueAndTrue","True","False"]}]]}},
    },
    "TrueAndFalse":{
      "Value":{"Fn::Join" : [",",[{"Fn::If": ["TrueAndFalse","True","False"]}]]}},
    },
    "FalseAndTrue":{
      "Value":{"Fn::Join" : [",",[{"Fn::If": ["FalseAndTrue","True","False"]}]]}},
    },
    "FalseAndFalse":{
      "Value":{"Fn::Join" : [",",[{"Fn::If": ["FalseAndFalse","True","False"]}]]}},
    },
    "TrueOrTrue":{
      "Value":{"Fn::Join" : [",",[{"Fn::If": ["TrueOrTrue","True","False"]}]]}},
    },
    "TrueOrFalse":{
      "Value":{"Fn::Join" : [",",[{"Fn::If": ["TrueOrFalse","True","False"]}]]}},
    },
    "FalseOrTrue":{
      "Value":{"Fn::Join" : [",",[{"Fn::If": ["FalseOrTrue","True","False"]}]]}},
    },
    "FalseOrFalse":{
      "Value":{"Fn::Join" : [",",[{"Fn::If": ["FalseOrFalse","True","False"]}]]}},
    }
  }
}

ElasticIP.template

This template attaches an Elastic IP to a new and existing instance. You must pass along the existing instance ID.

{
  "AWSTemplateFormatVersion":"2010-09-09",
  "Description":"Create an EC2 instance running a specified EMI and some elastic IP addresses.",
  "Parameters":{
    "ImageId":{
      "Description":"Image id",
      "Type":"String"
    },
    "OtherInstanceId":{
      "Description":"Other instance id",
      "Type":"String"
    }
    },
    "Resources":{
      "Ec2Instance1":{
        "Type":"AWS::EC2::Instance",
        "Properties":{
          "ImageId":{"Ref":"ImageId"}
        }
      },
      "EIP1":{
        "Type":"AWS::EC2::EIP",
        "Properties":{
          "InstanceId":{"Ref":"Ec2Instance1"}
        }
      },
      "EIP2":{
        "Type":"AWS::EC2::EIP",
        "Properties":{
        }
      },
      "EIPAssociation2":{
        "Type":"AWS::EC2::EIPAssociation",
        "Properties":{
          "InstanceId":{"Ref":"OtherInstanceId"},
          "EIP":{"Ref":"EIP2"}
        }
      }
    },
    "Outputs":{
      "Output1":{
        "Value":{"Ref":"EIPAssociation2"}
      }
  }
}

ElasticLoadBalancer.template

There is a hard-coded image ID in the Mapping section here to test FindInMap . Change the value to an instance that exists in your cloud.

{
  "AWSTemplateFormatVersion":"2010-09-09",
  "Description":"Based on the AWS Cloudformation Sample Template for ELB.  Modify this template, and put the correct emi-XXXX in the value fields with a blank key of the AWSRegionArch2AMI mapping.",
  "Parameters":{
    "InstanceType":{
      "Description":"WebServer EC2 instance type",
      "Type":"String",
      "Default":"m1.small",
      "AllowedValues":["t1.micro","m1.small","m1.medium","m1.large","m1.xlarge","m2.xlarge","m2.2xlarge",
                       "m2.4xlarge","m3.xlarge","m3.2xlarge","c1.medium","c1.xlarge","cc1.4xlarge",
                       "cc2.8xlarge","cg1.4xlarge"],
      "ConstraintDescription":"must be a valid EC2 instance type."
    },
    "WebServerPort":{
      "Description":"TCP/IP port of the web server",
      "Type":"String",
      "Default":"8888"
    },
    "KeyName":{
      "Description":"Name of an existing EC2 KeyPair to enable SSH access to the instances",
      "Type":"String",
      "MinLength":"1",
      "MaxLength":"255",
      "AllowedPattern":"[\\x20-\\x7E]*",
      "ConstraintDescription":"can contain only ASCII characters."
    },
    "SSHLocation":{
      "Description":"The IP address range that can be used to SSH to the EC2 instances",
      "Type":"String",
      "MinLength":"9",
      "MaxLength":"18",
      "Default":"0.0.0.0/0",
      "AllowedPattern":"(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription":"must be a valid IP CIDR range of the form x.x.x.x/x."
    }
  },
  "Mappings":{
    "AWSInstanceType2Arch":{
      "t1.micro":{"Arch":"64"},
      "m1.small":{"Arch":"64"},
      "m1.medium":{"Arch":"64"},
      "m1.large":{"Arch":"64"},
      "m1.xlarge":{"Arch":"64"},
      "m2.xlarge":{"Arch":"64"},
      "m2.2xlarge":{"Arch":"64"},
      "m3.xlarge":{"Arch":"64"},
      "m3.2xlarge":{"Arch":"64"},
      "m2.4xlarge":{"Arch":"64"},
      "c1.medium":{"Arch":"64"},
      "c1.xlarge":{"Arch":"64"}
    },
    "AWSRegionArch2AMI":{
      "":{"32":"emi-ddbacddf","64":"emi-ddbacddf"}
    }
  },
  "Resources":{
    "ElasticLoadBalancer":{
      "Type":"AWS::ElasticLoadBalancing::LoadBalancer",
      "Properties":{
        "AvailabilityZones":{"Fn::GetAZs":""},
        "Instances":[{"Ref":"Ec2Instance1"},{"Ref":"Ec2Instance2"}],
        "Listeners"{"LoadBalancerPort":"80","InstancePort":{"Ref":"WebServerPort"},"Protocol":"HTTP"}],
        "HealthCheck":{
          "Target":{"Fn::Join":["",["HTTP:",{"Ref":"WebServerPort"},"/"]]},
          "HealthyThreshold":"3",
          "UnhealthyThreshold":"5",
          "Interval":"30",
          "Timeout":"5"
        }
      }
    },
    "Ec2Instance1":{
      "Type":"AWS::EC2::Instance",
      "Properties":{
        "SecurityGroups":[{"Ref":"InstanceSecurityGroup"}],
        "KeyName":{"Ref":"KeyName"},
        "InstanceType":{"Ref":"InstanceType"},
        "ImageId":{
          "Fn::FindInMap":[
            "AWSRegionArch2AMI",
            {"Ref":"AWS::Region"},
            {"Fn::FindInMap":["AWSInstanceType2Arch",{"Ref":"InstanceType"},"Arch"]}
          ]
        },
        "UserData":{"Fn::Base64":{"Ref":"WebServerPort"}}
      }
    },
    "Ec2Instance2":{
      "Type":"AWS::EC2::Instance",
      "Properties":{
        "SecurityGroups":[{"Ref":"InstanceSecurityGroup"}],
        "KeyName":{"Ref":"KeyName"},
        "InstanceType":{"Ref":"InstanceType"},
        "ImageId":{
          "Fn::FindInMap":[
            "AWSRegionArch2AMI",
            {"Ref":"AWS::Region"},
            {"Fn::FindInMap":["AWSInstanceType2Arch",{"Ref":"InstanceType"},"Arch"]}
          ]
        },
        "UserData":{"Fn::Base64":{"Ref":"WebServerPort"}}
      }
    },
    "InstanceSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Enable SSH access and HTTP access on the inbound port",
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":"22",
            "ToPort":"22",
            "CidrIp":{"Ref":"SSHLocation"}
          },
          {
             "IpProtocol":"tcp",
             "FromPort":{"Ref":"WebServerPort"},
             "ToPort":{"Ref":"WebServerPort"},
             "CidrIp":"0.0.0.0/0"
          }
        ]
      }
    }
  },
  "Outputs":{
    "URL":{
      "Description":"URL of the sample website",
      "Value":{"Fn::Join":["",["http://",{"Fn::GetAtt":["ElasticLoadBalancer","DNSName"]}]]}
    }
  }
}

IAMGroup.template

{
  "AWSTemplateFormatVersion":"2010-09-09",
  "Resources":{
    "Group1":{
      "Type":"AWS::IAM::Group",
      "Properties":{
        "Path":"/myapplication/",
        "Policies":[{
          "PolicyName":"myapppolicy",
          "PolicyDocument":{
            "Version":"2012-10-17",
            "Statement":[
              {"Effect":"Allow","Action":["ec2:*"],"Resource":["*"]},
              {"Effect":"Deny","Action":["s3:*"],"NotResource":["*"]}
            ]
          }
        }]
      }
    }
  },
  "Outputs":{
    "Group1Ref":{
      "Value":{"Ref":"Group1"}
    },
    "Group1Arn":{
      "Value":{"Fn::GetAtt":["Group1","Arn"]}
    }
  }
}

IAMRole.template

{
  "AWSTemplateFormatVersion":"2010-09-09",
  "Resources":{
    "Role1":{
      "Type":"AWS::IAM::Role",
      "Properties":{
        "AssumeRolePolicyDocument":{
          "Version":"2012-10-17",
          "Statement":[{
            "Effect":"Allow",
            "Principal":{"Service":["ec2.amazonaws.com"]},
            "Action":["sts:AssumeRole"]
          }]
        },
        "Path":"/",
        "Policies":[{
          "PolicyName":"root",
          "PolicyDocument":{
            "Version":"2012-10-17",
            "Statement":[{"Effect":"Allow","Action":"*","Resource":"*"}]
          }
        }]
      }
    },
    "IP1":{
      "Type":"AWS::IAM::InstanceProfile",
      "Properties":{
        "Path":"/",
        "Roles":[{"Ref":"Role1"}]
      }
    }
  },
  "Outputs":{
    "Role1Ref":{
      "Value":{"Ref":"Role1"}
    },
    "Role1Arn":{
      "Value":{"Fn::GetAtt":["Role1","Arn"]}
    },
    "IP1Ref":{
      "Value":{"Ref":"IP1"}
    },
    "IP1Arn":{
      "Value":{"Fn::GetAtt":["IP1","Arn"]}
    }
  }
}

IAM_Users_Groups_and_Policies.template

{
  "AWSTemplateFormatVersion":"2010-09-09",
  "Description":"AWS CloudFormation Sample Template IAM_Users_Groups_and_Policies: Sample template showing how to create IAM users, groups and policies. It creates a single user that is a member of a users group and an admin group. The groups each have different IAM policies associated with them. Note: This example also creates an AWSAccessKeyId/AWSSecretKey pair associated with the new user. The example is somewhat contrived since it creates all of the users and groups, typically you would be creating policies, users and/or groups that contain references to existing users or groups in your environment. Note that you will need to specify the CAPABILITY_IAM flag when you create the stack to allow this template to execute. You can do this through the AWS management console by clicking on the check box acknowledging that you understand this template creates IAM resources or by specifying the CAPABILITY_IAM flag to the cfn-create-stack command line tool or CreateStack API call. ",
  "Parameters":{
    "Password":{
      "NoEcho":"true",
      "Type":"String",
      "Description":"New account password",
      "MinLength":"1",
      "MaxLength":"41"
    }
  },
  "Resources":{
    "CFNUser":{
      "Type":"AWS::IAM::User",
      "Properties":{
        "LoginProfile":{"Password":{"Ref":"Password"}}
      }
    },
    "Role1":{
      "Type":"AWS::IAM::Role",
      "Properties":{
        "AssumeRolePolicyDocument":{
          "Version":"2012-10-17",
          "Statement":[{
            "Effect":"Allow",
            "Principal":{"Service":["ec2.amazonaws.com"]},
            "Action":["sts:AssumeRole"]
          }]
        },
        "Path":"/",
        "Policies":[{
          "PolicyName":"root",
          "PolicyDocument":{
            "Version":"2012-10-17",
            "Statement":[{"Effect":"Allow","Action":"*","Resource":"*"}]
          }
        }]
      }
    },
    "CFNUserGroup":{
      "Type":"AWS::IAM::Group"
    },
    "CFNAdminGroup":{
      "Type":"AWS::IAM::Group"
    },
    "Users":{
      "Type":"AWS::IAM::UserToGroupAddition",
      "Properties":{
        "GroupName":{"Ref":"CFNUserGroup"},
        "Users":[{"Ref":"CFNUser"}]
      }
    },
    "Admins":{
      "Type":"AWS::IAM::UserToGroupAddition",
      "Properties":{
        "GroupName":{"Ref":"CFNAdminGroup"},
        "Users":[{"Ref":"CFNUser"}]
      }
    },
    "CFNUserPolicies":{
      "Type":"AWS::IAM::Policy",
      "Properties":{
        "PolicyName":"CFNUsers",
        "PolicyDocument":{
          "Statement":[{
            "Effect":"Allow",
            "Action":["cloudformation:Describe*","cloudformation:List*","cloudformation:Get*"],
            "Resource":"*"
          }]
        },
        "Groups":[{"Ref":"CFNUserGroup"}],
        "Users":[{"Ref":"CFNUser"}],
        "Roles":[{"Ref":"Role1"}]
      }
    },
    "CFNAdminPolicies":{
      "Type":"AWS::IAM::Policy",
      "Properties":{
        "PolicyName":"CFNAdmins",
        "PolicyDocument":{
          "Statement":[{"Effect":"Allow","Action":"cloudformation:*","Resource":"*"}]
        },
        "Groups":[{"Ref":"CFNAdminGroup"}]
      }
    },
    "CFNKeys":{
      "Type":"AWS::IAM::AccessKey",
      "Properties":{
        "UserName":{"Ref":"CFNUser"}
      }
    }
  },
  "Outputs":{
    "AccessKey":{
      "Value":{"Ref":"CFNKeys"},
      "Description":"AWSAccessKeyId of new user"
    },
    "SecretKey":{
      "Value":{"Fn::GetAtt":["CFNKeys","SecretAccessKey"]},
      "Description":"AWSSecretKey of new user"
    }
  }
}

IAMUser.template

{
  "AWSTemplateFormatVersion":"2010-09-09",
  "Parameters":{
    "Password":{
      "NoEcho":"true",
      "Type":"String",
      "Description":"New account password",
      "MinLength":"1",
      "MaxLength":"41"
    }
  },
  "Resources":{
    "CFNUserGroup":{
      "Type":"AWS::IAM::Group",
      "Properties":{
        "Policies":[{
          "PolicyName":"CFNUsers",
          "PolicyDocument":{
            "Statement":[{
              "Effect":"Allow",
              "Action":["cloudformation:Describe*","cloudformation:List*","cloudformation:Get*"],
              "Resource":"*"
            }]
          }
        }]
      }
    },
    "CFNAdminGroup":{
      "Type":"AWS::IAM::Group"
    },
    "CFNUser":{
      "Type":"AWS::IAM::User",
      "Properties":{
        "LoginProfile":{"Password":{"Ref":"Password"}},
        "Groups":[{"Ref":"CFNUserGroup"},{"Ref":"CFNAdminGroup"}],
        "Policies":[{
          "PolicyName":"CFNUsers",
          "PolicyDocument":{
            "Statement":[{
              "Effect":"Allow",
              "Action":["cloudformation:Describe*","cloudformation:List*","cloudformation:Get*"],
              "Resource":"*"
            }]
          }
        }]
      }
    }
  }
}

SecurityGroupRule.template

{
"AWSTemplateFormatVersion":"2010-09-09",
  "Description":"Create an EC2 instance running a specified EMI, a security group, and an ingress rule.",
  "Parameters":{
    "ImageId":{
      "Description":"Image id",
      "Type":"String"
    }
  },
  "Resources":{
    "Ec2Instance1":{
      "Description":"My instance",
      "Type":"AWS::EC2::Instance",
      "Properties":{
        "ImageId":{"Ref":"ImageId"}
      },
      "DependsOn":"Ec2Instance2"
    },
    "Ec2Instance2":{
      "Type":"AWS::EC2::Instance",
      "Properties":{
        "ImageId":{"Ref":"ImageId"},
        "SecurityGroups":[{"Ref":"InstanceSecurityGroup"}]
      }
    },
    "InstanceSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"Cloudformation Group",
        "SecurityGroupIngress":[{"IpProtocol":"tcp","FromPort":"22","ToPort":"22","CidrIp":"0.0.0.0/0"}]
      }
    },
    "IngressRule":{
      "Type":"AWS::EC2::SecurityGroupIngress",
      "Properties":{
        "GroupName":{"Ref":"InstanceSecurityGroup"},
        "FromPort":"80",
        "ToPort":"80",
        "IpProtocol":"tcp",
        "SourceSecurityGroupName":{"Ref":"InstanceSecurityGroup"}
      }
    }
  }
}

Volumes.template

{
  "AWSTemplateFormatVersion":"2010-09-09",
  "Description":"Create an EC2 instance running a specified EMI and attached volumes.",
  "Parameters":{
    "ImageId":{
      "Description":"Image id",
      "Type":"String"
    }
  },
  "Resources":{
    "Volume1":{
      "Type":"AWS::EC2::Volume",
      "Properties":{
        "Size":"5",
        "AvailabilityZone":{"Fn::GetAtt":["Instance1","AvailabilityZone"]}
      }
    },
    "Volume2":{
      "Type":"AWS::EC2::Volume",
      "Properties":{
        "Size":"5",
        "AvailabilityZone":{"Fn::GetAtt":["Instance1","AvailabilityZone"]}
      }
    },
    "MountPoint1":{
      "Type":"AWS::EC2::VolumeAttachment",
      "Properties":{
        "InstanceId":{"Ref":"Instance1"},
        "VolumeId":{"Ref":"Volume1"},
        "Device":"/dev/sdc"
      }
    },
    "Instance1":{
      "Type":"AWS::EC2::Instance",
      "Properties":{
        "ImageId":{"Ref":"ImageId"}
      }
    },
    "Instance2":{
      "Type":"AWS::EC2::Instance",
      "Properties":{
        "ImageId":{"Ref":"ImageId"},
        "Volumes":[{"VolumeId":{"Ref":"Volume2"},"Device":"/dev/sdc"}]
      } 
    }
  }
}

3 - Troubleshooting CloudFormation

This topic describes some of the issues that can happen with CloudFormation. It also talks about how you can detect these issues, and offers some ways to fix the issues.

Invalid JSON

JSON must be syntactically valid. For example, if you don’t type in the final } character in a template, the euform-create-stack command returns an error message.

euform-create-stack: error (ValidationError): Unexpected end-of-input: 
expected close marker for OBJECT (from [Source: java.io.StringReader@56b3916d; 
line: 1, column: 0]) at [Source: java.io.StringReader@56b3916d; line: 38, 
column : 849]

If you see an error like this, there is most likely something syntactically wrong with your JSON template. Some editors can detect things like unbalanced parentheses, but in the worst case you can paste your template into this URL http://jsonparseronline.com/ and it will help you find syntax errors.

Invalid Argument

If you try to create, for example, a stack that already exists, you will get a simple error message.

euform-create-stack: error (AlreadyExists): Stack already exists

Invalid Reference

If you use an invalid reference to, for example, a resource that doesn’t exit, Eucalyptus returns a simple error message.

euform-create-stack: error (ValidationError): Template format error: Unresolved resource dependencies [MySecurityGroup2] in the Resources block of the template>

Complex Errors

Not all errors are simple. We recommend that you use euform-describe-stacks (or aws cloudformation describe-stacks) and euform-describe-stack-resources to determine the current state of the stack. If there’s an error, it will usually be shown in the euform-describe-stack-events output. Otherwise, you will have to dig into the cloud-output.log file for further information. You can also manually delete resources if they are causing issues. If a euform-delete-stack fails, you can delete the offending resource and try again.