问题
I am writing CF code to launch ec2 instance, this is what my code looks like:
I am facing these 2 issues:
1) I get this error "Template validation error: Template error: unresolved condition dependency BackupSize in Fn::If"
2) I want to join Parameter Name and from Mappings USERDATA. (The remaining userdata works fine, but this join is not working and just puts the same code in the userdata.
Can anyone help me out please?
AWSTemplateFormatVersion: "2010-09-09"
Description: "This template should be used to deploy ONLY test servers"
Mappings:
Regions:
us-east-1:
"AMI": "ami-x"
"VPC": "vpc-x"
"SUBNET": "subnet-x"
"USERDATA": ".example.com"
"SHARE": "server1:/share"
"SecurityGroups": "sg-x"
"SecurityGroups2": "sg-y"
Parameters:
ApplSize:
Description: "Please enter application vol. size"
Type: "String"
BackupSize:
Description: "Please enter backup vol. size"
Type: "String"
Resources:
EC2Instance:
Type: "AWS::EC2::Instance"
Properties:
ImageId: !FindInMap [Regions, !Ref "AWS::Region", AMI]
InstanceType: !Ref InstanceType
SubnetId: !FindInMap [Regions, !Ref "AWS::Region", SUBNET]
SecurityGroupIds:
- !FindInMap [Regions, !Ref "AWS::Region", SecurityGroups]
- !FindInMap [Regions, !Ref "AWS::Region", SecurityGroups2]
BlockDeviceMappings:
-
DeviceName : "/dev/sda1"
Ebs:
VolumeSize: "20"
VolumeType: gp2
-
DeviceName : "/dev/sde"
Ebs:
VolumeSize: !Ref ApplSize
VolumeType: gp2
-
DeviceName : "/dev/sdc"
Ebs:
VolumeSize: "5"
VolumeType: gp2
- Fn::If:
- BackupSize
-
DeviceName : "/dev/sdg"
Ebs:
VolumeSize: !Ref BackupSize
VolumeType: gp2
- !Ref "AWS::NoValue"
UserData:
Fn::Base64: !Sub |
#!/bin/bash
NEW_HOSTNAME=Fn::Join: [ " ", [ !Ref Name, Fn::FindInMap:
[Regions, !Ref "AWS::Region", USERDATA] ] ]
hostname $NEW_HOSTNAME
myshortname=`hostname -s`
I expect the template to create Backup volume if I put any value in the parameter, and if I leave backupsize value blank, it should not create this disk.
回答1:
AWSTemplateFormatVersion: "2010-09-09"
Description: "This template should be used to deploy ONLY test servers"
Mappings:
Regions:
us-east-1:
"AMI": "ami-x"
"VPC": "vpc-x"
"SUBNET": "subnet-x"
"USERDATA": ".example.com"
"SHARE": "server1:/share"
"SecurityGroups": "sg-x"
"SecurityGroups2": "sg-y"
Parameters:
ApplSize:
Description: "Please enter application vol. size"
Type: "String"
BackupSize:
Description: "Please enter backup vol. size"
Type: "String"
VaultSize:
Description: "Please enter secret vol. size"
Type: "String"
InstanceType:
Description: "Please select the instance type"
Type: "String"
Name:
Description: "Please mention server name"
Type: "String"
CustomerName:
Description: "Please mention customer name"
Type: "String"
Url:
Description: "Please mention url without the domain name"
Type: "String"
Conditions:
BackupVol: !Equals [!Ref BackupSize, ""]
Resources:
EC2Instance:
Type: "AWS::EC2::Instance"
Properties:
ImageId: !FindInMap [Regions, !Ref "AWS::Region", AMI]
InstanceType: !Ref InstanceType
SubnetId: !FindInMap [Regions, !Ref "AWS::Region", SUBNET]
SecurityGroupIds:
- !FindInMap [Regions, !Ref "AWS::Region", SecurityGroups]
- !FindInMap [Regions, !Ref "AWS::Region", SecurityGroups2]
BlockDeviceMappings:
-
DeviceName : "/dev/sda1"
Ebs:
VolumeSize: "20"
VolumeType: gp2
-
DeviceName : "/dev/sde"
Ebs:
VolumeSize: !Ref ApplSize
VolumeType: gp2
-
DeviceName : "/dev/sdc"
Ebs:
VolumeSize: "5"
VolumeType: gp2
- Fn::If:
- BackupVol
- !Ref "AWS::NoValue"
- DeviceName : "/dev/sdg"
Ebs:
VolumeSize: !Ref BackupSize
VolumeType: gp2
UserData:
Fn::Base64: !Sub
- |+
#!/bin/bash -xe
NEW_HOSTNAME=${test}
- test:
Fn::FindInMap: [Regions, !Ref "AWS::Region", Name]
回答2:
The various versions of the template presented all have basic formatting problems. The latest version (attached in a comment below this answer):
▶ aws cloudformation validate-template --template-body file://cloudformation.yml
An error occurred (ValidationError) when calling the ValidateTemplate operation: [/Mappings/Regions] 'null' values are not allowed in templates
The formatting problems include duplicate keys, incorrect indentation, etc. These problems can't be detected by simply checking if the file is valid YAML. It can be valid YAML and still be invalid for Cloudformation. You need to use the validate-template command as I showed above.
After fixing up the various issues in the provided template (including the new version), I was unable to reproduce an error about
unresolved condition dependency BackupSize in Fn::If
What you have in Fn::If looks ok to me.
As for how to interpolate Fn::Join in the UserData:
I would consider refactoring so that complex logic lies outside of Cloudformation. For instance, you could pass the hostname as a separate parameter.
If you really want to do it this way you can do it like this:
UserData:
Fn::Base64: !Sub
- |
#!/bin/bash
NEWHOSTNAME=${newhostname}
hostname $NEW_HOSTNAME
myshortname=`hostname -s`
- newhostname: !Join ["", ["foo", "bar"]]
来源:https://stackoverflow.com/questions/54528284/template-validation-error-template-error-unresolved-condition-dependency-backu