How to create EC2 instance with EBS volume in CloudFormation? - amazon-web-services

Hi I am trying to create an Amazon EC2 instance with an EBS volume. I have created a CloudFormation template:
AWSTemplateFormatVersion: "2010-09-09"
Description: "First EC2 instance"
Resources:
FirstLinuxEC2instance:
Type: AWS::EC2::Instance
Properties:
AvailabilityZone: 'ap-southeast-2a'
ImageId: 'ami-0c1d8842b9bfc767c'
InstanceInitiatedShutdownBehavior: 'terminate'
InstanceType: 't2.micro'
SecurityGroupIds:
- 'sg-79862305'
Volumes:
Device: "/dev/sdf"
VolumeId: !Ref NewVolume
NewVolume:
Type: AWS::EC2::Volume
Properties:
Size: 1
AvailabilityZone: 'ap-southeast-2a'
Tags:
- Key: MyTag
Value: TagValue
DeletionPolicy: Snapshot
When I upload this template I am getting below error.
Value of property Volumes must be of type List
Can someone help me to figure it out the issue?

Try this!
Volumes:
-
Device: "/dev/sdf"
VolumeId: !Ref NewVolume

Yes volumes is of type array. So even a single volume needs to be in a pair of square brackets (json). You can try cloudkast which is an online cloudformation template generator. It is very useful to make it outright clear which property is of what type with inline description.

Related

AWS cloudformation spot instance parameters

I'm trying to add a parameter in my cloud formation stack that will allow the users to choose between on-demand and spot instances for the launch template, which will initiate the EC2 creation. This stack is designed to launch a workstation for a single user.
Currently there only seems to be one value available for the InstanceMarketType Parameter, does anyone know an alternative way of choosing the instance market type?
InstanceMarketTypeParameter:
Type: String
Default: spot
AllowedValues:
- spot
- on-demand
Description: Choose between on-demand and spot instances.
The launch template would look something like this
Ec2LaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: LinuxWorkstation
LaunchTemplateData:
InstanceMarketOptions:
MarketType:
Ref: InstanceMarketTypeParameter
Any ideas are welcome!
You can make InstanceMarketOptions optional using If:
Conditions:
IsOnDemand:
!Equals [!Ref InstanceMarketTypeParameter, "on-demand"]
Resources:
Ec2LaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: LinuxWorkstation
LaunchTemplateData:
InstanceMarketOptions:
!If
- IsOnDemand
- !Ref "AWS::NoValue"
- MarketType:
Ref: InstanceMarketTypeParameter

Error creating SpotFleet using CloudFormation

I'm creating a SpotFleet request using CloudFormation, but whenever I try to deploy it, fails with the message:
Unable to fetch parameters [ami-09bee01cc997a78a6] from parameter store for this account.
I'm using the following code (snippet):
SpotFleet:
Type: AWS::EC2::SpotFleet
Properties:
SpotFleetRequestConfigData:
ExcessCapacityTerminationPolicy: default
InstanceInterruptionBehavior: terminate
IamFleetRole: !GetAtt SpotFleetRole.Arn
TargetCapacity: !Ref ClusterSize
TerminateInstancesWithExpiration: false
LaunchSpecifications:
- IamInstanceProfile:
Arn: !Ref ECSInstanceProfile
ImageId: !Ref LatestAmiId
InstanceType: !Ref SpotFleetInstanceType
KeyName: !Ref KeyName
Monitoring:
Enabled: false
SecurityGroups:
- GroupId: !Ref ECSHostSecurityGroup
SubnetId: !Ref PublicSubnet
...
The ImageId is:
LatestAmiId:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: '/aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id'
When I manually fetch the image id from the AWS CLI I get:
aws ssm get-parameters --names /aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id --region us-east-1 --output json | jq -r ."Parameters[].Value"
Output:
ami-09bee01cc997a78a6
If a manually hardcode this value into the ImageId parameter, it returns the same error (Unable to fetch parameters...)
Why it is failing if I am able to fetch the id value from the CLI?
Thanks to #Marcin's comment and this answer, I found the problem.
The problem is that I was using the wrong parameter type for the Image Id. I was using:
LatestAmiId:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: '/aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id'
and I should be using this:
LatestAmiId:
Description: Linux AMI
Type: AWS::EC2::Image::Id

Launch ec2 using cloudformation which should use launch template

