AWS Cloudformation: Fn::GetAtt into Fn::ImportValue - amazon-web-services

I have a stack to create an VPC.
This stack exports an output for VPC ID with name VPCID. Lools like this.
Outputs:
Output0:
Description: The ID of the VPC
Value: !Ref VPC0
Export:
Name: VPCID
I can import the output into my child stacks.
sghttps:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: 'HTTPS'
GroupName: https
SecurityGroupIngress:
- FromPort: 443
ToPort: 443
IpProtocol: tcp
CidrIp: '0.0.0.0/0'
Description: 'HTTPS from EVERYWHERE'
SecurityGroupEgress:
- FromPort: 0
ToPort: 0
IpProtocol: '-1'
CidrIp: '0.0.0.0/0'
VpcId: !ImportValue VPCID
Tags:
- Key: CF
Value: true
Now, I need access to the attribute CidrBlock of this VPC in my child stacks.
Somethigs like this.
sgmongodb:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: 'MONGODB'
GroupName: mongodb
SecurityGroupIngress:
- FromPort: 27017
ToPort: 27017
IpProtocol: tcp
CidrIp: !ImportValue VPCID.CidrBlock
Description: 'MongoDB from our VPC TCP'
or like this.
sgmongodb:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: 'MONGODB'
GroupName: mongodb
SecurityGroupIngress:
- FromPort: 27017
ToPort: 27017
IpProtocol: tcp
CidrIp: !ImportValue 'Fn::GetAtt':
- VPCID
- CidrBlock
Description: 'MongoDB from our VPC TCP'
I'm aware that is posible export the value of CidrBlock.
Outputs:
Output0:
Description: The ID of the VPC
Value: !Ref VPC0
Export:
Name: VPCID
Output1:
Description: CidrBlock
Value: !GetAtt VPC0.CidrBlock
Export:
Name: VPCIDCidrBlock
But, Is posible pass only the main VPS (VPCID in my case) resource and get the attribute CidrBlock in the child stack?
I do not find the rigth syntax. Any idea?

But, Is posible pass only the main VPS (VPCID in my case) resource and get the attribute CidrBlock in the child stack?
No its not, without a Custom Resource in your child module. Such a resource would be in the form of a lambda function which would take the VPCID as an input paramter, used AWS SDK to query the VPC for its CIDR range, and return it to your child stack for further use.
If you don't want to create a custom resource, you have to export your CIDR range as well, and any other info that you require.

Related

Getting cloud formation error Value of property InstanceId must be of type String while attaching eip with ec2

AWSTemplateFormatVersion: '2010-09-09'
Resources:
DevEC2Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: ami-0e322da50e0e90e21
KeyName: "cnf-key-1"
SecurityGroups:
- default
- Ref: SSHSecurityGroup
SSHSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: my new SSH SG
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: '8080'
ToPort: '8080'
CidrIp: 0.0.0.0/0
MyElasticIP:
Type: AWS::EC2::EIP
Properties:
InstanceId:
- Ref: 'DevEC2Instance'
Due to - you are creating a list. Instead it should be:
MyElasticIP:
Type: AWS::EC2::EIP
Properties:
InstanceId: !Ref DevEC2Instance

Cannot access web server inside ec2

