AWS CloudFormation: How to handle manually-deleted resources - amazon-web-services

I am new in AWS so have couple of AWS VPC creation using CloudFormation service questions.
1. Scenario: I have created the yaml file and executed that in the stack. the VPC, route table and all the subnets get created successfully. now I have deleted one of the subnet manually (through console). Now I want that subnet back, so I was trying to run the "update" stack using the "current template" (though I have not made any modification in the template). it is showing me that there is no modification in the template error.
Question 1: How to install the deleted resource through template stack without modifying it.
2. Scenario: When we create VPC, we get default route table and NACL created.
Question 2: Why can't we use the default route table and NACL through cloudformation.
Question 3: is there any command from where we can get the default route table and NACL ID in cloudformation. (for eg : there is command where we can associate the subnets to routetable. something like that).
Thanks in advance.

It can be tricky indeed when stuff has changed outside of cloudformations state. Unlike some other IaC tools, it doesn't 'correct' the state of resources when they have deviated from the given state.
Remove the subnet resource from the template, update the stack with the removed resource, add the subnet back and again update the stack.
It's actually best practice to create new route tables and NACLs and associate them with the corresponding subnets, so there is actually no need to modify the default resources.
You can create a cloudformation custom resource to query for the id's and pass them to other resources. However this is not recommended due to answer 2. Ask yourself: what am I trying to achieve here? Is it really necessary?

Related

How to restrict creating AWS vpc if the CIDR in range 172.x.x.x/x using policies?

We've shared AWS accounts among multiple teams and even though we ask not to create identical VPCs, there is always a case.
So my question is, how can we achieve this via policies (or if there is another way), that we define the set of CIDRs in AWS account policy so that when somebody creates a VPC with a CIDR that belongs to one of those, it throws an error?
Thank you.
when somebody creates a VPC with a CIDR that belongs to one of those, it throws an error?
No there is no such IAM policies. You have to develop your own custom solution for that. For example, trigger a lambda function based on CloudTrial events for creating VPC, and have the lambda function verify the CIDRs.

How can I get InternetGatewayId of an existing AWS VPC

Background: We have an VPC, it has an Internet Gateway attached.
I would like to get the InternetGatewayId of the VPC via aws-cdk
vpc := awsec2.Vpc_FromLookup(stack, jsii.String(viper.GetString(`vpc.id`)), &awsec2.VpcLookupOptions{
VpcId: jsii.String(viper.GetString(`vpc.id`)),
}) //Here it returns awsec2.Ivpc
But according to the code, only awsec2.Vpc has a method InternetGatewayId(). How could I convert awsec2.Ivpc to awsec2.Vpc?
The Ivpc type returned from Vpc_FromLookup is a CDK convenience method to cache a limited set of VPC attributes at synth-time. Unfortunately, the Internet Gateway ID isn't one of them:
Currently you're unable to get the [Internet Gateway] ID for imported VPCs. To do that you'd have to specifically look up the Internet Gateway by name, which would require knowing the name beforehand.
A simple, deterministic workaround is to manually store the ID as a SSM Parameter Store Parameter. At synth-time, StringParameter_ValueFromLookup looks up and caches the IGW ID value as Context in cdk.context.json.:
igwID := awsssm.StringParameter_ValueFromLookup(stack, jsii.String("/my-params/vpc/igw-id"))
A more advanced CDK-only solution is to lookup the ID in a deploy-time CustomResource, which "can do arbitrary lookups or modifications during a CloudFormation deployment" (typically by making SDK calls using a Lambda). Note that this is not necessarily a better solution, because it introduces non-determinacy into the deployment.

Is there way to lie to CloudFormation about which VPC is default?

When instantiating resources (Security Groups, EC2 instances, etc) using a CloudFormation template, one does not always have to specify a VpcId explicitly. When one does not do so, the default VPC for a given account is selected automatically.
Is it possible to designate a different VPC as the default for the purposes of creating a stack, so that this other VPC is used in cases where a VpcId is not specified explicitly?
I am aware of this answer which suggests that one can pass a different VPC explicitly to all resources that require it, but this seems more verbose than necessary if there's a way to tell CloudFormation "Please treat VPC X as the default for all resources".
Sadly - There is no way to override the defaults in which AWS use through CloudFormation, and I would argue that being explicit when it comes to CloudFormation is a good thing.
However a way you this could be done is to delete the current default VPC and create a new VPC as the new default, with the configuration you want. Doing this requires slightly different creation steps to a standard VPC. Which you can find here : https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html#create-default-vpc
Unfortunately you cannot simply unset the current default and change it to a new existing VPC, it has to be made from scratch, as in the docs it states
"If you delete your default VPC, you can create a new one. You cannot restore a previous default VPC that you deleted, and you cannot mark an existing nondefault VPC as a default VPC." .

How to deploy all resources to another region using stack-sets in same aws account?

It seems that this question has already been asked in a different manner on this thread. But still, my confusion is not clear. I am struggling to copy all my resources from one region to another using stacksets.
I was successful in creating admin and target account trust relationship within the same owner account with the help from this thread.
I created a template of resources in the current region using cloudformer and saved it to the S3 bucket. But I am facing error when I am trying to deploy the resources using this template to another region with stacksets.
Error's like xxx availability zone doesn't exist or failed to create xxx resources or InvalidZone.NotFound etc.
Please someone brief about the correct way to deploy regional resources to another region. Should I use sample templates of stacksets or predefined template?
The key point to understand is that the template used to create the stack will be the same in each region. It sounds like you have a template that may reference something like an availability zone, so that template would work in the region where that availability zone exists, but fail in a region where that availability zone does not exist.
It sounds like you would benefit by using Conditions in your template, along with a map, so you can reference values that are region-specific, for example. Check out this documentation which includes examples that seem relevant based on your description:
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/conditions-section-structure.html
If the template works in any region, it will work via Stack Sets. Try creating a very simple template that only creates one simple thing and run that. You can get a feel for how it will work as it gets more complex.

How to get the count of total subnets in current VPC

Currently I'm writing a terraform script in which I wanted to set a subnet CIDR-BLOCK dynamically. I know the better approach is to use module instead of resources but this is the limitation at our end to only use resources.
CURRENT PROBLEM
I'had created only VPC in one configuration file. I have another configuration file in which I'm trying to provisioning VPC's configs (subnets,routing) etc.
Now I wanted to know the count of the existing subnets in the current VPC. For this I'm using the datasource to get the count. But while executing my plan I'm getting the following exception.
data.aws_subnet_ids.available-subnets: data.aws_subnet_ids.available-subnets:
no matching subnet found for vpc with id vpc-***************
This is how I'm getting the subnets
data "aws_subnet_ids" "available-subnets" {
vpc_id = "${data.aws_vpc.vpcobject.id}"
}
Do i need to add a depends-on attribute in it? if yes then what will be the condition or test for it? If this is not the case then what would be alternatives?
Thanks