Search code examples
amazon-web-servicesencryptionaws-cloudformationamazon-sqs

Enable encryption at rest in SQS for serverless


We are using serverless framework for our application with microservices (lambda functions). In the serverless.yml file we list down the resources which need to be created upon deployment.

The resources section of the serverles.yml file looks like the following:

resources:
    Resources:
        GatewayResponse:
            Type: "AWS::ApiGateway::GatewayResponse"
            Properties:
                ResponseParameters:
                    gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
                    gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
                ResponseType: EXPIRED_TOKEN
                RestApiId:
                    Ref: "ApiGatewayRestApi"
                StatusCode: "401"
        AuthFailureGatewayResponse:
            Type: "AWS::ApiGateway::GatewayResponse"
            Properties:
                ResponseParameters:
                    gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
                    gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
                ResponseType: UNAUTHORIZED
                RestApiId:
                    Ref: "ApiGatewayRestApi"
                StatusCode: "401"
        SqsQueue:
            Type: "AWS::SQS::Queue"
            Properties:
                QueueName: ${opt:stage}-${opt:product}-sqs-queue
                VisibilityTimeout: 900
                RedrivePolicy:
                    deadLetterTargetArn:
                        Fn::GetAtt:
                        - SqsDeadLetterQueue
                        - Arn
                    maxReceiveCount: 1
        SqsDeadLetterQueue:
            Type: AWS::SQS::Queue
            Properties:
                QueueName: ${opt:stage}-${opt:product}-deadletter-queue
                MessageRetentionPeriod: 1209600

As you can see we are creating the SQS queue resource there as well. Initially we had not enabled encryption for rest in our SQS but now the need has arised.

I can go into the AWS console and enable encryption at rest manually from there for each and every queue we have created but it will be tedious, also I want to include it in the serverless.yml creation so any SQS resources created from now on have encryption enabled by default.

I would like to know what I need to add to the resource section of serverless.yml. Do I add the CMK (customer master key) alias, can I use a default CMK alias or do I need to generate a new one for this purpose. Do I also need to modify other lambdas which are referring the SQS so they are able to access it?


Solution

  • To add encryption to your queues you have to add KmsMasterKeyId to your queues in the template. If you want to use AWS managed CMK, the id will be alias/aws/sqs (assuming both queues):

    resources:
        Resources:
            GatewayResponse:
                Type: "AWS::ApiGateway::GatewayResponse"
                Properties:
                    ResponseParameters:
                        gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
                        gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
                    ResponseType: EXPIRED_TOKEN
                    RestApiId:
                        Ref: "ApiGatewayRestApi"
                    StatusCode: "401"
            AuthFailureGatewayResponse:
                Type: "AWS::ApiGateway::GatewayResponse"
                Properties:
                    ResponseParameters:
                        gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
                        gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
                    ResponseType: UNAUTHORIZED
                    RestApiId:
                        Ref: "ApiGatewayRestApi"
                    StatusCode: "401"
            SqsQueue:
                Type: "AWS::SQS::Queue"
                Properties:
                    QueueName: ${opt:stage}-${opt:product}-sqs-queue
                    VisibilityTimeout: 900
                    RedrivePolicy:
                        deadLetterTargetArn:
                            Fn::GetAtt:
                            - SqsDeadLetterQueue
                            - Arn
                        maxReceiveCount: 1
                    KmsMasterKeyId: alias/aws/sqs
            SqsDeadLetterQueue:
                Type: AWS::SQS::Queue
                Properties:
                    QueueName: ${opt:stage}-${opt:product}-deadletter-queue
                    MessageRetentionPeriod: 1209600
                    KmsMasterKeyId: alias/aws/sqs