AWS CloudFormation use existing security group - amazon-web-services

I want to use existing security group on cloudformation template.
Now I have template that create 2 SG,
"InstanceMember1": {
"Type": "AWS::EC2::Instance",
"Properties": {
"SubnetId": {
"Ref": "privateSubnetA"
},
"SecurityGroupIds": [
{
"Ref": "MongoSg"
},
{
"Ref": "mongoTrafficSG"
}
],
}
}
"MongoSg": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "MongoDB security group",
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": "22",
"ToPort": "22",
"SourceSecurityGroupId": {
"Ref": "bastionSG"
}
}
],
"VpcId": "%%vpc-id%%",
}
}
}
Now I want to add to the instance exist security group id, any advice?

you can just go ahead and specify the security group name:
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-securitygroups
"InstanceMember1": {
"Type": "AWS::EC2::Instance",
"Properties": {
"SubnetId": {
"Ref": "privateSubnetA"
},
"SecurityGroups": [ "mysuperawesomealreadyexistinggroup"],
}
}

Related

AWS Cloud formation - create EC2 instance with security group name

I am trying to create a cloud formation template to create EC2 instance. I would like to use Security Group Name instead of Security Group Id. When I use that I am getting error "Encountered unsupported property SecurityGroup". How can I use Security Group Name while creating EC2 Instance through Cloud Formation
"Resources":
{
"EC2Instance":
{
"Type" : "AWS::EC2::Instance",
"Properties":
{
"InstanceType":
{
"Ref": "InstanceType"
},
"SecurityGroup":
[
{
"Ref" : "InstanceSecurityGroup"
}
],
"KeyName":
{
"Ref" : "AWS::Region"
},
"ImageId":
{
"Ref": "AMI"
}
}
},
"InstanceSecurityGroup":
{
"Type":"AWS::EC2::SecurityGroup",
"Properties":
{
"GroupDescription": "Enable SSH access via port 22",
"GroupName":
{
"Fn::FindInMap":
[
"EnvironmentConfig",
{
"Ref": "Environment"
},
"SGGroupName"
]
},
"SecurityGroupIngress":
[
{
"IpProtocol": "tcp",
"FromPort": 22,
"ToPort": 22,
"CidrIp":"10.252.0.0/16"
},
{
"IpProtocol": "tcp",
"FromPort": 22,
"ToPort": 22,
"CidrIp":"10.251.0.0/16"
}
],
"VpcId":
{
"Fn::FindInMap":
[
"EnvironmentConfig",
{
"Ref":"Environment"
},
"VPC"
]
}
}
}
It should be SecurityGroups instead of SecurityGroup, i.e.
"SecurityGroups" : [{ "Ref" : "InstanceSecurityGroup" }]
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/quickref-ec2.html

AWS Cloud Formation - Requested configuration not supported AWS::EC2::Instance

I am getting below error on one of my cloud formation template -
13:00:10 UTC+0550 CREATE_FAILED AWS::EC2::Instance WebApplicationServer The requested configuration is currently not supported. Please check the documentation for supported configurations.
My CloudFormation template is -
{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
"DevServerKeyPair": {
"Description": "Name of an existing EC2 KeyPair to enable SSH access to the instance",
"Type": "AWS::EC2::KeyPair::KeyName",
"ConstraintDescription": "Must be the name of an existing EC2 KeyPair."
}
},
"Resources": {
"DevVpc": {
"Type": "AWS::EC2::VPC",
"Properties": {
"CidrBlock": "172.31.0.0/16",
"EnableDnsSupport": "false",
"EnableDnsHostnames": "false",
"InstanceTenancy": "dedicated",
"Tags": [
{
"Key": "Name",
"Value": "DevStackVpc"
}
]
}
},
"DevSubnet": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": {
"Ref": "DevVpc"
},
"CidrBlock": "172.31.0.0/16",
"AvailabilityZone": {
"Fn::Select": [
0,
{
"Fn::GetAZs": ""
}
]
}
}
},
"WebApplicationServerSG": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"VpcId": {
"Ref": "DevVpc"
},
"GroupDescription": "Enable HTTP, HTTPS and SSH access",
"Tags": [
{
"Key": "Name",
"Value": "WebApplicationServer Service Group"
}
],
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": "443",
"ToPort": "443",
"CidrIp": "0.0.0.0/0"
},
{
"IpProtocol": "tcp",
"FromPort": "80",
"ToPort": "80",
"CidrIp": "0.0.0.0/0"
},
{
"IpProtocol": "tcp",
"FromPort": "22",
"ToPort": "22",
"CidrIp": "0.0.0.0/0"
}
],
"SecurityGroupEgress": [
{
"IpProtocol": "tcp",
"FromPort": "443",
"ToPort": "443",
"CidrIp": "0.0.0.0/0"
},
{
"IpProtocol": "tcp",
"FromPort": "80",
"ToPort": "80",
"CidrIp": "0.0.0.0/0"
},
{
"IpProtocol": "tcp",
"FromPort": "22",
"ToPort": "22",
"CidrIp": "0.0.0.0/0"
}
]
}
},
"WebApplicationServer": {
"Type": "AWS::EC2::Instance",
"Properties": {
"ImageId": "ami-f3e5aa9c",
"InstanceType": "t2.micro",
"Tags": [
{
"Key": "Name",
"Value": "WebApplicationServer"
}
],
"KeyName": {
"Ref": "DevServerKeyPair"
},
"NetworkInterfaces": [
{
"SubnetId": {"Ref": "DevSubnet"},
"AssociatePublicIpAddress": "true",
"DeviceIndex": "0",
"GroupSet": [{ "Ref" : "WebApplicationServerSG" }]
}
]
}
}
}
}
I tried to diagnose it but failed to understand which particular configuration in this simple template is not supported currently. Any help or pointer would be greatly appreciated.
Your VPC has an instance tenancy of dedicated, however t2 instances cannot be launched as dedicated instances. You will need to pick a different instance type or switch the tenancy of your VPC.
In my case I didn't have tenancy dedicated. The reason was I tried to use the instance type which is too new (r6g) and is missing in my region. So the solution was to fall back to older one (r5a).
Looks problem with subnet creation with fn::select function.
"DevSubnet" : {
"Type" : "AWS::EC2::Subnet",
"Properties" : {
"VpcId" : { "Ref" : "DevVpc" },
"CidrBlock" : "172.31.0.0/16",
"AvailabilityZone" : {
"Fn::Select" : [ "0", { "Fn::GetAZs" :""} ]
}
}
}
Try this. I hope it will work.

