Cloudformation DeletionPolicy policy missing for ec2 instance - amazon-web-services

I am trying to create a stack (see code below)
but I get the following error:
There was an error creating this change set.
The following resources to import [masterinstance] must have DeletionPolicy attribute specified in the template.
I am not sure how to resolve this one. I tried adding "DeletionPolicy": "Retain" under the InstanceType definition, but that's not correct.
"InstanceType": {
"Description": "EC2 instance type for the node instances",
"Type": "String",
"Default": "t3.micro",
"DeletionPolicy": "Retain",
Could somebody explain what I am doing wrong and how can I change the template?
thanks very much.
Template:
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "Template to create a RHEL8 instances for testings",
"Parameters": {
"instanceName": {
"Description": "The instance name.",
"Type": "String"
},
"Subnet": {
"Description": "The subnets where the instance is created.",
"Type": "AWS::EC2::Subnet::Id"
},
"securitygroup": {
"Description": "The subnets where workers can be created.",
"Type": "List<AWS::EC2::SecurityGroup::Id>"
},
"InstanceType": {
"Description": "EC2 instance type for the node instances",
"Type": "String",
"Default": "t3.micro",
"AllowedValues": [
"t3.micro", "t3.small", "t2.medium"
],
"ConstraintDescription": "Must be a valid EC2 instance type"
},
"KeyName": {
"Description": "The EC2 Key Pair to allow SSH access to the instances",
"Type": "AWS::EC2::KeyPair::KeyName"
},
"volumeSize": {
"Description": "Size of EBS volume in GB",
"Type": "Number"
},
"ami" : {
"Description": "ami of instance",
"Type" : "AWS::EC2::Image::Id",
}
},
"Resources" : {
"masterinstance" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
"BlockDeviceMappings" : [ {
"DeviceName" : "/dev/sda1",
"Ebs" : {
"DeleteOnTermination" : "False",
"Encrypted" : "False",
"VolumeSize" : {"Ref": "volumeSize"},
"VolumeType" : "gp2"
}
}],
"ImageId" : {"Ref": "ami"},
"InstanceType" : {"Ref" : "InstanceType"},
"KeyName" : {"Ref": "KeyName"},
"SecurityGroupIds" : {"Ref" : "securitygroup"},
"SubnetId" : {"Ref": "Subnet"},
"Tags" : [ {
"Key" : "Name",
"Value" : {"Ref": "instanceName"}
} ]
}
}
}
}

