I have a question regarding Fn::ImportValue function in CloudFormation. For example, one SNS Topic from Stack 1 is imported in Stack 2. What happens, if I try to change name of this topic in Stack 1? Will it trigger redeployment of Stack 2? If not, will the changes be recognized anyhow by resources created by Stack 2? Thank you.
Kind regard
Oleksii
Your update probably will fail, as you can't modify exported values if they are imported by other stacks. From docs:
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.
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'm trying to delete a stack on Cloudformation but it return a rollback UPDATE_ROLLBACK_COMPLETE.
I have removed all dependencies from the template and all the outputs as well but the error persists.
Is there a way to force a delete? or even better just to delete the outpus?
I removed the outputs from the template and ran update-stack but without success. The error persist.
Have you created a circular reference issue? I’ve run into this in the past, even referencing an export from the current stack in that stack (easy to do when you make updates). The solution is to modify the stacks that are referencing The export, and removing the resource(s) that has the reference. Update the stack with the reference(s) removed and then you can do the delete. If you no longer have the start template you can modify it in the console by editing the existing stack, or you can copy the template from the console and edit it elsewhere. Any way you go about it, the key is updating the stack(s) with ImportValue references removed, then deleting the stack(s).
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 need to get the cloudformation stack, (which is already existing), Output variable value in my current cdk stack, how should I get that?
I tried using core.Fn.get_att?, but no much luck, can anyone help?
Assuming the the output has been exported by the other stack, in CDK there is Fn.importValue for importing the output:
The intrinsic function Fn::ImportValue returns the value of an output exported by another stack.