简体   繁体   English

Terratest - 如何在函数之间传递 Terraform 输出

[英]Terratest - How to pass Terraform outputs between functions

I tried to use 'test_structure.SaveTerraformOptions' but it doesn't save resources IDs.我尝试使用“test_structure.SaveTerraformOptions”,但它不保存资源 ID。 For example, I'm running 2 modules - Module 1 creating the networking and the subnets, module 2 needs module's 1 subnets ids.例如,我正在运行 2 个模块 - 模块 1 创建网络和子网,模块 2 需要模块的 1 个子网 ID。 How can I pass this info between them?我怎样才能在他们之间传递这些信息?

When I'm running both functions in the same 'test_structure.RunTestStage' I am able to pass resource id from one function to another, but it doesn't test the first function and doesn't destroy at the end.当我在同一个“test_structure.RunTestStage”中运行这两个函数时,我能够将资源 id 从一个 function 传递给另一个,但它不会测试第一个 function 并且最后不会破坏。

I am going to write a helper function that will only load everything and the other functions will do the testing.我将编写一个助手 function ,它只会加载所有内容,其他函数将进行测试。 Maybe this will help.也许这会有所帮助。

However, what is the best practice to this?但是,对此的最佳做法是什么?

This is my code:这是我的代码:

package test

import (
    "testing"

    //"github.com/gruntwork-io/terratest/modules/random"

    "github.com/gruntwork-io/terratest/modules/azure"
    "github.com/gruntwork-io/terratest/modules/terraform"
    test_structure "github.com/gruntwork-io/terratest/modules/test-structure"
    "github.com/stretchr/testify/assert"
)

// An example of how to test the simple Terraform module in examples/terraform-basic-example using Terratest.

func TestRunAll(t *testing.T) {
    t.Parallel()

    environmentName := "dev"
    projectName := "toha"
    rgName := environmentName + "-" + projectName + "-rg"
    subscriptionID := "96b72f1a-1bdc-4fc7-b971-05e7cea7d850"

    rg_net := test_structure.CopyTerraformFolderToTemp(t, "../", "001_networking")

    test_structure.RunTestStage(t, "test_azure_resource_group", func() {
        terraformOptions := testAzureResourceGroup(t, rgName, subscriptionID)
        test_structure.SaveTerraformOptions(t, rg_net, terraformOptions)
        
        testTerraformAzureFunctionApp(t, rgName, terraformOptions)
        terraform.Destroy(t, terraformOptions)
    })
}

func testAzureResourceGroup(t *testing.T, rgName string, subscriptionID string) *terraform.Options {

    //uniquePostfix := strings.ToLower(random.UniqueId())
    terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{

        TerraformDir: "../001_networking",

        Vars: map[string]interface{}{
            "rg_name": rgName,
        },

        VarFiles: []string{"../../environments/dev/vars.tfvars"},

        // Disable colors in Terraform commands so its easier to parse stdout/stderr
        NoColor: true,
    })

    terraform.InitAndApply(t, terraformOptions)
    rg_name_out := terraform.Output(t, terraformOptions, "rg-name")

    assert.Equal(t, rgName, rg_name_out)

    return terraformOptions
}

func testTerraformAzureFunctionApp(t *testing.T, rgName string, netOpts *terraform.Options) {

    azurePortalIPRange := []string{"61.100.129.0/24"}

    subnet_1 := terraform.Output(t, netOpts, "azurerm_subnet_1")
    subnet_2 := terraform.Output(t, netOpts, "azurerm_subnet_2")

    terraformOptions := &terraform.Options{
        TerraformDir: "../002_function_app",

        Vars: map[string]interface{}{
            "subnet_id_1":           subnet_1,
            "subnet_id_2":           subnet_2,
            "rg_name":               rgName,
            "azure_portal_ip_range": azurePortalIPRange,
            "cosmos_db_endpoint":    "test",
            "cosmos_db_password":    "test",
        },

        VarFiles: []string{"../../environments/dev/vars.tfvars"},
    }

    defer terraform.Destroy(t, terraformOptions)
    terraform.InitAndApply(t, terraformOptions)

    resourceGroupName := terraform.Output(t, terraformOptions, "resource_group_name")
    appName := terraform.Output(t, terraformOptions, "function_app_name")

    appId := terraform.Output(t, terraformOptions, "function_app_id")
    appDefaultHostName := terraform.Output(t, terraformOptions, "default_hostname")
    appKind := terraform.Output(t, terraformOptions, "function_app_kind")

    // website::tag::4:: Assert
    assert.True(t, azure.AppExists(t, appName, resourceGroupName, ""))
    site := azure.GetAppService(t, appName, resourceGroupName, "")

    assert.Equal(t, appId, *site.ID)
    assert.Equal(t, appDefaultHostName, *site.DefaultHostName)
    assert.Equal(t, appKind, *site.Kind)

    assert.NotEmpty(t, *site.OutboundIPAddresses)
    assert.Equal(t, "Running", *site.State)
}

I think the best way you can use the test_structure is separate by stages ( https://pkg.go.dev/github.com/gruntwork-io/terratest/modules/test-structure#RunTestStage ):我认为您可以使用 test_structure 的最佳方式是按阶段分开( https://pkg.go.dev/github.com/gruntwork-io/terratest/modules/test-structure#RunTestStage ):

  1. Configure terratest, save the options for your specific configuration to terraform --> SETUP配置 terratest,将您特定配置的选项保存到 terraform --> SETUP

     test_structure.RunTestStage(t, "SETUP", func() { terraformOption:= &terraform.Options{ TerraformDir: "your/path/here", } test_structure.SaveTerraformOptions(t, directory, terraformOption) terraform.InitAndApply(t, terraformOption) })
  2. Destroy your infra at the end of the testing --> TEARDOWN在测试结束时销毁你的基础设施 --> TEARDOWN

     defer test_structure.RunTestStage(t, "TEARDOWN", func() { terraformOptions:= test_structure.LoadTerraformOptions(t, directory) terraform.Destroy(t, terraformOptions) })
  3. Your test cases --> TESTS你的测试用例 --> TESTS

     test_structure.RunTestStage(t, "TESTS", func() { terraformOption:= test_structure.LoadTerraformOptions(t, "your/path/") // Your outputs resourceGroupName:= terraform.Output(t, terraformOptions, "resource_group_name") appName:= terraform.Output(t, terraformOptions, "function_app_name") appId:= terraform.Output(t, terraformOptions, "function_app_id") // your functions // it can receive the outputs or anything t.Run("Test1", func(t *testing.T) { testAzureResourceGroup(t, resourceGroupName, subscriptionID) }) t.Run("Test2", func(t *testing.T) { testTerraformAzureFunctionApp(t, appId, appName) }) })

Microsoft have one example more explain https://docs.microsoft.com/en-us/azure/developer/terraform/best-practices-end-to-end-testing :)微软还有一个例子来解释https://docs.microsoft.com/en-us/azure/developer/terraform/best-practices-end-to-end-testing :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM