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

如何为Terraform ec2_instances模块编写Golang验收测试并关联资源测试逻辑

核心实现逻辑

打通Terraform模块验收测试和自定义Provider资源测试的核心逻辑是:将EC2模块定义与你自定义的resource_ravendb_server资源放在同一个测试Terraform配置中,依赖Terraform自身的资源依赖关系,先完成EC2实例部署,再执行自定义Provider的资源逻辑,最后在同一个测试用例中同时校验模块输出和自定义资源的状态。

具体改造步骤
  • 第一步:修改测试配置函数testAccRavenDbServerConfig的返回内容,把EC2模块和自定义资源放在同一份配置中,将EC2模块的输出作为自定义资源的入参关联二者:
locals {
  nodes = toset(["a", "b", "c"])
}

module "ec2_instances" {
  source  = "terraform-aws-modules/ec2-instance/aws"
  version = "~> 3.0"

  for_each = local.nodes

  name = "${each.key}.ravendb"

  ami                    = "ami-09e67e426f25ce0d7" 
  instance_type          = "t2.micro"
  key_name               = "omer-tf"
  monitoring             = false
  vpc_security_group_ids = ["sg-03525214aee516d50"]
  subnet_id              = "subnet-0ee70783a7dd19aa5"
  associate_public_ip_address   = true
}

# 你的自定义Provider资源,直接引用EC2模块的输出作为参数
resource "resource_ravendb_server" "test" {
  endpoints = [for inst in module.ec2_instances : inst.public_ip]
  healthcheck_database = "firewire"
  # 其他自定义资源需要的参数
}
  • 第二步:调整测试用例逻辑,同时注册AWS Provider和自定义Provider的工厂函数,在检查步骤中同时校验EC2模块的资源属性和自定义资源的属性:
func TestAccRavenDbFullStack(t *testing.T) {
    var (
        customResName = "resource_ravendb_server.test"
        // for_each创建的模块资源地址需要带上对应key
        ec2ResA = "module.ec2_instances[\"a\"].aws_instance.this"
        ec2ResB = "module.ec2_instances[\"b\"].aws_instance.this"
        ec2ResC = "module.ec2_instances[\"c\"].aws_instance.this"
    )

    resource.ParallelTest(t, resource.TestCase{
        PreCheck: func() {
            testAccPreCheck(t)
            checkAwsEnv(t)
        },
        // 同时注册测试需要的所有Provider
        ProviderFactories: map[string]func() (*schema.Provider, error){
            "aws": func() (*schema.Provider, error) {
                return aws.Provider(), nil
            },
            // 替换为你自定义Provider的名称
            "ravendb": testAccProviderFactories["ravendb"],
        },
        CheckDestroy: resource.ComposeTestCheckFunc(
            testAccRavenDbServerDestroy,
            // 可补充EC2资源销毁校验逻辑
        ),
        Steps: []resource.TestStep{
            {
                Config: testAccRavenDbServerConfig(),
                Check: resource.ComposeTestCheckFunc(
                    // 校验EC2模块部署结果符合预期
                    resource.TestCheckResourceAttr(ec2ResA, "tags.Name", "a.ravendb"),
                    resource.TestCheckResourceAttr(ec2ResB, "tags.Name", "b.ravendb"),
                    resource.TestCheckResourceAttr(ec2ResC, "instance_type", "t2.micro"),
                    // 校验自定义Provider资源逻辑符合预期
                    resource.TestCheckResourceAttr(customResName, "healthcheck_database", "firewire"),
                    // 可补充自定义校验函数,比如直接调用RavenDB接口验证服务可用性
                ),
            },
        },
    })
}
  • 第三步:如果需要更深度的验收逻辑,可以自定义CheckFunc函数,从Terraform状态中拿到EC2实例ID、自定义资源的属性值,分别调用AWS API、RavenDB接口做实际的业务校验。
注意事项
  • 带for_each的模块资源地址必须带上对应的key,格式为module.<模块名>["<key>"].<底层资源类型>.<资源名>,写错会导致属性校验失败
  • 如果自定义资源的校验需要等EC2实例内部服务完全启动,可以在自定义Provider的Create逻辑中增加重试机制,避免实例还未初始化完成就校验失败

内容的提问来源于stack exchange,提问作者Omer ayende

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 19:24:03