I have created below four resources successfully using the Cloud Formation Template (CFT):
VPC
Subnet
InternetGateway
AttachGateway
Now, I am trying to create a security group with EC2 instance, here is the code.
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow http and ssh to client host
VpcId:
Ref: InsuranceVPC
SecurityGroupIngress:
- 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: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Ec2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: "ami-08706cb5f68222d09"
KeyName:
Ref: "DevOpsAutomation"
NetworkInterfaces:
- AssociatePublicIpAddress: "true"
DeviceIndex: "0"
GroupSet:
- Ref: "InsuranceSecurityGroup"
SubnetId:
Ref: "InsuranceSubnet"
But, when I use the Key parameter in (CFT, as shown above, code) which is my key present in the same region of the resources, my CFT stack fails with below error:
Template format error: Unresolved resource dependencies [DevOpsAutomation] in the Resources block of the template
note: DevOpsAutomation is my keyname
Steps I validated:
CFT template resources and the key is in the same region
deleted and freshly created key pair
tried to use different key pair
I couldn't see an option anywhere to import the key along with the CFT stack so that my EC2 instance can use it.
Even while creating the stack the key DOESN'T appear (which is visible in keypair section) in the parameter section of the stack.
My query is, how should I create EC2 instance (as a part of CFT) using the key pair which is present in my AWS account?
Remove the Ref in front of the key name. Ref is used to reference other resources that have been defined as part of the CloudFormation template. If the key pair already exists, you can simply use the key name.
KeyName: "DevOpsAutomation"
I have copied here an example
AWSTemplateFormatVersion: '2010-09-09'
Description: >
AWS CloudFormation template to create Jenkins server
Parameters:
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Default: ritefit-keypair
Resources:
JenkinsEC2Instance:
Type: AWS::EC2::Instance
Properties:
KeyName: !Ref KeyName
Show us more what have defined KeyName so we can help you what the issue is
Related
We are trying to get traffic from the internet to hit our ALB, get decrypted and then sent through the Palo Alto Cloud NGFW and finally reach our containers. See image below:
For some reason we are not able to get this to work when we allow traffic from the security group of the ALB into the security group of the ECS containers. So this is not working:
ContainerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "Security group for containers"
SecurityGroupIngress:
- SourceSecurityGroupId: !Ref ALBSecurityGroup
Description: "From load balancer"
FromPort: 80
IpProtocol: tcp
ToPort: 80
VpcId: !ImportValue app-vpc
While this is working:
ContainerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "Security group for containers"
SecurityGroupIngress:
- CidrIp: "<IP_ADDRESSES_OF_ALB>"
Description: "From load balancer"
FromPort: 80
IpProtocol: tcp
ToPort: 80
VpcId: !ImportValue app-vpc
Not been able to find any clear documentation on this, does anyone know if this can be solved somehow, if I am missing something? It would rather not hardcode IP addresses in the security group as we are setting up this using CloudFormation.
I am working with cloudformation. I am creating a security group for RDS and trying to white list the EC2 private ip. But it is failed to create security group
TestSecuri:
Type: AWS::EC2::SecurityGroup
DependsOn: EC2Instance
Properties:
GroupDescription: allow connections from specified CIDR ranges
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 800
ToPort: 800
CidrIp: !GetAtt "EC2Instance.PrivateIp/32"
You can just do with Sub:
CidrIp: !Sub "{EC2Instance.PrivateIp}/32"
I am trying to set up EC2 Instance Connect for an EC2 instance:
AWSTemplateFormatVersion: 2010-09-09
Description: Part 1 - Spawn Ec2 instance with CloudFormation
Resources:
WebAppInstance:
Type: AWS::EC2::Instance
Properties:
AvailabilityZone: us-east-2a
ImageId: ami-074cce78125f09d61
InstanceType: t2.micro
Although the template above allows me to create an EC2 instance, it does not allow me to access it using EC2 Instance Connect.
How do I configure EC2 Instance Connect within the CloudFormation template?
Solution
AWSTemplateFormatVersion: 2010-09-09
Description: Part 1 - Build a webapp stack with CloudFormation
Resources:
WebAppInstance:
Type: AWS::EC2::Instance
Properties:
AvailabilityZone: us-east-2a
ImageId: ami-074cce78125f09d61
InstanceType: t2.micro
SecurityGroupIds:
- !Ref WebAppSecurityGroup
WebAppSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Join ["-", [webapp-security-group, dev]]
GroupDescription: "Allow HTTP/HTTPS and SSH inbound and outbound traffic"
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
WebAppEIP:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
InstanceId: !Ref WebAppInstance
Tags:
- Key: Name
Value: !Join ["-", [webapp-eip, dev]]
Outputs:
WebsiteURL:
Value: !Sub http://${WebAppEIP}
Description: WebApp URL
On Amazon Linux 2 (any version) and Ubuntu 16.04 or later EC2 Instance Connect is installed and working by default. So you don't have to do anything.
For other AMIs, you have to use user_data to install and setup
the connect yourself.
Ensure you have a public IP assigned.
As per docs:
To connect using the Amazon EC2 console (browser-based client), the instance must have a public IPv4 address.**
You can also
connect to the EC2 instance via other methods if you do not want to / cannot assign a public IPv4 address:
If the instance does not have a public IP address, you can connect to the instance over a private network using an SSH client or the EC2 Instance Connect CLI. For example, you can connect from within the same VPC or through a VPN connection, transit gateway, or AWS Direct Connect.
FYI: for other AMIs with Linux distributions other than Amazon Linux 2 or Ubuntu 16.04+, you will need extra configuration as Marcin's answer points out.
ami-074cce78125f09d61 in us-east-2 is coming up for me as Amazon Linux 2 AMI (HVM), SSD Volume Type which supports EC2 Instance Connect by default, so your AMI should be fine.
I'm trying to set up a tech stack through cloudformation. I've had to deploy it many times as it's difficult to piece together, and am currently stuck on one thing. I have the following resource defined which I constantly need to rename, as when I delete my stack then go to recreate it, I receive an error stating that the resource already exists by that name. This is especially confusing as I can't find the resource being listed anywhere in my AWS console ( I'm in the correct region ). Please see below, any advice would be appreciated.
Thanks,
Erik
DBSecurityGroupTwentyFour:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: DBSecurityGroupTwentyFour
GroupDescription: Security group for NGINX container
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 3306
ToPort: 3306
CidrIp: 0.0.0.0/0
In these case I usually add the stack name in the field to preserve the uniqueness.
Example:
DBSecurityGroupTwentyFour:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub ${AWS::StackName}DBSecurityGroupTwentyFour
GroupDescription: !Sub ${AWS::StackName} - Security group for NGINX container
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 3306
ToPort: 3306
CidrIp: 0.0.0.0/0
You can also just skip GroupName: DBSecurityGroupTwentyFour:
DBSecurityGroupTwentyFour:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group for NGINX container
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 3306
ToPort: 3306
CidrIp: 0.0.0.0/0
This way CFN will auto-generate a name for the SG, and you don't have to worry about naming it.
I'm passing as a parameter a "Subnet ID"
VPCPrivateSubnet1:
Description: VPCPrivateSubnet1
Type: String
Default: 'subnet-83733e21'
Then, I'm creating a "Security Group"
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !Ref VPCid
GroupDescription: Security Group
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 10
ToPort: 10
CidrIp: ???
And for the CidrIp I would like to have a way to refer to it without having to type it. Something like VPCPrivateSubnet1.CidrIp. I don't have the Subnet exported (so I can import it). I am not creating it in the template, so I cannot use Ref.
I will appreciate help.
Unfortunately this is not easily achievable. But even if you had your subnet defined in the same template as your security group, or exported from other stack, AWS::EC2::Subnet can't return its CIDR.
However, you could design Custom Resource in CloudFormation which would give you the CIDR of a subnet you want.
For this you would have to write your own custom lambda function, which would take the subnet's id and using, e.g., boto3 SDK, return the CIDR into CloudFormation.
Having this you could do !GetAtt CustomGetSubnetInfoResource.CidrIp, where CustomGetSubnetInfoResource could be the name of your custom resource.