When uploading my template to CloudFormation I am receiving the following validation error:
Template validation error: Template error: the attribute in Fn::ImportValue must not depend on any resources, imported values, or Fn::GetAZs
I have a test template below that reproduces the issue:
Resources:
EC2Instance:
Type: "AWS::EC2::Instance"
Properties:
ImageId: ami-3bfab942
InstanceType: t2.micro
KeyName: mykeypair
UserData:
"Fn::Base64":
!Sub |
#!/bin/bash
yum update -y aws-cfn-bootstrap
/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource EC2Instance --configsets testset --region ${AWS::Region}
yum -y update
Metadata:
AWS::CloudFormation::Init:
configSets:
testset:
- "testConfiguration"
testConfiguration:
commands:
CreateTestFile:
cwd: "~"
command:
"Fn::ImportValue":
!Sub |
touch ${myexport}
To keep things as simple as I can I'm basically trying to create a bash command using the export. So in the above example I want to create a file named based on what the export value is. I don't understand the error message in the context of what I'm trying to do. I've validated that the export exists in another stack that I've created.
The problem is not Sub, but you are not using ImportValue correctly. The thing you are actually importing in your code is not myexport, but touch ${myexport} as a whole. You should put your ImportValue inside Sub.
Also, if the export value is literally called myexport, you don't put it inside ${}; you only do this if it is a parameter you defined in the template.
You could change that last few lines to this:
command: !Sub
- "touch ${filename}"
- filename: !ImportValue myexport
Just as a syntax alternative to the accepted answer, one might prefer to do:
command: !Sub ['touch ${filename}', filename: !ImportValue myexport]
I was looking to do the same thing but, with a different syntax as I had multi-line sub function content. Below, is the code-snippet that worked for me.
UserData:
Fn::Base64:
!Sub
- |
#!/bin/bash -xe
echo ${VpcId}
- VpcId: !ImportValue MyVPCId