-
Notifications
You must be signed in to change notification settings - Fork 171
Description
Description
When using a CF module, if you use an intrincic function expression to assign the value of module parameter, and the template source of the module uses the parameter name in a condition, CF cannot preprocess the stack and exits with error
CloudFormation failed to preprocess the stack:
Template format error:
Unresolved dependencies [resSampleModule1resSourceQueue]. Cannot reference resources in the Conditions block of the template
Steps to reproduce
1. Create a module called Fujitsu::CF::SampleModule1::MODULE using the template module1.yml as fragment:
module1.yml
===========
AWSTemplateFormatVersion: 2010-09-09
Description: "Template to generate an example module with name Fujitsu::CF::SampleModule1::MODULE"
Parameters:
parMaxReceiveCount:
Description: Number of times a message is received by a consumer of the source queue before being moved to the dead-letter queue
Type: Number
Default: 3
Resources:
resDeadLetterQueue:
Type: AWS::SQS::Queue
resSourceQueue:
Type: AWS::SQS::Queue
Properties:
RedrivePolicy:
deadLetterTargetArn:
Fn::GetAtt:
- "resDeadLetterQueue"
- "Arn"
maxReceiveCount: !Ref parMaxReceiveCount
Commands:
mkdir module1
cd module1
cfn init -t Fujitsu::CF::SampleModule1::MODULE -a MODULE --region eu-west-1
Replace fragmets/sample.json with module1.yml
cfn validate
cfn submit --region eu-west-1 --set-default
2. Create a module called Fujitsu::CF::SampleModule2::MODULE using the template module2.yml as fragment:
module2.yml
===========
AWSTemplateFormatVersion: 2010-09-09
Description: "Template to generate a samplemodule with name Fujitsu::CF::SampleModule2::MODULE"
Parameters:
parBucketName:
Description: S3 bucket name. If not specified, the S3 service assigns a name
Type: String
parVersioningConfiguration:
Description: If versioning is enabled (Enabled) or disabled (Suspended)
Type: String
AllowedValues: ["Enabled","Suspended"]
Conditions:
cndIsBucketNameSpecified: !Not
- !Equals
- ""
- !Ref parBucketName
Resources:
resS3Bucket:
Type: 'AWS::S3::Bucket'
Properties:
BucketName: !If
- cndIsBucketNameSpecified
- !Sub ${parBucketName}-${AWS::Region}-${AWS::AccountId}
- !Ref AWS::NoValue
VersioningConfiguration:
Status: !Ref parVersioningConfiguration
Outputs:
outBucketName:
Description: S3 bucket name
Value: !Ref resS3Bucket
Commands:
mkdir module2
cd module2
cfn init -t Fujitsu::CF::SampleModule2::MODULE -a MODULE --region eu-west-1
Replace fragmets/sample.json with module2.yml
cfn validate
cfn submit --region eu-west-1 --set-default
3. Create a stack (called test in the image), from this template:
AWSTemplateFormatVersion: 2010-09-09
Description: "Sample parent template that uses Fujitsu::CF::SampleModule1::MODULE and Fujitsu::CF::SampleModule2::MODULE"
Parameters:
parMaxReceiveCount:
Description: Number of times a message is received by a consumer of the source queue before being moved to the dead-letter queue
Type: Number
Default: 3
Resources:
resSampleModule1:
Type: Fujitsu::CF::SampleModule1::MODULE
Properties:
parMaxReceiveCount: !Ref parMaxReceiveCount
resSampleModule2:
Type: Fujitsu::CF::SampleModule2::MODULE
Properties:
parBucketName: !GetAtt [resSampleModule1, resSourceQueue.QueueName]
parVersioningConfiguration: "Suspended"
I will refer to this as the 'parent template'.
Expected behavior
The stack is created without errors.
Actual behavior
CF reports an error:
CloudFormation failed to preprocess the stack:
Template format error:
Unresolved dependencies [resSampleModule1resSourceQueue]. Cannot reference resources in the Conditions block of the template
The problem is the parent template uses an intrinsic function expression to assign value to a module parameter (parBucketName: !GetAtt [resSampleModule1, resSourceQueue.QueueName]), and the template fragment of the module uses the name of the assigned parameter (parBucketName) in a condition (cndIsBucketNameSpecified).
I think this is a bug because parBucketName in template fragment must be a name internal to the module.