3

我正在尝试通过 terraform 进行 AWS 资源配置,并计划拥有一个 CICD 管道,其中包含用于 terraform 代码的 terratest 单元测试用例。我的问题是我的基础设施中有 CloudFront,创建大约需要 20 分钟,而删除大约需要 20 分钟。我不希望 CI 构建仅仅为了运行单元测试用例就需要大约 45 分钟。

我遇到了 localstack 来模拟 AWS 环境,但没有找到将 terratest 指向 localstack 资源的方法。这是我尝试过的

  • 创建了一个 localstack docker 容器
  • 将 terraform 配置为指向 localstack - 在提供程序部分添加了端点 url。
  • 应用 terraform 配置并验证在 localstack 中创建的存储桶。
  • 编写了一个简单的 terratest 测试用例来断言存储桶是否存在。

Terraform代码如下,

terraform {
  backend "s3" {
    bucket  = "<bucket-name>"
    key     = "state/terraform.tfstate"
    region  = "us-east-1"
    profile = "default"
  }
}

provider "aws" {
  region = "us-east-1"
  s3_force_path_style = true
  skip_metadata_api_check = true
  endpoints {
    s3             = "http://localhost:4572"
  }
}

resource "aws_s3_bucket" "test_bucket" {

  bucket = "test-bucket"
  acl    = "public-read-write"
  cors_rule {
    allowed_headers = ["*"]
    allowed_methods = ["GET", "HEAD", "PUT"]
    allowed_origins = ["*"]
    expose_headers  = ["ETag"]
  }
  region = "us-east-1"
}

output "name" {
  value = "${aws_s3_bucket.test_bucket.bucket}"
}

output "region" {
  value = "${aws_s3_bucket.test_bucket.region}"
}

当执行下面给出的 terratest 测试用例时,会在 localstack 中创建一个存储桶。但我找不到任何将 terratest AWS 模块指向 localstack 端点的 api 或配置。AssertS3BucketExists 默认检查存储桶的 AWS 环境,断言失败。

Terratest 代码如下。

package aws

import (
"fmt"
"testing"

"github.com/gruntwork-io/terratest/modules/aws"
"github.com/gruntwork-io/terratest/modules/terraform"
)

func TestWebServer(t *testing.T) {
    terraformOptions := &terraform.Options{
    // The path to where your Terraform code is located
    TerraformDir: ".",
}


terraform.InitAndApply(t, terraformOptions)

name := terraform.Output(t, terraformOptions, "name")
region := terraform.Output(t, terraformOptions, "region")
aws.AssertS3BucketExists(t, region, name)

在这里的任何帮助将不胜感激。

4

2 回答 2

1

有一个有效的PR可以让 Terratest 验证 Localstack 中的资源。

您可以使用 replace 指令更新您的 go.mod 文件以对其进行测试。

module github.com/GITHUB_USERNAME/REPO_NAME

go 1.15

require (
    github.com/gruntwork-io/terratest v0.30.0
    github.com/stretchr/testify v1.6.1
)

replace github.com/gruntwork-io/terratest v0.30.0 => github.com/ffernandezcast/terratest v0.28.6-0.20200915124510-25813206bebc

然后使用以下变量更新您的 Terratest 测试以配置aws包的自定义端点。

    var LocalEndpoints = map[string]string{
        "apigateway":     "http://localhost:4566",
        "cloudformation": "http://localhost:4566",
        "cloudwatch":     "http://localhost:4566",
        "dynamodb":       "http://localhost:4566",
        "es":             "http://localhost:4566",
        "firehose":       "http://localhost:4566",
        "iam":            "http://localhost:4566",
        "kinesis":        "http://localhost:4566",
        "lambda":         "http://localhost:4566",
        "route53":        "http://localhost:4566",
        "redshift":       "http://localhost:4566",
        "s3":             "http://localhost:4566",
        "secretsmanager": "http://localhost:4566",
        "ses":            "http://localhost:4566",
        "sns":            "http://localhost:4566",
        "sqs":            "http://localhost:4566",
        "ssm":            "http://localhost:4566",
        "stepfunctions":  "http://localhost:4566",
        "sts":            "http://localhost:4566",
    }
    aws.SetAwsEndpointsOverrides(LocalEndpoints)

然后,运行go test,Terratest 现在将验证 LocalStack 中的资源。我在这里详细介绍了https://jq1.io/posts/go_mod_terratest_localstack/

希望该 PR 将很快并入 Terratestmaster分支。

~jq1

于 2020-09-24T07:12:32.457 回答
1

要在不修改库的情况下完成模拟 AWS terratest,您可以使用类似moto's standalone server mode 的东西。由于没有(明显的)方法可以更改 中的端点terratest,因此可能需要修改本地 DNS 解析以将端点指向本地moto服务器。

使用terratest,没有办法将模拟 AWS 注入库本身,因为用于连接 AWS 的接口未公开。

于 2020-07-24T15:45:50.803 回答