Core encryption key management framework for serverless

I’ve started hacking this together…

functions:
  KeysResource:
    role: digidevlambda
    handler: vapidkeys.handler
  
resources:
  Resources:

    MyKeysResource:
      Type: Custom::MyKeysResource
      Properties:
        TriggerRun: "1"  # increment this to force the VAPID Key generation function to run
        Stage: $<opt:stage, self:provider.stage>
        ServiceToken:
          'Fn::GetAtt': [KeysResourceLambdaFunction, Arn]
    digidevlambda:
      Type: AWS::IAM::Role
      Properties:
        Path: /
        RoleName: digidevlambda
        AssumeRolePolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Principal:
                Service:
                  - lambda.amazonaws.com
              Action: sts:AssumeRole
        Policies:
          - PolicyName: digiDefaultPolicy
            PolicyDocument:
              Version: '2012-10-17'
              Statement:
                - Effect: Allow # note that these rights are given in the default policy and are required if you want logs out of your lambda(s)
                  Action:
                    - logs:CreateLogGroup
                    - logs:CreateLogStream
                    - logs:PutLogEvents
                  Resource: arn:aws:logs:$<opt:region, self:provider.region>:*:log-group:/aws/lambda/*:*:*
                - Effect: Allow
                  Action:
                    - ssm:PutParameter
                  Resource: "*"

  Outputs:
    VAPIDPublicKey:
      Value:
        {"Fn::GetAtt": ["MyKeysResource", "VAPIDPublicKey"]}

And the lambda routine

  const response = require('cfn-response');
  const webpush = require('web-push');
  const AWS = require("aws-sdk");
  const ssm = new AWS.SSM();
  
  exports.handler = function(event, context) {
    console.log(event);

    if (event.RequestType == "Update") {
      let keys = webpush.generateVAPIDKeys();
      var params = {
        Name: '/VAPID/' + event.ResourceProperties.Stage + '/publicKey', /* required */
        Type: 'SecureString',
        Value: keys.publicKey,
        Description: 'VAPID public key for server push',
        Overwrite: true
      };
      ssm.putParameter(params, function(err, data) {
        if (err) console.log(err, err.stack); // an error occurred
        else     console.log(data);           // successful response
      });
      params.Name = '/VAPID/' + event.ResourceProperties.Stage + '/privateKey';
      params.Value = keys.privateKey;
      params.Description = "VAPID private key for server push"
      ssm.putParameter(params, function(err, data) {
        if (err) console.log(err, err.stack); // an error occurred
        else     console.log(data);           // successful response
      });
      return response.send(event, context, response.SUCCESS, {
        VAPIDPublicKey: keys.publicKey
      });
    } else {
      return response.send(event, context, response.SUCCESS, {
        VAPIDPublicKey: ''
      });
    }
  };