AWS Lambda in VPC doesn't have internet access behind NAT

My problem is that a Lambda function that I run behind NAT inside a VPC with an IGW doesn't have access to anything on the Internet.
What I'm trying to do is creating a VPC that has:
Internet Gateway;
2 private subnets (PrivateA and PrivateB) in availability zones A and B respectively;
1 public subnet (PublicA) in availability zone A
NAT Gateway in PublicA subnet
PrivateA and PrivateB have a route table that routes 0.0.0.0/0 to the NAT Gateway.
PublicA has a route table that routes 0.0.0.0/0 to the Internet Gateway.
Private subnets, as well as the public subnet have Access Control Lists allowing all Ingress and Egress traffic.
That part kind of works.
Next, I want to create a Lambda function inside the VPC. I put it into PrivateA and PrivateB and assign to it a Security Group that allows all Egress and Ingress traffic.
Below is a self-contained example (the whole template) that reproduces the issue. I've read all the possible docs and articles on the Internet so I would very much appreciate it if anybody could point me in the right direction.
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"Vpc": {
"Type": "AWS::EC2::VPC",
"Properties": {
"CidrBlock": "10.0.0.0/16",
"EnableDnsSupport": true,
"EnableDnsHostnames": true,
"InstanceTenancy": "default"
}
},
"InternetGateway": {
"Type": "AWS::EC2::InternetGateway"
},
"VpcGatewayAttachment": {
"Type": "AWS::EC2::VPCGatewayAttachment",
"Properties": {
"VpcId": { "Ref": "Vpc" },
"InternetGatewayId": { "Ref": "InternetGateway" }
}
},
"ElasticIP":{
"Type": "AWS::EC2::EIP",
"Properties": {
"Domain": "vpc"
}
},
"NatGateway": {
"Type": "AWS::EC2::NatGateway",
"DependsOn": [ "VpcGatewayAttachment" ],
"Properties": {
"AllocationId": { "Fn::GetAtt": [ "ElasticIP", "AllocationId" ] },
"SubnetId": { "Ref": "SubnetAPublic" }
}
},
"SubnetAPublic": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"AvailabilityZone": { "Fn::Select" : [ "0", { "Fn::GetAZs" : "" } ] },
"CidrBlock": "10.0.0.0/19",
"MapPublicIpOnLaunch": true,
"VpcId": { "Ref": "Vpc" }
}
},
"SubnetAPrivate": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"AvailabilityZone": { "Fn::Select" : [ "0", { "Fn::GetAZs" : "" } ] },
"CidrBlock": "10.0.64.0/19",
"VpcId": { "Ref": "Vpc" }
}
},
"SubnetBPrivate": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"AvailabilityZone": { "Fn::Select" : [ "1", { "Fn::GetAZs" : "" } ] },
"CidrBlock": "10.0.96.0/19",
"VpcId": { "Ref": "Vpc" }
}
},
"RouteTablePublic": {
"Type": "AWS::EC2::RouteTable",
"Properties": {
"VpcId": { "Ref": "Vpc" }
}
},
"RouteTablePrivate": {
"Type": "AWS::EC2::RouteTable",
"Properties": {
"VpcId": { "Ref": "Vpc" }
}
},
"RouteTableAssociationAPublic": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"SubnetId": { "Ref": "SubnetAPublic" },
"RouteTableId": { "Ref": "RouteTablePublic" }
}
},
"RouteTableAssociationAPrivate": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"SubnetId": { "Ref": "SubnetAPrivate" },
"RouteTableId": { "Ref": "RouteTablePrivate" }
}
},
"RouteTableAssociationBPrivate": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"SubnetId": { "Ref": "SubnetBPrivate" },
"RouteTableId": { "Ref": "RouteTablePrivate" }
}
},
"RouteTablePrivateInternetRoute": {
"Type": "AWS::EC2::Route",
"DependsOn": [ "VpcGatewayAttachment" ],
"Properties": {
"RouteTableId": { "Ref": "RouteTablePrivate" },
"DestinationCidrBlock": "0.0.0.0/0",
"NatGatewayId": { "Ref": "NatGateway" }
}
},
"RouteTablePublicInternetRoute": {
"Type": "AWS::EC2::Route",
"DependsOn": [ "VpcGatewayAttachment" ],
"Properties": {
"RouteTableId": { "Ref": "RouteTablePublic" },
"DestinationCidrBlock": "0.0.0.0/0",
"GatewayId": { "Ref": "InternetGateway" }
}
},
"NetworkAclPublic": {
"Type": "AWS::EC2::NetworkAcl",
"Properties": {
"VpcId": { "Ref": "Vpc" }
}
},
"NetworkAclPrivate": {
"Type": "AWS::EC2::NetworkAcl",
"Properties": {
"VpcId": { "Ref": "Vpc" }
}
},
"SubnetNetworkAclAssociationAPublic": {
"Type": "AWS::EC2::SubnetNetworkAclAssociation",
"Properties":{
"SubnetId": { "Ref": "SubnetAPublic" },
"NetworkAclId": { "Ref": "NetworkAclPublic" }
}
},
"SubnetNetworkAclAssociationAPrivate": {
"Type": "AWS::EC2::SubnetNetworkAclAssociation",
"Properties":{
"SubnetId": { "Ref": "SubnetAPrivate" },
"NetworkAclId": { "Ref": "NetworkAclPrivate" }
}
},
"SubnetNetworkAclAssociationBPrivate": {
"Type": "AWS::EC2::SubnetNetworkAclAssociation",
"Properties": {
"SubnetId": { "Ref": "SubnetBPrivate" },
"NetworkAclId": { "Ref": "NetworkAclPrivate" }
}
},
"NetworkAclEntryInPublicAllowAll": {
"Type": "AWS::EC2::NetworkAclEntry",
"Properties": {
"NetworkAclId": { "Ref": "NetworkAclPublic" },
"RuleNumber": 99,
"Protocol": -1,
"RuleAction": "allow",
"Egress": false,
"CidrBlock": "0.0.0.0/0"
}
},
"NetworkAclEntryOutPublicAllowAll": {
"Type": "AWS::EC2::NetworkAclEntry",
"Properties": {
"NetworkAclId": { "Ref": "NetworkAclPublic" },
"RuleNumber": 99,
"Protocol": -1,
"RuleAction": "allow",
"Egress": true,
"CidrBlock": "0.0.0.0/0"
}
},
"NetworkAclEntryInPrivateAllowVpc": {
"Type": "AWS::EC2::NetworkAclEntry",
"Properties": {
"NetworkAclId": { "Ref": "NetworkAclPrivate" },
"RuleNumber": 99,
"Protocol": -1,
"RuleAction": "allow",
"Egress": false,
"CidrBlock": "0.0.0.0/16"
}
},
"NetworkAclEntryOutPrivateAllowVpc": {
"Type": "AWS::EC2::NetworkAclEntry",
"Properties": {
"NetworkAclId": { "Ref": "NetworkAclPrivate" },
"RuleNumber": 99,
"Protocol": -1,
"RuleAction": "allow",
"Egress": true,
"CidrBlock": "0.0.0.0/0"
}
},
"LambdasSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Lambdas security group",
"SecurityGroupEgress": [
{ "CidrIp": "0.0.0.0/0", "IpProtocol": "-1" }
],
"SecurityGroupIngress": [
{ "CidrIp": "0.0.0.0/0", "IpProtocol": "-1" }
],
"VpcId": { "Ref": "Vpc" }
}
},
"LambdaFunctionExecutionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "lambda.amazonaws.com" },
"Action": "sts:AssumeRole"
}
]
},
"ManagedPolicyArns": [
"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
"arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
]
}
},
"LambdaFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Handler": "index.lambda_handler",
"Runtime": "python2.7",
"Role": {
"Fn::GetAtt": ["LambdaFunctionExecutionRole", "Arn"]
},
"Code": {
"ZipFile": {
"Fn::Join": ["\n", [
"import urllib2",
"def lambda_handler(event, context):",
"\tresponse = urllib2.urlopen('http://python.org/')",
"\treturn response.read()"
]]
}
},
"VpcConfig": {
"SecurityGroupIds": [
{ "Fn::GetAtt": [ "LambdasSecurityGroup", "GroupId"] }
],
"SubnetIds": [
{ "Ref": "SubnetAPrivate" },
{ "Ref": "SubnetBPrivate" }
]
}
}
}
}
}
The cause of the failed connectivity lies within your ACL config for "NetworkAclEntryInPrivateAllowVpc" and "NetworkAclEntryOutPrivateAllowVpc".
If you open that CIDR block from "0.0.0.0/16" to "0.0.0.0/0", Lambda can access the internet.
I'm not that knowledgeable about NAT, but it seems that the NAT traffic is blocked by that ACL rule.

