James Deehan
James Deehan

Reputation: 96

Deploy lambda resource with aws stacksets

I'm using AWS CloudFormation Stacksets to deploy resources to different accounts. The Lambda resource requires an S3Bucket, ObjectKey and ObjectVersion to reference the zip file containing the code. This code lives in an S3 bucket within the master account.

When deploying a stack instance to an account, the account cannot access the zip file to create the lambda as it lives in the master and I get this error:

Your access has been denied by S3, please make sure your request credentials have permission to GetObject for bucket-name/python_lambdas.zip. S3 Error Code: AccessDenied. S3 Error Message: Access Denied (Service: AWSLambdaInternal; Status Code: 403; Error Code: AccessDeniedException; Request ID: XXX)"

I have tried to allow the role within the account to assume a role in the master that has access to the S3 bucket. However, I believe that the cloudformation principal is trying to access the bucket from the web rather than by assuming the role in the master.

This is the resource:

GenericLambda:
  Type: AWS::Lambda::Function
  Properties:
    Code:
      S3Bucket: !Ref LambdaBucket
      S3Key:  !Ref LambdaObjectKey
      S3ObjectVersion: !Ref LambdaObjectVersion
    FunctionName: UserAccessLambda
    Handler:  index.handler
    Role: !GetAtt ExecutionRole.Arn
    Runtime:  python3.6

I expected the stackset to create a copy of the lambda code and deploy this to the account but it seems that the account reads in the code when generating the resource

Upvotes: 1

Views: 2182

Answers (3)

Jorge Santaella
Jorge Santaella

Reputation: 1

If you're uploading your lambda code from another aws account into the S3 bucket make sure your bucket has the following features since creation:

S3Bucket:
Condition: <AnyConditionYouWant> --OPTIONAL
Type: 'AWS::S3::Bucket'
Properties:
  OwnershipControls:
    Rules:
      - ObjectOwnership: BucketOwnerEnforced --THIS ONE
  BucketName: !Ref MyBucketParameterName 
  BucketEncryption: 
    ServerSideEncryptionConfiguration:
      - ServerSideEncryptionByDefault:
          SSEAlgorithm: AES256
  PublicAccessBlockConfiguration: -- OPTIONAL, A BEST PRACTICE WITH S3
    BlockPublicAcls: true
    BlockPublicPolicy: true
    IgnorePublicAcls: true
    RestrictPublicBuckets: true

When you upload an object from different account than the owner your object will have the ownership marked from the origin. [Here][1]

[1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html More information.

Upvotes: 0

RSingh
RSingh

Reputation: 700

You need add the below tags to your bucket policy to allow your cross-account role to have access to it.

{"Action": [
            "s3:GetObject",
            "s3:ListBucket"

            ],
    "Effect": "Allow",
                "Principal": {
                        "AWS": [
                            "arn:aws:iam::awsaccount:role/crossaccount role"
                                ]
                            }
}

Upvotes: 1

James Deehan
James Deehan

Reputation: 96

The bucket that contains the code needs to have a policy allowing the role - with which you are deploying the stack set instance - to list and get objects from it.

Upvotes: 0

Related Questions