Run AWS CLI KMS encrypt commands from Cloudformation - amazon-web-services

I have 2 cloudformation templates - one that creates a kms key and the other template uses the kms key to encrypt a env variable used in the lambda function.
I wanted to know if there is a way to run the kms encrypt command from within the cloudformation as a prior step and then use the encrypted text for the environment variable while creating the lambda function.
aws kms encrypt --key-id <key-id-output-from-stack1> --plaintext fileb://file.txt --query CiphertextBlob --output text > fileoutput.txt
This command outputs the encrypted text and I would need to use this text in the lambda function for one of the environment variables as below.
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-
If this is not possible is there any recommendations on how to achieve this? Thanks in advance.

You can use a custom resource for this. It will execute a Lambda function that will encrypt and return the value. That value can then be used in the environment variable.
Something like the following. Make sure to have a resource/parameter/output called KeyId with the KMS key 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-

Related

How to set up a trigger for lambda when there's a new file is S3

I've never done this and there's so much material it's kinda overwhelming and I feel like i just keep trying different things and none of them work ...
I have a function that reads from S3 and writes to RS.
I'm trying to figure out how to set up a trigger so it only runs when it detects that new files have been uploaded to an S3 bucket.
I'm kinda confused by whether i should be using SNS or SQS or both. But i have added this to my template and it creates both a Topic and a Queue.
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
Sample SAM Template
Globals:
Function:
Timeout: 600
MemorySize: 128
Tracing: Active
Api:
TracingEnabled: true
Resources:
RSUploadFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: <...>
CodeUri: upload_to_rs/
Handler: app.lambda_handler
Runtime: python3.9
PackageType: Zip
Architectures:
- x86_64
Policies:
- Statement:
- Sid: KMSGenerateDataKey
Effect: Allow
Action:
- kms:GenerateDataKey
Resource: arn:aws:kms:<...>
- Statement:
- Sid: ExecuteStatement
Effect: Allow
Action:
- redshift-data:ExecuteStatement
Resource: arn:aws:redshift:<...>
- Statement:
- Sid: DescribeStatement
Effect: Allow
Action:
- redshift-data:DescribeStatement
Resource: '*'
- KMSDecryptPolicy:
KeyId: <...>
- KMSEncryptPolicy:
KeyId: <...>
- S3CrudPolicy:
BucketName: <...>
- AWSSecretsManagerGetSecretValuePolicy:
SecretArn: arn:aws:secretsmanager:<...>
Events:
SNS1:
Type: SNS
Properties:
Topic:
Ref: SNSTopic
Statement:
Condition:
ArnLike:
aws:SourceArn: arn:aws:s3:::<...>
SNSTopic:
Type: "AWS::SNS::Topic"
Properties:
DisplayName: "My SNS topic"
Subscription:
-
Endpoint:
Fn::GetAtt:
- "RSUploadFunction"
- "Arn"
Protocol: "lambda"
TopicName: "SNSTopic"
SQSQueue:
Type: "AWS::SQS::Queue"
Properties:
VisibilityTimeout: 600
QueueName: "SQSQueue"
MyQueuePolicy:
Type: "AWS::SQS::QueuePolicy"
Properties:
PolicyDocument:
Statement:
Effect: Allow
Principal:
Service: "sns.amazonaws.com"
Action: "sqs:SendMessage"
Resource: "*"
Condition:
ArnEquals:
"aws:SourceArn":
!Ref SNSTopic
Queues:
[!Ref SQSQueue]
Outputs:
Function1:
Description: "Function ARN"
Value: !GetAtt <...>.Arn
Now i'm not super sure where to go from here. I tried going into bucket settings and creating an event with either a queue or a topic, but i get the same error:
Unknown Error
An unexpected error occurred.
API response
Unable to validate the following destination configurations
Really lost as to where to go from here.
Take a look at the below resources,
https://docs.aws.amazon.com/lambda/latest/dg/with-s3-example.html
https://aws.amazon.com/premiumsupport/knowledge-center/cloudformation-s3-notification-lambda/
The essence of the KB article is, you use a custom resource to create a S3 trigger by adding a bucket notification through the BucketNotification.put API.
One thing you need to be careful about is, in real-world scenarios, there could be other bucket notifications already present. So first call get_bucket_notification_configuration and add/update the notifications.
Shamelessly copy-pasting the Cloudformation stack from the aws kb article since a link only answer is not a good idea on SO since they can go dead anytime.
AWSTemplateFormatVersion: 2010-09-09
Description: >-
Sample template to illustrate use of existing S3 bucket as an event source for a Lambda function
Parameters:
NotificationBucket:
Type: String
Default : my-bucket-name
Description: S3 bucket that's used for the Lambda event notification
Resources:
S3NotificationLambdaFunction:
Type: 'AWS::Lambda::Function'
Properties:
Code:
ZipFile: !Join
- |+
- - import json
- 'def lambda_handler(event,context):'
- ' return ''Welcome... This is a test Lambda Function'''
Handler: index.lambda_handler
Role: !GetAtt LambdaIAMRole.Arn
Runtime: python3.9
Timeout: 5
LambdaInvokePermission:
Type: 'AWS::Lambda::Permission'
Properties:
FunctionName: !GetAtt S3NotificationLambdaFunction.Arn
Action: 'lambda:InvokeFunction'
Principal: s3.amazonaws.com
SourceAccount: !Ref 'AWS::AccountId'
SourceArn: !Sub 'arn:aws:s3:::${NotificationBucket}'
LambdaIAMRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
Policies:
- PolicyName: root
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- 's3:GetBucketNotification'
- 's3:PutBucketNotification'
Resource: !Sub 'arn:aws:s3:::${NotificationBucket}'
- Effect: Allow
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
Resource: 'arn:aws:logs:*:*:*'
CustomResourceLambdaFunction:
Type: 'AWS::Lambda::Function'
Properties:
Handler: index.lambda_handler
Role: !GetAtt LambdaIAMRole.Arn
Code:
ZipFile: |
from __future__ import print_function
import json
import boto3
import cfnresponse
SUCCESS = "SUCCESS"
FAILED = "FAILED"
print('Loading function')
s3 = boto3.resource('s3')
def lambda_handler(event, context):
print("Received event: " + json.dumps(event, indent=2))
responseData={}
try:
if event['RequestType'] == 'Delete':
print("Request Type:",event['RequestType'])
Bucket=event['ResourceProperties']['Bucket']
delete_notification(Bucket)
print("Sending response to custom resource after Delete")
elif event['RequestType'] == 'Create' or event['RequestType'] == 'Update':
print("Request Type:",event['RequestType'])
LambdaArn=event['ResourceProperties']['LambdaArn']
Bucket=event['ResourceProperties']['Bucket']
add_notification(LambdaArn, Bucket)
responseData={'Bucket':Bucket}
print("Sending response to custom resource")
responseStatus = 'SUCCESS'
except Exception as e:
print('Failed to process:', e)
responseStatus = 'FAILED'
responseData = {'Failure': 'Something bad happened.'}
cfnresponse.send(event, context, responseStatus, responseData)
def add_notification(LambdaArn, Bucket):
bucket_notification = s3.BucketNotification(Bucket)
response = bucket_notification.put(
NotificationConfiguration={
'LambdaFunctionConfigurations': [
{
'LambdaFunctionArn': LambdaArn,
'Events': [
's3:ObjectCreated:*'
]
}
]
}
)
print("Put request completed....")
def delete_notification(Bucket):
bucket_notification = s3.BucketNotification(Bucket)
response = bucket_notification.put(
NotificationConfiguration={}
)
print("Delete request completed....")
Runtime: python3.9
Timeout: 50
LambdaTrigger:
Type: 'Custom::LambdaTrigger'
DependsOn: LambdaInvokePermission
Properties:
ServiceToken: !GetAtt CustomResourceLambdaFunction.Arn
LambdaArn: !GetAtt S3NotificationLambdaFunction.Arn
Bucket: !Ref NotificationBucket