I am learning AWS and is trying to setup a web server on ec2, but I can't access the web server from outside even after I tried everything I can think of.
Here is the cloudformation template I am using:
AWSTemplateFormatVersion: "2010-09-09"
Resources:
## VPC
# Create a VPC
HelloVpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: "true"
EnableDnsSupport: "true"
Tags:
- Key: Name
Value: HelloVpc
# Create internet gateway for public subnet
HelloInternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: HelloInternetGateway
HelloVPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId:
Ref: HelloVpc
InternetGatewayId:
Ref: HelloInternetGateway
# Create route table for public subnet
HelloPublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
Tags:
- Key: Name
Value: HelloPublicRouteTable
VpcId:
Ref: HelloVpc
HelloInternetGatewayRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId:
Ref: HelloPublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId:
Ref: HelloInternetGateway
# create subnets
HelloVpcPrivateSubNet:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: HelloVpc
AvailabilityZone: { "Fn::Select": [0, { "Fn::GetAZs": "" }] }
CidrBlock: 10.0.2.0/24
Tags:
- Key: Name
Value: HelloVpcPrivateSubNet
HelloVpcPublicSubNet:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: HelloVpc
AvailabilityZone: { "Fn::Select": [1, { "Fn::GetAZs": "" }] }
CidrBlock: 10.0.1.0/24
Tags:
- Key: Name
Value: HelloVpcPublicSubNet
HelloPublicSubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId:
Ref: HelloPublicRouteTable
SubnetId:
Ref: HelloVpcPublicSubNet
## Security group
HelloSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow http and ssh
VpcId:
Ref: HelloVpc
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 5000
ToPort: 5000
CidrIp: 0.0.0.0/0
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 5000
ToPort: 5000
CidrIp: 0.0.0.0/0
## EC2
HelloEc2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-0c91eefc31e3b0867
InstanceType: t3.nano
KeyName: EC2-KP
NetworkInterfaces:
- AssociatePublicIpAddress: "true"
DeviceIndex: "0"
SubnetId:
Ref: HelloVpcPublicSubNet
GroupSet:
- Ref: HelloSecurityGroup
Then I SSH into the instance and started a web server with
mkdir app
cd app
dotnet new web
dotnet run
which starts a web server on port 5000 and curl http://localhost:5000 works fine.
Since I can ssh into the instance, the ACL and security group should be correct. I googled around and tried to disable the firewall with
sudo iptables -P INPUT ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -F
but it still doesn't work.
At this point, I really have no idea what goes wrong. Can anyone please help?
The problem is that dotnet run causes your app to listen on localhost, so it's only reachable locally within the server itself.
You need it to bind to the public IP of the server, which you can do as follows:
dotnet run --urls http://0.0.0.0:5000
For additional options to set the URL, see here.

CloudFormation template fails with error "Service: AmazonEC2; Status Code: 400; Error Code: Unsupported"

