重命名Terraform模块后EventBridge Target报RoleArn必填错误
问题描述
使用Terraform 1.3.5,模块此前运行正常,重命名模块后执行apply时出现以下错误:
Error: creating EventBridge Target (cleanup-terraform-20221130175229684800000001): ValidationException: RoleArn is required for target arn:aws:events:us-east-1:123456789012:api-destination/services-destination/c187090f-268b-4d9b-b09d-f9b077e0c0cf. │ status code: 400, request id: 63dc6425-2a94-4f66-b7c2-106b0607d964 │ │ with module.a-eventbridge-trigger.aws_cloudwatch_event_target.api_destination, │ on ..\a-eventbridge-trigger\main.tf line 61, in resource "aws_cloudwatch_event_target" "api_destination": │ 61: resource "aws_cloudwatch_event_target" "api_destination" {
模块内main.tf完整代码:
# configures api connection resource "aws_cloudwatch_event_connection" "auth" { name = "services-token" description = "Gets oauth bearer token" authorization_type = "OAUTH_CLIENT_CREDENTIALS" auth_parameters { oauth { authorization_endpoint = "${var.vars.apiBaseUrl}${var.vars.auth}" http_method = "POST" client_parameters { client_id = var.secretContent.Client_Id client_secret = var.secretContent.Client_Secret } oauth_http_parameters { body { key = "grant_type" value = "client_credentials" is_value_secret = true } body { key = "client_id" value = var.secretContent.Client_Id is_value_secret = true } body { key = "client_secret" value = var.secretContent.Client_Secret is_value_secret = true } } } } } # configures api destination resource "aws_cloudwatch_event_api_destination" "request" { name = "services-destination" description = "Requests clean up" invocation_endpoint = "${var.vars.apiBaseUrl}${var.vars.endpoint}" http_method = "POST" invocation_rate_limit_per_second = 20 connection_arn = aws_cloudwatch_event_connection.auth.arn } # sets up the scheduling resource "aws_cloudwatch_event_rule" "every_midnight" { name = "${var.name}-services-cleanup" description = "Fires on every day at midnight of UTC+0" schedule_expression = "cron(0 0 * * ? *)" is_enabled = true } # tells the scheduler to call the api destination resource "aws_cloudwatch_event_target" "api_destination" { rule = aws_cloudwatch_event_rule.every_midnight.name arn = aws_cloudwatch_event_api_destination.request.arn }
根模块调用方式:
module "a-eventbridge-trigger" { source = "../a-eventbridge-trigger" name = local.prefixName resourceTags = local.commonTags vars = var.vars secretContent = var.secrets }
providers.tf内容:
terraform { required_providers { aws = { source = "hashicorp/aws" version = "4.43.0" } } backend "s3" {} }
已执行destroy后重新apply,问题依然存在。
解决方案
问题原因
AWS EventBridge的API目标(API Destination)类型的Event Target必须指定role_arn,这是AWS官方要求的必填项。此前模块正常运行可能是因为:
- 旧版本的AWS Provider或Terraform对该参数的校验不严格,允许跳过
- 原模块的状态文件中保留了旧资源的隐含权限配置,重命名模块后Terraform销毁旧资源并重新创建,触发了AWS当前的严格校验逻辑
修复步骤
- 在模块中添加一个IAM角色,授予EventBridge调用API目标的权限
- 在
aws_cloudwatch_event_target资源中引用该角色的ARN
修改后的main.tf如下:
# configures api connection resource "aws_cloudwatch_event_connection" "auth" { name = "services-token" description = "Gets oauth bearer token" authorization_type = "OAUTH_CLIENT_CREDENTIALS" auth_parameters { oauth { authorization_endpoint = "${var.vars.apiBaseUrl}${var.vars.auth}" http_method = "POST" client_parameters { client_id = var.secretContent.Client_Id client_secret = var.secretContent.Client_Secret } oauth_http_parameters { body { key = "grant_type" value = "client_credentials" is_value_secret = true } body { key = "client_id" value = var.secretContent.Client_Id is_value_secret = true } body { key = "client_secret" value = var.secretContent.Client_Secret is_value_secret = true } } } } } # IAM角色:允许EventBridge调用API Destination resource "aws_iam_role" "eventbridge_api_target" { name = "${var.name}-eventbridge-api-target-role" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = "events.amazonaws.com" } } ] }) tags = var.resourceTags } # 角色权限:允许调用API Destination resource "aws_iam_role_policy" "eventbridge_api_target" { name = "${var.name}-eventbridge-api-target-policy" role = aws_iam_role.eventbridge_api_target.id policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "events:InvokeApiDestination" Effect = "Allow" Resource = aws_cloudwatch_event_api_destination.request.arn } ] }) } # configures api destination resource "aws_cloudwatch_event_api_destination" "request" { name = "services-destination" description = "Requests clean up" invocation_endpoint = "${var.vars.apiBaseUrl}${var.vars.endpoint}" http_method = "POST" invocation_rate_limit_per_second = 20 connection_arn = aws_cloudwatch_event_connection.auth.arn } # sets up the scheduling resource "aws_cloudwatch_event_rule" "every_midnight" { name = "${var.name}-services-cleanup" description = "Fires on every day at midnight of UTC+0" schedule_expression = "cron(0 0 * * ? *)" is_enabled = true } # tells the scheduler to call the api destination resource "aws_cloudwatch_event_target" "api_destination" { rule = aws_cloudwatch_event_rule.every_midnight.name arn = aws_cloudwatch_event_api_destination.request.arn role_arn = aws_iam_role.eventbridge_api_target.arn # 添加这一行 }
说明
- 添加的IAM角色允许EventBridge服务扮演该角色
- 附加的策略明确授予调用指定API Destination的权限
- 在Event Target中指定
role_arn后,AWS会使用该角色的权限执行API调用,满足必填项要求
内容的提问来源于stack exchange,提问作者Matt W
相关产品推荐
相关产品推荐