AWS SAM Lambda policy for OpenSearch

I couldn't get a valid IAM policy to work for a Lambda function to OpenSearch.
Replicate:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub ${AWS::StackName}-Replicate
Description: !Sub
- Stack ${StackTagName} Environment ${EnvironmentTagName} Function ${ResourceName}
- ResourceName: DBReplicate
CodeUri: ../src/Replicate
Handler: index.handler
Runtime: nodejs16.x
MemorySize: 3008
Timeout: 30
Tracing: Active
Policies:
- PolicyName: Access
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- es:*
Resource:
- arn:aws:es:eu-west-1:22222222222:domain/mynewdomain
- DomainName: mynewdomain
Events:
MyDynamoDBtable:
Type: DynamoDB
Properties:
Stream: !Ref TableStreamArn
StartingPosition: TRIM_HORIZON
BatchSize: 1
Running sam validate, I'm getting:
Policy at index 0 in the 'Policies' property is not valid
Got the answer from another post, the structure was wrong, the correct way is:
Add inline policy to aws SAM template
QueryFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: query/
Handler: app.lambda_handler
Policies:
- AmazonDynamoDBFullAccess
- AWSLambdaVPCAccessExecutionRole
- Version: '2012-10-17' # Policy Document
Statement:
- Effect: Allow
Action:
- dynamodb:*
Resource: 'arn:aws:dynamodb:*:*:table/dynamo_db_table_endpoint'

