Cannot access S3 bucket from Lambda function - amazon-web-services

I created a simple Lambda function that receives a file as a Base64 string and uploads it to my S3 bucket. I used the default S3 role suggested by the Lambda console:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::*"
]
}
]
}
But I'm still getting an access error:
{
"errorMessage": "The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.",
"errorType": "PermanentRedirect",
"stackTrace": [
Doesn't the "arn:aws:s3:::*" cover all my needs? What else do I need to add to use this function?

The must be addressed using the specified endpoint error normally indicates a mismatch between the bucket region and the endpoint that you are calling with your code.
For example: The AWS client connection is established with Sydney but the bucket is in Tokyo.
Try something like this:
var s3 = new AWS.S3({region: 'ap-southeast-2'});

It might also happens to your sourceKey settings, try to add the exact file path in your S3 like:
{
"Records": [
{
"eventVersion": "2.0",
"eventTime": "1970-01-01T00:00:00.000Z",
"requestParameters": {
"sourceIPAddress": "127.0.0.1"
},
"s3": {
"configurationId": "testConfigRule",
"object": {
"eTag": "0123456789abcdef0123456789abcdef",
"sequencer": "0A1B2C3D4E5F678901",
"key": "images/HappyFace.jpg",
"size": 1024
},
"bucket": {
"arn": "arn:aws:s3:::mybucket",
"name": "mybucket",
"ownerIdentity": {
"principalId": "EXAMPLE"
}
},
"s3SchemaVersion": "1.0"
},
"responseElements": {
"x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH",
"x-amz-request-id": "EXAMPLE123456789"
},
"awsRegion": "us-east-1",
"eventName": "ObjectCreated:Put",
"userIdentity": {
"principalId": "EXAMPLE"
},
"eventSource": "aws:s3"
}
]
}

Related

How to switch roles on AWS Console while requiring sts:RoleSessionName?

I have two AWS accounts, A and B. I authenticate to account A using SAML, then to access account B I switch roles. The setup worked well until I tried to enforce that, when switching roles the users need to provide their AWS username as the RoleSessionName. When I require that, then switching roles using the AWS cli works fine, but switching roles in the AWS Console stops working.
Here's the role trust policy that works on both cli and console:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::84...10:root"
},
"Action": "sts:AssumeRole"
}
]
}
Enforcing that the RoleSessionName be the AWS username means to change the policy like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::84...10:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringLike": {
"sts:RoleSessionName": "${aws:username}"
}
}
}
]
}
Note: if instead of "sts:RoleSessionName": "${aws:username}" I do "sts:RoleSessionName": "*", then I can switch roles on the AWS console, but I can't find a way to figure out a pattern that includes the user name and works. I tried *${aws:username}, ${aws:username}*, and *${aws:username}*.
Once I enforce the sts:RoleSessionName condition on the role trust policy, I can no longer switch roles on the AWS Console. What I see in the CloudTrail events (only visible on us-east-1 region), is that switching the role in the AWS Console is recorded as 2 events: a SwitchRole followed by a AssumeRole.
When I switch roles in the AWS console with the first policy, I see the two events in CloudTrail.
Successful SwitchRole event:
{
"eventVersion": "1.08",
"userIdentity": {
"type": "AssumedRole",
"principalId": "ARO...BYP:me#email.com",
"arn": "arn:aws:sts::84...10:assumed-role/my-saml-role/me#email.com",
"accountId": "84...10"
},
"eventTime": "2022-12-21T19:34:55Z",
"eventSource": "signin.amazonaws.com",
"eventName": "SwitchRole",
"awsRegion": "us-east-1",
"sourceIPAddress": "4...0",
"userAgent": "Mozilla/5.0 ...",
"requestParameters": null,
"responseElements": {
"SwitchRole": "Success"
},
"additionalEventData": {
"RedirectTo": "https://us-east-1.console.aws.amazon.com/cloudtrail/home?region=us-east-1#/events?ReadOnly=false",
"SwitchTo": "arn:aws:iam::13...20:role/my-role"
},
"eventID": "ef759d28-37cb-4ece-af7d-3d7c5326691d",
"readOnly": false,
"eventType": "AwsConsoleSignIn",
"managementEvent": true,
"recipientAccountId": "84...10",
"eventCategory": "Management",
"tlsDetails": {
"tlsVersion": "TLSv1.2",
"cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256",
"clientProvidedHostHeader": "signin.aws.amazon.com"
}
}
Successful AssumeRole event:
{
"eventVersion": "1.08",
"userIdentity": {
"type": "AssumedRole",
"principalId": "ARO...BYP:me#email.com",
"arn": "arn:aws:sts::84...10:assumed-role/my-saml-role/me#email.com",
"accountId": "84...10",
"accessKeyId": "ASIA...OA",
"sessionContext": {
"sessionIssuer": {
"type": "Role",
"principalId": "AR...BYP",
"arn": "arn:aws:sts::84...10:assumed-role/my-saml-role",
"accountId": "84...10",
"userName": "my-saml-role"
},
"webIdFederationData": {},
"attributes": {
"creationDate": "2022-12-21T19:10:25Z",
"mfaAuthenticated": "false"
}
}
},
"eventTime": "2022-12-21T19:34:55Z",
"eventSource": "sts.amazonaws.com",
"eventName": "AssumeRole",
"awsRegion": "us-east-1",
"sourceIPAddress": "4...0",
"userAgent": "AWS Signin, aws-internal/3 aws-sdk-java/1.12.339 Linux/5.4.215-mr.86.metal1.x86_64 OpenJDK_64-Bit_Server_VM/25.352-b09 java/1.8.0_352 kotlin/1.3.72 vendor/Oracle_Corporation cfg/retry-mode/standard",
"requestParameters": {
"roleArn": "arn:aws:iam::13...20:role/my-role",
"roleSessionName": "me#email.com"
},
"responseElements": {
"credentials": {
"accessKeyId": "AS...FJ",
"sessionToken": "IQ...VMRCMyvsQ==",
"expiration": "Dec 21, 2022, 8:34:55 PM"
},
"assumedRoleUser": {
"assumedRoleId": "AR...PX:me#email.com",
"arn": "arn:aws:sts::13...20:assumed-role/my-role/me#email.com"
}
},
"requestID": "6d9b977a-e489-4261-97b5-48c0167d82ea",
"eventID": "1f7178bd-046b-4e20-b264-dd86b8753a45",
"readOnly": true,
"resources": [
{
"accountId": "13...20",
"type": "AWS::IAM::Role",
"ARN": "arn:aws:iam::13...20:role/my-role"
}
],
"eventType": "AwsApiCall",
"managementEvent": true,
"recipientAccountId": "84...10",
"sharedEventID": "e49297fc-883e-4160-86bc-d157bc58a3ee",
"eventCategory": "Management",
"tlsDetails": {
"tlsVersion": "TLSv1.2",
"cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256",
"clientProvidedHostHeader": "sts.us-east-1.amazonaws.com"
}
}
When I enforce the sts:RoleSessionName requirement, then the SwitchRole event fails with error switchrole.error.invalidparams.
Failed SwitchRole event
{
"eventVersion": "1.08",
"userIdentity": {
"type": "AssumedRole",
"principalId": "AR..YP:me#email.com",
"arn": "arn:aws:sts::84...10:assumed-role/my-saml-role/me#email.com",
"accountId": "84...10"
},
"eventTime": "2022-12-21T19:25:23Z",
"eventSource": "signin.amazonaws.com",
"eventName": "SwitchRole",
"awsRegion": "us-east-1",
"sourceIPAddress": "4...0",
"userAgent": "Mozilla/5.0 ...",
"errorMessage": "switchrole.error.invalidparams",
"requestParameters": null,
"responseElements": {
"SwitchRole": "Failure"
},
"additionalEventData": {
"RedirectTo": "https://eu-central-1.console.aws.amazon.com/cloudtrail/home?region=eu-central-1#/events?ReadOnly=false",
"SwitchTo": "arn:aws:iam::13..20:role/my-role"
},
"eventID": "76de870e-7e75-43a9-a908-d34616022553",
"readOnly": false,
"eventType": "AwsConsoleSignIn",
"managementEvent": true,
"recipientAccountId": "84...10",
"eventCategory": "Management",
"tlsDetails": {
"tlsVersion": "TLSv1.2",
"cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256",
"clientProvidedHostHeader": "signin.aws.amazon.com"
}
}
The AWS docs mentions that sts:RoleSessionName is available when assuming a role in the AWS Console.
sts:RoleSessionName Works with string operators.
Use this key to compare the session name that a principal specifies
when assuming a role with the value that is specified in the policy.
Availability – This key is present in the request when the principal
assumes the role using the AWS Management Console, any assume-role CLI
command, or any AWS STS AssumeRole API operation.
Src: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#condition-keys-sts

