首页 > 解决方案 > 如何在 CloudFormation 中创建可变计数资源?

问题描述

我需要创建变量计数 S3 存储桶,名称来自参数。例如,我有带有 S3 存储桶名称的数组。def bucketNames = ["first-bucket", "second-bucket", ..., "n-bucket"]. 有可能做到吗?也许有嵌套堆栈。

标签: amazon-web-servicesamazon-cloudformationaws-cloudformation-custom-resource

解决方案


您可以使用自定义资源执行此操作:

此模板将创建自定义资源:

    AWSTemplateFormatVersion: '2010-09-09'
    Description: create buckets from parameters
    Parameters:
      BucketList:
        Description: comma delimited list of bucket names
        Type: CommaDelimitedList
        Default: athos,porthos,aramis
    Resources:
      BucketCreatorLambda:
        Type: AWS::Lambda::Function
        Properties:
          Handler: index.handler
          Code: ./bucketor/
          Runtime: python3.8
          Role: !GetAtt 'LambdaExecutionRole.Arn'
      CustomBucketCreator:
        Type: AWS::CloudFormation::CustomResource
        Properties:
          loglevel: info
          Buckets: !Ref 'BucketList'
          RoleArn: !GetAtt 'LambdaExecutionRole.Arn'
          ServiceToken: !GetAtt 'BucketCreatorLambda.Arn'
      LambdaExecutionRole:
        Type: AWS::IAM::Role
        Properties:
          AssumeRolePolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Principal:
                  Service:
                    - lambda.amazonaws.com
                Action:
                  - sts:AssumeRole
          ManagedPolicyArns:
            - !Sub 'arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
          Path: /
          Policies:
            - PolicyName: BucketPolicy
              PolicyDocument:
                Version: '2012-10-17'
                Statement:
                  - Effect: Allow
                    Action:
                      - s3:CreateBucket
                    Resource: arn:aws:s3:::*
    Outputs:
      BucketsCreated:
        Description: names of buckets created
        Value: !GetAtt 'CustomBucketCreator.BucketNames'

和 lambda 的 python 脚本:

    # python file named index.py located ./bucketor/ with respect to cloudformation file
    from crhelper import CfnResource
    import logging
    import boto3
    
    logger = logging.getLogger(__name__)
    # Initialise the helper, all inputs are optional, this example shows the defaults
    helper = CfnResource(json_logging=True, log_level='DEBUG',
                         boto_level='CRITICAL', sleep_on_delete=120)
    
    s3 = boto3.client("s3")
    
    try:
        # Init code goes here
        pass
    except Exception as e:
        logger.error(e, exc_info=True)
        helper.init_failure(e)
    
    
    @helper.create
    def create(event, context):
        bucket_names = []
        buckets = event["ResourceProperties"]["Buckets"]
        for bucket in buckets:
            bucket_names.append(s3.create_bucket(Bucket=bucket)["Bucket"])
        helper.Data.update({"BucketNames": ",".join(bucket_names)})
    
    
    def handler(event, context):
        global logger
        helper(event, context)

@helper.create将为您创建存储桶。您还需要编写适当的@helper.delete装饰@helper.update器,如果您不这样做,自定义资源将需要手动删除


推荐阅读