snyk / driftctl

Detect, track and alert on infrastructure drift
Apache License 2.0
2.48k stars 160 forks source link

Assume multiple roles with aws providers #1173

Open ichasco-heytrade opened 3 years ago

ichasco-heytrade commented 3 years ago

Hi, I have a problem. In my case, I use multiple AWS providers with different assumed roles:

# ROOT

provider "aws" {
  alias  = "root"
  region = var.region
  assume_role {
    role_arn     = "arn:aws:iam::XXXXXXXXXX:role/Terraform-Role"
    session_name = "root-terraform"
  }
}

# DEVOPS

provider "aws" {
  alias  = "devops"
  region = var.region
  assume_role {
    role_arn     = "arn:aws:iam::XXXXXXXXXX:role/Terraform-Role"
    session_name = "devops-terraform"
  }
}

# NETWORKING

provider "aws" {
  alias  = "networking"
  region = var.region
  assume_role {
    role_arn     = "arn:aws:iam::XXXXXXXXXX:role/Terraform-Role"
    session_name = "networking-terraform"
  }
}

And the user who runs the terraform is able to assume these roles. Is there any way to do this with driftctl?

Now I am getting 403 in every resources.

Thanks!

eliecharra commented 3 years ago

Hi @ichasco-heytrade thanks for your interest in driftctl 🙏🏻

Are you running driftctl with the same user that you use in your terraform workflow ?

Have you tried the recommended way to setup driftctl authentication ? We recommend to setup a dedicated user with read-only access policy, you can find more details here : https://docs.driftctl.com/0.15.0/providers/aws/authentication

ichasco-heytrade commented 3 years ago

Hi @eliecharra. Yes I am using the same user as in terraform workflow. The problem I think that is driftctl can't read the assumed roles from terraform provider. Is there anyway to assume multiple users?

Thanks!

wbeuil commented 3 years ago

Hey @ichasco-heytrade, thanks for opening this issue. I will test it on my side and get back to you asap with a review.

wbeuil commented 3 years ago

@ichasco-heytrade I tested with this simple use case:

provider "aws" {
  alias = "ec2"
  region  = "us-east-2"
  assume_role {
    role_arn     = "arn:aws:iam::XXX:role/ec2_assume_role" #AmazonEC2FullAccess policy
    session_name = "ec2-terraform"
  }
}

provider "aws" {
  alias = "sqs"
  region  = "us-east-2"
  assume_role {
    role_arn     = "arn:aws:iam::XXX:role/sqs_assume_role" #AmazonSQSFullAccess policy
    session_name = "sqs-terraform"
  }
}

resource "aws_instance" "foo" {
  provider = aws.ec2
  ami           = "ami-074cce78125f09d61"
  instance_type = "t2.micro"
  availability_zone = "us-east-2a"
}

resource "aws_sqs_queue" "foo" {
  provider = aws.sqs
  name = "foo"
}

Terraform works well if I run AWS_PROFILE=user terraform plan. Indeed like you said, it is possible to output a plan with one user assuming multiple roles.

From driftctl point of view, it is not yet possible. If I try to run AWS_PROFILE=user driftctl scan, it will output just like you only 403 errors. Because when you run the scan command we're only using the shared credentials of this user without assuming any roles, thus having all these 403 errors.

At this point, if you want to try with just assuming one role, you could create a named profile as per our documentation:

# .aws/config file
[profile ec2]
role_arn = arn:aws:iam::XXX:role/ec2_assume_role
source_profile = user
region = us-east-2

Run after that AWS_PROFILE=ec2 driftctl scan (we use the newly created profile). It will scan for all ec2 related resources of your states, and will output 403 for the rest.

I will open a bug issue for this kind of use case. I hope I answer your question.

ichasco-heytrade commented 3 years ago

Thanks for the work around @wbeuil, but for the moment doesn't work for my pipeline. I'll wait to see if this enhancement can be done :) If you need some help to test anything. Please ask me

eliecharra commented 2 years ago

@wbeuil We may want to keep one of this one or #1177 if I understand well ? These two issues sounds as duplicates WDYT ?

wbeuil commented 2 years ago

Yep I duplicate the issue, we can keep only one of them.

prein commented 2 years ago

Should it be possible to use credential_source to get the cred from env vars instead of source_profile? Is it related to https://github.com/aws/aws-cli/issues/3875 ?

spr-mweber3 commented 2 years ago

I need this feature, too.

jurgen-weber-deltatre commented 2 years ago

Yeah, so I can see two ways to do this.. Actually follow the TF way but that might be hard OR you could create a reconciliation mechanic in the CLI tool.

what I mean by that is, go and run the drift against all of your states for all of the accounts. These results would have 'this is missing' but else where 'this is not covered by the code'... give it all of the results to reconcile, etc.

sergeyshevch commented 1 year ago

I have the same issue. I have states where resources from multiple accounts exist. In driftctl it will appear as missing.

datfinesoul commented 1 year ago

In general, the lack of alias provider support is pretty much the main reason I've not been able to adopt driftctl anywhere. Having this fixed would be fantastic since about 95% of all Terraform stacks I work with use alias providers with assume_role.

jurgen-weber-deltatre commented 1 year ago

totally agree, the idea is great but the lack of this feature mean it is not viable.