You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

重命名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当前的严格校验逻辑

修复步骤

  1. 在模块中添加一个IAM角色,授予EventBridge调用API目标的权限
  2. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 10:35:24