[英]What's the most efficient way to determine the minimum AWS permissions necessary for a Terraform configuration?
I have a Terraform configuration targeting deployment on AWS.我有一个针对 AWS 上的部署的 Terraform 配置。 It applies beautifully when using an IAM user that has permission to do anything (ie
{actions: ["*"], resources: ["*"]}
.它适用于使用有权执行任何操作的 IAM 用户(即
{actions: ["*"], resources: ["*"]}
。
In pursuit of automating the application of this Terraform configuration, I want to determine the minimum set of permissions necessary to apply the configuration initially and effect subsequent changes.为了实现此 Terraform 配置应用的自动化,我想确定最初应用配置和影响后续更改所需的最小权限集。 I specifically want to avoid giving overbroad permissions in policy, eg
{actions: ["s3:*"], resources: ["*"]}
.我特别想避免在策略中给予过于宽泛的权限,例如
{actions: ["s3:*"], resources: ["*"]}
。
So far, I'm simply running terraform apply
until an error occurs.到目前为止,我只是在运行
terraform apply
直到出现错误。 I look at the output or at the terraform log output to see what API call failed and then add it to the deployment user policy.我查看输出或 terraform 日志输出以查看失败的 API 调用,然后将其添加到部署用户策略中。 EC2 and S3 are particularly frustrating because the name of the actions seems to not necessarily align with the API method name.
EC2 和 S3 特别令人沮丧,因为操作的名称似乎不一定与 API 方法名称一致。 I'm several hours into this with easy way to tell how far long I am.
我花了几个小时来用简单的方法来判断我走了多远。
Is there a more efficient way to do this?有没有更有效的方法来做到这一点?
It'd be really nice if Terraform advised me what permission/action I need but that's a product enhancement best left to Hashicorp.如果 Terraform 告诉我我需要什么样的权限/操作,那就太好了,但这是最好留给 Hashicorp 的产品增强功能。
Here is another approach, similar to what was said above, but without getting into CloudTrail -这是另一种方法,类似于上面所说的,但没有进入 CloudTrail -
TF_LOG=trace terraform apply --auto-approve &> log.log
TF_LOG=trace terraform apply --auto-approve &> log.log
cat log.log | grep "DEBUG: Request"
cat log.log | grep "DEBUG: Request"
cat log.log | grep "DEBUG: Request"
You will get a list of all AWS Actions used.您将获得所有使用的 AWS 操作的列表。
EDIT Feb 2022: there is a better way using iamlive and client side monitoring.编辑 2022 年 2 月:使用 iamlive 和客户端监控有更好的方法。 Please see my other answer.
请看我的另一个回答。
As I guess that there's no perfect solution, treat this answer a bit as result of my brain storming.因为我猜没有完美的解决方案,所以把这个答案当作我头脑风暴的结果。 At least for the initial permission setup, I could imagine the following:
至少对于初始权限设置,我可以想象以下内容:
Allow everything first and then process the CloudTrail logs to see, which API calls were made in a terraform apply
/ destroy
cycle.首先允许所有内容,然后处理 CloudTrail 日志以查看在
terraform apply
/ destroy
循环中进行了哪些 API 调用。
Afterwards, you update the IAM policy to include exactly these calls.之后,您更新 IAM 策略以准确包含这些调用。
While I still believe that such super strict policy will be a continuous pain and likely kill productivity (but might depend on the project), there is now a tool for this.虽然我仍然相信这种超级严格的政策将是一个持续的痛苦并且可能会扼杀生产力(但可能取决于项目),但现在有一个工具可以做到这一点。
iamlive uses the Client Side Monitoring feature of the AWS SDK to create a minimal policy based on the executed API calls. iamlive使用 AWS 开发工具包的客户端监控功能根据执行的 API 调用创建最小策略。 As Terraform uses the AWS SDK, this works here as well.
由于 Terraform 使用 AWS 开发工具包,这也适用于此。
In contrast to my previous (and accepted) answer, iamlive should even get the actual IAM actions right, which not necessarily match the API calls 1:1 (and which would be logged by CloudTrail).与我之前(并接受)的答案相反,iamlive 甚至应该正确执行实际的 IAM 操作,这些操作不一定与 API 调用 1:1 匹配(并且将由 CloudTrail 记录)。
The way I deal with is, allow all permissions (*) for that service first, then deny some of them if not required.我的处理方式是,首先允许该服务的所有权限 (*),然后在不需要的情况下拒绝其中的一些权限。
For example例如
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSpecifics",
"Action": [
"ec2:*",
"rds:*",
"s3:*",
"sns:*",
"sqs:*",
"iam:*",
"elasticloadbalancing:*",
"autoscaling:*",
"cloudwatch:*",
"cloudfront:*",
"route53:*",
"ecr:*",
"logs:*",
"ecs:*",
"application-autoscaling:*",
"logs:*",
"events:*",
"elasticache:*",
"es:*",
"kms:*",
"dynamodb:*"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Sid": "DenySpecifics",
"Action": [
"iam:*User*",
"iam:*Login*",
"iam:*Group*",
"iam:*Provider*",
"aws-portal:*",
"budgets:*",
"config:*",
"directconnect:*",
"aws-marketplace:*",
"aws-marketplace-management:*",
"ec2:*ReservedInstances*"
],
"Effect": "Deny",
"Resource": "*"
}
]
}
You can easily adjust the list in Deny session, if terraform doesn't need or your company doesn't use some aws services.如果不需要 terraform 或您的公司不使用某些 aws 服务,您可以在拒绝会话中轻松调整列表。
The tracking of minimum permissions is now provided by AWS itself.最低权限的跟踪现在由 AWS 自己提供。 https://aws.amazon.com/blogs/security/iam-access-analyzer-makes-it-easier-to-implement-least-privilege-permissions-by-generating-iam-policies-based-on-access-activity/ .
https://aws.amazon.com/blogs/security/iam-access-analyzer-makes-it-easier-to-implement-least-privilege-permissions-by-generating-iam-policies-based-on-access-活动/ 。
If you wanted to be picky about the minimum viable permission principle, you could use CloudFormation StackSets to deploy different roles with minimum permissions, so Terraform could assume them on each module call via different providers, ie if you have a module that deploys ASGs, LBs and EC2 instances, then:如果您想对最小可行权限原则挑剔,您可以使用 CloudFormation StackSets 以最小权限部署不同的角色,因此 Terraform 可以通过不同的提供者在每个模块调用中承担它们,即如果您有一个部署 ASG、LB 的模块和 EC2 实例,然后:
The burden is to manage possibly quite a few terraform roles, but as I said, if you want to be picky or you have customer requirements to shrink down terraform user's permissions.负担是管理可能相当多的 Terraform 角色,但正如我所说,如果您想挑剔或者您有客户要求缩小 Terraform 用户的权限。
You could also download the CloudTrail event history for the last X days (up to 90) and run the following:您还可以下载最近 X 天(最多 90 天)的 CloudTrail 事件历史记录并运行以下命令:
cat event_history.json <(echo "]}") | jq '[.Records[] | .eventName] | unique'
The echo thing is due to the file being too big and shrunk (unknown reason) when downloaded from CloudTrail's page.回声是由于从 CloudTrail 的页面下载时文件太大和缩小(未知原因)。 You can see it below:
你可以在下面看到它:
> jsonlint event_history.json
Error: Parse error on line 1:
...iam.amazonaws.com"}}
-----------------------^
Expecting ',', ']', got 'EOF'
at Object.parseError (/usr/local/Cellar/jsonlint/1.6.0/libexec/lib/node_modules/jsonlint/lib/jsonlint.js:55:11)
at Object.parse (/usr/local/Cellar/jsonlint/1.6.0/libexec/lib/node_modules/jsonlint/lib/jsonlint.js:132:22)
at parse (/usr/local/Cellar/jsonlint/1.6.0/libexec/lib/node_modules/jsonlint/lib/cli.js:82:14)
at main (/usr/local/Cellar/jsonlint/1.6.0/libexec/lib/node_modules/jsonlint/lib/cli.js:136:14)
at Object.<anonymous> (/usr/local/Cellar/jsonlint/1.6.0/libexec/lib/node_modules/jsonlint/lib/cli.js:178:1)
at Module._compile (node:internal/modules/cjs/loader:1097:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1149:10)
at Module.load (node:internal/modules/cjs/loader:975:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
As an addition to either of TF_LOG=trace
/ iamlive / CloudTrail approaches suggested before, please also note that to capture a complete set of actions required to manage a configuration (create/update/delete resources) one would need to actually apply three configurations:作为之前建议的
TF_LOG=trace
/ iamlive / CloudTrail 方法的补充,还请注意,要捕获管理配置(创建/更新/删除资源)所需的一组完整操作,需要实际应用三个配置:
terraform destroy
to capture actions required to delete resources.terraform destroy
以捕获删除资源所需的操作。 While configurations 1 and 3 are common to consider, configuration 2 is sometimes overlooked and it can be a tedious one to prepare.虽然配置 1 和 3 很常见,但配置 2 有时会被忽略,而且准备起来可能很乏味。 Without it Terraform will fail to apply changes that modify resources instead of deleting and recreating them.
没有它,Terraform 将无法应用修改资源的更改,而不是删除和重新创建它们。
Here is an extension on AvnerSo's answer :这是AvnerSo 答案的扩展:
cat log.log | ack -o "(?<=DEBUG: Request )[^ ]*" | sort -u
This command outputs every unique AWS request that Terraform has logged.此命令输出 Terraform 记录的每个唯一 AWS 请求。
"(?<=DEBUG: Request )[^ ]*"
pattern performs a negative lookahead to find the first word after the match. "(?<=DEBUG: Request )[^ ]*"
模式执行否定先行查找匹配后的第一个单词。-o
flag only shows the match in the output. -o
标志仅在输出中显示匹配项。sort -u
selects the unique values from the list and sorts them. sort -u
从列表中选择唯一值并对它们进行排序。 Another option in addition to the previous answers is:除了前面的答案之外的另一个选择是:
"s3:*", ...
as explained earlier"s3:*", ...
如前所述The method you are attempting is a bit unusual in cloud technology.您尝试的方法在云技术中有点不寻常。 Instead of giving fine grained control to the terraform user running the API calls, you could run terraform on an EC2 instance with an EC2 IAM profile that allows the instance itself to call the API's with the correct set of AWS service permissions.
您可以使用 EC2 IAM 配置文件在 EC2 实例上运行 terraform,而不是为运行 API 调用的 terraform 用户提供细粒度控制,该配置文件允许实例本身使用正确的 AWS 服务权限集调用 API。
Each call is made to a specific API endpoint.每次调用都针对特定的 API 端点。 Some terraform operations applied during a apply would be different if you pushed an update.
如果您推送更新,则在应用期间应用的某些 terraform 操作会有所不同。 You also need to know what happens during a modify operation where a resource is updated in place.
您还需要知道在资源更新到位的修改操作期间会发生什么。
Instead of restricting that API key to specifics, let it have more leeway, if it needs to create and destroy EC2, let it have EC2 full perms maybe with conditionals to restrict to account level or VPC.与其将 API 密钥限制为特定的细节,不如让它有更多的回旋余地,如果它需要创建和销毁 EC2,让它拥有 EC2 完整权限,也许有条件限制到帐户级别或 VPC。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.