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

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)"
}
}
}

Related

Cloudformation DeletionPolicy policy missing for ec2 instance

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",
...

in JSON, Template format error: Unresolved resource dependencies ~~ in the Resources block of the template

i tried to create an EC2 instance with the template below,
{
"Description" : "Create an EC2 instance running the Amazon Linux 64 bit AMI.",
"Parameters" : {
"KeyPair" : {
"Description" : "The EC2 Key Pair to allow SSH access to the instance",
"Type" : "String",
"Default" : "formationKey"
}
},
"Resources" : {
"Ec2Instance" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
"KeyName" : { "Ref" : "formationKeyPair" },
"ImageId" : "ami-0eb14fe5735c13eb5",
"SecurityGroups" : [ { "Ref" : "FormationSecurityGroup" } ],
"InstanceType" : "t2.micro",
"UserData": {
"Fn::Base64": {
"Fn::Join": [ "",
[ "#!/bin/bash\n",
"/opt/aws/bin/cfn-init --region ", { "Ref": "AWS::Region" },
" -s ", { "Ref": "AWS::StackName" },
" -r Ec2Instance\n" ]
]
}
}
},
"Metadata" : {
"AWS::CloudFormation::Init" : {
"config" : {
"packages" : {
"yum" : {
"httpd" : []
}
},
"services" : {
"sysvinit" : {
"httpd" : {
"enabled" : "true",
"ensureRunning" : "true"
}
}
}
}
}
}
},
"InstanceSecurityGroup" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupDescription" : "Allow HTTP and SSH access",
"SecurityGroupIngress" : [ {
"IpProtocol" : "tcp",
"FromPort" : "22",
"ToPort" : "22",
"CidrIp" : "0.0.0.0/0"
}, {
"IpProtocol" : "tcp",
"FromPort" : "80",
"ToPort" : "80",
"CidrIp" : "0.0.0.0/0"
} ]
}
}
},
"Outputs" : {
"InstanceId" : {
"Description" : "The InstanceId of the newly created EC2 instance",
"Value" : {
"Ref" : "FormationEC2"
}
}
},
"AWSTemplateFormatVersion" : "2010-09-09"
}
but i get this error
" Template format error: Unresolved resource dependencies
[formationKeyPair, FormationSecurityGroup] in the Resources block of
the template "
it seems to be a problem caused by not defining a parameter.
but, isn't it that i defined the parameter in the first place??
i saw a question article similar to my problem, but it was written in YAML
how can i troubleshoot in JSON?
There are some errors with your json. The reference of the security group and SSH is wrong. I've edited it and it looks like it is working.
{
"Description": "Create an EC2 instance running the Amazon Linux 64 bit AMI.",
"Parameters": {
"KeyPair": {
"Description": "The EC2 Key Pair to allow SSH access to the instance",
"Type": "String",
"Default": "formationKey"
}
},
"Resources": {
"Ec2Instance": {
"Type": "AWS::EC2::Instance",
"Properties": {
"KeyName": {
"Ref": "KeyPair"
},
"ImageId": "ami-0eb14fe5735c13eb5",
"SecurityGroups": [
{
"Ref": "InstanceSecurityGroup"
}
],
"InstanceType": "t2.micro",
"UserData": {
"Fn::Base64": {
"Fn::Join": [
"",
[
"#!/bin/bash\n",
"/opt/aws/bin/cfn-init --region ",
{
"Ref": "AWS::Region"
},
" -s ",
{
"Ref": "AWS::StackName"
},
" -r Ec2Instance\n"
]
]
}
}
},
"Metadata": {
"AWS::CloudFormation::Init": {
"config": {
"packages": {
"yum": {
"httpd": []
}
},
"services": {
"sysvinit": {
"httpd": {
"enabled": "true",
"ensureRunning": "true"
}
}
}
}
}
}
},
"InstanceSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Allow HTTP and SSH access",
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": "22",
"ToPort": "22",
"CidrIp": "0.0.0.0/0"
},
{
"IpProtocol": "tcp",
"FromPort": "80",
"ToPort": "80",
"CidrIp": "0.0.0.0/0"
}
]
}
}
},
"Outputs": {
"InstanceId": {
"Description": "The InstanceId of the newly created EC2 instance",
"Value": {
"Ref": "Ec2Instance"
}
}
}
}

How can I let my VPC have access to the internet via cloudformation?

