'AWS CloudFormation function call fails: Fn::ImportValue must not depend on any resources, imported values, or Fn::GetAZs
I have a cloud formation template (mainVPC) that creates few Subnets in a VPC and exports the subnets with names "PrivateSubnetA", "PrivateSubnetB" ... I have a different cloud formation template that creates DBSubnetGroup. I want to use "PrivateSubnetA", "PrivateSubnetB" as default values if user does not provide data. CloundFormation does not support imported values in parameters. So I put some default value (XXXX) and had a condition section to see if the user has provided some input
Conditions:
userNotProvidedSubnetA: !Equals
- !Ref PrivateSubnetA
- XXXX
userNotProvidedSubnetB: !Equals
- !Ref PrivateSubnetB
- XXXX
This helps me in figuring out if the user has provided data. Now I want to use default values, if the user has not provided values, else use user-provided values. below is code for that
DBSubnetGroup:
Type: 'AWS::RDS::DBSubnetGroup'
Properties:
DBSubnetGroupDescription: RDS Aurora Cluster Subnet Group
SubnetIds:
- !If
- userNotProvidedSubnetA
- Fn::ImportValue:
!Sub '${fmMainVpc}-PrivateSubnetA'
- !Ref PrivateSubnetA
- !If
- userNotProvidedSubnetB
- Fn::ImportValue:
!Sub '${fmMainVpc}-PrivateSubnetB'
- !Ref PrivateSubnetB
This fails with the error "Template error: the attribute in Fn::ImportValue must not depend on any resources, imported values, or Fn::GetAZs". ImportValue is not used anywhere else in the template.
Is there a way for using exported values as default values ( the default values cannot be hardcoded, they come as exported values from a run of another stack), while providing an option for the users to provide their own values (to create resources).
Thanks.
Solution 1:[1]
This can also be caused by having a reference inside Fn::ImportValue to a parameter be misnamed. For example, if I have the following parameter NetworkStackName defined and I mis-reference it in the Fn::ImportValue statement (as NetworkName), I will get this error. I would need to change the NetworkName to match the value in Parameters, NetworkStackName to fix the error.
Parameters:
NetworkStackName:
Type: String
Default: happy-network-topology
Resources:
MySQLDatabase:
Type: AWS::RDS::DBInstance
Properties:
Engine: MySQL
DBSubnetGroupName:
Fn::ImportValue:
!Sub "${NetworkName}-DBSubnetGroup"
Solution 2:[2]
I had a problem where I needed to get my artifact bucket name from my prerequisite stack, I tried this:
Fn::ImportValue:
- 'arn:aws:s3:::${ArtifactStore}/*'
turns out you can do this and it will work. Hope his helps someone out one day!
- !Sub
- 'arn:aws:s3:::${BucketName}/*'
- BucketName : !ImportValue 'ArtifactStore'
Solution 3:[3]
Currently, Cloudformation didn't support dynamic default value. It's not possible to have a dynamic default value for CloudFormation. As the template has not executed at the time all parameters are being collected. However, you can use SSM parameter for as the workaround, something like below.
Parameters
PagerDutyUrl:
Type: AWS::SSM::Parameter::Value<String>
Description: The Pagerduty url
Going back to your current cloudformation, I am thinking that value ${fmMainVpc} might not be initialized correctly.
Solution 4:[4]
I'm my case, I had the follow resource:
# removed for brevity
Subnets:
- !ImportValue: parent-stack-subnet-a
- !ImportValue: parent-stack-subnet-b
I forgot to remove the : when changing the syntax from Fn::ImportValue to the shorthand !ImportValue. Confusing error message, but removing the : resolved it because that was incorrect usage on my part.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | user1847 |
| Solution 2 | lczapski |
| Solution 3 | sayboras |
| Solution 4 | Jason M. |