I have created CloudFormaton Template with below resources
---
Resources:
InsuranceVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 11.0.0.0/16
EnableDnsSupport: 'false'
EnableDnsHostnames: 'false'
InstanceTenancy: dedicated
Tags:
- Key: work
Value: insurance
- Key: name
Value: InsuranceVPC
InsuranceInternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: work
Value: insurance
- Key: name
Value: InsuranceInternetGateway
InsuranceSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: InsuranceVPC
CidrBlock: 11.0.2.0/24
AvailabilityZone: "ap-south-1a"
Tags:
- Key: work
Value: insurance
- Key: name
Value: InsuranceSubnet
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId:
Ref: InsuranceVPC
InternetGatewayId:
Ref: InsuranceInternetGateway
Ec2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: "ami-0732b62d310b80e97"
InstanceType: "t2.medium"
KeyName: "DevOpsAutomation"
NetworkInterfaces:
- AssociatePublicIpAddress: "true"
DeviceIndex: "0"
GroupSet:
- Ref: "InsuranceSecurityGroup"
SubnetId:
Ref: "InsuranceSubnet"
InsuranceSecurityGroup:
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
All resources creations are successful except EC2Instance which fails with below error:
The requested configuration is currently not supported. Please check the documentation for supported configurations. (Service: AmazonEC2; Status Code: 400; Error Code: Unsupported; Request ID: a59a2d39-3aa9-4f7b-9cbd-db05dca0d61e)
The following resource(s) failed to create: [Ec2Instance]. . Rollback requested by use
What I have checked:
The ImageID and InstanceType exist in the same region (or AZ)
All other objects and its dependencies are met
though I understand I haven't yet created route table, route entries but that shouldn't affect EC2 instance resource creation
I am privileged user to create resources.
Please help or guide what I am missing here
I launched your template on my sandbox account.
I've identified some issues.
missing DependsOn on the instance,
VPC has dedicated tenancy,
and incorrect GroupSet.
I modified the template so it fully works now in us-east-1. You have to adjust it to your own region (AMI also needs to be changed back to your original one if not using us-east-1).
---
Resources:
InsuranceVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 11.0.0.0/16
EnableDnsSupport: 'false'
EnableDnsHostnames: 'false'
InstanceTenancy: default
Tags:
- Key: work
Value: insurance
- Key: name
Value: InsuranceVPC
InsuranceInternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: work
Value: insurance
- Key: name
Value: InsuranceInternetGateway
InsuranceSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: InsuranceVPC
CidrBlock: 11.0.2.0/24
AvailabilityZone: "us-east-1a"
Tags:
- Key: work
Value: insurance
- Key: name
Value: InsuranceSubnet
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId:
Ref: InsuranceVPC
InternetGatewayId:
Ref: InsuranceInternetGateway
Ec2Instance:
Type: AWS::EC2::Instance
DependsOn: AttachGateway
Properties:
ImageId: "ami-08f3d892de259504d"
InstanceType: "t2.medium"
KeyName: "MyKeyPair"
NetworkInterfaces:
- AssociatePublicIpAddress: "true"
DeviceIndex: "0"
GroupSet:
- !GetAtt InsuranceSecurityGroup.GroupId
SubnetId:
Ref: "InsuranceSubnet"
InsuranceSecurityGroup:
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
Your VPC is set to dedicated tenancy, which has limits over the resources you can use launch in it (including certain instances types.
Some AWS services or their features won't work with a VPC with the instance tenancy set to dedicated. Check the service's documentation to confirm if there are any limitations.
Some instance types cannot be launched into a VPC with the instance tenancy set to dedicated. For more information about supported instances types, see Amazon EC2 Dedicated Instances.
You should check the above link above, to compare against your instance type.

Getting 'Property IpProtocol cannot be empty' error while creating security group using cloud formation

I am creating a basic security group using cloud formation on AWS but I am getting Property IpProtocol cannot be empty. error. Following is the yml code I am running:
Resources:
testsecuritygroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: test-group
GroupDescription: test security group
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
- SourceSecurityGroupId: sg-xxxxxxxxxx
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0
Tags:
- Key: group
Value: test
VpcId: !ImportValue VPC
When I run create-stack command it is running successfully but the stack is rolled back with CREATE_FAILED status and Property IpProtocol cannot be empty error. What I am doing wrong here?
I resolved this issue. To add a security group we have to create an Ingress rule and attach it to the security group instead of defining it in the security group.
Resources:
test:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !ImportValue VPC
GroupName: test-group
GroupDescription: test security group
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Tags:
- Key: group
Value: test
TestInboundRule:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt test.GroupId
IpProtocol: tcp
FromPort: 80
ToPort: 80
SourceSecurityGroupId: sg-xxxxxxxxx
Your cidr is not valid. It should be 0.0.0.0/0

How do I add a cloudformation security group ingress rule that refers to another security group?

I have the following security group in a yaml template. I'd like to have the "SecurityGroupApplication" security group allow incoming connections from the "SecurityGroupBastion". However, the validate-template function of the aws client is telling me unhelpful information like "unsupported structure". Ok, but what is wrong with the structure? Ideas?
Resources:
SecurityGroupBastion:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Bastion security group
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
IpProtocol: tcp
FromPort: 22
ToPort: 22
VpcId: !Ref vpcId
SecurityGroupApplication:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Application security group
SecurityGroupIngress:
- SourceSecurityGroupId: !Ref SecurityGroupBastion
IpProtocol: tcp
Your template works perfectly find for me, except that I had to specify the ports for the App security Group:
Resources:
SecurityGroupBastion:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Bastion security group
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
IpProtocol: tcp
FromPort: 22
ToPort: 22
VpcId: vpc-abcd1234
SecurityGroupApplication:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Application security group
SecurityGroupIngress:
- SourceSecurityGroupId: !Ref SecurityGroupBastion
IpProtocol: tcp
FromPort: 22
ToPort: 22
If you want SecurityGroupApplication to be a Security Group, then you should use Type: AWS::EC2::SecurityGroup instead of Type: AWS::EC2::SecurityGroupIngress. That is probably the cause of the "unsupported structure" error you are seeing.
Just if someone falls into this old question, now, there is a way to reference cross account SG in cloudformation, so if you want to add an SG ingress rule pointing to another AWS account just add the key SourceSecurityGroupOwnerId and the account ID.
i.e.
AWSTemplateFormatVersion: 2010-09-09
Resources:
TargetSG:
Type: 'AWS::EC2::SecurityGroup'
Properties:
VpcId: vpc-1a2b3c4d
GroupDescription: Security group allowing ingress for security scanners
InboundRule:
Type: 'AWS::EC2::SecurityGroupIngress'
Properties:
GroupId: !GetAtt TargetSG.GroupId
IpProtocol: tcp
FromPort: 80
ToPort: 80
SourceSecurityGroupId: sg-12345678 # SG in the other AWS account
SourceSecurityGroupOwnerId: '123456789012' # Account ID