Update existing security group when creating new ec2 CloudFormation

I have ec2 instance which was created using such cfn template:
Parameters:
"VPCId": {
"Type": "AWS::EC2::VPC::Id"
"Description": "The VPC Id to where this instance is being created"
}
"Subnet": {
"Description": "Subnet to put Instance",
"Type": "AWS::EC2::Subnet::Id",
},
Have the following Security Group:
"InstanceSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Enables access to instance by port 80",
"VPCId": {
"Ref": "VPCId"
},
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": "80",
"ToPort": "80",
"CidrIp": {
"Ref": "ClientCIDR"
}
}
]
},
And part of Instance Resource:
"WebServer": {
"Type": "AWS::EC2::Instance",
"Properties": {
"IamInstanceProfile": "access-profile",
"SecurityGroupIds": [
{ "Fn::GetAtt": [
"InstanceSecurityGroup",
"GroupId"
]
}
],
"SubnetId": {
"Ref": "Subnet"
},
I want to create a few another instances using another template. This instances should have access to the above instance by port 22 and connect to it in UserData.
I'm not sure how it can be organized, the one way i see is update security group using aws cli through UserData before establishing ssh connection to the first instance. How it can be organized using resources? I didn't find any information or examples regarding this. Please help! Thanks!
You can modify the InstanceSecurityGroup to allow access from the other instances:
"InstanceSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Enables access to instance by port 80",
"VPCId": {
"Ref": "VPCId"
},
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": "80",
"ToPort": "80",
"CidrIp": {
"Ref": "ClientCIDR"
}
},
{
"IpProtocol": "tcp",
"FromPort": "22",
"ToPort": "22",
"SourceSecurityGroupId": {
"Ref": "OtherInstancesSecurityGroup"
}
}
]
},
where OtherInstancesSecurityGroup is a new Security Group you will assign the the other instances.