Security Hub with Chatbot not receiving response from Custom Resource

I'm following this tutorial on enabling aws security hub with aws chatbot. I seem to be having an issue with deploying the custom resource named AddCustomActionSHResource1 in the following code, which is linked from the tutorial to here.
AWSTemplateFormatVersion: "2010-09-09"
Description: Deploys CustomAction in SecurityHub to enable sending findings to Slack via AWS Chatbot
#==================================================
# Parameters
#==================================================
Parameters:
SlackWorkSpaceID:
Description: Slack workspace ID (Copy and Paste from AWS Chatbot Configured Clients Interface)
Type: String
MinLength: 9
MaxLength: 15
AllowedPattern: ^[a-zA-Z0-9_]*$
ConstraintDescription: |
Malformed Input Parameter: Environment must contain only upper and numbers. Length should be minimum of 9 characters and a maximum of 15 characters.
SlackChannelID:
Description: Slack Channel ID
Type: String
MinLength: 9
MaxLength: 15
AllowedPattern: ^[a-zA-Z0-9_]*$
ConstraintDescription: |
Malformed Input Parameter: Environment must contain only upper and numbers. Length should be a minimum of 9 characters and a maximum of 15 characters.
# CustomActionName:
# Description: Name of the Custom Action in SecurityHub
# Type: String
# AllowedPattern: ^[a-zA-Z0-9_]*$
# Default: Send_To_Slack
# #Default: 'Send To !Sub "${ChatApplication}"'
#==================================================
# Resources
#==================================================
Resources:
#======================================================
# Lambda Role to create Custom Action
#======================================================
LambdaIAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action:
- sts:AssumeRole
Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Version: 2012-10-17
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AWSLambdaExecute
Path: /
#======================================================
# Lambda Policy to create Custom Action
#======================================================
LambdaIAMPolicy:
Type: AWS::IAM::Policy
DependsOn: LambdaIAMRole
Properties:
PolicyName: LambdaCreateCustomActionPolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- 'securityhub:CreateActionTarget'
Resource: '*'
Roles:
- !Ref LambdaIAMRole
#======================================================
# Lambda Function to create Custom Action
#======================================================
LambdaCreateCustomAction:
Type: AWS::Lambda::Function
DependsOn: LambdaIAMPolicy
Properties:
FunctionName: addcustomactionsecurityhub
Description: CreateCustom Action in SecurityHub
Runtime: python3.7
Handler: index.lambda_handler
Code:
ZipFile: |
import boto3
import cfnresponse
def lambda_handler(event, context):
securityhub = boto3.client('securityhub')
response = securityhub.create_action_target(Name="Send_To_Slack",Description='Send Messages to ChatApplication via AWS ChatBot',Id='SendToSlack')
responseData = {}
responseData['Data'] = response
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
MemorySize: 128
Timeout: 10
Role: !GetAtt LambdaIAMRole.Arn
#======================================================
# Custom Resource to Invoke the Lambda Function
#======================================================
AddCustomActionSHResource1:
Type: Custom::AddCustomActionSH
DependsOn: LambdaCreateCustomAction
Properties:
ServiceToken: !GetAtt LambdaCreateCustomAction.Arn
#======================================================
# SNS Topic
#======================================================
SNSTopicAWSChatBot:
Type: AWS::SNS::Topic
Properties:
DisplayName: AWS Chatbot SNS Topic
EventTopicPolicy:
Type: AWS::SNS::TopicPolicy
Properties:
PolicyDocument:
Id: topicPolicyCustomaction
Statement:
- Effect: Allow
Principal:
Service: events.amazonaws.com
Action: 'sns:Publish'
Resource: '*'
Topics:
- !Ref SNSTopicAWSChatBot
#======================================================
# CloudWatch Event Rule
#======================================================
EventRuleCustomAction:
Type: AWS::Events::Rule
Properties:
Description: "SecurityHub Chatbot CustomAction"
EventPattern:
source:
- "aws.securityhub"
detail-type:
- "Security Hub Findings - Custom Action"
resources:
- !Sub 'arn:aws:securityhub:${AWS::Region}:${AWS::AccountId}:action/custom/SendToSlack'
State: "ENABLED"
Targets:
-
Arn:
Ref: "SNSTopicAWSChatBot"
Id: "OpsTopic"
ChatBotManageIAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Principal:
Service:
- "sns.amazonaws.com"
Action:
- "sts:AssumeRole"
SlackChannelConfig:
Type: AWS::Chatbot::SlackChannelConfiguration
Properties:
ConfigurationName: securityhubnotification
IamRoleArn: !GetAtt ChatBotManageIAMRole.Arn
LoggingLevel: NONE
SlackChannelId: !Ref SlackChannelID
SlackWorkspaceId: !Ref SlackWorkSpaceID
SnsTopicArns:
- !Ref SNSTopicAWSChatBot
When deploying this cloudformation file to cloudformation in AWS, everything deploys successfully except for AddCustomActionSHResource1. The error message is:
CloudFormation did not receive a response from your Custom Resource. Please check your logs for requestId [18sa90d1-49s1-4as7-9fsc-b79ssd6csd9]. If you are using the Python cfn-response module, you may need to update your Lambda function code so that CloudFormation can attach the updated version.
I found some information on updating the lambda function by just adding comments to it, but I don't believe that's the issue. Most of the useful information I found was from this aws link.

