AWS Cloud formation - create EC2 instance with security group name - amazon-web-services

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

Related

Adding Elastic IP to ec2 instance using cloudformation

Is where anyway I could attach elastic ip from my cloudformation template?
{
"Description" : "Staging single instance",
"Outputs": {
"InstanceID": {
"Description": "The WWW instance id",
"Value": { "Ref": "StageInstance" }
}
},
"Parameters": {
"AMI": {
"Description": "The Amazon Ubuntu AMI",
"Type": "String",
"Default": "ami-009110a2bf8d7dd0a"
},
"EBSVolumeSize": {
"Description": "The size of the EBS volume for the transcoder",
"Type": "String",
"Default": "20"
},
"InstanceType": {
"AllowedValues": [
"t2.micro",
"t2.small",
"t2.medium",
"t2.large",
"c4.large",
"c4.xlarge",
"c4.2xlarge",
"c4.4xlarge",
"c4.8xlarge",
"t3.medium"
],
"ConstraintDescription": "must be a valid EC2 instance type",
"Default": "t2.micro",
"Description": "EC2 instance type",
"Type": "String"
},
"KeyName": {
"Description" : "Name of an existing EC2 KeyPair to enable SSH access to NAT instances.",
"Type": "AWS::EC2::KeyPair::KeyName",
"ConstraintDescription" : "Must be the name of an existing EC2 KeyPair." }
},
"Resources": {
"InstanceProfile" : {
"Type" : "AWS::IAM::InstanceProfile",
"Properties" : {
"Path" : "/",
"Roles" : ["Ec2CloudDeploy"]
}
},
"StageSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Allow SSH, HTTP, and HTTPS 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"
},
{
"IpProtocol": "tcp",
"FromPort": "443",
"ToPort": "443",
"CidrIp": "0.0.0.0/0"
}
]
}
},
"StageInstance": {
"Type" : "AWS::EC2::Instance",
"Properties": {
"SecurityGroupIds": [{"Ref": "StageSecurityGroup"}],
"KeyName": {"Ref": "KeyName" },
"ImageId": {"Ref": "AMI"},
"InstanceType": {"Ref": "InstanceType"},
"IamInstanceProfile" : {"Ref" : "InstanceProfile"},
"Tags": [
{"Key" : "Staging", "Value" : "Staging"}
]
}
}
}
}
Is there any configuration which I can add to attach the elastic ip to the instance which would be launched by this instance.I know I can attach it using cli command buT i would like to add it through my cloudformation template.
You would use AWS::EC2::EIPAssociation:
{
"Type" : "AWS::EC2::EIPAssociation",
"Properties" : {
"AllocationId" : String,
"EIP" : String,
"InstanceId" : String,
"NetworkInterfaceId" : String,
"PrivateIpAddress" : String
}
}
Sure. as documented in AWS::EC2::EIP:
Specifies an Elastic IP (EIP) address and can, optionally, associate it with an Amazon EC2 instance.
By setting InstanceId, you associate the EIP to your CloudFormation's EC2 instance.
For your case this snippet should do the trick:
"Resources": {
...,
"ElasticIP": {
"Type": "AWS::EC2::EIP",
"Properties": {
"InstanceId": {"Ref" : "StageInstance"}
}
}
}

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.

Parameters: [KeyPair] must have values

I am trying to mirror my EC2 instance using cloudformation. Currently, I've been able to create the following JSON using troposphere and I come across the error 'Parameters: [KeyPair] must have values'. I am not sure what this 'values' has to be?
I understand the error but not sure what's the solution.
{
"Outputs": {
"InstanceAccess": {
"Description": "",
"Value": {
"Fn::Join": [
"",
[
"ssh -i ",
{
"Ref": "KeyPair"
},
" ubuntu#",
{
"Fn::GetAtt": [
"MyInstance",
"PublicDnsName"
]
}
]
]
}
}
},
"Parameters": {
"KeyPair": {
"Description": "jj",
"Type": "AWS::EC2::KeyPair::launch"
}
},
"Resources": {
"MyInstance": {
"Properties": {
"ImageId": "< my image id goes here>",
"InstanceType": "t1.micro",
"KeyName": {
"Ref": "KeyPair"
},
"SecurityGroups": [
{
"Ref": "SecurityGroup"
}
]
},
"Type": "AWS::EC2::Instance"
},
"SecurityGroup": {
"Properties": {
"GroupDescription": "Allow access to MyInstance",
"SecurityGroupIngress": [
{
"CidrIp": "0.0.0.0/0",
"FromPort": "22",
"IpProtocol": "tcp",
"ToPort": "22"
},
{
"CidrIp": "0.0.0.0/0",
"FromPort": "80",
"IpProtocol": "tcp",
"ToPort": "80"
},
{
"CidrIp": "0.0.0.0/0",
"FromPort": "8080",
"IpProtocol": "tcp",
"ToPort": "8080"
},
{
"CidrIp": "0.0.0.0/0",
"FromPort": "443",
"IpProtocol": "tcp",
"ToPort": "443"
}
]
},
"Type": "AWS::EC2::SecurityGroup"
}
}
}
Your KeyPair parameter should have a valid type. According to the Parameters section of the CloudFormation User Guide, the type for a KeyPair parameter is AWS::EC2::KeyPair::KeyName. So it should look like this:
"KeyPair": {
"Description": "The name of the keypair to use for SSH access",
"Type": "AWS::EC2::KeyPair::KeyName"
}
Also, if you declare a key pair name as a parameter in your template, you'll have to pass an existing key pair name as an argument when you create a stack using that template.
To expand on the accepted answer, you can add a default value for the parameter. This would have also resolved the error you were seeing. If KeyPair has a static value, you may prefer a default over passing an argument. You can still override the default by passing an argument.
"KeyPair": {
"Description": "The name of the keypair to use for SSH access",
"Type": "AWS::EC2::KeyPair::KeyName",
"Default": "launch"
}

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.

AWS CloudFormation use existing security group

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