I have a VPC setup to that my lambda function can talk to my RDS server. This is working. I also need my lambda functions to have access to the internet. To this end I'm trying to setup an internet gateway and the routes to allow it. I'm failing.
The VPC routes and gateway are created as the following
"VPC": {
"Type": "AWS::EC2::VPC",
"Properties": {
"CidrBlock": "10.0.0.0/16",
"EnableDnsSupport": "true",
"EnableDnsHostnames": "true",
"InstanceTenancy": "default",
"Tags" : [{ "Key": "Name", "Value": { "Ref": "DomainName" } }]
}
},
"VPCRouteTable" : {
"Type" : "AWS::EC2::RouteTable",
"Properties" : {
"VpcId" : { "Ref" : "VPC" },
"Tags" : [{ "Key": "Name", "Value": { "Ref": "DomainName" } }]
}
},
"InternetGateway" : {
"Type" : "AWS::EC2::InternetGateway",
"Properties" : {
"Tags" : [{ "Key": "Name", "Value": { "Ref": "DomainName" } }]
}
},
"AttachGateway": {
"Type" : "AWS::EC2::VPCGatewayAttachment",
"Properties" : {
"VpcId" : { "Ref" : "VPC" },
"InternetGatewayId" : { "Ref" : "InternetGateway" }
}
},
"InternetRoute" : {
"Type" : "AWS::EC2::Route",
"DependsOn" : "InternetGateway",
"Properties" : {
"RouteTableId" : { "Ref" : "VPCRouteTable" },
"DestinationCidrBlock" : "0.0.0.0/0",
"GatewayId" : { "Ref" : "InternetGateway" }
}
},
I create the subnets and associate them with the route table
"SubnetA": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": { "Ref": "VPC" },
"CidrBlock": "10.0.0.0/24",
"AvailabilityZone": { "Fn::Select": [ "0", { "Fn::GetAZs": { "Ref": "AWS::Region" } }]},
"Tags" : [{ "Key": "Name", "Value": { "Ref": "DomainName" } }]
}
},
"SubnetB": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": { "Ref": "VPC" },
"CidrBlock": "10.0.1.0/24",
"AvailabilityZone": { "Fn::Select": [ "1", { "Fn::GetAZs": { "Ref": "AWS::Region" } }]},
"Tags" : [{ "Key": "Name", "Value": { "Ref": "DomainName" } }]
}
},
"SubnetARouteTableAssociation" : {
"Type" : "AWS::EC2::SubnetRouteTableAssociation",
"Properties" : {
"SubnetId" : { "Ref" : "SubnetA" },
"RouteTableId" : { "Ref" : "VPCRouteTable" }
}
},
"SubnetBRouteTableAssociation" : {
"Type" : "AWS::EC2::SubnetRouteTableAssociation",
"Properties" : {
"SubnetId" : { "Ref" : "SubnetB" },
"RouteTableId" : { "Ref" : "VPCRouteTable" }
}
},
I have the database security groups
"DBSubnetGroup": {
"Type": "AWS::RDS::DBSubnetGroup",
"Properties": {
"DBSubnetGroupDescription": "Database Access",
"SubnetIds" : [{ "Ref": "SubnetA" }, { "Ref": "SubnetB" }],
"Tags" : [{ "Key": "Name", "Value": { "Ref": "DomainName" } }]
}
},
"DBEC2SecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Security group for RDS DB Instance",
"VpcId": {"Ref": "VPC"},
"SecurityGroupIngress" : [{
"IpProtocol": "tcp",
"FromPort": "3306",
"ToPort": "3306",
"CidrIp": "10.0.0.0/16"
}],
"Tags" : [{ "Key": "Name", "Value": { "Ref": "DomainName" } }]
}
},
and the lambda security group
"LambdaSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Security group for Lambda",
"VpcId": {"Ref": "VPC"},
"Tags" : [{ "Key": "Name", "Value": { "Ref": "DomainName" } }]
}
},
So As it stands now, my lambda's can talk to the database just fine. but they can't reach the internet. What am I missing?
If your lambda function needs to have access to both your VPC resources and Internet, then create 2 subnets: public and private. Put your lambda in private subnet and configure NAT in public subnet.
From http://docs.aws.amazon.com/lambda/latest/dg/vpc.html
Therefore, if your Lambda function requires Internet access (for
example, to access AWS services that don't have VPC endpoints, such as
Amazon Kinesis), you can configure a NAT instance inside your VPC or
you can use the Amazon VPC NAT gateway. For more information, see NAT
Gateways in the Amazon VPC User Guide.

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"
}
}