The DeletionPolicy should be placed in your actual instance resource, not input parameter. For example:
"MyEC2Instance" : {
"Type" : "AWS::EC2::Instance",
"DeletionPolicy" : "Retain",
"Properties" : {
"ImageId" : "ami-79fd7eee",
"KeyName" : "testkey",
...

Related

cloudformation, error creating a change: set Parameter 'ami' must be one of AllowedValues

I am trying to create a stack in CloudFormation. When I go through the process and populate the fields, I am asked to enter an AMI.
I key in the instance ID, but on the next screen I get the following error message:
There was an error creating this change set Parameter 'ami' must be one of AllowedValues
I am not sure what type of parameter is expected here. What else should I be entering instead of the ID?
Looking at the AMI details, I see the AMI is set to private. It's not shared with any account or organisation. Is this the reason why it's not working?
I tried to Google that error message but I haven't found anything relevant.
Thanks
template:
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "Template to create a Ubuntu grafana server",
"Parameters": {
"instanceName": {
"Description": "Ubuntu Grafana",
"Type": "String"
},
"Subnet": {
c
"Description": "The subnets where the instance is created.",
"Type": "AWS::EC2::Subnet::Id"
},
"securitygroup": {
"Description": "The subnets where workers can be created.",
"Type": "List<AWS::EC2::SecurityGroup::Id>"
},
"InstanceType": {
"Description": "EC2 instance type for the node instances",
"Type": "String",
"Default": "t3.micro",
"AllowedValues": [
"t3.micro", "t3.small", "t2.medium"
],
"ConstraintDescription": "Must be a valid EC2 instance type"
},
"KeyName": {
"Description": "The EC2 Key Pair to allow SSH access to the instances",
"Type": "AWS::EC2::KeyPair::KeyName"
},
"volumeSize": {
"Description": "Size of EBS volume in GB",
"Type": "Number"
},
"ami" : {
"Description": "ami of instance",
"Type" : "AWS::EC2::Image::Id",
"AllowedValues" : [
"ami-00000000","ami-00000000", "ami-00000000"
]
}
},
"Resources" : {
"masterinstance" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
"BlockDeviceMappings" : [ {
"DeviceName" : "/dev/sda1",
"Ebs" : {
"DeleteOnTermination" : "False",
"Encrypted" : "False",
"VolumeSize" : {"Ref": "volumeSize"},
"VolumeType" : "gp2"
}
}],
"ImageId" : {"Ref": "ami"},
"InstanceType" : {"Ref" : "InstanceType"},
"KeyName" : {"Ref": "KeyName"},
"SecurityGroupIds" : {"Ref" : "securitygroup"},
"SubnetId" : {"Ref": "Subnet"},
"Tags" : [ {
"Key" : "Name",
"Value" : {"Ref": "instanceName"}
} ]
}
}
}
}
"ami" : {
"Description": "ami of instance",
"Type" : "AWS::EC2::Image::Id",
"AllowedValues" : [
"ami-00000000","ami-00000000", "ami-00000000"
]
}
Whatever value you are providing as value of the ami parameter needs to be one of AllowedValues. Since all the IDs in the AllowedValues are invalid, it is safe to assume that you aren't providing one of these values. Removing the AllowedValues constraint (or correcting the list) would fix this:
"ami" : {
"Description": "ami of instance",
"Type" : "AWS::EC2::Image::Id"
}
I'm late, but I have just faced that problem some days ago.
The problem is that you have defined some allowed values but the informed value of the ami is not in the list of allowed values. If you don't inform a default value for the ami it will take empty as the value.
Maybe I can explain myself better using and example:
Code block with the problem...
"ami" : {
"Description": "ami of instance",
"Type" : "AWS::EC2::Image::Id",
"AllowedValues" : [
"ami-00000000","ami-00000001", "ami-00000002"
]
}
You need to specify a Default value for the ami, that must be one of the allowed values or you must to add empty value in the allowed values list.
Solution 1. Setting ami default value
"ami" : {
"Default": "ami-00000000",
"Description": "ami of instance",
"Type" : "AWS::EC2::Image::Id",
"AllowedValues" : [
"ami-00000000","ami-00000001", "ami-00000002"
]
}
Solution 2. Adding empty value
"ami" : {
"Description": "ami of instance",
"Type" : "AWS::EC2::Image::Id",
"AllowedValues" : [
"","ami-00000000","ami-00000001", "ami-00000002"
]
}
I hope it helps!

CloudFormation - Template contains errors.: Invalid template parameter property 'Properties'

I am uploading following template to create an EC2 instance in CloudFormation. And when I "Validate Template" from console getting following error- Template contains errors.: Invalid template parameter property 'Properties'
Template Code:
Template is attached. Open template with notepad or notepad++
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "This is an AWS Cloud Formation template to create an EC2 instance in a Custom VPC.",
"Parameters" : {
"KeyName" : {
"Type" : "String",
"Default" : "ec2-us-east",
"Description" : "SSH Key to access the EC2 instance"
},
"MyVpc" : {
"Type" : "AWS::EC2::VPC",
"Properties" : {
"CidrBlock" : "10.0.0.0/16",
"EnableDnsHostnames" : "true"
}
},
"PublicSubnet" : {
"Type" : "AWS::EC2::Subnet",
"Properties" : {
"VpcId" : {"Ref" : "MyVpc"},
"CidrBlock" : "10.0.0.0/24",
"AvailabilityZone" : "us-east-1a"
}
},
"InstanceType" : {
"Type" : "String",
"Default" : "t2.micro",
"Description" : "Select EC2 instance type"
}
},
"Resources" : {
"SecurityGroup" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupName" : "My Security Group",
"GroupDescription" : "My CFSecurity Group",
"VpcId" : {"Ref" : "MyVpc"},
"SecurityGroupIngress" : [{
"CidrIp" : "0.0.0.0/0",
"FromPort" : "22",
"IpProtocol" : "tcp",
"ToPort" : "22"
}]
}
},
"Server" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
"ImageId" : "ami-1853ac65",
"InstanceType" : {"Ref" : "InstanceType"},
"KeyName" : {"Ref" : "KeyName"},
"SecurityGroupIds" : {"Ref" : "SecurityGroup"},
"SubnetId" : {"Ref" : "PublicSubnet"}
}
}
},
"Outputs" : {
"PublicName" : {
"Value" : {"Fn::GetAtt" : ["Server", "PublicDnsName"]},
"Description" : "Public Name (connect via ssh)"
}
}
}
Can you please help me to find out What I am doing wrong?
You are creating VPC and public subnet under key Parameters. You need to define vpc and subnet under key resources. This should work:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "This is an AWS Cloud Formation template to create an EC2 instance in a Custom VPC.",
"Parameters": {
"KeyName": {
"Type": "String",
"Default": "ec2-us-east",
"Description": "SSH Key to access the EC2 instance"
},
"InstanceType": {
"Type": "String",
"Default": "t2.micro",
"Description": "Select EC2 instance type"
}
},
"Resources": {
"SecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupName": "My Security Group",
"GroupDescription": "My CFSecurity Group",
"VpcId": {
"Ref": "MyVpc"
},
"SecurityGroupIngress": [{
"CidrIp": "0.0.0.0/0",
"FromPort": "22",
"IpProtocol": "tcp",
"ToPort": "22"
}]
}
},
"Server": {
"Type": "AWS::EC2::Instance",
"Properties": {
"ImageId": "ami-1853ac65",
"InstanceType": {
"Ref": "InstanceType"
},
"KeyName": {
"Ref": "KeyName"
},
"SecurityGroupIds": {
"Ref": "SecurityGroup"
},
"SubnetId": {
"Ref": "PublicSubnet"
}
}
},
"MyVpc": {
"Type": "AWS::EC2::VPC",
"Properties": {
"CidrBlock": "10.0.0.0/16",
"EnableDnsHostnames": "true"
}
},
"PublicSubnet": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": {
"Ref": "MyVpc"
},
"CidrBlock": "10.0.0.0/24",
"AvailabilityZone": "us-east-1a"
}
}
},
"Outputs": {
"PublicName": {
"Value": {
"Fn::GetAtt": ["Server",
"PublicDnsName"]
},
"Description": "Public Name (connect via ssh)"
}
}
}