Unable to copy Elasticache backup

I have followed those instructions step by step: https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/backups-exporting.html
However I have the following error:
An error occurred (InvalidParameterValue) when calling the CopySnapshot operation: Elasticache was unable to validate the authenticated user has access on the S3 bucket ...
The bucket is in the same region of the backup
This is my bucket configuration:
{
"LocationConstraint": "eu-central-1"
}
{
"Version": "2012-10-17",
"Id": "xxxxxxxx",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "eu-central-1.elasticache-snapshot.amazonaws.com"
},
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket",
"s3:GetBucketAcl",
"s3:ListMultipartUploadParts",
"s3:ListBucketMultipartUploads"
],
"Resource": [
"arn:aws:s3:::my-bucket-name/*",
"arn:aws:s3:::my-bucket-name"
]
}
]
}
This is the snapshot
{
"Snapshots": [
{
"SnapshotName": "my-snapshot-name",
"CacheClusterId": "xxxxxxxx-xxx",
"SnapshotStatus": "available",
"SnapshotSource": "manual",
"CacheNodeType": "cache.t2.micro",
"Engine": "redis",
"EngineVersion": "5.0.3",
"NumCacheNodes": 1,
"PreferredAvailabilityZone": "eu-central-1c",
"CacheClusterCreateTime": "xxxxxxx",
"PreferredMaintenanceWindow": "mon:02:30-mon:03:30",
"Port": 6379,
"CacheParameterGroupName": "default.redis5.0",
"CacheSubnetGroupName": "internal",
"VpcId": "xxxxx",
"AutoMinorVersionUpgrade": true,
"SnapshotRetentionLimit": 7,
"SnapshotWindow": "00:00-02:00",
"NodeSnapshots": [
{
"CacheNodeId": "0001",
"CacheSize": "33 MB",
"CacheNodeCreateTime": "xxxxxx",
"SnapshotCreateTime": "xxxxxx"
}
],
"ARN": "arn:aws:elasticache:eu-central-1:000000000:snapshot:my-snapshot-name",
"DataTiering": "disabled"
}
]
}
UPDATE
Apparently AWS updated their docs by adding a crucial piece of information regarding the ACL, look the accepted answer for more info.
Here very important step is to add ACL as mentioned in doc:
Add grantee Canonical Id 540804c33a284a299d2547575ce1010f2312ef3da9b3a053c8bc45bf233e4353 with the following options:
Objects: List, Write
Bucket ACL: Read, Write
I added this ACL permission and it started working like a charm.
After adding this ACL my configuration looks below.
Full Ref document link: https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/backups-exporting.html#backups-exporting-grant-access
Based on the article you linked, you also need additional S3 permission:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListAllMyBuckets",
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::*"
}]
}
Have you verified that your IAM user has these access?
When you create the S3 bucket, enable ACLs. Then you can continue with the Permissions section of the instructions.

