I want to create a AWS Cross account role using boto3. Created the role from Console. But not able to create using boto3. I have two different AWS Accounts. I want to access one account from other using Assume Role. For that i need to create a permission in Account 1 so that Account 2 can access the same. But, I need to perform all the functionality using boto3 only.I used this code -
iam = boto3.client('iam',aws_access_key_id='XXXXX',aws_secret_access_key='YYYY')
role = iam.create_role(RoleName=<Role Name>,AssumeRolePolicyDocument='{"Version" : "2012-10-17","Statement": [{"Effect": "Allow","Principal":{"AWS":"arn:aws:iam::<Account ID to which permission is granted>:root"} ,"Action":["sts:AssumeRole" ]}]}')
policy = iam.create_policy(PolicyName=<Policy Name>, PolicyDocument='{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Action": "*","Resource": "*"}]}')
policy_arn = policy['Policy']['Arn']
iam.attach_role_policy(PolicyArn=<Policy arn>,RoleName=<Name of the role to which policy need to be attached>)
Can this code be more optimized, may be lesser calls
no optimizing required. code working fine.
In order to assume a role of account A from account B, here is the procedure.
In account A create a role with the following trust relationship.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "Root arn of the account B"
},
"Action": "sts:AssumeRole"
}
]
}
Save the above json in one of the file. Then write a function to create a role using this above trust relationship.
import boto3
role_name = "Name of the role"
client = boto3.client('iam')
client.create_role(RoleName=role_name,
AssumeRolePolicyDocument=trust_relationship())
def trust_relationship(self, role_name):
with open('json_file_name', 'r') as data_file:
trust_relationship = json.load(data_file)
return json.dumps(trust_relationship)
Now in account B, create a role with the following json document, to assume the role of account A.
Policy Document:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": [
"sts:AssumeRole",
"Any other required actions"
],
"Resource": "*"
}
]
}
Now use this policy document to attach to the role in account B which then assumes the role of account A.
Related
Context:
At the moment I manually create a Policy and Role in the stag account (destination) to allow devops group users from the root account to list all S3 objects taht live in stag account. What I need to do is that, get rid of manual Policy and Role creation process in the stag account to have a configuration in Terraform which handles it as usual.
So far I tried replicating some examples that I've seen on the web but the problem is, most of them duplicate users in all accounts which is not fit for my setup. On the other hand, when I follow some other examples, the Policy and Role is created in the root account rather than the stag account. As a result using role_arn = arn:aws:iam::222222222222:role/devops in CLI config for john gives me An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::111111111111:user/john is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::222222222222:role/devops. I would greatly appreciate it if someone would help me out with this.
Setup:
The root (111111111111) account is dedicated to IAM groups and users only, nothing else.
There is user john who is part of devops group.
The stag (222222222222) account is dedicated to S3 only (for now), not for IAM groups or users.
There are many buckets.
Requirement:
Allow john to run $ aws s3 ls to list all objects in all S3 buckets.
Manually created policy in stag account
# arn:aws:iam::222222222222:policy/devops-role-permissions
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
Manually created role in stag account
# arn:aws:iam::222222222222:role/devops
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Principal": {
"AWS": "arn:aws:iam::111111111111:root"
}
}
]
}
Terraform root policy config
resource "aws_iam_policy" "devops_role_assumption_in_stag_account" {
name = "devops-role-assumption-in-stag-account"
description = "Allows devops group to assume role in stag account."
policy = jsonencode(
{
"Version" : "2012-10-17",
"Statement" : [
{
"Effect" : "Allow",
"Action" : "sts:AssumeRole",
"Resource" : "arn:aws:iam::222222222222:role/devops"
}
]
}
)
}
Terraform root group policy attachment config
resource "aws_iam_group_policy_attachment" "devops_role_assumption_in_stag_account" {
group = aws_iam_group.devops.name
policy_arn = aws_iam_policy.devops_role_assumption_in_stag_account.arn
}
{
"Version": "2012-10-17",
"Id": "Policy1612574490300",
"Statement": [
{
"Sid": "Stmt1612574488073",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:ec2:us-east-1:258977512672:instance/i-041123c1993c370ba"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my_bucket",
"arn:aws:s3:::my_bucket/*"
]
}
]
}
response is Invalid Principal. I dont see why it's invalid.
An EC2 instance isn't a valid principal. I think what you actually need to do here is use the ARN of the IAM role assigned to the EC2 instance.
You can specify following Principal in a policy
AWS account and root user
IAM users
Federated users (using web identity or SAML federation)
IAM roles
Assumed-role sessions
AWS services
Anonymous users (not recommended)
S3 Documentation Principal
AWS JSON policy elements: Principal
If you wanna give that instant access to the bucket then you can use Instance profiles
I have created a role to get objects from s3 bucket as below:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "S3GetObjects",
"Effect": "Allow",
"Action": [
"s3:Get*"
],
"Resource": [
"arn:aws:s3:::cat-pics",
"arn:aws:s3:::cat-pics/"
]
}
]
}
Next, created a lambda function to assume this role. For that added the following statement to the basic lambda execution role which is attached to lambda:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::same-account-id:role/AssumeS3RoleDemo"
}
]
}
However, the following code
import json
import boto3
def lambda_handler(event, context):
print("this test should be printed")
# create an STS client object that represents a live connection to the
# STS service
sts_client = boto3.client('sts')
# Call the assume_role method of the STSConnection object and pass the role
# ARN and a role session name.
assumed_role_object=sts_client.assume_role(
RoleArn="arn:aws:iam::same-account-id:role/AssumeS3RoleDemo",
RoleSessionName="AssumeRoleSession"
)
# From the response that contains the assumed role, get the temporary
# credentials that can be used to make subsequent API calls
credentials=assumed_role_object['Credentials']
print("credentials are")
print(credentials)
does not work. I keep getting the following error:
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:sts::same-account-id:assumed-role/lambda_basic_execution_new/AssumeRoleDemo is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::same-account-id:role/AssumeS3RoleDemo: ClientError
Here AssumeRoleDemo is name of the lambda function and AssumeS3RoleDemo is the role name which has access to S3.
Is it possible to assume role in the same account ? Is so, what step am I missing here ? Please let me know.
thanks
You need amend the role with trust policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
In addition to that make sure your S3 bucket doesnt have a bucket policy. Because resource based policy and IAM based policies both should be allowing.
You don't need to use STS and AssumeRole in your lambda code to access S3 if both are in the same account, if role attached to lambda has policy allowing access on S3 it will work just fine.
But if you really want to do it, you need to make sure your role AssumeS3RoleDemo trust policy allow lambda execution role to assume it.
Below is a link to one exemplo using two different accounts, but the mechanism is the same using just one account:
https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-assume-iam-role/#:~:text=1.,the%20role%20in%20account%20B%3A&text=Update%20your%20Lambda%20function%20code,to%20create%20a%20service%20client.
I'm trying to follow the instructions in How can I allow a Group to assume a Role?, but run into the following error when I try to switch roles:
Invalid information in one or more fields. Check your information or contact your administrator.
In this scenario I have three AWS Accounts with example ids
CompanyMain - 000000000001
CompanyProd - 000000000002
CompanyDev - 000000000003
Where the main account has an organization that includes the the prod and dev accounts
What I'd like to do is set up a single set of IAM users on the main account and allow them to login and switch between either of the two subaccounts, instead of forcing everyone to have three separate logins.
Here's what I've done so far all on the CompanyMain account:
Create Role for accessing Prod Account
Set trusted Entity to "Another AWS Account"
Set Permission Policy to AdministratorAccess
So when I go to Role > "Trust Relationship" > Show Policy Document - it looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::000000000002:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
With the name "company-prod-admin" so the ARN is like this:
arn:aws:iam::000000000001:role/company-prod-admin
This also comes with the link to switch roles as follows:
https://signin.aws.amazon.com/switchrole?roleName=company-prod-admin&account=000000000001
Create a Policy to Assume this Role
Service: STS
Actions: AssumeRole
Role ARN: arn:aws:iam::000000000001:role/company-prod-admin
So the Policy Document looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::000000000002:root"
}
]
}
Create Admin Group
Create a group on the main account called admin and attach the policy we just created
Create IAM User
Create user on the main account and place in admin group
Sign in as IAM User
I can now sign in as an IAM user against the main account
From there, I'd like to switch roles by using the role link or going to https://signin.aws.amazon.com/switchrole and entering the account / role info
However, I get the error that the following info is invalid
Org Setup Question
How can I create roles that across organizations? I'm a little confused as to where the role / permission needs to originate between the three accounts, but ideally I'd like to have a way for someone to login to one set of permissions for the whole organization.
You need to do the IAM policy the other way around if you want to be able to access the CompanyProd from CompanyMain then you need to create a IAM policy in the CompanyProd like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::000000000001:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
Next you login into the MainCompany and go to switch role.
in the Account, you write 000000000002, in the Role field you write root.
In S3, can we create an IAM user and give it rights to create other IAM users?
S3 and IAM are 2 different AWS services. S3 has nothing to do with IAM user creation.
I'll go ahead and assume that you meant creating an IAM user with permissions to create other users.
Yes, it is possible to do so. You just have to attach a suitable IAM policy to the newly created user. Following policy should get you started.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"iam:CreateUser",
"iam:CreateAccessKey"
],
"Resource": "*"
}
]
}
The policy specified by Maverick in the above answer can create a new user and create access and secret keys for the user. However, it cannot create or attach any policies to the created user. So, I'm adding the required permission to create and attach IAM and inline policies for IAM users.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:AttachUserPolicy",
"iam:CreateAccessKey",
"iam:CreatePolicy",
"iam:CreateUser",
"iam:PutUserPolicy"
],
"Resource": "*"
}
]
}
Refer this for more information about actions related to Identity and Access Management (IAM) in AWS: https://docs.aws.amazon.com/IAM/latest/UserGuide/list_identityandaccessmanagement.html