I'm trying to run AWS CLI commands using a different profile:
.aws$ cat config
[default]
region = us-east-1
output = json
[profile secondaccount]
role_arn = arn:aws:iam::<SECOND_ACCOUNT_ID>:role/admin
source_profile = default
.aws$ cat credentials
[default]
aws_access_key_id = ID
aws_secret_access_key = KEY
The SECOND_ACCOUNT has admin role (access to all resources) that has Trust Relationship to allow any users from FIRST_ACCOUNT to assume it.
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<FIRST_ACCOUNT>:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
My account on the FIRST_ACCOUNT also has policy to assume role:
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "*"
}
]
I can switch role using the console.
I have tried to attach policies directly to my username on the FIRST_ACCOUNT to have sts:assumeRole.
I've tried to attach my user ARN from the FIRST_ACCOUNT to the Trust Relationship of the admin role of the SECOND_ACCOUNT.
There's no explicit DENY attached to my username.
I've tried adding the admin role of the SECOND_ACCOUNT to both my .aws/config and .aws/credentials.
However, I can't switch to another profile using the CLI:
$ aws s3 ls --profile secondaccount
An error occurred (AccessDenied) when calling the AssumeRole operation: Access denied
I've tried what suggested here, here, here, and here
So I've found the solution from an AWS post.
The issue:
In the Trust Relationships of the SECOND_ACCOUNT admin, there's the condition:
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
that means it requires token from MFA to execute CLI commands.
So I did:
$ aws sts get-session-token --serial-number MFA_NUM --token-code CODE_FROM_MFA
{
"Credentials": {
"AccessKeyId": ID,
"SecretAccessKey": KEY,
"SessionToken": TOKEN,
"Expiration": "2019-07-12T01:14:07Z"
}
}
Then I added to the .aws/credentials:
[mfa]
aws_access_key_id = ID_FROM_ABOVE
aws_secret_access_key = KEY_FROM_ABOVE
aws_session_token = TOKEN_FROM_ABOVE
Then edited the .aws/config:
[mfa]
output = json
region = us-east-1
[profile secondaccount]
role_arn = arn:aws:iam::<SECOND_ACCOUNT_ID>:role/admin
source_profile = mfa
Then I was able to run CLI commands with --profile secondaccount.
If you choose to do this way which is AWS best practice, AWS recommends that having a script to automate the process of getting new token.
If you're "lazy", remove the condition in the Trust Relationship.
In order for secondaccount to assume the admin role, it must use the credentials from your default profile. In the provided example your default profile doesn't have access keys defined, hence it can't magically assume role in the secondaccount. For instance
[default]
region = us-east-1
aws_access_key_id=AKIAJQZVTAZXBSTXXXX
aws_secret_access=MYSECRERACCESS
output = json
[profile secondaccount]
role_arn = arn:aws:iam::<SECOND_ACCOUNT_ID>:role/admin
source_profile = default
It works for you in the console, because you're using username+password combination login before assuming target role, whereas for CLI you suppose to provide access key + secret key to do that
Related
I'm trying to create a new IAM role and attach the S3 Read only Access policy but when I'm running the below code. I'm getting the following error: An error occurred (InvalidClientTokenId) when calling the CreateRole operation: The security token included in the request is invalid.
I have set up the correct aws access key and security key in the configuration file but still I'm not able to get through this error.
Code for creating the IAM role.
try:
print('1.1 Creating a new IAM Role')
dwhRole = iam.create_role(
Path='/',
RoleName=DWH_IAM_ROLE_NAME,
Description='Allows Redshift clusters to call AWS services on your behalf.',
AssumeRolePolicyDocument=json.dumps({
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "redshift.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}),
)
except Exception as e:
print(e)
# TODO: Attach Policy
print('1.2 Attaching Policy')
iam.attach_role_policy(RoleName=DWH_IAM_ROLE_NAME,
PolicyArn="arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
)['ResponseMetadata']['HTTPStatusCode']
# TODO: Get and print the IAM role ARN
print('1.3 Get the IAM role ARN')
roleArn = iam.get_role(RoleName=DWH_IAM_ROLE_NAME)['Role']['Arn']
print(roleArn)
DWH_IAM_ROLE_NAME is a variable which is defined the configuration file as well.
First, unset the below env variables:-
unset AWS_ACCESS_KEY_ID
unset AWS_SECRET_ACCESS_KEY
unset AWS_SESSION_TOKEN
Get a new session token and save it or copy it to your clipboard:-
aws sts get-session-token
Run the below command and it is ask for SECRET KEY, ID, TOKEN
aws configure
Finally, re-run your script.
I am trying to assign a role to a user using the AWS console but not having a whole lot of success with it. So i created a user David and i created a role with a trust policy in which i am assigning the David i.e. IAM user as the principal which looks like this :-
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::Account-ID:user/David"
},
"Action": "sts:AssumeRole"
}
]
}
and i also attached a policy to the role which lets the user listbuckets and getobject. The policy looks like this :-
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Allowsusertotolistbuckets",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::*"
}
]
}
Now when i run aws configure and authenticate as David user with the right access key and secret access key and run aws s3 ls. I run into the following: An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied. How can i have the user assume the role. Any help will be appreciated.
IAM Roles are not 'attached' to a user. Rather, an IAM User can be permitted to assume an IAM Role.
Using the AWS CLI, they would assume an IAM Role like this:
aws sts assume-role --role-arn arn:aws:iam::123456789012:role/xaccounts3access --role-session-name s3-access-example
In response, AWS STS will return a set of temporary credentials:
{
"AssumedRoleUser": {
"AssumedRoleId": "AROA3XFRBF535PLBIFPI4:s3-access-example",
"Arn": "arn:aws:sts::123456789012:assumed-role/xaccounts3access/s3-access-example"
},
"Credentials": {
"SecretAccessKey": "9drTJvcXLB89EXAMPLELB8923FB892xMFI",
"SessionToken": "AQoXdzELDDY//////////wEaoAK1wvxJY12r2IrDFT2IvAzTCn3zHoZ7YNtpiQLF0MqZye/qwjzP2iEXAMPLEbw/m3hsj8VBTkPORGvr9jM5sgP+w9IZWZnU+LWhmg+a5fDi2oTGUYcdg9uexQ4mtCHIHfi4citgqZTgco40Yqr4lIlo4V2b2Dyauk0eYFNebHtYlFVgAUj+7Indz3LU0aTWk1WKIjHmmMCIoTkyYp/k7kUG7moeEYKSitwQIi6Gjn+nyzM+PtoA3685ixzv0R7i5rjQi0YE0lf1oeie3bDiNHncmzosRM6SFiPzSvp6h/32xQuZsjcypmwsPSDtTPYcs0+YN/8BRi2/IcrxSpnWEXAMPLEXSDFTAQAM6Dl9zR0tXoybnlrZIwMLlMi1Kcgo5OytwU=",
"Expiration": "2016-03-15T00:05:07Z",
"AccessKeyId": "ASIAJEXAMPLEXEG2JICEA"
}
}
These credentials can then be used to call AWS service 'as the IAM Role' rather than 'as the IAM User'.
See: assume-role — AWS CLI Command Reference
To make things easier, it is possible to define a profile that uses an IAM Role. The AWS CLI will automatically use IAM User credentials to call AssumeRole(), then use the resulting credentials to make the desired API call.
Here is an example profile entry:
[profile marketingadmin]
role_arn = arn:aws:iam::123456789012:role/marketingadminrole
source_profile = user1
This is saying: "Use the IAM User credentials from profile user1 to call AssumeRole() on the marketingadminrole"
It can then be used like this:
aws s3 ls s3://marketing-bucket --profile marketingadmin
See: Using an IAM role in the AWS CLI - AWS Command Line Interface
I am trying to use aws cli to run some commands. I do not have a user account in the target region, but I am trying to use a role called "AssumedAdministrator" which has sts:assumerole.
I can log into the aws web console OK using the "switch role" option.
but when I run a CLI command like :
aws --profile $profile sts get-caller-identity --region $region
I am getting the following error:
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::111111111111:user/john.smith is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::222222222222:role/AssumedAdministrator
Here's the Trusted Entities tied to that role:
AssumedAdministrator role
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "false"
}
}
}
]
}
What am I doing wrong? How can I run aws cli commands
my sections in the credentials file:
[default]
aws_access_key_id = ##########################
aws_secret_access_key = ############################
region = ##########
[assumed-#####-admin]
role_arn = arn:aws:iam::222222222222:role/AssumedAdministrator
source_profile = default
Thanks
I'm trying to run terraform plan locally with a non-default aws credentials profile, where my default profile will not work. I also need to use assume_role in terraform provider "aws". My code looks something like this:
provider "aws" {
version = "~> 2.45"
region = "us-east-1"
profile = <profile name>
allowed_account_ids = [<account_id>]
assume_role {
role_arn = "arn:aws:iam::<account id>:role/<role name>"
}
}
The error I'm getting is:
Error: The role "arn:aws:iam::<account_id>:role/<role_name>" cannot be assumed.
There are a number of possible causes of this - the most common are:
* The credentials used in order to assume the role are invalid
* The credentials do not have appropriate permission to assume the role
* The role ARN is not valid
Interestingly, when I put access_key and secret_key in the provider like this:
provider "aws" {
version = "~> 2.45"
region = "us-east-1"
access_key = <aws access key>
secret_key = <aws secret key>
assume_role {
role_arn = "arn:aws:iam::<account_id>:role/<role_name>"
}
}
terraform plan works fine. I've double checked my aws credentials file several time and it's setup correctly, but I'm not sure why terraform plan doesn't work.
I've also tried deleting the assume_role parameter in provider "aws" when i have access_key and secret_key in the file, and terraform plan works fine, which means i don't need the assume_role. however, if i use the profile from aws credentials without assume_role in terraform file, i'm getting:
Error: error using credentials to get account ID: error calling sts:GetCallerIdentity: SignatureDoesNotMatch: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
status code: 403, request id:
You need amend the Trust Policy on the IAM Role like below
How to use trust policies with IAM roles
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:user/<Your username>"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
Once you update the Trust Policy on the IAM Role you can verify this via assume-role command
aws sts assume-role --role-arn arn:aws:iam::123456789012:role/xaccounts3access --role-session-name s3-access-example
You would receive something like:
{
"AssumedRoleUser": {
"AssumedRoleId": "AROA3XFRBF535PLBIFPI4:s3-access-example",
"Arn": "arn:aws:sts::123456789012:assumed-role/xaccounts3access/s3-access-example"
},
"Credentials": {
"SecretAccessKey": "9drTJvcXLB89EXAMPLELB8923FB892xMFI",
"SessionToken": "AQoXdzELDDY//////////wEaoAK1wvxJY12r2IrDFT2IvAzTCn3zHoZ7YNtpiQLF0MqZye/qwjzP2iEXAMPLEbw/m3hsj8VBTkPORGvr9jM5sgP+w9IZWZnU+LWhmg+a5fDi2oTGUYcdg9uexQ4mtCHIHfi4citgqZTgco40Yqr4lIlo4V2b2Dyauk0eYFNebHtYlFVgAUj+7Indz3LU0aTWk1WKIjHmmMCIoTkyYp/k7kUG7moeEYKSitwQIi6Gjn+nyzM+PtoA3685ixzv0R7i5rjQi0YE0lf1oeie3bDiNHncmzosRM6SFiPzSvp6h/32xQuZsjcypmwsPSDtTPYcs0+YN/8BRi2/IcrxSpnWEXAMPLEXSDFTAQAM6Dl9zR0tXoybnlrZIwMLlMi1Kcgo5OytwU=",
"Expiration": "2016-03-15T00:05:07Z",
"AccessKeyId": "ASIAJEXAMPLEXEG2JICEA"
}
}
You also have to specify the role arn on the backend.tf:
terraform {
backend "s3" {
bucket = "your_bucket"
key = "your_key"
region = "us-east-1" (or whataver is the one you're using)
role_arn = "arn:aws:iam::<account_id>:role/<role_name>"
}
}
I want to perform MFA for Terraform so it's expected to ask the 6-digit token from my virtual MFA device for every terraform [command]. After reading the documentation:
cli-roles
terraform mfa
I created a role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[ACCOUNT_ID]:user/testuser"
},
"Action": "sts:AssumeRole",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}
This user is forced to use MFA by default and I have a configured virtual MFA device for him.
~/.aws/credentials:
[default]
...
[terraform_role]
role_arn = arn:aws:iam::[ACCOUNT_ID]:role/terraform-test-role
source_profile = default
mfa_serial = arn:aws:iam::[ACCOUNT_ID]:mfa/testuser
in my Terraform environment I placed the following:
provider "aws" {
profile = "terraform_role"
}
But when i run terraform plan it throws me an error:
Error refreshing state: 1 error(s) occurred:
* provider.aws: No valid credential sources found for AWS Provider.
Please see https://terraform.io/docs/providers/aws/index.html for more information on
providing credentials for the AWS Provider
The solution is to specify an assume_role statement:
provider "aws" {
profile = "default"
assume_role {
role_arn = "arn:aws:iam::[ACCOUNT_ID]:role/terraform-test-role"
}
}
Unfortunately, the assume_role statement by itself is not a working solution. You need to use a MFA authentication wrapper aws-runas that eases the process not only of assuming the role but providing support for the mfa_serial clause on the .aws/credentials file.
In short, there are 3 steps:
You'll need to have your .aws/credentials file as you have.
Install aws-runas
Run the apply: aws-runas [your_profile] - terraform apply