Terraform-Cloudformation- aws instance provider: Provided Arn is not in correct format

I am creating a cloudformation stack to generate aws instance scheduler in aws gov cloud via TF. The goal is to start/stop ec2 based on tags. Many way to achieve it but I have to use terraform and cloudformation. Here is the repo --> https://github.com/Vinod1908/TestTerraform/blob/master/instanceScheduler.tf
Below is the part of the code where I think I am blocked:
"InstanceSchedulerEncryptionKey": {
"Type": "AWS::KMS::Key",
"Properties": {
"Description": "Key for SNS",
"Enabled": true,
"EnableKeyRotation": true,
"KeyPolicy": {
"Statement": [
{
"Sid": "default",
"Effect": "Allow",
"Principal": {
"AWS": {
"Fn::Sub": "arn:$${AWS::Partition}:iam::$${AWS::AccountId}:root"
}
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allows use of key",
"Effect": "Allow",
"Principal": {
"AWS": {
"Fn::GetAtt": [
"SchedulerRole",
"Arn"
]
}
},
"Action": [
"kms:GenerateDataKey*",
"kms:Decrypt"
],
"Resource": "*"
}
]
}
}
},
"Code": {
"S3Bucket": {
"Fn::Join": [
"-",
[
"solutions",
{
"Ref": "AWS::Region"
}
]
]
},
"S3Key": "aws-instance-scheduler/v1.3.1/instance-scheduler.zip"
The error :
Error: error waiting for CloudFormation Stack creation: failed to create CloudFormation stack, rollback requested (ROLLBACK_COMPLETE): ["The following resource(s) failed to create: [InstanceSchedulerEncryptionKey, SchedulerRule]. Rollback requested by user."
"Resource creation cancelled" "Parameter arn:aws:lambda:us-gov-west-1:###########..:function:Schedule-InstanceSchedulerMain is not valid. Reason: Provided Arn is not in correct format. (Service: AmazonCloudWatchEvents; Status Code: 400; Error Code: ValidationException; Request ID: 37adac0c-6758-4b4f-ac86-0d0140742c80; Proxy: null)"]
Not sure if it's doable in gov cloud but I am looking for potential solutions and found this https://github.com/awslabs/aws-instance-scheduler/issues/11. I am testing it but no success yet.. please help !!
Adding a new line:
Thank you all for the response. My issue was using the correct arn arn:aws-us-gov
I just apply the code and it's going through. Now I am getting this below and I am sure it's related to the policy/role on my s3. Please let me know what is wrong in my code below. Any thoughts?
the s3 code part:
"SchedulerPolicy": {
"Type": "AWS::IAM::Policy",
"Metadata": {
"cfn_nag": {
"rules_to_suppress": [
{
"id": "W12",
"reason": "All policies have been scoped to be as restrictive as possible. This solution needs to access ec2/rds resources across all regions."
}
]
}
},
"Properties": {
"PolicyName": "SchedulerPolicy",
"Roles": [
{
"Ref": "SchedulerRole"
}
],
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:PutRetentionPolicy"
],
"Resource": [
{
"Fn::Join": [
":",
[
"arn:aws-us-gov:logs",
{
"Ref": "AWS::Region"
},
{
"Ref": "AWS::AccountId"
},
"log-group",
{
"Ref": "SchedulerLogGroup"
},
"*"
]
]
},
{
"Fn::Join": [
":",
[
"arn:aws-us-gov:logs",
{
"Ref": "AWS::Region"
},
{
"Ref": "AWS::AccountId"
},
"log-group:/aws/lambda/*"
]
]
}
]
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:*"
],
"Resource": {
"Fn::Join": [
":",
[
"arn:aws-us-gov:s3:::instanceschedulertest",
"arn:aws-us-gov:s3:::instanceschedulertest/*"
]
]
}
},
{
"Effect": "Allow",
"Action": [
"rds:DeleteDBSnapshot",
"rds:DescribeDBSnapshots",
"rds:StopDBInstance"
],
"Resource": {
"Fn::Join": [
":",
[
"arn:aws-us-gov:rds:*",
{
"Ref": "AWS::AccountId"
},
"snapshot:*"
]
]
}
},
{
"Effect": "Allow",
"Action": [
"rds:AddTagsToResource",
"rds:RemoveTagsFromResource",
"rds:DescribeDBSnapshots",
"rds:StartDBInstance",
"rds:StopDBInstance"
The error:
Error: error waiting for CloudFormation Stack creation: failed to create CloudFormation stack, rollback requested (ROLLBACK_COMPLETE): ["The following resource(s) failed to create: [Main]. Rollback requested by user." "Your access has been denied by S3, please make sure your request credentials have permission to GetObject for solutions-us-gov-west-1/aws-instance-scheduler/v1.3.1/instance-scheduler.zip. S3 Error Code: AccessDenied. S3 Error Message: Access Denied (Service: AWSLambdaInternal; Status Code: 403; Error Code: AccessDeniedException; Request ID: 95db6874-d4ad-4499-95f7-f73777a6d4db; Proxy: null)"]
Thank you all for all the pointers I really appreciate your input.
The reason why it is failing is because you are forming the wrong ARN in your Terraform Code.
In your repo,
link
Replace these following lines with respect to Lambda: 1047, 1358, 1420 as "arn:aws-us-gov:lambda" instead of "arn:aws:lambda".
As per the documentation of aws: The ARN should be in this format arn:aws-us-gov:lambda:account-id:function:function-name.
The answer to your question is to update the above-mentioned line. But I am sure you will get errors with respect to other resources as all resources which you are creating are in the Us-Region. So please update all the necessary Joining Function Arn lines which your forming in your code. :)

AWS Lambda function pipeline fails on deploy stage: Action execution failed Role ... is invalid or cannot be assumed

The AWS Lambda function pipeline I did just set up following the official AWS documentation (Building a Continuous Delivery Pipeline for a Lambda Application with AWS CodePipeline) fails for me on deploy stage (both source and build stages do succeed) with this message:
Action execution failed
Role arn:aws:iam::************:role/service-role/AWSCodePipelineServiceRole-eu-west-1-lambda-pipeline
is invalid or cannot be assumed
(Service: AmazonCloudFormation; Status Code: 400; Error Code: ValidationError; Request ID: ********-****-****-************)
I did try to edit the deploy stage and change the specified service role (WSCodePipelineServiceRole-eu-west-1-lambda-pipeline), an run again the pipeline, with no success... More, editing again the deploy stage after re-running the pipeline, I see the previous role is there again... ( solved myself: I was not saving changes... :-( )
This is my template.yml:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Outputs the time
Resources:
TimeFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs10.x
CodeUri: ./
Events:
MyTimeApi:
Type: Api
Properties:
Path: /TimeResource
Method: GET
This is my buildspec.yml:
version: 0.2
phases:
install:
runtime-versions:
nodejs: 10
build:
commands:
- npm install
- export BUCKET=lambda-pipeline-repo-bucket
- aws cloudformation package --template-file template.yml --s3-bucket $BUCKET --output-template-file outputtemplate.yml
artifacts:
type: zip
files:
- template.yml
- outputtemplate.yml
This is the WSCodePipelineServiceRole-eu-west-1-lambda-pipeline role policy JSON:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "*",
"Condition": {
"StringEqualsIfExists": {
"iam:PassedToService": [
"cloudformation.amazonaws.com",
"elasticbeanstalk.amazonaws.com",
"ec2.amazonaws.com",
"ecs-tasks.amazonaws.com"
]
}
}
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"opsworks:DescribeStacks",
"rds:*",
"devicefarm:GetRun",
"cloudformation:CreateChangeSet",
"autoscaling:*",
"codebuild:BatchGetBuilds",
"servicecatalog:ListProvisioningArtifacts",
"devicefarm:ScheduleRun",
"devicefarm:ListDevicePools",
"cloudformation:UpdateStack",
"servicecatalog:DescribeProvisioningArtifact",
"cloudformation:DescribeChangeSet",
"devicefarm:ListProjects",
"cloudformation:ExecuteChangeSet",
"sns:*",
"codedeploy:RegisterApplicationRevision",
"cloudformation:*",
"opsworks:DescribeDeployments",
"devicefarm:CreateUpload",
"cloudformation:DescribeStacks",
"codecommit:GetUploadArchiveStatus",
"cloudwatch:*",
"opsworks:DescribeInstances",
"cloudformation:DeleteStack",
"ecr:DescribeImages",
"ecs:*",
"ec2:*",
"codebuild:StartBuild",
"opsworks:DescribeApps",
"opsworks:UpdateStack",
"cloudformation:ValidateTemplate",
"codedeploy:CreateDeployment",
"codedeploy:GetApplicationRevision",
"codedeploy:GetDeploymentConfig",
"servicecatalog:CreateProvisioningArtifact",
"sqs:*",
"cloudformation:DeleteChangeSet",
"codecommit:GetCommit",
"servicecatalog:DeleteProvisioningArtifact",
"codedeploy:GetApplication",
"cloudformation:SetStackPolicy",
"codecommit:UploadArchive",
"s3:*",
"elasticloadbalancing:*",
"codecommit:CancelUploadArchive",
"devicefarm:GetUpload",
"elasticbeanstalk:*",
"opsworks:UpdateApp",
"opsworks:CreateDeployment",
"cloudformation:CreateStack",
"servicecatalog:UpdateProduct",
"codecommit:GetBranch",
"lambda:*",
"codedeploy:GetDeployment",
"opsworks:DescribeCommands"
],
"Resource": "*"
},
{
"Sid": "VisualEditor2",
"Effect": "Allow",
"Action": "codestar-connections:UseConnection",
"Resource": "*"
}
]
}
Please feel free to ask for any additional information...
Please give me some direction, I'm out of my depth here...
UPDATE 1
After #omuthu answer, I did check my pipeline policy (AWSCodePipelineServiceRole-eu-west-1-lambda-pipeline):
{
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "*",
"Condition": {
"StringEqualsIfExists": {
"iam:PassedToService": [
"cloudformation.amazonaws.com",
"elasticbeanstalk.amazonaws.com",
"ec2.amazonaws.com",
"ecs-tasks.amazonaws.com"
]
}
}
},
...
],
"Version": "2012-10-17"
}
and I see I already have iam:PassRole...
It is conditioned to services "cloudformation.amazonaws.com", "elasticbeanstalk.amazonaws.com", "ec2.amazonaws.com", "ecs-tasks.amazonaws.com"... Should I add some other services? Or better remove the condition?
UPDATE 2
I did try to remove the condition, with no different result.
UPDATE 3
#shariqmaws: I did export my pipeline (named "lambda-pipeline"); here it is:
{
"pipeline": {
"version": 1,
"artifactStore": {
"location": "codepipeline-eu-west-1-##########",
"type": "S3"
},
"roleArn": "arn:aws:iam::##########:role/service-role/AWSCodePipelineServiceRole-eu-west-1-lambda-pipeline",
"name": "lambda-pipeline",
"stages": [
{
"name": "Source",
"actions": [
{
"inputArtifacts": [],
"region": "eu-west-1",
"name": "Source",
"configuration": {
"PollForSourceChanges": "true",
"BranchName": "master",
"RepositoryName": "lambda-pipeline-repo"
},
"outputArtifacts": [
{
"name": "SourceArtifact"
}
],
"runOrder": 1,
"actionTypeId": {
"provider": "CodeCommit",
"owner": "AWS",
"version": "1",
"category": "Source"
}
}
]
},
{
"name": "Build",
"actions": [
{
"inputArtifacts": [
{
"name": "SourceArtifact"
}
],
"region": "eu-west-1",
"name": "Build",
"configuration": {
"ProjectName": "lambda-pipeline-build"
},
"outputArtifacts": [
{
"name": "BuildArtifact"
}
],
"runOrder": 1,
"actionTypeId": {
"provider": "CodeBuild",
"owner": "AWS",
"version": "1",
"category": "Build"
}
}
]
},
{
"name": "Deploy",
"actions": [
{
"inputArtifacts": [
{
"name": "BuildArtifact"
}
],
"region": "eu-west-1",
"name": "Deploy",
"configuration": {
"TemplatePath": "BuildArtifact::outputtemplate.yml",
"ActionMode": "CHANGE_SET_REPLACE",
"ChangeSetName": "lambda-pipeline-changeset",
"Capabilities": "CAPABILITY_IAM",
"RoleArn": "arn:aws:iam::##########:role/service-role/AWSCodePipelineServiceRole-eu-west-1-lambda-pipeline",
"StackName": "lambda-pipeline-stack"
},
"outputArtifacts": [],
"runOrder": 1,
"actionTypeId": {
"provider": "CloudFormation",
"owner": "AWS",
"version": "1",
"category": "Deploy"
}
}
]
}
]
},
"metadata": {
"updated": 1584382274.615,
"created": 1584382274.615,
"pipelineArn": "arn:aws:codepipeline:eu-west-1:##########:lambda-pipeline"
}
}
Can you find any issue with this pipeline? (and thanks for your help!)
UPDATE 4
#Shawn: I did read the document you pointed me to, and checked my configuration... I am in region eu-west-1, and it is enabled, as I see in my account settings:
Thanks for any comment...
Add iam:PassRole to your codepipeline policy as it tries to pass the role (attach the role) to lambda
Read more about it here
The problem is with the CloudFormation 'Deploy' action configuration:
"configuration": {
"TemplatePath": "BuildArtifact::outputtemplate.yml",
"ActionMode": "CHANGE_SET_REPLACE",
"ChangeSetName": "lambda-pipeline-changeset",
"Capabilities": "CAPABILITY_IAM",
"RoleArn": "arn:aws:iam::##########:role/service-role/AWSCodePipelineServiceRole-eu-west-1-lambda-pipeline",
"StackName": "lambda-pipeline-stack"
},
The 'RoleArn' above is a role in target account that CloudFormation will assume to execute the stack. Think of this role as the identity that will actually be creating the resources you have defined in the CloudFormation template. Now since CloudFormation service need to assume this role, the trust policy of this role should be for Cloudformation and NOT CodePipeline as it currently is.
Correct Trust Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "cloudformation.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Fix:
Create a new role for the CloudFormation service
Provide the permissions to this role that are required to create the resources defined in the template
Update the pipeline Action 'Deploy' in Stage 'Deploy' and set the RoleARN in configuration properties of this Action to the new role's ARN instead of "arn:aws:iam::##########:role/service-role/AWSCodePipelineServiceRole-eu-west-1-lambda-pipeline".

