启用SCP标签策略时Terraform无法创建EC2实例的问题排查
问题分析与解决
核心原因
你的SCP策略明确拒绝未携带CostCenter标签的ec2:RunInstances操作,覆盖实例和卷两类资源。问题出在Terraform的标签机制上:
- 控制台和CloudFormation在发起
RunInstances请求时,会把指定标签直接包含在请求参数中,同时满足实例和卷的标签检查条件,因此能通过SCP验证。 - 但Terraform的
default_tags以及root_block_device内定义的标签,都是在资源创建完成后,通过单独的CreateTagsAPI追加,而非在RunInstances的初始请求中携带。这就导致RunInstances请求本身不符合SCP中aws:RequestTag/CostCenter不为空的要求,触发了针对卷资源的拒绝规则。
解决办法
要让Terraform在RunInstances请求中直接携带标签,需在aws_instance资源内显式定义tags块,确保标签被包含在创建实例的核心请求中:
provider "aws" { region = var.region profile = var.awsProfile default_tags { tags = { CostCenter = var.CostCenter } } } resource "aws_instance" "app_server" { ami = data.aws_ami.rhel-ami.id instance_type = var.instanceType subnet_id = aws_subnet.subnet.id key_name = aws_key_pair.kp.key_name iam_instance_profile = aws_iam_role.screener-role.name # 关键:此处显式定义tags,Terraform会将其加入RunInstances请求参数 tags = { CostCenter = var.CostCenter } root_block_device { volume_size = var.rootVolumeSize delete_on_termination = true encrypted = true kms_key_id = aws_kms_key.kmsKey.id tags = { CostCenter = var.CostCenter } } }
修改后,RunInstances请求会携带CostCenter标签,满足SCP的条件限制,即可正常创建EC2实例。
你可以通过AWS CloudTrail查看RunInstances事件的requestParameters字段,对比修改前后的请求差异,验证标签是否已被加入初始请求。
内容的提问来源于stack exchange,提问作者Pavan Kumar N
相关产品推荐
相关产品推荐

