运行 AWS CLI KMS 加密来自 Cloudformation 的命令

Run AWS CLI KMS encrypt commands from Cloudformation

我有 2 个 cloudformation 模板 - 一个创建 kms 密钥,另一个模板使用 kms 密钥加密 lambda 函数中使用的环境变量。

我想知道是否有办法先从 cloudformation 中 运行 kms encrypt 命令,然后在创建 lambda 函数时将加密文本用于环境变量。

aws kms encrypt --key-id <key-id-output-from-stack1> --plaintext fileb://file.txt --query CiphertextBlob --output text > fileoutput.txt

此命令输出加密文本,我需要在 lambda 函数中使用此文本作为以下环境变量之一。

GTMLambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: s3://test.google.com/lambdas/09yu567943879
      Handler: src/lambda.handler
      FunctionName: !Ref GTMLambdaFunctionName
      Runtime: nodejs10.x
      MemorySize: !Ref GTMLambdaMemorySize
      Timeout: !Ref GTMLambdaTimeout
      AutoPublishAlias: prod
      Role: !GetAtt GTMLambdaRole.Arn
      KmsKeyArn: !ImportValue GTMKMSKeyArn
      Environment:
        Variables:
          url: >-
            **{insert encrypted text}**
          tbl_prefix: gtm-

如果这不可能,是否有关于如何实现这一点的建议?提前致谢。

您可以为此使用自定义资源。它将执行一个 Lambda 函数,该函数将加密 return 值。然后可以在环境变量中使用该值。

类似下面的内容。确保有一个名为 KeyId 的 resource/parameter/output 和 KMS 密钥 ID。

Resources:
  EncryptEnvRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies:
        - PolicyName: DescribeImages
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Action: kms:Encrypt
                Effect: Allow
                Resource: "*"
  EncryptEnvFunction:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: python3.6
      Handler: index.handler
      Role: !Sub ${EncryptEnvRole.Arn}
      Timeout: 60
      Code:
        ZipFile:
          Fn::Sub: |
            import base64
            import boto3
            import cfnresponse
            import traceback

            def handler(event, context):
              try:
                t = event['ResourceProperties']['Value']
                k = event['ResourceProperties']['KeyId']
                v = base64.b64encode(boto3.client('kms').encrypt(KeyId=k, Plaintext=t.encode('utf-8'))['CiphertextBlob']).decode('utf-8')

                cfnresponse.send(event, context, cfnresponse.SUCCESS, {}, v)
              except:
                traceback.print_last()
                cfnresponse.send(event, context, cfnresponse.FAIL, {}, 'ok')
  EncryptedEnv:
    Type: Custom::EncryptEnv
    Properties:
      ServiceToken: !Sub ${EncryptEnvFunction.Arn}
      Value: "hello world"
      KeyId: !ImportValue KeyId
  GTMLambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: s3://test.google.com/lambdas/09yu567943879
      Handler: src/lambda.handler
      FunctionName: !Ref GTMLambdaFunctionName
      Runtime: nodejs10.x
      MemorySize: !Ref GTMLambdaMemorySize
      Timeout: !Ref GTMLambdaTimeout
      AutoPublishAlias: prod
      Role: !GetAtt GTMLambdaRole.Arn
      KmsKeyArn: !ImportValue GTMKMSKeyArn
      Environment:
        Variables:
          url: !Ref EncryptedEnv
          tbl_prefix: gtm-