Creating IAM policy and role in destination account - amazon-web-services

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
}

Related

Unable to use terraform with AWS IAM role with MFA configuration

My organisation uses a gateway account for which i have aws credentials.
We also have our personal account, in order to access our personal account users in gateway account assume IAM roles ( created in the personal account).
With such configuration i am trying to create terraform resource but somehow keep on getting error -> Error: operation error STS: AssumeRole, https response error StatusCode: 403, RequestID: xxxxxxx, api error AccessDenied: User: arn:aws:iam::xxxxxx:user/xx-xxxxxx is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::xxxxxxx2:role/xxxxxx
Here is the provider configuration i am trying.
provider "aws" {
alias = "mad"
profile = "personal account"
region = "ap-south-1"
assume_role {
role_arn = "arn:aws:iam::xxxxxxx:role/personal account"
}
}
Update :- the role uses mfa too.
Personal account has trust relationship which allows gatgeway account iam user to assume to role.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::gateway-account-id:user/user"
},
"Action": "sts:AssumeRole",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}
The user user/xx-xxxxxx which you use to run the TF script which is going to assume role role/xxxxxx must have sts:AssumeRole.
You can add such permission to the user, by adding the following inline policy to it:
{
"Effect": "Allow",
"Action": [
"sts:AssumeRole"
],
"Resource": [
"arn:aws:iam::xxxxxxx2:role/xxxxxx"
]
}
UPDATE
Also for MFA you need to use token option in your provider configuration, or use any of the workarounds provided in TF github issue.

Configure AWS Role to switch between Organization Accounts

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.

How to set proper IAM role(s) for an AWS Batch job?

I have a job that, after submission to the Batch service, goes from RUNNABLE to FAILED state, with the following job status error message (from AWS Console):
ECS was unable to assume the role 'arn:aws:iam::347134692569:role/my-custom-role' that was provided for this task. Please verify that the role being passed has the proper trust relationship and permissions and that your IAM user has permissions to pass this role.
The role referenced above is managed with Terraform, with two policy attachments (AWSBatchServiceRole and AmazonEC2ContainerServiceforEC2Role) like so:
resource "aws_iam_role" "batch" {
name = "my-custom-role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement":
[
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "batch.amazonaws.com"
}
},
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
}
},
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "ecs.amazonaws.com"
}
}
]
}
EOF
tags = {
Terraform = "true"
}
}
# attach a policy to the role that allows using AWS Batch service
resource "aws_iam_role_policy_attachment" "batch_service_role" {
role = data.aws_iam_role.batch.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSBatchServiceRole"
}
# attach a policy to the role that allows using AWS Elastic Container service
resource "aws_iam_role_policy_attachment" "elastic_container_service_role" {
role = aws_iam_role.batch.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role"
}
The above role is used as the compute environment's service role as well as the job role for job definition.
It seems that the above doesn't provide sufficient permission to enable assuming the role and/or necessary trust relationship(s). What else can I try to get past this error?
Based on the comments, the issue was solved by adding ecs-tasks.amazonaws.com as a principle for AssumeRole.
Seems that same permissions were required as those for ECS task execution role and the task:
Amazon ECS Task Execution IAM Role
IAM Roles for Tasks

API Gateway resource policy: specify IAM role as AWS principal

I am trying to setup an API Gateway endpoint with a resource policy, which allows access to a specific IAM role in my account. The IAM role is cross-account, setup with a trust policy which allows AssumeRole to a specific IAM user principal from another account.
In the API Gateway resource policy, when I set AWS principal to the role ARN: arn:aws:iam::********:role/myRole, I get the following 403 error when invoking the API:
User: arn:aws:sts::********:assumed-role/myRole/mySession is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-west-2:********:********/test/POST/echo
But, if I change the AWS principal to be the temporary STS user ARN: arn:aws:sts::********:assumed-role/myRole/mySession, then I can invoke the API successfully.
Here's the resource policy that doesn't work:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::********:role/myRole"
},
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-west-2:********:********/*"
}
]
}
Here's the resource policy that works:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:sts::********:assumed-role/myRole/mySession"
},
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-west-2:********:********/*"
}
]
}
Can IAM roles be used as AWS principals for API Gateway resource policy?
Based on the documentation https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-policy-language-overview.html,
Principal – The account or user who is allowed access to the actions
and resources in the statement. In a resource policy, the principal is
the IAM user or account who is the recipient of this permission.
Looks like roles cannot be added as a principal.
P.S: Spent two days trying to restrict access using roles, but couldn't get it to work.

Cross Account access Role creation for AWS Account using boto3

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.