Jiew Meng
Jiew Meng

Reputation: 88367

CloudFormation StackSet S3 Error: the region 'us-east-1' is wrong; expecting 'ap-southeast-1'

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

Answers (1)

Madhukar Mohanraju
Madhukar Mohanraju

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 ArtifactsBucketparameter, 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

Related Questions