AWS IAM policy to allow Cloudformation actions

Originally asked on https://forums.aws.amazon.com/thread.jspa?messageID=825006#825006
I am trying to restrict certain actions to specific sources. For example, EC2 and Cloudformation should only be accessible from a certain source IP address. I am able to achieve this with the following policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": ["ec2:*", "cloudformation:*"],
"Resource": "*",
"Condition": {
"NotIpAddress": { "aws:SourceIp": ["1.2.3.4"] }
}
}
]
}
This works great (assuming there is an allow on ec2 and cloudformation without condition for the user) in that I can now create / view EC2 instances from source IP 1.2.3.4 but get errors trying from other sources.
However, if I try create a Cloudformation stack that contains an EC2 instance, the RunInstance action inherits my user account, but not my source IP. I would like to update the condition to allow Cloudformation source to be excluded from the Deny. I have tried this:
"Condition": {
"NotIpAddress": { "aws:SourceIp": ["1.2.3.4"] },
"StringNotEquals": {"aws:SourceIp":"cloudformation.amazonaws.com" }
}
}
I have also tried 2 Allow statements on those actions, each statement only having 1 condition - IpAddress with the sourceIp and the 2nd allow statement with "StringEquals" : {"aws:SourceIp":"cloudformation.amazonaws.com"} to those actions. I still get an error when CloudFormation tries to execute RunInstances action.
Here's the CloudTrail event showing the failure:
{
"eventVersion": "1.05",
"userIdentity": {
"type": "AssumedRole",
"principalId": "REDACTED",
"arn": "REDACTED",
"accountId": "REDACTED",
"sessionContext": {
"attributes": {
"creationDate": "2018-01-19T07:47:40Z"
},
"sessionIssuer": {
"type": "Role",
"principalId": "REDACTED",
"arn": "arn:aws:iam::REDACTED",
"accountId": "REDACTED",
"userName": "REDACTED"
}
},
"invokedBy": "cloudformation.amazonaws.com"
},
"eventTime": "2018-01-19T08:10:39Z",
"eventSource": "ec2.amazonaws.com",
"eventName": "RunInstances",
"awsRegion": "REDACTED",
"sourceIPAddress": "cloudformation.amazonaws.com",
"userAgent": "cloudformation.amazonaws.com",
"errorCode": "Client.UnauthorizedOperation",
"errorMessage": "You are not authorized to perform this operation. Encoded authorization failure message: REDACTED",
"requestParameters": { <details of instance here> },
"responseElements": null,
"requestID": "REDACTED",
"eventID": "REDACTED",
"eventType": "AwsApiCall",
"recipientAccountId": "REDACTED"
}
I have tried string matches on aws:SourceIp, aws:SourceIpAddress, aws:UserAgent - How can I allow ec2 actions to cloudformation?
Thanks.