AWS Cloudformation Master Template creation - amazon-web-services

I am trying to create a master template which calls other templates.My first template is VPC and subnet creation and second one is creating bastion host. Problem i am facing is i am not able to ref. the created VPC in my second template due to which its failing. My master template looks like below:-
Description: >
This template deploys the full agyle time stack as follows, which consists of:
A VPC with with public and private subnets spread across two Availabilty Zones.
It deploys an Internet Gateway and a pair of NAT Gateways, with the relevant routes in each of the subnets.
It then deploys the API ECS cluster distributed across multiple Availability Zones.
Finally, it deploys the API ECS services deployed as containers within the ECS repository
Parameters:
S3TemplateKeyPrefix:
Description: >
An S3 key prefix which will be used to resolve referenced templates
Type: String
Resources:
VPC:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: !Sub ${S3TemplateKeyPrefix}/infrastructure/vpc.yaml
Bastion:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: !Sub ${S3TemplateKeyPrefix}/infrastructure/bastion.yaml
Parameters:
EnvironmentName: !Ref AWS::StackName
VPC: !GetAtt VPC.Outputs.VPC
Can someone help me here do i have to modify VPC and Bastion host template to reference my VPC in bastion template.

Based on your master template, I believe it fails because CFN starts creating both of them in parallel, whereas Bastion needs to be created after your VPC resource. Just add the DependsOn: VPC for your Bastion resource to have it created only after your VPC has been created.
Bastion:
Type: AWS::CloudFormation::Stack
DependsOn: VPCStack
Properties:
Here's a working example from AWS saas-identity-cognito-master.template.

I was able to resolve the issue with modifying the child templates with Export and Import Function and calling it in master template. below is what I used:-
Outputs:
PubPrivateVPC:
Description: A reference to the created VPC
Value: !Ref PubPrivateVPC
Export:
Name: VPC-PROD
and import
Parameter:-
NetworkStackName:
Description: >-
Name of an active CloudFormation stack that contains the networking
resources, such as the subnet and security group, that will be used in
this stack.
Type: String
MinLength: 1
MaxLength: 255
AllowedPattern: '^[a-zA-Z][-a-zA-Z0-9]*$'
Default: VPC-PROD
and in resources called like below:-
VpcId: !ImportValue VPC-PROD
No i am able to call child templates in master successfully.

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.

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.

Use all subnet IDs in a given VPC with DBSubnetGroup in Cloudformation

I'm trying to figure out how I'd use the DBSubnetGroup resource in Cloudformation to grab every subnet under the configured VPC. Here's my code as of now:
DBSubnetGroup:
Type: 'AWS::RDS::DBSubnetGroup'
Properties:
DBSubnetGroupDescription: !Ref 'AWS::StackName'
SubnetIds:
- subnet-54b7e96a
- subnet-68eb3125
- subnet-744c4613
I'd like to avoid having to specify exactly which subnet IDs to use in my VPC.
Sadly, there is no such functionality in CloudFormation (CFN) to query a VPC and get ids of all its subnets.
If you require this, you would have to develop your own AWS::CloudFormation::CustomResource. The resource would be in the form of a lambda function which would take the VPC Id as an input argument, and then, using AWS SDK, query the VPC for its subnets. The subnets found would be returned to your template for use in AWS::RDS::DBSubnetGroup.

AWS CloudFormation errors when template gets AllocationID for AWS::EC2::EIP (Elastic IP)

I've created a stack with an EIP resource and I'm trying to get the allocation ID and the CloudFormation validator keeps yelling at me. I extracted the EIP into a very simple stack where it's the only resource and I still can't get a valid template. Am I going crazy or AWS messing with me?? Below is the simple stack template that fails validation, and if I use it as a nested stack it fails on creation.
AWSTemplateFormatVersion: 2010-09-09
Description: Create an EIP to be used by Alliance web proxy EC2 instance.
Resources:
EIPForProxy:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
Outputs:
EIPAllocationID:
Value: !GetAtt EIPForProxy.AllocationID
EIPPublicIP:
Value: !Ref EIPForProxy
Being a VPC elastic IP addresse, you can only export that as a value and use this template as a sub-stack to your parent stack. You cannot output it as a value using GetAtt function.
---
AWSTemplateFormatVersion: '2010-09-09'
Description: Create an EIP to be used by Alliance web proxy EC2 instance.
Resources:
EIPForProxy:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
Outputs:
EIPAllocationID:
Value: 'null'
Export:
Name: MyEIP::AllocationId
EIPPublicIP:
Value:
Ref: EIPForProxy

Is there a way to reference a security group from a previous Cloudformation stack in a new CF stack?

I'm trying to build a stack with multiple EC2 instances that have varied security groups.
It would be easy for me if I could create my security groups in advance and reference them in my EC2 stack.
Is there a way to reference an existing security group resource in a CF stack?
Thanks in advance for the help!
yes this is totally possible with standard Cloudformation templates.
You can solve this in a couple of ways.
If you are using nested stacks, you can create all the security groups you need in one sub-stack. That stack should have Outputs for each of the Security Group Ids you created.
Outputs:
SecurityGroup1Id:
Description: Security Group 1 ID
Value: !Ref SecurityGroup1
In the stack that then creates your EC2 instances, you can define Parameters for each of the security Groups. It can either be an array or one parameter for each Group, depending on your use case.
Single Template
If the EC2 instances and security groups are being defined in the same template, then you can use a simple Ref to access the ID of the already created security group. ie: !Ref SecurityGroup1Name
If you already have a security group deployed and you know the Id of it you can reference it like this under Properties.
You can reference multiple security groups, as it is a list
SecurityGroupIds:
- <the id of the security group>
- <another security group ID>
Yes, you can cross reference outputs from a stack in another.
Here is a walkthrough from the AWS official documentation.
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/walkthrough-crossstackref.html
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html
If the Security Groups were created outside of CloudFormation (Console/CLI) or the CloudFormation stacks aren't linked via nesting or exports, you should define them as Parameters, then reference that parameter name in your template:
Parameters:
MySecurityGroup:
Type: String
Description: ID of an existing VPC security group (sg-xxxxxx)
Resources:
MyInstance:
Type: AWS::EC2::Instance
Properties:
# All of your other properties
SecurityGroupIds:
- !Ref MySecurityGroup
If the security group ID is something you're going to reference often, put it in SSM Parameter Store and link the two by following the steps in this blog post: https://aws.amazon.com/blogs/mt/integrating-aws-cloudformation-with-aws-systems-manager-parameter-store/
Yes, you can create a security group in advance and refer them into the new stack.
In the below example we are creating a securty group through cloudformation template to allowing 3389/RDP Protocol for user(user name is User1) and exporting security group
name.
And in EC2 CloudFormation stack we are importing the exported value(sg name) of security group CloudFormation stack.
AWSTemplateFormatVersion: 2010-09-09
Description: CloudFormation template for Security Group definitions
Parameters:
User1:
Description: Public IP OF Deven .
Type: String
Default: 106.209.184.29/32
AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
ConstraintDescription: Must be valid IP Range.
Resources:
MySG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Common Jenkins SG.
VpcId: vpc-8587d522
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 3389
ToPort: 3389
CidrIp: !Ref User1
Description: User1 - RDP access .
- Key: Name
Value: test-security-group
SecurityGroupEgress: []
Outputs:
Ec2SecurityGroup:
Description: Security Group ID for EC2
Value: !Ref MySG
Export:
Name: !Sub "${AWS::StackName}-testapplication"
In Youe EC2 instance template import the value . below is the example for the same.
Type: 'AWS::EC2::Instance'
Properties:
.
.
(your other parameters mentioned in 'AWS::EC2::Instance' )
.
.
KeyName: !Ref Key
SubnetId: !Ref SubnetA
SecurityGroups:
Fn::ImportValue:
!Sub "${SGStackName}-RenderEngine" ##### SGStackName is Security group CloudFormation Stack name
.
.
(your other parameters mentioned in 'AWS::EC2::Instance' )
.
.
For more detail please gough with official link