如何在子堆栈模板中为多个参数使用主堆栈模板的重复组件?

时间:2018-02-14 23:10:39

标签: amazon-web-services nested stack amazon-cloudformation

我创建了一个嵌套堆栈,并且本质上希望将相同的基本堆栈资源格式应用于多个案例,但是,我不确定如何将其转换为cloudformation模板脚本。

例如,在下面的(非嵌套)堆栈模板中,我有几个Lambda函数参数,它们对lambda函数资源和lambda函数执行角色资源都使用相同的基本格式:

---
AWSTemplateFormatVersion: "2010-09-09"
Description: "Master template for wgs-pipeline. Calls to other stack templates."
Parameters:
  CloudspanLambdaFuncS3BucketName:
    Type: String
  CloudspanLambdaFuncS3KeyName:
    Default: 'sfn.deployable.zip'
    Type: String
  CloudspanLambdaFuncModuleName:
    Default: 'cloudspan'
    Type: String
  AlignmentLambdaFuncS3BucketName:
    Type: String
  AlignmentLambdaFuncS3KeyName:
    Type: String
  AlignmentLambdaFuncModuleName:
    Type: String
Resources:
  CloudspanLambdaExecutionRole:
  Type: "AWS::IAM::Role"
  Properties:
    AssumeRolePolicyDocument:
      Version: "2012-10-17"
      Statement:
        - Effect: Allow
          Principal:
            Service: lambda.amazonaws.com
          Action: "sts:AssumeRole"
    Policies:
      - PolicyName: CanListBuckets
        PolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Action:
                - "s3:GetBucketLocation"
                - "s3:ListAllMyBuckets"
              Resource: "arn:aws:s3:::*"
      - PolicyName: CanLog
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Action:
            - logs:*
            Resource: arn:aws:logs:*:*:*

CloudspanLambdaFunction:
  Type: "AWS::Lambda::Function"
  Properties:
    Handler:
      Fn::Join: [ ".", [ Ref: CloudspanLambdaFuncModuleName, "handler"] ]
    Role:
      Fn::GetAtt: [ CloudspanLambdaExecutionRole, Arn ]
    Code:
      S3Bucket:
        Ref: CloudspanLambdaFuncS3BucketName
      S3Key:
        Ref: CloudspanLambdaFuncS3KeyName
    Runtime: "python3.6"
    Timeout: "60"

AlignmentLambdaExecutionRole:
  Type: "AWS::IAM::Role"
  Properties:
    AssumeRolePolicyDocument:
      Version: "2012-10-17"
      Statement:
        - Effect: Allow
          Principal:
            Service: lambda.amazonaws.com
          Action: "sts:AssumeRole"
    Policies:
      - PolicyName: CanListBuckets
        PolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Action:
                - "s3:GetBucketLocation"
                - "s3:ListAllMyBuckets"
              Resource: "arn:aws:s3:::*"
      - PolicyName: CanCallBatch
        PolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Action:
                - "batch:*"
              Resource: "*"
      - PolicyName: CanLog
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Action:
            - logs:*
            Resource: arn:aws:logs:*:*:*

AlignmentLambdaFunction:
  Type: "AWS::Lambda::Function"
  Properties:
    Handler:
      Fn::Join: [ ".", [ Ref: AlignmentLambdaFuncModuleName, "handler"] ]
    Role:
      Fn::GetAtt: [ AlignmentLambdaExecutionRole, Arn ]
    Code:
      S3Bucket:
        Ref: AlignmentLambdaFuncS3BucketName
      S3Key:
        Ref: AlignmentLambdaFuncS3KeyName
    Runtime: "python3.6"
    Timeout: "60"

您可以看到存在一些差异,例如:在lambda函数资源之间的PolicyNames中,以及它们引用的参数。

我的问题是,如果我将上述主模板分开以使Lambda函数资源在子模板中,我如何在所有这些参数(CloudspanLambda,AlignmentLambda等)中应用相同的基本资源格式?

以下是我到目前为止如何设置子模板的示例。

---
AWSTemplateFormatVersion: '2010-09-09'
Description: lambda function and execution role stack.
Parameters:
  {x}LambdaFuncS3BucketName:
    Type: String
  {x}LambdaFuncS3KeyName:
    Type: String
  {x}LambdaFuncModuleName:
    Type: String
Resources:
  LambdaFunction:
    Type: "AWS::Lambda::Function"
    Properties:
      Handler:
        Fn::Join: [ ".", [ Ref: {x}LambdaFuncModuleName, "handler"] ]
      Role:
        Fn::GetAtt: [ {x}LambdaExecutionRole, Arn ]
      Code:
        S3Bucket:
          Ref: {x}LambdaFuncS3BucketName
        S3Key:
          Ref: {x}LambdaFuncS3KeyName
      Runtime: "python3.6"
  LambdaExecutionRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: "sts:AssumeRole"
      Policies:
        - PolicyName: CanListBuckets
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - "s3:GetBucketLocation"
                  - "s3:ListAllMyBuckets"
                Resource: "arn:aws:s3:::*"
        - PolicyName: CanLog
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
            - Effect: Allow
              Action:
              - logs:*
              Resource: arn:aws:logs:*:*:*

我现在把{x}放在那里,基本上代表所有这些参数的可迭代。我还需要改变PolicyNames的使用,具体取决于引用哪个Lambda函数。什么是正确的方法?

1 个答案:

答案 0 :(得分:1)

以下是给您一个想法的示例模板。

<强> Master.yaml:

Resources:
  Cloudspan:
    Type: "AWS::CloudFormation::Stack"
    Properties:
      Parameters:
        LambdaName: Cloudspan
        BucketName: <BucketName>
        S3KeyName: <S3KeyName>
        FunctionName: <FunctionName>
      TemplateURL: <TemplateURL>
  Alignment:
    Type: "AWS::CloudFormation::Stack"
    Properties:
      Parameters:
        LambdaName: Alignment
        BucketName: <BucketName>
        S3KeyName: <S3KeyName>
        FunctionName: <FunctionName>
      TemplateURL: <TemplateURL>

<强>λ-child.yaml:

Parameters:
  LambdaName:
    Type: String
  BucketName:
    Type: String
  S3KeyName:
    Type: String
  FunctionName:
    Type: String

Resources:
  LambdaFunction:
    Type: "AWS::Lambda::Function"
    Properties:
      Handler: !Sub '${LambdaName}-{FunctionName}.Handler'
      Role:
        Fn::GetAtt: [!Sub '${LambdaName}LambdaExecutionRole', Arn ]
      Code:
        S3Bucket: !Sub '${LambdaName}{BucketName}'
        S3Key: !Sub '${LambdaName}{S3KeyName}'
      Runtime: "python3.6"