首页 > 解决方案 > 在 CloudFormation 中创建“映射”的目的是什么?

问题描述

请看下面的代码:

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}"

这段代码还有更多内容,但是我只包含了该问题的相关片段。

总而言之-为什么在“资源”部分中使用区域和帐户 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-servicesamazon-s3amazon-cloudformation

解决方案


StateS3Bucket正在从区域和帐户 ID 构建,但这与该部分无关。Mappings

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


有时您可能想要基于特定键的动态值 - CloudFormationMappings部分是解决此问题的完美解决方案。

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

ExecutorLambdaFunction 必须从相关区域的 S3 存储桶中加载代码,否则将无法正常工作。

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

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

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

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


推荐阅读