Lambda destination not being triggered on Lambda error

I have a Cloudformation stack which connects two Lambdas together via a Lambda destination config and an SQS queue.
The idea is that ErrorsFunction is fired when there is an error in HelloAddFunction.
This stack deploys fine, and HelloAddFunction works fine when I invoke it with some integer values.
I can see an error in HelloAddFunction when I invoke it with non- integer values, but no corresponding error seems to be received by ErrorsFunction.
The binding of ErrorsFunction to ErrorsQueue seems to be working - if I push a message onto ErrorsQueue via the console, it's received by ErrorsFunction.
So it feels like the Lambda destination config is somehow not working.
What am I missing here ?
TIA
AWSTemplateFormatVersion: '2010-09-09'
Outputs: {}
Parameters:
AppName:
Type: String
MemorySizeSmall:
Default: 512
Type: Number
RuntimeVersion:
Default: '3.8'
Type: String
TimeoutShort:
Default: 5
Type: Number
Resources:
HelloAddEventConfig:
Properties:
DestinationConfig:
OnFailure:
Destination:
Fn::GetAtt:
- ErrorsQueue
- Arn
FunctionName:
Ref: HelloAddFunction
MaximumRetryAttempts: 0
Qualifier: $LATEST
Type: AWS::Lambda::EventInvokeConfig
HelloAddFunction:
Properties:
Code:
ZipFile: |
def handler(event, context):
x, y = int(event["x"]), int(event["y"])
return x+y
Handler: index.handler
MemorySize:
Ref: MemorySizeSmall
Role:
Fn::GetAtt:
- HelloAddRole
- Arn
Runtime:
Fn::Sub: python${RuntimeVersion}
Timeout:
Ref: TimeoutShort
Type: AWS::Lambda::Function
HelloAddRole:
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: lambda.amazonaws.com
Version: '2012-10-17'
Policies:
- PolicyDocument:
Statement:
- Action: logs:*
Effect: Allow
Resource: '*'
- Action: sqs:*
Effect: Allow
Resource: '*'
Version: '2012-10-17'
PolicyName:
Fn::Sub: hello-add-role-policy-${AWS::StackName}
Type: AWS::IAM::Role
ErrorsFunction:
Properties:
Code:
ZipFile: |
def handler(event, context):
print (event)
Handler: index.handler
MemorySize:
Ref: MemorySizeSmall
Role:
Fn::GetAtt:
- ErrorsRole
- Arn
Runtime:
Fn::Sub: python${RuntimeVersion}
Timeout:
Ref: TimeoutShort
Type: AWS::Lambda::Function
ErrorsQueue:
Properties: {}
Type: AWS::SQS::Queue
ErrorsQueueBinding:
Properties:
EventSourceArn:
Fn::GetAtt:
- ErrorsQueue
- Arn
FunctionName:
Ref: ErrorsFunction
Type: AWS::Lambda::EventSourceMapping
ErrorsRole:
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: lambda.amazonaws.com
Version: '2012-10-17'
Policies:
- PolicyDocument:
Statement:
- Action: logs:*
Effect: Allow
Resource: '*'
- Action: sqs:*
Effect: Allow
Resource: '*'
Version: '2012-10-17'
PolicyName:
Fn::Sub: errors-role-policy-${AWS::StackName}
Type: AWS::IAM::Role
Your template is fine, but lambda destinations are for asynchronous invocations of your function only. So you have to make such an invocation, which can be done using AWS CLI (--invocation-type Event). AWS Console is synchronous only.
aws lambda invoke --function-name <HelloAddFunctionnaem> --invocation-type Event --payload '{"x": 3, "y": "SSS"}' /dev/stdout