Ec2 instance getting terminated instantly in cloud formation

I have created a simple JSON template for launching an EC2 instance using CloudFormation. The JSON code works for RedHat ami-2051294a (in us-east-1 region) but does not work for Amazon Linux ami-0b33d91d.
What could be the issue?
"Resources": {
"Ec2Instance" :{
"Type" : "AWS::EC2::Instance",
"Properties" : {
"Tags": [
{ "Key" : "Name" , "Value" : "BIP-Spark" }
],
"KeyName": { "Ref" : "KeyName" },
"InstanceType" : { "Ref" : "BipDevInstanceType" },
"ImageId" : { "Ref" : "NATAMI" },
"IamInstanceProfile" : { "Ref": "RoleName" },
"BlockDeviceMappings" : [ {
"DeviceName" : "/dev/sda1",
"Ebs" : { "VolumeSize" : "30", "VolumeType": "gp2" }
},
{
"DeviceName" : "/dev/sdb",
"Ebs" : { "VolumeSize" : "30", "VolumeType": "gp2" }
}
],
"NetworkInterfaces" : [ {
"GroupSet": [ "sg-***" ],
"SubnetId": { "Ref" : "SubnetID" },
"AssociatePublicIpAddress": "true",
"DeleteOnTermination": "true",
"DeviceIndex":"0" }
]
}
}
}
}
Both AMIs launched perfectly well for me.
Here is the minimal version of the template that I used to successfully launch an Amazon EC2 instance with Amazon Linux AMI ami-0b33d91d:
{
"AWSTemplateFormatVersion":"2010-09-09",
"Resources": {
"Ec2Instance" :{
"Type" : "AWS::EC2::Instance",
"Properties" : {
"InstanceType" : "t2.micro",
"ImageId" : "ami-0b33d91d",
"NetworkInterfaces" : [ {
"GroupSet": [ "sg-xxxxxxxx" ],
"SubnetId": "subnet-xxxxxxxx",
"AssociatePublicIpAddress": "true",
"DeleteOnTermination": "true",
"DeviceIndex":"0" }
]
}
}
}
}
The instance successfully entered the Running state and kept running correctly.
It is likely that one of your manually-entered parameters was incorrect.

How to add a RDS instance to a VPC using aws cloudformation

