I probably misunderstand something about IAM permissions. I need a Lambda function to generate STS tokens, and here is my terraform to do that:
resource "aws_iam_role" "cloudfront_logs_to_es_lambda_role" {
name = "cloudfront-logs-to-elasticsearch-test"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
},
{
"Sid": "AllowlambdaToAssumeRole",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::MY-ACCOUNT-ID:role/cloudfront-logs-to-elasticsearch-test"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
This code raises this error: MalformedPolicyDocument: Invalid principal in policy: "AWS":"arn:aws:iam::MY-ACCOUNT-ID:role/cloudfront-logs-to-elasticsearch-test"
I understand that I cannot put in the assume_role_policy a role that I am creating in the same time.
However, my question is: How can I attach this statement:
{
"Sid": "AllowlambdaToAssumeRole",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::MY-ACCOUNT-ID:role/cloudfront-logs-to-elasticsearch-test"
},
"Action": "sts:AssumeRole"
}
to the role, after creating the role.
The only way I could make my code work is by first making a terraform apply of:
resource "aws_iam_role" "cloudfront_logs_to_es_lambda_role" {
name = "cloudfront-logs-to-elasticsearch-${local.env_type}"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
And then making:
resource "aws_iam_role" "cloudfront_logs_to_es_lambda_role" {
name = "cloudfront-logs-to-elasticsearch-test"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
},
{
"Sid": "AllowlambdaToAssumeRole",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::MY-ACCOUNT-ID:role/cloudfront-logs-to-elasticsearch-test"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
Edit:
Here is the Python code that requires the role can assume itself for STS token generation:
sts = boto3.client("sts")
creds = sts.assume_role(RoleArn=terraform_role_arn, RoleSessionName="lambdastsassume")
Related
Im new to IAM policies. Trying to combine below two policies and make single one. The role is
AmazonEKSVPCCNIRole
below are two policies :
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
and
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "<arn-value>"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.us-east-1.amazonaws.com/id/<id>:sub": "system:serviceaccount:kube-system:aws-node",
"oidc.eks.us-east-1.amazonaws.com/id/<id>:aud": "sts.amazonaws.com"
}
}
}
]
}
i just need single policy combining above two policies. Im getting JSON error when trying to combine.
please help to create single policy
Can add the element in the statement array separated by comma. This is trust policy and not a normal policy.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "<arn-value>"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.us-east-1.amazonaws.com/id/<id>:sub": "system:serviceaccount:kube-system:aws-node",
"oidc.eks.us-east-1.amazonaws.com/id/<id>:aud": "sts.amazonaws.com"
}
}
},
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
I'm trying to create a job in AWS Glue using the Windows AWS Client and I'm receiving that I'm not authorized to perform: iam:PassRole as you can see:
Console>aws glue create-job --name "aws_glue_test" --role "My_Role" --command "Name=glueetlpythonshell,ScriptLocation=s3://mys3bucket/jobs/aws_glue_test.py,PythonVersion=3"
An error occurred (AccessDeniedException) when calling the CreateJob operation: User: arn:aws:iam::1111:user/My_User is not authorized to perform: iam:PassRole on resource: arn:aws:iam::1111:role/My_Role because no identity-based policy allows the iam:PassRole action
The configuration in AWS is set by using Terraform, something like this:
resource "aws_s3_bucket" "mys3bucket" {
bucket = "mys3bucket"
tags = {
Name = "mys3bucket"
ITOwnerEmail = "my#email.com"
}
}
resource "aws_s3_bucket_acl" "mys3bucket_acl" {
bucket = aws_s3_bucket.mys3bucket.id
acl = "private"
}
#=========IAM user======#
resource "aws_iam_user" "My_User" {
name = "My_User "
path = "/"
}
resource "aws_iam_user_policy" "My_User-p" {
name = "My_User-p"
user = "My_User"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::mys3bucket"
},
{
"Action": "glue:*",
"Effect": "Allow",
"Resource": "*"
},
#-- THIS IS THE SOLUTION -- #
{
"Action":[
"iam:GetRole",
"iam:PassRole"
],
"Effect":"Allow",
"Resource": "*"
}
]
}
EOF
}
#===========S3-Bucket-policy=======#
resource "aws_s3_bucket_policy" "mys3bucket-p" {
bucket = aws_s3_bucket.mys3bucket.id
policy = <<POLICY
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1111:user/My_User"
},
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::mys3bucket/*"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1111:user/My_User"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::mys3bucket"
}
]
}
POLICY
}
#===========Glue-policy=======#
resource "aws_iam_role" "My_Role" {
name = "My_Role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": [
"ec2.amazonaws.com",
"glue.amazonaws.com"
]
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
### Attach policy to above Role ###
resource "aws_iam_role_policy_attachment" "My_Role_GlueService_attach" {
role = aws_iam_role.My_Role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole"
}
#===========IAM-Pass-Role=======#
resource "aws_iam_policy" "My_IAMPass_policy" {
name = "My_IAMPass_policy"
description = "IAM Pass Role Policy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:GetRole",
"iam:PassRole"
],
"Resource": "arn:aws:iam::1111:role/My_Role"
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "My_IAMPass_attach" {
role = aws_iam_role.My_Role.name
policy_arn = aws_iam_policy.My_IAMPass_policy.arn
}
I tried to attach IAM Pass Role but it still failing and I don't know why.
Any help is welcomed. Thank you in advance
SOLUTION: Added in the Code.
You need to add iam:PassRole action to the policy of the IAM user that is being used to create-job. Something like:
{
"Action": [
"iam:PassRole"
],
"Effect": "Allow",
"Resource": [
"arn:aws:iam::1111:role/My_Role"
],
"Condition": {
"StringLike": {
"iam:PassedToService": [
"glue.amazonaws.com"
]
}
}
}
I'm having issues with calling a lambda in account B from a different lambda in account A.
Account A's role arn is arn:aws:iam::ACCOUNT_A:role/DeviceApiStack-simServiceRole427DA44E-1WS2T3INIV6IP
Account A's role name is DeviceApiStack-simServiceRole427DA44E-1WS2T3INIV6IP
Account B's role name is Chris-APIStack1-Q6AJ1PZ8V-LambdaCrossAccountExecut-1N3JU88L5AON1
Account B's role arn is arn:aws:lambda:us-east-1:462087996972:function:GetActiveDeviceIdsLambdaChris
For account A my lambda role has the following permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::ACCOUNT_B:role/Chris-APIStack1-Q6AJ1PZ8V-LambdaCrossAccountExecut-1N3JU88L5AON1",
"Effect": "Allow"
},
{
"Action": "lambda:InvokeFunction",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:iam::ACCOUNT_B:role/Chris-APIStack1-Q6AJ1PZ8V-LambdaCrossAccountExecut-1N3JU88L5AON1",
"Effect": "Allow"
}
]
}
My lambda in account B has the following role as defined using cloudformation:
"CrossAccountExecutionRoleDemo": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:sts::ACCOUNT_A:role/DeviceApiStack-simServiceRole427DA44E-1WS2T3INIV6IP"
},
"Action": "sts:AssumeRole"
},
{
"Effect": "Allow",
"Principal": { "Service": ["lambda.amazonaws.com"] },
"Action": ["sts:AssumeRole"]
}
]
}
}
},
"CrossAccountExecutionPolicyDemo": {
"Type": "AWS::IAM::ManagedPolicy",
"Properties": {
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "lambda:InvokeFunction",
"Resource": { "Fn::GetAtt": ["GetActiveDeviceIdsLambdaDemo", "Arn"] }
}
]
},
"Roles": [
{
"Ref": "CrossAccountExecutionRoleDemo"
}
]
}
}
When I make the following request I get an error
let roleArn = 'arn:aws:iam::ACCOUNT_B:role/Chris-APIStack1-Q6AJ1PZ8V-CrossAccountExecutionRol-1ANKXFZ6YS23'
sts.assumeRole(
{
RoleArn: roleArn,
RoleSessionName: 'NightlySimService',
}, function(err, res){ ... }
Error:
'
AccessDenied: User: arn:aws:sts::ACCOUNT_A:assumed-role/DeviceApiStack-simServiceRole427DA44E-1WS2T3INIV6IP/DeviceApiStack-nightlySimServiceLambdaA51B2AFE-JSUFU8F5BZGC is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::ACCOUNT_B:role/Chris-APIStack1-Q6AJ1PZ8V-CrossAccountExecutionRol-1ANKXFZ6YS23F
'
I can spot two apparent issues in the roles, which could be the cause of your errors.
First. Incorrect principle:
"Principal": {
"AWS": "arn:aws:sts::ACCOUNT_A:role/DeviceApiStack-simServiceRole427DA44E-1WS2T3INIV6IP"
},
As you wrote the role arn is arn:aws:iam::ACCOUNT_A:role/DeviceApiStack-simServiceRole427DA44E-1WS2T3INIV6IP, which does not match of what you provided in the Principal.
Second. Incorrect resource:
{
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:iam::ACCOUNT_B:role/Chris-APIStack1-Q6AJ1PZ8V-LambdaCrossAccountExecut-1N3JU88L5AON1",
"Effect": "Allow"
}
The action lambda:InvokeFunction applies to lambda functions, not IAM roles. Thus, the Resource should be ARN of the lambda.
There could be more issues, which are not that obvious at present.
i have the following policy on an IAM role which i'm assuming into:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::mybucket/${aws:RequestTag/personalid}/*"
}
]
}
When performing assume role, i'm passing the tag:
response = sts_client.assume_role(
RoleArn=arn,
RoleSessionName=role_session_name,
Tags=[
{
'Key': 'personalid',
'Value':'a'
},
])
but i get access denied when trying to read an object under folder 'a':
s3 = boto3.resource(
's3',
aws_access_key_id=response['Credentials']['AccessKeyId'],
aws_secret_access_key=response['Credentials']['SecretAccessKey'],
aws_session_token=response['Credentials']['SessionToken'],
region_name=client_main_region
)
obj = s3.Object('mybucket', f'a/file.txt')
print(obj.get()['Body'].read().decode('utf-8'))
I've replaced the policy with "principalTag", while adding a tag to the role, and it works - what am i doing wrong?
=====
Another thing i tried, is to tag the s3 object with that ID, and with the following policy:
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Condition": {
"StringEqualsIfExists": {
"aws:RequestTag/personalid": "${s3:ExistingObjectTag/personalid}"
}
},
"Resource": "arn:aws:s3:::mybucket/*"
}
Not working
If anyone ever looks for this - apparently the trust relationship should declare those tags - so they will be available:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123:role/lambda_role"
},
"Action": "sts:AssumeRole"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123:role/lambda_role"
},
"Action": "sts:TagSession",
"Condition": {
"StringLike": {
"aws:RequestTag/personalid": "*"
}
}
}
]
}
Then, i could use this tag as principal tag in the assumed role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::mybucket/${aws:PrincipalTag/personalid}/*"
}
]
}
I'm attempting to attach an aws_iam_role_policy to an aws_iam_role using Terraform variables: ${aws_iam_role.AutoTagMasterRole.id}
I'm using the TF docs found at: iam_role_policy.html
Terraform error message:
aws_iam_role_policy.AutoTagMasterPolicy: Resource
'aws_iam_role.AutoTagMasterRole' not found for variable
'aws_iam_role.AutoTagMasterRole.arn'
Here's my Terraform configuration:
resource "aws_iam_role_policy" "AutoTagMasterPolicy" {
name = "AutoTagMasterPolicy"
role = "${aws_iam_role.AutoTagMasterRole.id}"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketTagging",
"s3:PutBucketTagging",
"ec2:CreateTags",
"elasticloadbalancing:AddTags",
"autoscaling:CreateOrUpdateTags",
"rds:AddTagsToResource",
"elasticmapreduce:AddTags",
"datapipeline:AddTags"
],
"Resource": [
"*"
]
}
]
}
EOF
}
resource "aws_iam_role" "AutoTagMasterRole" {
name = "AutoTagMasterRole"
path = "/gorillastack/autotag/master/"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": { "${aws_iam_role.AutoTagExecutionRole.arn}" }
},
"Action": [
"sts:AssumeRole"
]
}
]
}
EOF
}
Can someone tell me what it is I've done incorrectly?
UPDATE I've been told this relates to my attempt at porting the cloudformation function to it's equivalent in terraform.
This is what cloudformation lists:
"Principal": {
"AWS" : { "Fn::GetAtt" : [ "AutoTagExecutionRole", "Arn" ] }
},
I am trying to find the equivalent in terraform. This is what I used, but it's throwing the error.
"Principal": {
"AWS": { "${aws_iam_role.AutoTagExecutionRole.arn}" }
}
The definition of Principal is wrong in aws_iam_role
Here is the sample for you.
resource "aws_iam_role" "test_role" {
name = "test_role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
So your codes should be changed to
resource "aws_iam_role" "AutoTagMasterRole" {
name = "AutoTagMasterRole"
path = "/gorillastack/autotag/master/"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": [
"sts:AssumeRole"
]
}
]
}
EOF
}
Refer: terraform aws_iam_role
After troubleshooting realized I had incorrect syntax:
"Principal": {
"AWS": { "${aws_iam_role.AutoTagExecutionRole.arn}" }
},
Should be:
"Principal": {
"AWS": "${aws_iam_role.AutoTagExecutionRole.arn}"
},
The incorrect syntax (although not accurately reported by Terraform) caused the aws_iam_role to fail writing to the tf.state file which caused the error message reporting the failure to find the resources.