如何通过IAM权限禁止CLI/远程工具删除AWS资源并保留控制台权限?
问题分析
你的核心需求是禁止通过CLI、Terraform等直接调用API的工具删除AWS资源,但允许AWS控制台执行删除操作。现有配置的问题在于aws:ViaAWSService条件的逻辑错误,导致控制台操作被误限制。
aws:ViaAWSService的作用
AWS的这个上下文键用于标识请求是否由AWS内部服务发起:
- 通过AWS控制台操作时,请求由AWS内部服务转发,
aws:ViaAWSService会被设为true - 通过CLI、Terraform、SDK等直接调用API时,该键不存在(或不会被设置)
修正后的Terraform配置
将原来的aws:ViaAWSService条件改为否定匹配true,这样只有当请求不是来自控制台时(即无该键或键值不为true),才会触发Deny规则:
data "aws_iam_policy_document" "delete_prevention" { statement { sid = "PreventDeleteNonConsole" effect = "Deny" actions = [ "rds:Delete*", "ec2:Delete*", "ec2:TerminateInstances", "ec2:Disassociate*", "elasticache:Delete*", "s3:Delete*", "dynamodb:DeleteTable", "route53:Delete*", "lambda:Delete*", "lambda:RemovePermission", "sns:Delete*", "secretsmanager:Delete*", "ssm:Delete*", "ecr:Delete*", "acm:Delete*", "ses:Delete*" ] resources = ["*"] # 核心修正:拒绝所有非控制台发起的删除请求 condition { test = "BoolIfExists" values = ["true"] variable = "aws:ViaAWSService" negate = true # 否定匹配,即当aws:ViaAWSService不是true时触发Deny } dynamic "condition" { for_each = local.fuzzy_delete_protect content { test = "StringLikeIfExists" values = condition.value variable = "aws:RequestTag/${condition.key}" } } dynamic "condition" { for_each = local.exact_delete_protect content { test = "StringEqualsIfExists" values = condition.value variable = "aws:RequestTag/${condition.key}" } } } } resource "aws_iam_policy" "delete_prevention" { count = length(var.delete_protect_tags) > 0 ? 1 : 0 name = "prevent-tool-delete" description = "阻止通过CLI/Terraform等工具删除资源,仅允许AWS控制台操作" policy = data.aws_iam_policy_document.delete_prevention.json }
关键说明
negate = true:反转条件判断,当aws:ViaAWSService不存在(CLI/Terraform)或存在但不为true时,触发Deny规则- 控制台操作时
aws:ViaAWSService=true,条件不满足,因此不会被拒绝,允许执行删除 - 保留原有的标签条件逻辑,确保仅对带有指定标签的资源生效(如果
var.delete_protect_tags有值的话)
内容的提问来源于stack exchange,提问作者eltiare
相关产品推荐
相关产品推荐

