Reputation: 88367
I am trying to deploy my lambda functions using CloudFormation StackSets to multiple AWS accounts and regions. But failed because of the below error
ResourceLogicalId:OfficeHoursAutoScalingStart, ResourceType:AWS::Lambda::Function, ResourceStatusReason:Error occurred while GetObject. S3 Error Code: AuthorizationHeaderMalformed. S3 Error Message: The authorization header is malformed; the region 'us-east-1' is wrong; expecting 'ap-southeast-1'
It seems like its a permissions thing? How do I resolve this?
My template:
AWSTemplateFormatVersion : '2010-09-09'
Description: 'Skynet. AWS Management Assistant'
Parameters:
AppName:
Type: String
Description: Prefix for resources
Default: skynet-lambda-stackset
ArtifactsBucket:
Type: String
Description: S3 bucket storing lambda function zip
ArtifactZipPath:
Type: String
Description: Path to lambda function zip
CostCenter:
Type: String
Description: Cost center
Default: Admin
Owner:
Type: String
Description: Owner
Default: Jiew Meng
Resources:
LambdaRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub '${AppName}-lambda'
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
- apigateway.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/AmazonEC2FullAccess'
- 'arn:aws:iam::aws:policy/AWSLambdaFullAccess'
- 'arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess'
- 'arn:aws:iam::aws:policy/AmazonAPIGatewayInvokeFullAccess'
- 'arn:aws:iam::aws:policy/CloudWatchLogsFullAccess'
NewEc2AutoTag:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: !Ref ArtifactsBucket
S3Key: !Ref ArtifactZipPath
Handler: ec2/newEc2_autoTag.handler
Runtime: nodejs6.10
FunctionName: 'NewEC2_AutoTag'
Description: 'Auto tag new EC2 instances with Owner tag'
Timeout: 30
Role: !GetAtt LambdaRole.Arn
Tags:
- Key: Cost Center
Value: !Ref CostCenter
- Key: Owner
Value: !Ref Owner
NewEc2Event:
Type: AWS::Events::Rule
Properties:
Name: !Sub ${AppName}-newEc2
Description: On new EC2 instance created
EventPattern:
source:
- 'aws.ec2'
detail-type:
- 'AWS API Call via CloudTrail'
detail:
eventName:
- RunInstances
Targets:
- !Ref NewEc2AutoTag
AfterhoursEc2Shutdown:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: !Ref ArtifactsBucket
S3Key: !Ref ArtifactZipPath
Handler: ec2/afterHours_shutdown.handler
Runtime: nodejs6.10
FunctionName: 'Afterhours_Shutdown'
Description: 'Shutdown instances tagged Auto Shutdown: true'
Timeout: 30
Role: !GetAtt LambdaRole.Arn
Tags:
- Key: Cost Center
Value: !Ref CostCenter
- Key: Owner
Value: !Ref Owner
AfterHoursEvent:
Type: AWS::Events::Rule
Properties:
Name: !Sub ${AppName}-afterHours
Description: Triggered on weekdays 2400 SGT
ScheduleExpression: cron(0 16 ? * MON,TUE,WED,THUR,FRI *)
Targets:
- !Ref AfterhoursEc2Shutdown
- !Ref AfterhoursAutoScalingShutdown
OfficeHoursEc2Start:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: !Ref ArtifactsBucket
S3Key: !Ref ArtifactZipPath
Handler: ec2/officeHours_start.handler
Runtime: nodejs6.10
FunctionName: 'OfficeHours_Start'
Description: 'Starts instances with Auto Shutdown: true'
Timeout: 30
Role: !GetAtt LambdaRole.Arn
Tags:
- Key: Cost Center
Value: !Ref CostCenter
- Key: Owner
Value: !Ref Owner
OfficeHoursEvent:
Type: AWS::Events::Rule
Properties:
Name: !Sub ${AppName}-officeHours
Description: Triggered on 7AM SGT weekdays
ScheduleExpression: cron(0 23 ? * SUN,MON,TUE,WED,THU *)
Targets:
- !Ref OfficeHoursEc2Start
- !Ref OfficeHoursAutoScalingStart
StartedEc2ConfigureDns:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: !Ref ArtifactsBucket
S3Key: !Ref ArtifactZipPath
Handler: ec2/started_configureDns.handler
Runtime: nodejs6.10
FunctionName: 'StartedEc2_ConfigureDns'
Description: 'When EC2 started, configure DNS if required'
Timeout: 30
Role: !GetAtt LambdaRole.Arn
Tags:
- Key: Cost Center
Value: !Ref CostCenter
- Key: Owner
Value: !Ref Owner
Ec2StartedEvent:
Type: AWS::Events::Rule
Properties:
Name: !Sub ${AppName}-ec2-started
Description: Triggered on EC2 starts
EventPattern:
source:
- 'aws.ec2'
detail-type:
- 'EC2 Instance State-change Notification'
detail:
state:
- running
Targets:
- !Ref StartedEc2ConfigureDns
AfterhoursAutoScalingShutdown:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: !Ref ArtifactsBucket
S3Key: !Ref ArtifactZipPath
Handler: autoscaling/afterHours_shutdown.handler
Runtime: nodejs6.10
FunctionName: 'Afterhours_AutoScalingShutdown'
Description: 'Scales down autoscaling groups tagged Auto Shutdown: true'
Timeout: 30
Role: !GetAtt LambdaRole.Arn
Tags:
- Key: Cost Center
Value: !Ref CostCenter
- Key: Owner
Value: !Ref Owner
OfficeHoursAutoScalingStart:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: !Ref ArtifactsBucket
S3Key: !Ref ArtifactZipPath
Handler: autoscaling/officeHours_start.handler
Runtime: nodejs6.10
FunctionName: 'OfficeHours_AutoScalingStart'
Description: 'Scales up auto scaling groups that are scaled down to 0 and tagged autostart: true'
Timeout: 30
Role: !GetAtt LambdaRole.Arn
Tags:
- Key: Cost Center
Value: !Ref CostCenter
- Key: Owner
Value: !Ref Owner
NewAutoScalingGroupEvent:
Type: AWS::Events::Rule
Properties:
Name: !Sub ${AppName}-autoscaling-new
Description: Triggered when new autoscaling group created
EventPattern:
source:
- 'aws.autoscaling'
detail-type:
- 'AWS API Call via CloudTrail'
detail:
eventName:
- CreateAutoScalingGroup
Targets:
- !Ref NewAutoScalingGroupAutoTag
NewAutoScalingGroupAutoTag:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: !Ref ArtifactsBucket
S3Key: !Ref ArtifactZipPath
Handler: autoscaling/new_autoTag.handler
Runtime: nodejs6.10
FunctionName: 'NewAutoScalingGroup_AutoTag'
Description: 'Tags new autoscaling groups with owner and autoshutdown tags if not existing'
Timeout: 30
Role: !GetAtt LambdaRole.Arn
Tags:
- Key: Cost Center
Value: !Ref CostCenter
- Key: Owner
Value: !Ref Owner
Upvotes: 3
Views: 7337
Reputation: 2863
Looks like you have created the s3 bucket (referenced by variable ArtifactsBucket
in your template) in AWS region ap-southeast-1
.
Using AWS Stacksets, You have selected us-east-1
as one of the regions in Deployment Order.
The AWS Stackset passes the SAME parameters to all the stacks which it tries to create in multiple regions/accounts.
So when it is trying to create the lambda function OfficeHoursAutoScalingStart
in us-east-1
region, It is tryin to access the s3 bucket(GETObject request) in us-east-1
region itself, with the same bucket name.
ie. It is presuming that the s3 bucket with name passed by ArtifactsBucket
parameter, is present in us-east-1 itself.But since the source code of the lambda function is actually in the bucket present in region ap-southeast-1
,the header malformed error
is thrown. In this case the bucket name is matching, but the region is not.
Currently, when you create lambda function using CloudFormation, there is a restriction that the S3 bucket that contains the source code of your Lambda function must be in the SAME region as the STACK which you are creating. Doc Reference Link
If this is the issue, then as a fix, you can think of creating s3 buckets (add region-name as a prefix to the bucket name) in the required regions and use them in the template based on the region.
Example:
us-east-1-lambdabkt
us-east-2-lambdabkt
ap-southeast-1-lambdabkt
Upvotes: 11