Template validation error: Template error: unresolved condition dependency BackupSize in Fn::If

亡梦爱人 提交于 2019-12-12 06:58:10

问题


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:

  1. I would consider refactoring so that complex logic lies outside of Cloudformation. For instance, you could pass the hostname as a separate parameter.

  2. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!