如何使用!FindInMap in!Sub | userdata部分

时间:2016-11-09 11:52:32

标签: amazon-web-services amazon-cloudformation

目前我正在将CFT从JSON转换为Yaml。一切正常,直到Userdata部分。我很难在userdata部分使用任何函数,如!Ref或!FindInMap。

UserData:

Fn::Base64: !Sub |
        #!/bin/bash -v
        /command {Fn::FindInMap: [ "url", Ref: AWS::Region, Ref: EnvironmentType ] } 

如果有人可以分享任何代码片段,那将非常有用。

4 个答案:

答案 0 :(得分:8)

我也一直在玩这个游戏。虽然the documentation表示Fn::FindInMap支持Fn::Sub,但没有使用示例,我尝试过各种引号和冒号组合但没有成功,但是我似乎终于使用映射找到了功能性解决方案。以下应该有效:

Fn::Base64: !Sub
  - |+
    #!/bin/bash -v
    /command ${Url}
  - Url:
      Fn::FindInMap:
        - UrlMap
        - !Ref AWS::Region
        - !Ref EnvironmentType

arg0开头的管道告诉YAML保留换行符,加号告诉它后来保留换行符。 Arg1告诉它用Fn::FindInMap的结果替换arg0中的Url。

以下较短版本也应该有效:

Fn::Base64: !Sub
  - |+
    #!/bin/bash -v
    /command ${Url}
  - Url:
      Fn::FindInMap: [UrlMap, Ref: "AWS::Region", Ref: EnvironmentType]

但你应该测试一下。请注意逗号,引号和还原为Ref: s而不是!Ref s。这可能告诉我们一些文件是如何被预处理的,但我不确定那是什么。

我确信这个解决方案对于有经验的YAMLers来说是显而易见的,但是当我将所有这些YAMLy优点添加到CloudFormation时,我才刚刚开始理解JSON。

答案 1 :(得分:1)

我有类似的用例:用地图中的值替换相应的参数值。如果参数值与映射条目不匹配,则使用默认值。 这是我的工作示例,希望对您有所帮助。

AWSTemplateFormatVersion: '2010-09-09'

Parameters:
  Env:
    Type: String
    Description: The environment.

Mappings:
  envResourcesMap:
    dev:
      someHost: "hostVal_D"
    staging:
      someHost: "hostVal_S"
    prod:
      someHost: "hostVal_P"
    other:
      someHost: "hostValm_XXX"

Conditions:
  IsDevEnv: !Equals
    - !Ref Env
    - dev
  IsStagingEnv: !Equals
    - !Ref Env
    - staging
  IsProdEnv: !Equals
    - !Ref Env
    - prod
  IsStandardEnv:
    Fn::Or:
      - Condition: IsDevEnv
      - Condition: IsStagingEnv
      - Condition: IsProdEnv

Resources:
  storeSSM:
    Type: AWS::SSM::Parameter
    Properties:
      Description: !Sub "DESC for ${Env}"
      Name: !Sub "/Global/ssmpath/someHost"
      Type: String
      Value: !Sub
        - ${spiderman}
        - spiderman: !If [
            IsStandardEnv,
            !FindInMap [ "envResourcesMap", !Ref Env, "someHost" ],
            !FindInMap [ "envResourcesMap", "other", "someHost" ]]

答案 2 :(得分:0)

这对我来说很好

UserData :
  Fn::Base64 : !Sub
  - |
    #!/bin/bash -v
    export some_variable = ${url}
  - url : !FindInMap [Mapping, !Ref AWS::Region, !Ref EnvironmentType]

答案 3 :(得分:0)

  UserData :
    Fn::Base64 : !Sub
    - |
        #!/bin/bash
        echo "test ${SetTopologyScript}" >> /home/ec2-user/test.logs
    - SetTopologyScript : !FindInMap [ MappingName, !Ref "AWS::AccountId", SetTopologyScript ]

您可以参考完整的userdata代码段。这里的“映射”部分中的参数为SetTopologyScript,其中包含dev,qa和prod的三个say部分,由AWS AccountIDs表示