-
Notifications
You must be signed in to change notification settings - Fork 9.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Determining a minimal IAM policy required to perform a terraform run #2834
Comments
+1 for this. I'm getting this error If I give the AWS user full access then |
Here is an attempt to parse out what each resource does, even though some resources are chained. It is in Resource:Actions format, and the Actions are the actions in aws go lib, rather than ec2 actions but they correlate very closely. Might be of help |
Thanks for the response @gtmtech unfortunately I can't make sense of that but I appreciate you trying to help. |
I'm still working on something a bit more coherent for my usecase - hopefully it will be useful to you too.. will keep you posted |
Excellent thanks @gtmtech |
This is great stuff, and would be awesome to have included in the docs somewhere as it gets fleshed out.
|
In working on this myself, I realised that in practice you want to define multiple terraform policies, otherwise terraform is just too much of a powerful tool and you could accidentally wreck your infrastructure if not careful. As such, with the aws resources I use, I've defined a "terraform builder" policy which allows my team to build stuff, and a separate "terraform destroyer" policy, which allows people to destroy stuff, and must be used with much greater caution (imagine for example accidentally destroying all your production databases). I've gone through the code for the resources I use, and split up the actions into CREATE, READ, UPDATE, DELETE (CRUD) operations. A terraform builder policy would then typically be the amalgamation of the CREATE+READ rules. Perhaps a terraform updater policy could be the CREATE+READ+UPDATE rules, and finally the destroyer policy would be READ+UPDATE+DELETE. I would suggest that we build a database of files (one per aws_resource in terraform), that document the CREATE,READ,UPDATE,DELETE ec2 IAM rules which must be allowed for terraform to do its job, then a simple tool or addition to the terraform cmdline could spit out your minimal IAM policy. It's not perfect of course - for example when terraform creates a security group, it also revokes the default security group rule , which is a DELETE level operation, so in order to create stuff, you do need a couple of delete privileges. But I've found overall this really protects the infrastructure and the team from mishaps - because in our infrastructure now, it is impossible to accidentally delete what we've built. Anyway, here are the list of rules I've managed to do so far - there may be a couple of bugs, but its a start. CSV format. The 4th column is the most interested, and you can simply filter by the aws resources you use, and the CRUD operations you want with a simple grep
|
Please provide this as part of the docs/repo so that policy can be generated as needed. |
That's pretty excellent @gtmtech. Would really like to see official support for this. |
oh, neat. AWS has a maximum policy size limit of 2k. so if you've got an even moderately-sized terraform config for AWS you've basically gotta just wildcard everything. :-( |
@blalor my IAM skills aren't very sharp... anyways, perhaps you can use a short Deny to allow TF to do most things but deny deletes?
*edit: corrected myself after not reading far enough ahead.. d'oh |
Thanks, Steve. I'll give that a look. I was also thinking that resource groups may be a thing to limit scope (allow the iam user to only manage resources tagged with a particular environment), but that inky seems to apply to the console. Maybe I'm thinking of something else.
|
Ah, this is what I was thinking of: http://blogs.aws.amazon.com/security/post/Tx29HCT3ABL7LP3/Resource-level-Permissions-for-EC2-Controlling-Management-Access-on-Specific-Ins |
So, reading through that, policy documents can be bigger, depending on how they're used (ie policies attached to users are limited to 2k, but managed policies are I think 5k). I'm using Vault's AWS secret backend to create a user with the required permissions to apply Terraform configs, and that doesn't currently seem to support managed policies. |
Hi Guys, Was able to launch instance with the following policy.
|
Here is a script to convert the CSV policies list as extracted by @gtmtech into AWS JSON format: https://gist.github.com/lkraider/65fae06e8b71ef593c403db2e9f7f7bf |
I was able to generate the JSON policies, but they are too big to use :( |
@gtmtech Thanks so much for the csv export. Incase anyone else needs a quick and easy way to process it, I'm using the wonderful E.g. the following will generate a json array of all csvgrep -c 3 -r "^CREATE" policies.csv | csvcut -c 4 | sort -u | csvjson | jq '{Action: [.[] | .["PolicyRule Required"]]}' |
The way I approached this problem was by creating an instance with terraform using a policy that was too lenient. Then, I checked the affected resources logged through CloudTrail. The result was a policy that looked like this: {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ec2:RunInstances",
"ec2:StartInstances"
],
"Effect": "Allow",
"Resource": [
"arn:aws:ec2:::instance/*",
"arn:aws:ec2:::network-interface/eni-hexadeci",
"arn:aws:ec2:::subnet/subnet-hexadeci",
"arn:aws:ec2:::security-group/sg-hexadeci",
"arn:aws:ec2:::key-pair/name_of_key",
"arn:aws:ec2:region::image/ami-hexadeci"
]
},
{
"Action": [
"ec2:Describe*",
"ec2:CreateTags",
"ec2:CreateVolume",
"ec2:RegisterImage",
"ec2:CreateImage",
"ec2:CopyImage",
"ec2:CreateSnapshot",
"ec2:DeleteSnapshot",
"ec2:DetachVolume",
"ec2:ModifyImageAttribute"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"ec2:StopInstances",
"ec2:TerminateInstances"
],
"Condition": {
"StringEquals": {
"ec2:ResourceTag/provisioned_by": "ci"
}
},
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"ec2:StopInstances",
"ec2:TerminateInstances"
],
"Condition": {
"StringLike": {
"ec2:ResourceTag/environment": [
"prod",
"qa",
"stage",
"automation"
]
}
},
"Effect": "Deny",
"Resource": "*"
}
]
} Since |
There are some great suggestions here, although they are very limited in scope (e.g. just spinning up an instance). I still think there's mileage in generating a role specific to the resources you are actually using, with a higher level terraform command. (or jq wizardry as above) To the commenter above, you can have multiple policies attached to a role (when you run out of space), so this wasnt a problem for us. (You can ask AWS about this). In the end, we did enough to have some level of confidence that if the role got into the wrong hands, people still aren't going to be able to delete some of the critical infrastructure in production, and accompanied with terraform's own lifecycle prevent_destroy, and other backup/DR options, thats at least 3 levels of protection. I'd like to see some fundamental terraform support for the generation of an iam role - just as there is a well documented one in packer. |
It seems like this sort of thing would necessarily be provider-specific rather than something Terraform could handle generically, so I think I'd be inclined to try to model this as a data source in the AWS provider: data "aws_terraform_resource_policy" "example" {
resources = ["aws_elb", "aws_instance", "aws_security_group"]
}
resource "aws_iam_policy" "example" {
# ...
policy = "${data.aws_terraform_resource_policy.example.json}"
} My idea here is that the data source produces a JSON policy that has enough access to CRUD the resource types listed. This is not a complete solution as-specified, though. For example, I expect it would be pretty common to want to constrain the access to subsets of the given resources... for example, to create resources only within a particular VPC. Perhaps the logical conclusion of this is just an extra attribute on the existing |
Just came across this today, thanks for the great list @gtmtech. I took that and created some IAM Policy Document resources from them as a starting point for myself (and others). Seems like it's doing what we need although I'm sure there always going to be adjustments and new resources to be added. Here are my 4 policies if anyone else wants to use them: https://gist.github.com/arsdehnel/70e292467ced2a39f472ddca44629c08 By posting these I take no legal responsibility whatsoever if they have some security loophole in them that allows someone to take down your entire infrastructure. They're just a starting point :) |
Also wanted to note that I got that same error @gilesbutler and adding the |
Hi all thanks for your efforts so far, It would be really good if we could get a list of policy actions that each terraform resource needs to execute. For example: something like this: aws_security_groups How can I determine what each resource needs? Thanks |
@richardbowden Is the policy I shared not sufficient? It was the bare minimum permissions required for it to work. |
might it be possible to have terraform print the privileges it needs for the actions it' trying to complete when it fails? I would think you could make a map for each attempted change to a privilege. |
Only if the AWS API responds with it. Sometimes it does and sometimes it doesn't. TF won't inherently know what it needs, that's an AWS thing. |
:/ I was thinking since TF is designing itself to manage these things presumably it could maintain a map of privileges required... per resource maintained... although I can see that getting ridiculous fast |
I could imagine terraform keeping track of which AWS APIs it will call (and
how) in a first-class manner so that we could deduce the IAM policy from
that. There are subtleties (e.g., PassRole or KMS stuff) but a list of all
API actions is a good starting point.
…On Sun, Mar 12, 2017 at 00:36 Caleb Cushing ***@***.***> wrote:
:/ I was thinking since TF is designing itself to manage these things
presumably it could maintain a map of privileges required... per resource
maintained... although I can see that getting ridiculous fast
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#2834 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAAKP17Bj-FUgvtgBZlK1n1gUOFxO2xdks5rk4RagaJpZM4FeqJO>
.
|
heck, even just emitting the last api called would be helpful, probably has had 80% of what I needed to figure out which permission failed, and then a ton of other less useful information. If it said Id just called s3/GetBucketLogging on error... well I bet there's a perm that corresponds to that. 2017/03/12 06:51:06 [DEBUG] plugin: terraform: aws-provider (internal) 2017/03/12 06:51:06 [DEBUG] [aws-sdk-go] DEBUG: Response s3/GetBucketLogging Details: |
Hi everyone! Thanks to @gtmtech for introducing this request and to everyone else for the great discussion on it in the mean time. After spending some time thinking about this, we've concluded that this is a non-trivial problem to solve due to the many and varied capabililties of IAM across all of the AWS services and the difficulty of predicting the right granularity for a policy. Therefore we (the Terraform team) are not planning to move forward with any specific feature in this area, and instead suggest that people should refer to the AWS documentation to get the full details about the various possibilities for granting access to each AWS action. However, we know that right now it's often hard to determine from the Terraform documentation exactly what actions are being executed for a given resource, and thus know how to map what's in the AWS documentation. In future we'd like to add additional information to the documentation for various resources to be a bit more explicit about what actions are being executed, though that is a big project and not something that's going to happen against a single, broad issue like this one. So with all of that said, I'm going to close this issue as part of our effort to prune issues that don't have a clear short-term action plan. If there are resources with particularly-hairy policy requirements we would be happy to review small PRs to update the relevant documentation. |
being a total newbie maybe I miss the point.
|
@dhoffi That definitely works, but the point is to give the minimal access required, so as to limit the damage that can be caused if you accidentally apply something you didn't intend to (or worse, if someone else gets a hold of the access keys). |
@gtmtech Love the list. If you put it on github somewhere we can crowd source the remaining entries. As you started the list, would you like to do the honours? If you are too busy I would be happy to. I would b every interested in being able to extract the resources programmatically as well but that is one step further. Walking would be a good start. |
It really seems like it should be able to parse a script and spit out an IAM policy (or Role) that define what exactly it needs, essentially doing a dry run against possible states (Might recreate the resource, change it, or make one from scratch, etc...). The concern isn't even necessarily terraform so much as giving the credentials using terraform power they don't need. |
Thanks! That helped a lot. I still got an authorized when creating VPC even though I got AmazonEC2FullAccess , AmazonSSMFullAccess , AmazonVPCFullAccess.
|
You probably want to triple check that you dont have an explicit deny of some sort somewhere in your Terraform. |
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. |
I am trying to create a minimal IAM policy which can govern the CRUD of my defined terraform resources in AWS, so I can run terraform with my configuration.
I couldn't find any guidance on this, so I started off by creating an IAM policy with no access, hooking up cloudtrail and cloudwatch logs, and then going through the creation of a VPC (as an example), and watching for what actions were unauthorized, and slowly piecing together an IAM profile which would allow terraform to CRUD a VPC.
The job of tracking which Actions need to be allowed would be made a lot easier if under TF_LOG=true, the debugger would print out which action it was trying to do at the point it got a NotAuthorized.
It also struck me that by looking at the terraform code, that these are all available from the terraform code itself, if you can be bothered to walk through it ...
e.g.
conn.CreateVPC
conn.DescribeVPCAttribute
conn.DescribeRouteTables
I wonder if relevant IAM policies could be autogenerated somehow from this.
In any case a little line of debug present would help millions.
Thanks
The text was updated successfully, but these errors were encountered: