【问题标题】:What is the purpose of creating "Mappings" in CloudFormation?在 CloudFormation 中创建“映射”的目的是什么?
【发布时间】:2021-12-01 18:32:05
【问题描述】:

请看下面的代码:

Mappings:
    RegionMap:
        us-east-1:
            bucketname: s3bucketname-us-east-1
        us-east-2:
            bucketname: s3bucketname-us-east-2
        us-west-1:
            bucketname: s3bucketname-us-west-1
        us-west-2:
            bucketname: s3bucketname-us-west-2
        ap-south-1:
            bucketname: s3bucketname-ap-south-1
        ap-northeast-2:
            bucketname: s3bucketname-ap-northeast-2
        ap-southeast-1:
            bucketname: s3bucketname-ap-southeast-1
        ap-southeast-2:
            bucketname: s3bucketname-ap-southeast-2
        ap-northeast-1:
            bucketname: s3bucketname-ap-northeast-1
        ca-central-1:
            bucketname: s3bucketname-ca-central-1
        eu-central-1:
            bucketname: s3bucketname-eu-central-1
        eu-west-1:
            bucketname: s3bucketname-eu-west-1
        eu-west-2:
            bucketname: s3bucketname-eu-west-2
        eu-west-3:
            bucketname: s3bucketname-eu-west-3
        eu-north-1:
            bucketname: s3bucketname-eu-north-1
        sa-east-1:
            bucketname: s3bucketname-east-1
        af-south-1:
            bucketname: s3bucketname-south-1
        ap-east-1:
            bucketname: s3bucketname-east-1
        ap-northeast-3:
            bucketname: s3bucketname-ap-northeast-3
        eu-south-1:
            bucketname: s3bucketname-eu-south-1
        me-south-1:
            bucketname: s3bucketname-me-south-1

Resources:
    StateS3Bucket:
        Type: AWS::S3::Bucket
        Properties:
            BucketName: !Sub "cfntf-${AWS::Region}-${AWS::AccountId}"

此代码还有更多内容,但我只包含了该问题的相关 sn-ps。

总结一下 - 为什么在“资源”部分中使用区域和账户 ID 直接设置存储桶名称时包含存储桶名称的映射?

这里使用了Fn::FindInMap 函数作为ExecutorLambdaFunction 的一部分:

ExecutorLambdaFunction:
        Type: AWS::Lambda::Function
        Properties:
            FunctionName: myfunction
            Handler: index.handler
            Role: !GetAtt ExecutorLambdaServiceRole.Arn
            Environment:
                Variables:
                    BUCKET: !Ref StateS3Bucket
            Code:
                S3Bucket: !If
                  - S3Defined
                  - !Ref S3Bucket
                  - Fn::FindInMap:
                      - RegionMap
                      - !Ref AWS::Region
                      - bucketname
                S3Key: !If
                  - S3Defined
                  - !Ref S3Key
                  - /app.zip
            Runtime: python3.8
          

【问题讨论】:

    标签: amazon-web-services amazon-s3 amazon-cloudformation


    【解决方案1】:

    StateS3Bucket 是根据区域和帐户 ID 构建的,但这与 Mappings 部分无关

    在这种情况下,映射用于为 ExecutorLambdaFunction 的打包源代码所在的位置提供正确的特定于区域的 S3 存储桶名称 - 这就是在 Lambda 声明中使用 Fn::FindInMap 的原因。


    有时您可能希望获得基于特定键的动态值 - CloudFormation Mappings 部分是解决此问题的完美解决方案。

    在这种情况下,您打包的 Lambda(源代码)指向一个 S3 位置,并且由于 S3 存储桶是特定于区域的,您需要一种方法来获取该区域的 正确 存储桶名称堆栈正在部署。

    ExecutorLambdaFunction 的代码必须从相关区域的 S3 存储桶中加载,否则将不起作用。

    例如,当您的 Lambda 部署在 eu-west-2 中时,尝试从 us-east-1 中的存储桶加载 Lambda 源代码将不起作用(注意:如果它部署在 us-east-2 中,它将起作用虽然它在另一个可用区,但它仍然在同一区域内)

    即使您只打算将堆栈放在一个区域中,拥有Mappings 部分也不会对您造成伤害,因为它会在未来证明您的 CloudFormation 模板。

    如果您没有任何特定于区域的基础架构(非常少见,但例如仅创建全局且在账户级别设置的 IAM 角色),那么您不能包含一个。

    与您在编写模板时仅花费额外 3 分钟定义和使用 Mappings 相比,您将花费更多时间尝试添加一个 - 如果您稍后决定部署您的堆栈,您会感谢自己在另一个地区。

    【讨论】:

    • 所以,还有其他区域,但为了清楚起见,我省略了它们。这是否意味着映射会覆盖直接设置的名称?
    • 啊,这极大地改变了叙述 - FindInMap 是否在您的模板中的任何地方使用?这不是覆盖 - 它更像是字典查找
    • 请在问题中添加它,我会重新格式化 - 也请阅读How to create a Minimal, Reproducible Example,因为它会为大家节省大量时间:) 一旦你更新了,我可以更新我的答案相对于你的代码 sn-p
    • 好的,谢谢,复制这段代码有点棘手,因为有很多依赖项,但是我现在以更简洁的方式添加了它。
    • 稍后我会看看并告诉你,谢谢! :)
    猜你喜欢
    • 1970-01-01
    • 2012-06-10
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    • 2013-05-11
    • 1970-01-01
    • 2013-12-18
    • 2010-12-07
    相关资源
    最近更新 更多