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'
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
I am trying to access RDS mysql database via lambda function. I am deploying as SAM template. I have a lambda function attached to an execution role as the following:
LambdaExecutionRole:
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:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: arn:aws:logs:*:*:*
- Effect: Allow
Action:
- rds:*
Resource: "*"
CreateTaskFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./components/lambdaFunctions/createTask
Handler: createTask.handler
Runtime: nodejs12.x
Role: !GetAtt LambdaExecutionRole.Arn
Timeout: 500
Events:
ProxyApiRoot:
Type: Api
Properties:
RestApiId: !Ref ApiGatewayApi
Path: /
Method: ANY
ProxyApiGreedy:
Type: Api
Properties:
RestApiId: !Ref ApiGatewayApi
Path: /{proxy+}
Method: ANY
Layers:
- !Ref NodeModulesLayer
After deploying the stack the lambda can't connect to RDS, and I found only the cloudwatch logs roles in the permission section of lambda:
As you see the RDS permission is not listed. Any suggestions?
Oh my bad. I figured it out, it was a VPC issue. Lambda has to be attached to a VPC, and a security group that is allowed by the security group of the database.
I need to provide the name of the S3 bucket, which serverless create for me, to my application. Here is a simplified version of my serverless.yml file.
service: dummy-service
app: dummy-service
custom:
bucket: "I have no idea what to write here!"
provider:
name: aws
runtime: nodejs10.x
region: eu-central-1
iamRoleStatements:
- Effect: Allow
Action:
- s3:PutObject
- s3:GetObject
Resource:
- "Fn::Join":
- ""
- - "arn:aws:s3:::"
- Ref: DummyBucket
- "*"
environment:
BUCKET: ${self:custom.bucket}
resources:
Resources:
DummyBucket:
Type: AWS::S3::Bucket
functions:
createOrUpdate:
handler: handler.dummy
events:
- http:
path: dummy
method: POST
I have figured out how to make a reference in the iamRoleStatements section. But can't understand how to get it as a string for the environment variable.
Any help is welcome. Thanks.
You can use Ref to get the bucket name
service: dummy-service
app: dummy-service
custom:
bucket:
Ref: DummyBucket
provider:
name: aws
runtime: nodejs10.x
region: eu-central-1
iamRoleStatements:
- Effect: Allow
Action:
- s3:PutObject
- s3:GetObject
Resource:
- "Fn::Join":
- ""
- - "arn:aws:s3:::"
- Ref: DummyBucket
- "*"
environment:
BUCKET: ${self:custom.bucket}
resources:
Resources:
DummyBucket:
Type: AWS::S3::Bucket
functions:
createOrUpdate:
handler: handler.dummy
events:
- http:
path: dummy
method: POST
I'm working on setting up my Java AWS lambda functions to be deployed via Codepipeline -> Cloudformation and am having some difficulty with Cloudformation. I've worked with Terraform before, so I understand the general concepts...
To clarify, my code is housed in a Codecommit repository and everything was setup by Codestar, so it created a Codepipeline with a single stage, two-step deployment (generate changeset, execute changeset).
For right now, I am just marking up the sample template.yml file that Codestar created in the repository, hence the HelloWorld references.
In addition to the template.yml file, I also have a buildspec.yml file for Codebuild, though the build process completes successfully.
Below is my template.yml cloudformation script. The ChangeSet step in the Codepipeline deployment stage completes successfully, however the ExecuteChangeset step fails, with "No reason provided" (super helpful). Clicking on the details link brings me to the Cloudformation page for the execute step which does not actually show any errors. It shows a few of the add/remove steps I would expect to see, though not all of the ones I would think would need to happen. If I click "Execute", it fails with the following error:
Error: Failed to execute change set: ChangeSet [arn:aws:cloudformation:us-east-1:XXXXXXXXXXXX:stack/awscodestar-test2-lambda/07e71ee0-6a73-11e7-bee5-50d5cd24fac6] cannot be executed in its current execution status of [EXECUTE_FAILED]
What am I doing wrong here? I don't have a good grasp of the Fn::GetAtt call, but I've tried that a few different ways with no joy.
**In addition to identifying what's going wrong, I have two questions:
Please explain what exactly I'm supposed to reference in the Fn::GetAtt function call? Is it the resource name I provide at the top of the resource I'm trying to call (e.g. GetHelloWorld)? Or an explicit name that's provided as a property of that resource (i.e. FunctionName)?
In the Lambda function declaration, I'm trying to setup the Event trigger in-line, which then needs to reference the Lambda function. Can I refer to the Lambda function resource from within the Event declaration that's nested within the Lambda function resource??
Below is my template.yml file.
AWSTemplateFormatVersion: 2010-09-09
Transform:
- AWS::Serverless-2016-10-31
- AWS::CodeStar
Parameters:
ProjectId:
Type: String
Description: AWS CodeStar projectID used to associate new resources to team members
Resources:
RoleForLambda:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service: "lambda.amazonaws.com"
Action: "sts:AssumeRole"
Policies:
- PolicyName: s3put
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
- 's3:PutObject'
Resource:
- 'arn:aws:logs:*:*:*'
- 'arn:aws:s3:*'
GetHelloWorld:
Type: AWS::Serverless::Function
Properties:
Handler: com.aws.codestar.projecttemplates.handler.HelloWorldHandler
Runtime: java8
Timeout: 60
MemorySize: 256
Role:
'Fn::GetAtt':
- RoleForLambda
- Arn
ScheduleRule:
Type: 'AWS::Events::Rule'
Properties:
Name: DownloadFiles
ScheduleExpression: 'cron(2,7,12,17,22,27,32,37,42,47,52,57 * * * ? *)'
State: ENABLED
Targets:
- Arn:
'Fn::GetAtt':
- GetHelloWorld
- Arn
Id: downloadFiles
LambdaInvokePermission:
Type: "AWS::Lambda::Permission"
Properties:
Action: lambda:InvokeFunction
FunctionName: GetHelloWorld
Principal: events.amazonaws.com
SourceAccount: AWS::XXXXXXXXXXXX
SourceArn:
- Arn:
'Fn::GetAtt':
- ScheduleRule
- Arn
In case anyone else gets to this with similar issues. Turns out, I had a few syntax errors and, I'm sure, other problems... Here is a working template.
AWSTemplateFormatVersion: 2010-09-09
Description: >-
This Lambda function does something
Parameters:
ProjectId:
Description: AWS CodeStar projectID used to associate new resources to team members
Type: String
Resources:
DownloadRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Sid: ''
Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: 'sts:AssumeRole'
Policies:
- PolicyName: PutS3Policy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
- 's3:PutObject'
- 's3:PutObjectAcl'
- 's3:PutObjectTagging'
- 'sns:Publish'
Resource:
- 'arn:aws:logs:*:*:*'
- 'arn:aws:s3:::myBucket'
- 'arn:aws:s3:::myBucket/*'
- 'arn:aws:sns:us-east-1:xxxxxxxxxxxx:SNS_TOPIC'
Path: /
DownloadFunction:
Type: 'AWS::Lambda::Function'
Properties:
Handler: 'com.mycompany.download.LambdaFunction::lambdaHandler'
MemorySize: '256'
Description: A scheduled Lambda function
FunctionName: Download
Role: !GetAtt
- DownloadRole
- Arn
Runtime: java8
Timeout: '60'
DependsOn:
- DownloadRole
ScheduleRule:
Type: 'AWS::Events::Rule'
Properties:
Name: DownloadFiles
ScheduleExpression: 'cron(2,7,12,17,22,27,32,37,42,47,52,57 * * * ? *)'
State: ENABLED
Targets:
- Arn: !GetAtt
- DownloadFunction
- Arn
Id: DownloadFiles
DependsOn:
- DownloadFunction
LambdaInvokePermission:
Type: 'AWS::Lambda::Permission'
Properties:
FunctionName: !GetAtt
- DownloadFunction
- Arn
Action: 'lambda:InvokeFunction'
Principal: events.amazonaws.com
SourceArn: !GetAtt
- ScheduleRule
- Arn
DependsOn:
- DownloadFunction
- ScheduleRule
Maybe not exactly the same issue
This was our error message:
An error occurred (InvalidChangeSetStatus) when calling the ExecuteChangeSet operation: ChangeSet [arn:aws:cloudformation:....]
cannot be executed in its current execution status of [OBSOLETE]
And to resolve I simply reran the same Cloudformation script. Strange enough - this issue occurred in all environments (DEV, TETS, and PROD) and the same step for all 3 situations.