I'm trying to solve this mystery for few days now, but no joy. Basically, Terraform cannot assume role and failing with:
Initializing the backend...
2019/10/28 09:13:09 [DEBUG] New state was assigned lineage "136dca1a-b46b-1e64-0ef2-efd6799b4ebc"
2019/10/28 09:13:09 [INFO] Setting AWS metadata API timeout to 100ms
2019/10/28 09:13:09 [INFO] Ignoring AWS metadata API endpoint at default location as it doesn't return any instance-id
2019/10/28 09:13:09 [INFO] AWS Auth provider used: "SharedCredentialsProvider"
2019/10/28 09:13:09 [INFO] Attempting to AssumeRole arn:aws:iam::72xxxxxxxxxx:role/terraform-admin-np (SessionName: "terra_cnp", ExternalId: "", Policy: "")
Error: The role "arn:aws:iam::72xxxxxxxxxx:role/terraform-admin-np" 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
In AWS:
I have role: terraform-admin-np with 2 AWS managed policy: AmazonS3FullAccess & AdministratorAccess and a trust relationship with this:
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::72xxxxxxxxxx:root"
},
"Action": "sts:AssumeRole"
}
]
}
Then I have an user with policy document attached:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "TfFullAccessSts",
"Effect": "Allow",
"Action": [
"sts:AssumeRole",
"sts:DecodeAuthorizationMessage",
"sts:AssumeRoleWithSAML",
"sts:AssumeRoleWithWebIdentity"
],
"Resource": "*"
},
{
"Sid": "TfFullAccessAll",
"Effect": "Allow",
"Action": "*",
"Resource": [
"*",
"arn:aws:ec2:region:account:network-interface/*"
]
}
]
}
and a S3 bucket: txxxxxxxxxxxxxxte with this policy document attached:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "TFStateListBucket",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::72xxxxxxxxxx:root"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::txxxxxxxxxxxxxxte"
},
{
"Sid": "TFStateGetPutObject",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::72xxxxxxxxxx:root"
},
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::txxxxxxxxxxxxxxte/*"
}
]
}
In Terraform:
The snippet from the provider.tf:
###---- Default Backend and Provider config values -----------###
terraform {
required_version = ">= 0.12"
backend "s3" {
encrypt = true
}
}
provider "aws" {
region = var.region
version = "~> 2.20"
profile = var.profile
assume_role {
role_arn = var.role_arn
session_name = var.session_name
}
}
Snippet from tgw_cnp.tfvars backend config:
## S3 backend config
key = "backend/tgw_cnp_state"
bucket = "txxxxxxxxxxxxxxte"
region = "us-east-2"
profile = "local-tgw"
role_arn = "arn:aws:iam::72xxxxxxxxxx:role/terraform-admin-np"
session_name = "terra_cnp"
and then running this way:
TF_LOG=debug terraform init -backend-config=tgw_cnp.tfvars
With this, I can assume role using AWS CLI without any issue:
# aws --profile local-tgw sts assume-role --role-arn "arn:aws:iam::72xxxxxxxxxx:role/terraform-admin-np" --role-session-name AWSCLI
{
"Credentials": {
"AccessKeyId": "AXXXXXXXXXXXXXXXXXXA",
"SecretAccessKey": "UixxxxxxxxxxxxxxxxxxxxxxxxxxxxMt",
"SessionToken": "FQoGZXIvYXdzEJb//////////wEaD......./5LFwNWf6riiNw9vtBQ==",
"Expiration": "2019-10-28T13:39:41Z"
},
"AssumedRoleUser": {
"AssumedRoleId": "AROA2P7ZON5TSWMOBQEBC:AWSCLI",
"Arn": "arn:aws:sts::72xxxxxxxxxx:assumed-role/terraform-admin-np/AWSCLI"
}
}
but terraform fails with the above error. Any idea what's I'm doing wrong?
Okay, answering to my own question........
It worked now. I have had a silly mistake - the region in tgw_cnp.tfvars was wrong, which I was keep missing out. In AWS CLI as I didn't have to specify the region (it was getting it from the profile), so it worked without any issue but in TF I specified the region and the value was wrong, hence the failure. The suggestions in the error reporting was a bit misleading.
I can confirm the above config works fine. It's all good now.
Related
Hey im trying to cross account access for a role. i have 2 accounts: prod and non-prod.
and bucket in prod account, which im trying to write files to there from a non-prod role which is used as a service account in k8s cluster.
in prod account i configured:
a role with the following policy(read write access to the bucket):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListObjectsInBucket",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::test2"
]
},
{
"Sid": "AllObjectActions",
"Effect": "Allow",
"Action": "s3:*Object",
"Resource": [
"arn:aws:s3:::test2/*"
]
}
]
}
and the following trust:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::non-prod-AccountID:role/name-of-the-non-prod-role"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
in non prod i configured:
a role with the following policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::prod-Account-ID:role/prod-role-name"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
and trust as follows:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::non-prod-accountID:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/1111111111111111111"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.us-east-1.amazonaws.com/id/1111111111111111111:sub":
"system:serviceaccount:name-space:name-of-the-service-account"
}
}
}
]
}
serviceAccount annotation is:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::non-prod-AccountID:role/non-prod-role-name
when running the command from inside the pod with the service account of the role in non-prod:
aws s3 cp hello.txt s3://test2/hello.txt
im having:
upload failed: ./hello.txt to s3://test2/hello.txt An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
by the way the cluster is in another account (devops account) if its related, surely added OIDC provider identity to both non-prod and prod accounts as identity provider.
If you're getting the error An error occurred (InvalidIdentityToken) when calling the AssumeRoleWithWebIdentity operation: No OpenIDConnect provider found in your account for $oidc_url when trying to cross-account assume roles, but you can assume roles in your cluster account normally, here's some points:
EKS ACCOUNT
Create a ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: $sa_name
namespace: $eks_ns
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::$resource_account_id:role/$role_name
Annotate your deployment
spec.template.spec:
serviceAccountName: $sa_name
Get info about your cluster OIDC Provider
aws iam get-open-id-connect-provider --open-id-connect-provider-arn arn:aws:iam::$eks_cluster_account_id:oidc-provider/$oidc_provider
3.1. The output will be like:
{
"Url": "...",
"ClientIDList": ["..."],
"ThumbprintList": ["..."],
"CreateDate": "...",
"Tags": [...]
}
3.2. Take note of the outputs (Url and ThumbprintList specially)
RESOURCE ACCOUNT
Add the provider (if you don`t have it already), using the output from your cluster account
aws iam create-open-id-connect-provider --url $oidc_url --client-id-list sts.amazonaws.com --thumbprint-list $oidc_thumbprint
This should be enought to the mentioned error stop. If you now get An error occurred (AccessDenied) when calling the AssumeRoleWithWebIdentity operation: Not authorized to perform sts:AssumeRoleWithWebIdentity, you're problably using the $eks_cluster_account_id on Principal.Federated, instead of $resource_account_id created on the previous step. So, make sure you're using the ARN from the IP that is assigned to the resource account, not the cluster account.
Create a role and a policy to access your resources with following trusted entities policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::$resource_account_id:oidc-provider/$oidc_provider"
},
"Action": "sts:AssumeRoleWithWebIdentity"
}
]
}
Also, there's no need to have two roles. One is enough.
Problem
I'm trying to enable audit logging on an AWS redshift cluster. I've been following the instructions provided by AWS here: https://docs.aws.amazon.com/redshift/latest/mgmt/db-auditing.html#db-auditing-enable-logging
Current Configuration
I've defined the relevant IAM role as follows
resource "aws_iam_role" "example-role" {
name = "example-role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "redshift.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
And have granted the following IAM permissions to the example-role role:
{
"Sid": "AllowAccessForAuditLogging",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetBucketAcl"
],
"Resource": [
"arn:aws:s3:::example-bucket",
"arn:aws:s3:::example-bucket/*"
]
},
The relevant portion of the redshift cluster configuration is as follows:
resource "aws_redshift_cluster" "example-cluster-name" {
cluster_identifier = "example-cluster-name"
...
# redshift audit logging to S3
logging {
enable = true
bucket_name = "example-bucket-name"
}
master_username = var.master_username
iam_roles = [aws_iam_role.example-role.arn]
...
Error
terraform plan runs correctly, and produces the expected plan based on the above configuration. However, when running terraform apply the following error occurs:
Error: error enabling Redshift Cluster (example-cluster-name) logging: InsufficientS3BucketPolicyFault: Cannot read ACLs of bucket example-bucket-name. Please ensure that your IAM permissions are set up correctly.
note: i've replaced all resource identifiers with example-* resource names and identifiers.
#shimo's answer is correct. I just detail for someone like me
Redshift has full access to S3. But you need add bucket policy too. ( S3's permission)
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::361669875840:user/logs"
},
"Action": [
"s3:GetBucketAcl",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::<your-bucket>",
"arn:aws:s3:::<your-bucket>/*"
]
}
- `361669875840` is match with your region check [here][1]
[1]: https://github.com/finos/compliant-financial-infrastructure/blob/main/aws/redshift/redshift_template_public.yml
Goal:
Create an IAM role policy that allows the role to perform defined actions on aws resources only if the role tag equals the resource tag.
For example:
IAM tag:
foo=bar
CodeBuild project tag:
foo=bar
IAM role policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"codebuild:List*",
"codebuild:DescribeTestCases",
"codebuild:DescribeCodeCoverages",
"codebuild:BatchGet*"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/foo": "${aws:PrincipalTag/foo}"
}
}
}
]
}
When the user assumes the role, the user is denied access to codebuild:ListProjects on projects that have the same foo=bar key pair as the role within the AWS console and AWS CLI.
AWS console error:
User: arn:aws:sts::123456789:assumed-role/example-role/example-user is not authorized to perform: codebuild:ListProjects
AWS CLI error using the command: aws codebuild list-projects --profile test
An error occurred (AccessDeniedException) when calling the ListProjects operation: User: arn:aws:sts::123456789:assumed-role/example-role/botocore-session-59458209 is not authorized to perform: codebuild:ListProjects
Attempts:
#1
Use actual key pair value in policy condition:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"codebuild:List*",
"codebuild:DescribeTestCases",
"codebuild:DescribeCodeCoverages",
"codebuild:BatchGet*"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/foo": "bar"
}
}
}
]
}
Result to codebuild:ListProjects access denied error on aws console
#2
Remove aws key brackets from aws:PrincipalTag/foo(shooting from the hip here)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"codebuild:List*",
"codebuild:DescribeTestCases",
"codebuild:DescribeCodeCoverages",
"codebuild:BatchGet*"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/foo": "aws:PrincipalTag/foo"
}
}
}
]
}
#3
Used the resource type within the resource tag condition codebuild:ResourceTag/foo
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"codebuild:List*",
"codebuild:DescribeTestCases",
"codebuild:DescribeCodeCoverages",
"codebuild:BatchGet*"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"codebuild:ResourceTag/foo": "${aws:PrincipalTag/foo}"
}
}
}
]
}
Same codebuild:ListProjects access denied error on aws console
From docs:
CodeBuild supports authorization based on tags for project-based actions
I think ListProjects action is not project-based. It is for entire codebuild, rather then for a specific project.
I'm following a tutorial where I assume roles on EC2 instances so it has access to services. I'm following this tutorial (https://medium.com/swlh/aws-iam-assuming-an-iam-role-from-an-ec2-instance-882081386c49), but I'm stuck on the cli part when I start running a "aws s3 ls". Just so I know it works, I gave the AssumedRole all access to s3.
This is my setup:
ImplicitRole // will be attached to EC2
policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::xxx:role/*"
}
]
}
AssumedRole // will be the role assumed once logged in to EC2
policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::*"
]
}
]
}
What happens is I would run the following on cli
aws sts assume-role --role-arn arn:aws:iam::****:role/AssumedRole --role-session-name test-session
Then I will get the Credentials
{
"Credentials": {
"AccessKeyId": "key",
"SecretAccessKey": "secret",
"SessionToken": "longtoken",
"Expiration": "2020-07-08T07:29:51+00:00"
},
"AssumedRoleUser": {
"AssumedRoleId": "AKDIEEOOKDLKSDJFDJ:test-session",
"Arn": "arn:aws:sts::xxxx:assumed-role/AssumedRole/test-session"
}
}
and then will update the variables eg: set AWS_ACCESS_KEY_ID=XXXX , etc
Once done I run the following but it would give me ListObject AccessDenied
aws s3 ls s3://bucket
An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
Im trying to setup a redshift cluster and an IAM role that will have access to the cluster. I am using terraform for this. According the documentation I need to create a Service role and attach the AmazonS3ReadOnlyAccess policy to it. I have the following config in my terraform script:
resource "aws_iam_role" "my_admin_role" {
name = "my-role"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*",
"redshift:*"
],
"Resource": "*"
}
]
}
EOF
}
However this gives me an error:
Errors:
* aws_iam_role.my_admin_role: "assume_role_policy": required field is not set
* aws_iam_role.my_admin_role: : invalid or unknown key: policy
How do I setup a service role for redshift ?
You mix the resources aws_iam_role and aws_iam_role_policy
Sample usage of resource aws_iam_role
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
}
Sample usage of resource aws_iam_role_policy
resource "aws_iam_role_policy" "test_policy" {
name = "test_policy"
role = "${aws_iam_role.test_role.id}"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ec2:Describe*"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
EOF
}