I am trying to create a ec2 instance using the launch template :
So I have created a launch template with below data.
LaunchTemplateVerybasic:
When I am trying to run a cloud formation template like below :
AWSTemplateFormatVersion: 2010-09-09
Resources:
TestTemplate:
Type: 'AWS::EC2::Instance'
Properties:
LaunchTemplate:
LaunchTemplateSpecification:
LaunchTemplateId: lt-00d9f13eea240e524
LaunchTemplateName: Testtemplate
Version: '1'
I get this error:
Encountered unsupported property LaunchTemplateSpecification, whereas
in designer it shows that instance can be created.
What is that I am missing? I checked the documentation and this is a property supported by AWS::EC2::instance..
Let me know if there is something I am missing in understanding and in yaml
Since the EC2 is not being launched from the launch template via auto-scaling group, rather its via a resource definition, you need first to remove the and have the config as follows
HostA:
Type: AWS::EC2::Instance
Properties:
LaunchTemplate:
LaunchTemplateId: !Ref HostALaunchTemplate
Version: !GetAtt HostALaunchTemplate.LatestVersionNumber
Launch Template example
When launching a launch template via auto-scaling group, usually there is no need to specify a network interface within the launch template because the auto-scaling group will take care of it.
Inside your launch template, remove the SecurityGroupIds at the LaunchTemplateData
HostALaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: HostALaunchTemplate
LaunchTemplateData:
SecurityGroupIds:
- !ImportValue MyASG
And add security group via network interface like so
HostALaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: HostALaunchTemplate
NetworkInterfaces:
- DeviceIndex: 0
Groups:
- !ImportValue MyASG
SubnetId: !ImportValue MySubnet
The CloudFormation Linter
catches this with:
E3002 Invalid Property Resources/TestTemplate/Properties/LaunchTemplate/LaunchTemplateSpecification
template.yaml:7:9
Try removing LaunchTemplateSpecification:
AWSTemplateFormatVersion: 2010-09-09
Resources:
TestTemplate:
Type: 'AWS::EC2::Instance'
Properties:
LaunchTemplate:
LaunchTemplateId: lt-00d9f13eea240e524
LaunchTemplateName: Testtemplate
Version: '1'
AWS::EC2::Instance.LaunchTemplate documentation

How to recover ebs from snapshot

Given a cloudformation template with an EC2 instance that uses a EBS volume defined as follows:
DefaultVolume:
Type: AWS::EC2::Volume
DeletionPolicy: Snapshot
Properties:
AvailabilityZone: eu-west-1a
Size: 8
Tags:
-
Key: Name
Value: Jenkins
VolumeType: gp2
How can I set up the cloudformation template so when I recreate the stack again (after a deletion and ebs snapshot created), the ebs recovers the data from the snapshot instead of creating a brand new volume?
I'm not sure there is a way to reference a snapshot of a deleted stack. One issue with that is how would it know which snapshot to take if there are multiple stacks created from the same template?
What you can do is add a parameter for your template for the snapshot id and use it with SnapshotId when specified.
Parameters:
OldSnapshot:
Type: String
Default: ""
Conditions:
OldSnapshotAvailable:
!Not [!Equals [!Ref OldSnapshot, ""]]
Resources:
DefaultVolume:
Type: AWS::EC2::Volume
DeletionPolicy: Snapshot
Properties:
AvailabilityZone: eu-west-1a
Size: 8
Tags:
-
Key: Name
Value: Jenkins
VolumeType: gp2
SnapshotId: !If [OldSnapshotAvailable, !Ref OldSnapshot, !Ref AWS::NoValue]

Encountered unsupported property EBS

I'm having some issues with a Cloudformation Template where when I attempt to roll it out it keeps failing on the instance creation prompting the error ' Encountered unsupported property EBS' which in turn causes a rollback. I find this quite interesting because I appear to have all of the necessary properties in there at the moment:
Also Including some links that could help speed up the research:
Instance Setup,
Block Device Mapping, &
Block Specific Properties
Resources:
Web01:
Type: AWS::EC2::Instance
Properties:
SecurityGroups:
- Ref: SecurityGoupSocoDrELB
- Ref: SecurityGoupSocoDrData
KeyName:
Ref: KeyPairName
ImageId: !FindInMap
- RegionMap
- Ref: "AWS::Region"
- AMI
Monitoring: 'false'
SubnetId:
Ref: SocoDrSubnet02
PrivateIpAddress: xxxxxxxx
InstanceInitiatedShutdownBehavior: 'stop'
InstanceType:
Ref: InstanceType
#I think the error occurs here-
BlockDeviceMappings:
- DeviceName: /dev/xvda
- EBS:
DeleteOnTermination: 'true'
VolumeType: gp2
VolumeSize: '300'
For reference I'm including other appropriate sections but the problem is stemming from the Resource's Instance section:
Parameters:
KeyPairName:
Description: The EC2 Key Pair to allow SSH access to the instance
Type: AWS::EC2::KeyPair::KeyName
# INSTANCE
InstanceType:
Type: String
AllowedValues:
- t2.nano
- t2.micro
- t2.small
- t2.medium
- t2.large
- t2.xlarge
- t2.2xlarge
Default: t2.small
Mappings:
RegionMap:
us-east-2:
AMI: ami-014a7d64
The correct property is Ebs and not EBS. Documentation can be found here.