3
votes

Given a CloudFormation template that defines:

  • A KMS Key
  • A KMS Key Alias
  • An S3 bucket

If for some reason I need to delete the CloudFormation stack and re-deploy, the deletion retains the KMS Key and Alias that was created. (This is sensible, I don't want to lose my key everything was encrypted with).

But this means when I re-deploy the stack it fails because an Alias with that name already exists.

I can delete the Alias through the CLI and re-deploy which will create an Alias for a new KMS Key.

Is there a way for the CloudFormation stack to use the existing KMS key from the initial deployment?

Also: I’m not 100% clear on what would happen for encrypted data in an S3 bucket that has it’s alias changed, does AWS know to automatically look for the previous KMS key it was encrypted with or does a re-encryption take place?

2

2 Answers

7
votes

I suggest you have one Stack that creates only the KMS and export its value on the outputs:

Resources:
  KmsKey:
    Type: AWS::KMS::Key
    Properties: 
      ...

Outputs:
  S3KmsKeyId:
    Description: The KMS Key used
    Value: !Ref KmsKey
    Export:
      Name: S3KmsKeyId

Then you can have a second Stack that only creates the S3 Bucket, where you reference the Exported Value:

Resources:
  S3Bucket:
      Type: AWS::S3::Bucket
      Properties: 
        ...
        BucketEncryption:
          ServerSideEncryptionConfiguration: 
          - ServerSideEncryptionByDefault: 
              KMSMasterKeyID: !ImportValue S3KmsKeyId
              SSEAlgorithm: aws:kms
1
votes

I was able to create an encrypted S3 bucket using a single stack:

Resources:
  S3EncryptionKey:
    Type: AWS::KMS::Key
       ...

  EncrypedS3Bucket:
    Type: AWS::S3::Bucket
      Properties:
        BucketEncryption:
          ServerSideEncryptionConfiguration:
            - ServerSideEncryptionByDefault:
                KMSMasterKeyID:
                  Ref: S3EncryptionKey
                SSEAlgorithm: aws:kms