How to add multiple security groups and group names in cloudformation using template?

"dbxSG":
{
"Type": "AWS::EC2::SecurityGroup",
"Properties":
{
"GroupDescription": "Enable dbX Access",
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": "22",
"ToPort": "22",
"CidrIp": "0.0.0.0/0"
}
]
}
},
"dbxSGIngress" :
{
"Type": "AWS::EC2::SecurityGroupIngress",
"Properties":
{
"GroupName": { "Ref": "dbxSG" },
"IpProtocol": "tcp",
"FromPort": "0",
"ToPort": "65535",
"SourceSecurityGroupName": { "Ref": "dbxSG" }
}
},
How do I add multiple security group names in above json file? "dbxSG" name is referring in many times. I want to add one more security group with a new name. How do I add it?
Yes, you can attach multiple Security Groups to an EC2 Instance when created using CloudFormation. Below is sample json to accomplish it. I have attached WebSubnetSG & AppSubnetSG to the EC2 Instance.
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Multiple Security Groups - Demo",
"Resources" : {
"VPC": {
"Type": "AWS::EC2::VPC",
"Properties": {
"CidrBlock": "10.0.0.0/16" ,
"Tags": [
{
"Key": "Name",
"Value": "Multi Security Group"
}
]
}
},
"WebSubnet": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": {
"Ref": "VPC"
},
"CidrBlock": "10.0.10.0/24",
"Tags": [
{
"Key": "Application",
"Value": "Multi SG Subnet"
}]
}
},
"WebServerSG": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "SG for the Web Server",
"VpcId": {
"Ref": "VPC"
},
"SecurityGroupEgress": [
{
"IpProtocol": "-1",
"CidrIp": "0.0.0.0/0"
}
],
"SecurityGroupIngress" : [
{
"IpProtocol": "tcp",
"CidrIp": "0.0.0.0/0",
"FromPort": "80",
"ToPort": "80"
},
{
"IpProtocol": "tcp",
"CidrIp": "0.0.0.0/0",
"FromPort": "443",
"ToPort": "443"
}
]
}
},
"AppServerSGIngress": {
"Type": "AWS::EC2::SecurityGroupIngress",
"Properties": {
"GroupId": {
"Ref": "AppServerSG"
},
"IpProtocol": "tcp",
"CidrIp": "0.0.0.0/0",
"FromPort" : "9090",
"ToPort" : "9090"
}
},
"AppServerSG": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "SG for the App Server",
"VpcId": {
"Ref": "VPC"
},
"SecurityGroupEgress": [
{
"IpProtocol": "-1",
"CidrIp": "0.0.0.0/0"
}
],
"SecurityGroupIngress" : [
{
"IpProtocol": "tcp",
"CidrIp": "0.0.0.0/0",
"FromPort": "8080",
"ToPort": "8080"
}
]
}
},
"MultiSGInstance": {
"Type": "AWS::EC2::Instance",
"Properties": {
"ImageId": "ami-12345678",
"KeyName": "your-key-pair",
"SecurityGroupIds": [
{
"Ref": "WebServerSG"
},
{
"Ref": "AppServerSG"
}
],
"InstanceType": "t2.micro",
"SubnetId": {
"Ref": "WebSubnet"
},
"Tags": [
{
"Key": "Name",
"Value": "MultiSG"
}
]
}
}
},
"Outputs" : {}
}