When I launch a RDS instance manually I'm able to assign what VPC I want it to be part of. I'm trying to create a stack using AWS cloudformation, however I do not see an API to be able to do that. I can create my VPC in the stack and then reference it for security groups both EC2 and DB security groups and they both end up been part of the VPC however the RDS instance itself does not. Is there a way to assign the VPC to the RDS instance?
Below is my template:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Metadata": {
"AWS::CloudFormation::Designer": {
"30e03bfc-b61a-4d6c-89db-1b62b258a305": {
"size": {
"width": 80,
"height": 80
},
"position": {
"x": 700,
"y": 170
},
"z": 0,
"embeds": []
}
}
},
"Parameters": {
"DBPreferredBkupWindow": {
"Description" : "The daily time range (in UTC) during which automated backups are created, ideally off peak-hours.",
"Type" : "String",
"MinLength" : "1",
"MaxLength" : "11",
"AllowedPattern" : "\\d[0-23]:\\d[0-59]-\\d[0-23]:\\d[0-59]",
"Default" : "01:00-02:00"
}
},
"Resources": {
"VPC": {
"Type": "AWS::EC2::VPC",
"Properties": {
"CidrBlock" : "172.16.0.0/16",
"EnableDnsSupport" : true
}
},
"DB": {
"Type": "AWS::RDS::DBInstance",
"Properties": {
"DBName" : "ems",
"Engine" : "postgres",
"EngineVersion" : "9.4.7",
"DBInstanceClass" : "db.t1.micro",
"DBInstanceIdentifier" : "rltdb",
"MasterUsername" : "pgadmin",
"MasterUserPassword" : "pgadmin1",
"AllocatedStorage" : "100",
"Iops" : "1000",
"BackupRetentionPeriod" : "7",
"PreferredBackupWindow" : { "Ref" : "DBPreferredBkupWindow" },
"MultiAZ" : true,
"PubliclyAccessible" : false,
"AutoMinorVersionUpgrade" : false,
"VPCSecurityGroups" : [{ "Ref" : "SecurityGroup" } ]
},
"Metadata": {
"AWS::CloudFormation::Designer": {
"id": "30e03bfc-b61a-4d6c-89db-1b62b258a305"
}
}
},
"DBSecurityGroup": {
"Type": "AWS::RDS::DBSecurityGroup",
"Properties": {
"EC2VpcId" : { "Ref" : "VPC" },
"DBSecurityGroupIngress" : { "EC2SecurityGroupName": { "Ref": "SecurityGroup"} },
"GroupDescription" : "Database Access"
}
},
"SecurityGroup" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"VpcId" : { "Ref" : "VPC" },
"GroupDescription" : "Enable database access for application",
"SecurityGroupIngress" : [
{"IpProtocol" : "tcp", "FromPort" : "5432", "ToPort" : "5432", "CidrIp" : "0.0.0.0/0"}
]
}
}
}
}
You have to create a DBSubnetGroup and at least two subnets in your CloudFormation template.
"subnet-1" : {
"Type" : "AWS::EC2::Subnet",
"Properties" : {
"CidrBlock" : "172.16.1.0/24",
"VpcId" : { "Ref" : "VPC" }
}
},
"subnet-2" : {
"Type" : "AWS::EC2::Subnet",
"Properties" : {
"CidrBlock" : "172.16.2.0/24",
"VpcId" : { "Ref" : "VPC" }
}
},
"DBSubnetGroup" : {
"Type" : "AWS::RDS::DBSubnetGroup",
"Properties" : {
"SubnetIds" : [
{ "Ref" : "subnet-1" },
{ "Ref" : "subnet-2" }
],
}
},
and in last you have to include DBSubnetGroup in your "DB" Object.
"DBSubnetGroupName": { "Ref": "DBSubnetGroup" }
You need to include the DBSubnetGroupName:
A DB subnet group to associate with the DB instance.
If there is no DB subnet group, then it is a non-VPC DB instance.
Create a DBSubnetGroup resource using subnets in your VPC, then tie that to your DBInstance:
"DBSubnetGroupName": { "Ref": "MySubnetGroup" }

How get "cidrblock" of a subnet in the "outputs" of a AWS Cloudformation?

I am writing a AWS Code formation. I have to print the Cidrblock of a subnet. But that does not work. Please help
"Resources": {
"Subnet": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": {
"Ref": "VPC"
},
"CidrBlock": "10.0.0.0/16",
}
},
Outputs : {
"SubnetCIDR": {
"Value": {
"Fn::GetAtt": [
"Subnet",
"CidrBlock"
]
},
"Description": "The CIDR"
},
}
This does not work. The following error message is shown while uploading the template:
Template validation error: Template error: resource Subnet does not
support attribute type CidrBlock in Fn::GetAtt
Not supported.
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html
If you look at the doc, the only supported attribute is AvailabilityZone
Since you seem to be hard coding the CIDR block anyway, you could set it as a parameter and then just reference the parameter in both places.
"Parameters" : {
"CidrBlock" : {
"Type" : "String",
"Default" : "10.0.0.0/16"
}
},
"Resources" : {
"Subnet" : {
"Type" : "AWS::EC2::Subnet",
"Properties" : {
"VpcId" : {
"Ref" : "VPC"
},
"CidrBlock" : { "Ref" : "CidrBlock" }
}
}
},
"Outputs" : {
"SubnetCIDR" : {
"Value" : { "Ref" : "CidrBlock" },
"Description": "The CIDR"
}
}