My application currently intakes cloudformation jsons/yamls and create stacks out of them. Currently, the struggles we are having are concerning the updating, since it's impossible to update a stack that contains custom-named resources.
My question is the following: is there a clean/smart way to remove custom names from those templates, and either service-aware or service-agnostic?
I've considered some regex/replacement but I wanted to see if there were a smarter way.
TIA
Related
I'm importing an ARN from another stack with the cdk.Fn.importValue method. This works fine if I know that the output value is always present, but I don't know how to handle the case when the value I try to import is optional.
How can I get something similar to: (checking if the value exists before importing it)
if(value exists) {
cdk.Fn.importValue("value")
}
AFAIK there currently is no way in CDK to perform a lookup of a CloudFormation exports during synthesis time.
If you don't want to fiddle around with performing CloudFormation API calls with the aws-sdk before creating the CDK stack, in my opinion the most elegant way to share conditional values between stacks, is to use SSM parameters instead of CloudFormation exports.
SSM parameters can be looked up during synthesis time. See docs: https://docs.aws.amazon.com/cdk/v2/guide/get_ssm_value.html
So, with StringParameter.valueFromLookup you are then able to only use the value if it exists (IIRC the method throws an error if the parameter doesn't exist, so try-catch is your friend here, but not 100% sure).
To help people create a Cloudformation stack, I can generate links to parameterized Cloudformation templates:
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-console-create-stacks-quick-create-links.html
Question: Is there a way to generate another link to update the previously created Cloudformation stack?
What I tried and what doesn't work:
I generated a link to create stack "ABC" using template Template1.
I generated a link to create stack "ABC", with a slightly modified template Template2.
What happens is that Cloudformation creates the first "ABC" stack based on Template1, but then complains that the "ABC" stack already exists when trying to create a stack with the same name using Template2.
I kind of expected this behavior, but I assumed that -- since stack names are unique -- that it would offer to apply updates instead of trying to create (and fail) to create the stack.
I have a Lambda which is having many versions and alias created for each version. Here is san example
Apple_Version_1
Apple_Version_1.1
Apple_Version_1.2
Apple_Version_1.2.1
Apple_Version_1.2.2
Apple_Version_1.3
Apple_Version_1.3.1
Now, i have a partial text, say "Apple_Version_1.2.", so with this, find out all the Versions that are starting with that text and be able to delete using cloud formation.
So in this case, need to get below
Apple_Version_1.2.1
Apple_Version_1.2.2
Thanks in advance
amazon-web-services
amaz
The short answer is: you can't do this in plain CloudFormation (CFN), as CFN is not a programming language and has very limited capabilities.
The long answer: you could design your own custom resource to use in your CFN template. The resource would be in the form of lambda function which would process and return the aliases to your stack for further use.
In CloudFormation we have the ability to output some values from a template so that they can be retrieved by other processes, stacks, etc. This is typically the name of something, maybe a URL or something generated during stack creation (deployment), etc.
We also have the ability to 'export' from a template. What is the difference between returning a value as an 'output' vs as an 'export'?
Regular output values can't be references from other stacks. They can be useful when you chain or nest your stacks and their scope/visibility is local. Exported outputs are visible globally within account and region, and can be used by any future stack you are going to deploy.
Chaining
When you chain your stacks, you deploy one stack, take it outputs, and use as input parameters to the second stack you are going to deploy.
For example, let's say you have two templates called instance.yaml and eip.yaml. The instance.yaml outputs its instance-id (no export), while eip.yaml takes instance id as an input parameter.
To deploy them both, you have to chain them:
Deploy instance.yaml and wait for its completion.
Note it outputs values (i.e. instance-id) - usually done programmatically, not manually.
Deploy eip.yaml and pass instance-id as its input parameter.
Nesting
When you nest stacks you will have a parent template and a child template. Child stack will be created from inside of the parent stack. In this case the child stack will produce some outputs (not exports) for the parent stack to use.
For example, lets use again instance.yaml and eip.yaml. But this time eip.yaml will be parent and instance.yaml will be child. Also eip.yaml does not take any input parameters, but instance.yaml outputs its instance-id (not export)
In this case, to deploy them you do the following:
Upload parrent template (eip.yaml) to s3
In eip.yaml create the child instance stack using AWS::CloudFormation::Stack and the s3 url from step 1.
This way eip.yaml will be able to access the instance-id from the outputs of the nested stack using GetAtt.
Cross-referencing
When you cross-reference stacks, you have one stack that exports it outputs so that they can be used by any other stack in the same region and account.
For example, lets use again instance.yaml and eip.yaml. instance.yaml is going to export its output (instance-id). To use the instance-id eip.yaml will have to use ImportValue in its template without the need for any input parameters or nested stacks.
In this case, to deploy them you do the following:
Deploy instance.yaml and wait till it completes.
Deploy eip.yaml which will import the instance-id.
Altough cross-referencing seems very useful, it has one major issue, which is that its very difficult to update or delete cross-referenced stacks:
After another stack imports an output value, you can't delete the stack that is exporting the output value or modify the exported output value. All of the imports must be removed before you can delete the exporting stack or modify the output value.
This is very problematic if you are starting your design and your templates can change often.
When to use which?
Use cross-references (exported values) when you have some global resources that are going to be shared among many stacks in a given region and account. Also they should not change often as they are difficult to modify. Common examples are: a global bucket for centralized logging location, a VPC.
Use nested stack (not exported outputs) when you have some common components that you often deploy, but each time they can be a bit different. Examples are: ALB, a bastion host instance, vpc interface endpoint.
Finally, chained stacks (not exported outputs) are useful for designing loosely-coupled templates, where you can mix and match templates based on new requirements.
Short answer from here, use export between stacks, and use output with nested stacks.
Export
To share information between stacks, export a stack's output values.
Other stacks that are in the same AWS account and region can import
the exported values.
Output
With nested stacks, you deploy and manage all resources from a single
stack. You can use outputs from one stack in the nested stack group as
inputs to another stack in the group. This differs from exporting
values.
I am trying to create a nested topology from 4 existing templates. These templates do the following:
1: deploys a policy and a role.
2: deploys an EC2 instance.
3: deploys an ELB.
4: deploys an RDS instance.
All of them are "linked" by using outputs. All of the parameters are also contained within these.
Now I want to create a fifth template (master) and treat the other 4 templates as child.
However I am not too sure about the minimum code that I need in the master template:
Parameters: these are defined within the child so I don't need them here, do I?
Resources: point to the 4 child templates by providing the S3 URL where they're stored.
DependsOn clause: I need this as the child templates need to be deployed in sequential order.
Outputs: not too sure what to include here, shall I leave the outputs on the child and define here only the master's?
The master I think it should be small but not too sure if I am missing something. Another question, do I need to change anything on the child templates?
Any help would be much appreciated.
A handful of questions here, so I'll address what I can :)
For the master, or parent template, I'd recommend including all Parameters that the child stacks will need.
When you want to make any updates in the future to any of the child stacks, you'll want to initiate that from the parent stack.
According to the docs:
Certain stack operations, such as stack updates, should be initiated
from the root stack rather than performed directly on nested stacks
themselves.
So your parent template could have a lot of parameters depending on how many parameters need to be passed directly to the child templates.
Depending on how the child stacks use the Outputs from the other child stacks, you may not need to use the DependsOn to enforce ordering, since Cloudformation is smart enough to figure out Implicit Dependencies (see docs discussing DependsOn). It certainly won't hurt to include these, but the DependsOn attribute isn't needed for most situations.
You'll want to make sure the child stacks have an Outputs section so that other child stacks can use them. Pay close attention to the Return values for AWS::CloudFormation::Stack
If you have many dependent stacks, it is much easier to run everything for example from Ansible. Add outputs in each CF template, then just write simple playbook that will run your templates in desired order. Please take a look at https://docs.ansible.com/ansible/devel/modules/cloudformation_module.html