如何使用 cloudformation 为 S3 存储桶设置半随机名称

Posted

技术标签:

【中文标题】如何使用 cloudformation 为 S3 存储桶设置半随机名称【英文标题】:How to set semi-random name for S3 bucket using cloud formation 【发布时间】:2019-07-20 16:50:49 【问题描述】:

我想创建一个云形成模板,该模板创建一个具有人类可读名称的 S3 存储桶,但它可以自动运行多次。 下面是一个具有预定义名称的存储桶。

除了随机的唯一 id 之外,我可以怎样做才能使名称包含人类可读的部分?比如:MyBucket-abcdabcdMyBucket-efghefghMyBucket-ijklijkl

"S3Bucket" : 
  "Type" : "AWS::S3::Bucket",
  "Properties" : 
    "BucketName": "MyBucket",
    "PublicAccessBlockConfiguration" : 
      "BlockPublicAcls" : true,
      "BlockPublicPolicy" : true
    
  

【问题讨论】:

CloudFormation 支持适用于您的用例的 Lambda 驱动的宏。 aws.amazon.com/blogs/aws/cloudformation-macros 我猜如果没有内置任何东西,这可能就是答案。 我不想把这个作为答案,但也许像 jinja2 这样的模板引擎在使用 YAML 模板时可以让你的生活更轻松! 【参考方案1】:

谢谢Sleeper Smith。这是一个很好的答案,我一直在寻找解决方案!


tl;dr

yaml CloudFormation 下面返回 "bucket-with-semi-random-name-51af3dc0"

BucketWithSemiRandomName:
  Type: "AWS::S3::Bucket"
  Properties:
    BucketName: !Join
      - "-"
      - - "bucket-with-semi-random-name"
        - !Select
          - 0
          - !Split
            - "-"
            - !Select
              - 2
              - !Split
                - "/"
                - !Ref "AWS::StackId"

代码示例provided Sleeper Smith 中有轻微的索引错误。您将需要替换选择索引,如下所示。

使用与原始答案相同的示例 Stack ARN...

arn:aws:cloudformation:us-west-2:123456789012:stack/teststack/51af3dc0-da77-11e4-872e-1234567db123
!Select [2, !Split [/, !Ref AWS::StackId ]]

以上代码示例从堆栈 ARN“51af3dc0-da77-11e4-872e-1234567db123”返回 UUID(索引 2)

!Select [0, !Split[-, !Select [2, !Split [/, !Ref AWS::StackId ]]]]

以上代码示例从堆栈 ARN“51af3dc0”返回 UUID 的第一段(索引 0)


这是我现在使用的基于Sleeper Smith's 答案的结果 yaml。我结合了一个 !Join 来为存储桶名称提供更多上下文。

BucketWithSemiRandomName:
  Type: "AWS::S3::Bucket"
  Properties:
    BucketName: !Join
      - "-"
      - - "bucket-with-semi-random-name"
        - !Select
          - 0
          - !Split
            - "-"
            - !Select
              - 2
              - !Split
                - "/"
                - !Ref "AWS::StackId"

以上代码示例返回“bucket-with-semi-random-name-51af3dc0”

【讨论】:

Rofl,2 个最难的计算机问题中的第 3 个,因 1 个错误而关闭。感谢您提供更全面和正确的答案。 正是我需要的。【参考方案2】:

你有两个选择。

第一个选项 - 您可以将 BucketName 属性留空。当您将其留空时,它将产生一个名称: --

因此,如果您有有意义的堆栈名称和模板逻辑名称,它应该每次都为您提供一个唯一的存储桶名称。

第二个选项 - 使用 Stack ARN 后缀,它是一个随机 guid: arn:aws:cloudformation:us-west-2:123456789012:stack/teststack/51af3dc0-da77-11e4-872e-1234567db123

!Select [2, !Split [/, !Ref AWS::StackId ]]

这将产生'51af3dc0-da77-11e4-872e-1234567db123' 如果需要,您可以再次拆分并选择一部分。

!Select [0, !Split[-, !Select [2, !Split [/, !Ref AWS::StackId ]]]]

给你51af3dc0

【讨论】:

【参考方案3】:

另一种方式可能是:

Resources:
    MyBucket:
      Type: "AWS::S3::Bucket"
Outputs:
  S3Bucket2:
    Description: "My Bucket" 
    Value: !Ref 'MyBucket'

【讨论】:

此方法将创建完全随机的 s3 存储桶名称而非半随机【参考方案4】:

感谢Phillip Mattheson 和Sleeper Smith 的出色回答!我想提供一种替代方法(恕我直言,更容易阅读)来产生相同的结果。我更喜欢尽可能使用!Sub 而不是!Join(有关更多信息,请参阅this great blog post):

  BucketWithSemiRandomName:
    Type: AWS::S3::Bucket
    Properties:
      BucketName:
        !Sub
          - 'bucket-with-semi-random-name-$RandomGUID'
          -  RandomGUID: !Select [0, !Split ["-", !Select [2, !Split ["/", !Ref AWS::StackId ]]]] 

【讨论】:

以上是关于如何使用 cloudformation 为 S3 存储桶设置半随机名称的主要内容,如果未能解决你的问题,请参考以下文章

CloudFormation 中如何派生 S3 存储桶名称?

CloudFormation 模板设置 S3 存储桶默认加密 [重复]

使用 cloudformation yaml 在 Lambda 函数上添加 S3 触发器

如何检查 CloudFormation 脚本中是不是已存在特定资源

使用 CloudFormation 在 S3 存储桶中创建 Lambda 通知

CloudFront 不能使用 S3 网站来源,只能使用 REST 来源 Cloudformation