AWS SAM managed policy for SSM get parameter

Is there any managed policy similar to DynamoDBReadPolicy for the ssm:GetParameter* permission for a Lambda function? I'm using aws-sam-cli and trying to follow this, but when I try to fetch the parameters when using sam local start-api, I get the following error:
InvalidAction: The action or operation requested is invalid. Verify that the action is typed correctly.
Here is the snippet where I try to get the parameter:
const ssm = new AWS.SSM();
const param = {
Name: "param1",
WithDecryption: true
};
const secret = await ssm.getParameter(param).promise();
The relevant template sections are below. Thanks!
KeyAlias:
Type: AWS::KMS::Alias
Properties:
AliasName: 'param1Key'
TargetKeyId: !Ref Key
Key:
Type: AWS::KMS::Key
Properties:
KeyPolicy:
Id: default
Statement:
- Effect: Allow
Principal:
AWS: !Sub arn:aws:iam::${AWS::AccountId}:root
Action:
- 'kms:Create*'
- 'kms:Encrypt'
- 'kms:Describe*'
- 'kms:Enable*'
- 'kms:List*'
- 'kms:Put*'
- 'kms:Update*'
- 'kms:Revoke*'
- 'kms:Disable*'
- 'kms:Get*'
- 'kms:Delete*'
- 'kms:ScheduleKeyDeletion'
- 'kms:CancelKeyDeletion'
Resource: '*'
Sid: Allow root account all permissions except to decrypt the key
Version: 2012-10-17
LambdaFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ../
Handler: app.lambda
Runtime: nodejs8.10
Policies:
- DynamoDBReadPolicy:
TableName: !Ref Table
- KMSDecryptPolicy:
KeyId: !Ref Key
# I think I need the ssm policy here
The available SAM policy templates are listed in their Github repository. None of these policy templates grants permissions for any SSM operation, so you can't use a SAM policy template to grant your AWS Lambda function access to SSM parameters as of now.
What you can do as a workaround is to manually add the required policy statement inline to your policies. That would look like:
LambdaFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ../
Handler: app.lambda
Runtime: nodejs8.10
Policies:
- DynamoDBReadPolicy:
TableName: !Ref Table
- KMSDecryptPolicy:
KeyId: !Ref Key
- Statement:
- Action:
- ssm:GetParameter
Effect: Allow
Resource: arn:aws:ssm:region:account-id:parameter/parameter_name
You should also consider opening a pull request for adding a policy template for SSM parameter access to SAM, as such a template would of course be a more convenient way to express such permissions. From my experience the developers are very friendly and always welcome such additions.
Update: There is a SSMParameterReadPolicy now available in AWS SAM, so instead of using the workaround you can now simply do:
LambdaFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ../
Handler: app.lambda
Runtime: nodejs8.10
Policies:
- DynamoDBReadPolicy:
TableName: !Ref Table
- KMSDecryptPolicy:
KeyId: !Ref Key
- SSMParameterReadPolicy:
ParameterName: parameter_name