CloudFormation - Route Table route Propagation for Tansit Gateway - amazon-web-services

I am creating the following resources using CloudFormation:
VPC
Two Public Subnet
Two private Subnet
Route Tables for the Subnet's
I have created a site-to-site VPN with my on-prem office manually.
I have created the transit gateway manually and attached my VPN to it.
Now since I will be creating the VPC with CloudFormation, I thought to avoid manual work lets associate VPC to Transit Gateway and propagate the route in the Route Tables in the CloudFormation Script itself.
Please refer the following snippet for the same:
VPCTransitGateayAttachment:
Type: AWS::EC2::TransitGatewayAttachment
Properties:
SubnetIds:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
TransitGatewayId: 'tgw-1234567890'
VpcId: !Ref VPC
#TransitGateWay Routes
TransitGateWayPublicRouteTableRoutes:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: '0.0.0.0/16'
TransitGatewayId: 'tgw-1234567890'
TransitGateWayPrivateRouteTable1Routes:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable1
DestinationCidrBlock: '0.0.0.0/16'
TransitGatewayId: 'tgw-1234567890'
TransitGateWayPrivateRouteTable2Routes:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable2
DestinationCidrBlock: '0.0.0.0/16'
TransitGatewayId: 'tgw-1234567890'
But I am facing the following error when I execute the script.
The transitGateway ID 'tgw-1234567890' does not exist. (Service: AmazonEC2; Status Code: 400; Error Code: InvalidTransitGatewayID.NotFound; Request ID: 30d31120-f9e2-4870-a378-55bc9a36f5bb)
For the AWS::EC2::Route resource.
I am not able to understand what is the issue. The document states the option for Transit Gateway for AWS::EC2::Route.
What else I am missing here ?

I was facing the same issue in cloudformation, the problem was the routes must wait for the AWS::EC2::TransitGatewayAttachment, I ran the cloudformation template with all of my routes that needed the TransitGatewayId paramter commented, then uncommented the routes, and it worked.
There is documentation that this is required for internet gateways attachments, but my test shows, this is also required for TransitGatewayAttachments.
What we should do is add a DependsOn and that should solve the problem.

Related

Do I need to create a seperate network stack for this cloudformation yaml file to work?

so I am tring to create Fargate instances into subnets using cloudformation.
I would like the user to be able to choose which vpc id, subnet ids to launch their Fargate instances into which I use as a parameter like this:
Parameters:
VPCSubnets:
Type: List<AWS::EC2::Subnet::Id>
Description: Provide the subnets you wish to deploy into.
VPCInformation:
Type: AWS::EC2::VPC::Id
Description: Provide the VPC ID that resources will be deployed into.
this information is used for the network settings for ECS and task definitions.
If I create network resouces just below parameters like this:
for example:
MyVpc:
Type: AWS::EC2::VPC
Description: VPC for the cluster and fargate instances
Properties:
CidrBlock: 10.0.0.0/26
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: interviewchallenge-vpc
Value: !Join ['', [!Ref "AWS::Region", "conversion-challenge-VPC" ]]
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: myVPC
CidrBlock: 10.0.0.0/28
AvailabilityZone: "us-east-1a"
Tags:
- Key: interviewchallenge-vpc-subnet1
Value: !Join ['', [!Ref "AWS::Region", "conversion-challenge-az1" ]]
At this point in the template, these network resouces havent been created right?
Can this be done in a single stack??
Can this be done in a single stack??
No. You need two templates and the corresponding stacks. The first template creates VPC, subnets and the remaining network resources. Then in the second stack, you use them in for ECS deployment.
Only this way your user will be able to choose the VPC and subnets when creating the ECS stack.

Lookup IGW after specifying VPC parameter in CloudFormation template

In the below snippet, can I do a lookup for the IGW using a function (or something) based on the VpcId parameter instead of needing it as a parameter?
Parameters:
VpcId:
Type: AWS::EC2::VPC::Id
Description: Enter the Existing Landing Zone VPC ID.
InternetGateway:
Type: String
Description: Enter the Existing Landing Zone IGW.
Resources:
DefaultRoute:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
RouteTableId: !Ref RouteTable
Thanks.
I have not tried anything because I can't find anything that makes me thinks this would work, just not sure if I am missing something.
No, that is not possible in CloudFormation.
The only way you can dynamically look up resources in such a way is if you leverage a CloudFormation macro to invoke a lambda function which executes custom code. For example, in Python, you could use the boto3 describe_internet_gateways API which returns a list of internet gateways (you could use a filter for the VPC ID).
More on CloudFormation macros:
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-macros.html
Macro example: https://stackoverflow.com/a/70475459/3390419

How to reference existing resources in CloudFormation yaml template?

I want to only create the EC2 instance for automation purposes but to point to existing VPC, Subnet, Security groups and Internet Gateway.
Does anyone know what would it look like in the template file?
My current template looks like this. It fails when creating the stack and the instance is deleted automatically.
The error I received is CREATE_FAILED with the description "No default VPC for this user. GroupName is only supported for EC2-Classic and default VPC."
AWSTemplateFormatVersion: 2010-09-09
Parameters:
VPCId:
Type: AWS::EC2::VPC::Id
Resources:
MySubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPCId
EC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-04ff9e9b51c1f62ca
InstanceType: c5.xlarge
KeyName: CloudFormation
SecurityGroupIds:
- mySecurityGroup
Edited with template
SecurityGroupIds should be ID, not name. The security group IDs have format of sg-xxxxxxxxx, and that's what you have to use.

DependsOn best practices in AWS Cloud Formation (example included)

What are the best practices for using Depends On in CloudFormation? I believe from what I read, it's not recommended to do so in Azure and to minimise it's use.
I want to put a DependsOn relationship between, for example, an ASG Policy, and an ASG Group.
In the above picture, you can see that ASG Policy has a field AutoScalingGroupName.
Therefore, ASG Policy depends on AutoScaling Group creation.
Would a depends On relationship exist between these two?
In general, any resource in a CloudFormation template that refers to another resource will automatically have an implied DependsOn.
For example:
PrivateRouteTable1:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub ${EnvironmentName} Private Routes (AZ1)
DefaultPrivateRoute1:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable1
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NatGateway1
DefaultPrivateRoute1 will have an implied DependsOn with PrivateRouteTable1 and NatGateway1.
So, the only time you particularly need to add a DependsOn is when there is no direct relationship, but there is an order of creation required. Here's an example of that:
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Ref EnvironmentName
NatGateway1EIP:
Type: AWS::EC2::EIP
DependsOn: InternetGatewayAttachment
Properties:
Domain: vpc
In this case, a DependsOn was defined between the Elastic IP Address and the InternetGateway. This is helpful because there is no direct relationship between an Elastic IP address and an Internet Gateway (which is linked to a VPC).
I have seen situations where an Amazon EC2 instance had failures in its User Data script because other resources were not 'ready', so the script was unable to access the Internet. It can be difficult to diagnose such situations because they can be transient. Therefore, you might want to specifically add some DependsOn references where there is no directly reference between required resources.

AccessControl property - s3 bucket

We have set following options amidst creation of bucket:
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
to get below restriction for any user trying to change this option:
We have also added below option:
AccessControl: Private
where possible values are: Private, PublicRead, PublicReadWrite, AuthenticatedRead, LogDeliveryWrite, BucketOwnerRead, BucketOwnerFullControl, or AwsExecRead
This is a single zone VPC:
1) What is the meaning of Private vs PublicRead?
2) EC2 is created within VPC(by default). Is bucket created outside VPC? in public domain... Where is bucket created?
Private means that only owner has access to that resource, whether it is bucket or object, PublicRead means that resource owner still has full control but allUsersGroup, which means everyone, whether it is IAM user or not has read access to the resource. Both Private and PublicRead specify predefined set of grants or so called canned ACLs.
S3 bucket is not created in your VPC, it lives in AWS plane which is not part of your VPC. So by default, when you make S3 API call from within your VPC, the traffic goes through the Internet. If you need this traffic between resources in your VPC and S3 to go through private network then you need to place VPC Gateway Endpoint for S3 into your VPC and route the S3 traffic through it.
Here is a minimal template containing new VPC, one subnet, S3 VPC endpoint and route table for that subnet with route to S3 endpoint for S3 traffic.
AWSTemplateFormatVersion: 2010-09-09
Resources:
MyVPC:
Type: 'AWS::EC2::VPC'
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
MySubnet:
Type: 'AWS::EC2::Subnet'
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.0.0/24
MyRouteTable:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId: !Ref MyVPC
SubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref MyRouteTable
SubnetId: !Ref MySubnet
S3Endpoint:
Type: 'AWS::EC2::VPCEndpoint'
Properties:
VpcId: !Ref MyVPC
RouteTableIds:
- !Ref MyRouteTable
ServiceName: !Sub com.amazonaws.${AWS::Region}.s3