0
votes

AWS CloudFormation template that includes a Lambda function with sensitive environment variables. I'd like to set up a KMS key and encrypt them with it

Add basic cloudformation to encrypt the key even is ok with aws/lambda default encryption

  LambdaFunction:
            Type: AWS::Lambda::Function
            DependsOn: LambdaRole
            Properties:
              Environment:
               Variables:
                 key: AKIAJ6W7WERITYHYUHJGHN
                 secret: PGDzQ8277Fg6+SbuTyqxfrtbskjnaslkchkY1
                 dest: !Ref dstBucket
              Code:
                ZipFile:  |
                   from __future__ import print_function
                   import os
                   import json
                   import boto3
                   import time
                   import string
                   import urllib
                   print('Loading function')
                   ACCESS_KEY_ID = os.environ['key']
                   ACCESS_SECRET_KEY = os.environ['secret']
                   #s3_bucket = boto3.resource('s3',aws_access_key_id=ACCESS_KEY_ID,aws_secret_access_key=ACCESS_SECRET_KEY)
                   s3 = boto3.client('s3',aws_access_key_id=ACCESS_KEY_ID,aws_secret_access_key=ACCESS_SECRET_KEY)
                   #s3 = boto3.client('s3')
                   def handler(event, context):
                      source_bucket = event['Records'][0]['s3']['bucket']['name']
                      key = event['Records'][0]['s3']['object']['key']
                      #key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key'])

                      #target_bucket     =  "${dstBucket}"
                      target_bucket = os.environ['dest']

                      copy_source = {'Bucket':source_bucket, 'Key':key}

                      try:
                        s3.copy_object(Bucket=target_bucket, Key=key, CopySource=copy_source)

                      except Exception as e:
                        print(e)
                        print('Error getting object {} from bucket {}. Make sure they exist '
                           'and your bucket is in the same region as this '
                           'function.'.format(key, source_bucket))
                        raise e

AWS CloudFormation template that includes a Lambda function with sensitive environment variables. I'd like to set up a KMS key and encrypt them with it

3
Are you using AWS Access and Secret keys? you should be looking at using lambda execution roles.Sudharsan Sivasankaran
I am copying the data from another AWS account hence I need to give ACCESS keyuser9075162
you should using Cross account roles which is more secured and is the best practiceSudharsan Sivasankaran

3 Answers

0
votes

You can use the AWS KMS service to create a KMS key manually (or) by using CFT (https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-kms-key.html)

The return value will have an ARN which can be used for KmsKeyArn property in Lambda CFT

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-kmskeyarn

Hope this helps !!

0
votes

You can store the access key and Secret key in AWS SSM Parameter Store by encrypting it with KMS Key. Go to AWS Systems Manager -> Parameter store -> Create Parameter. You can choose secure string option and choose the KMS key to encrypt with. You can access that Parameter through the boto3 function call. For example, response = client.get_parameter(Name='AccessKey', WithDecryption=True). you can use 'response' variable to refer to access key. Make sure that Lambda function has enough permissions to use that KMS Key to decrypt that Parameter you stored. Attach all necessary Decrypt permissions to the IAM Role the Lambda uses. In this way, you don't need to pass your access key and secret key as environment variables. Hope this will help!

0
votes

You can also use Secrets Manager AWS::SecretsManager::Secret CFN resource to store the secret values and Cloudformation. Use Cloudformation dynamic references to retrieve the secret's values from either SSM Paramenter store or Secrets Manager, in the template where you consume them.