Reputation: 7380
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
Upvotes: 5
Views: 11696
Reputation: 337
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.
Upvotes: 3
Reputation: 7380
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
Upvotes: 4