Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Error: Provider produced inconsistent result after apply. Vm creation. Same code executed but different results (Identical CI). #737

Closed
ValentinPhB opened this issue Feb 28, 2024 · 1 comment · Fixed by #763
Labels
bug Something isn't working community

Comments

@ValentinPhB
Copy link

ValentinPhB commented Feb 28, 2024

Terraform Core Version

1.7.3

Cloud Avenue Provider Version

0.15.4

Affected Resource(s)

Hi,

ressource cloudavenue_vm
https://registry.terraform.io/providers/orange-cloudavenue/cloudavenue/latest/docs/resources/vm

Expected Behavior

Hi,

If I run an unchanged CI twice, I should get the same result.

Actual Behavior

Hi,

Our CI executes the same stage at different times and gets different results. The code, Terraform version, and provider version remain unchanged.

Relevant Error/Panic Output Snippet

No response

Terraform Configuration Files

Hi,

terraform {
  required_providers {
    cloudavenue = {
      source  = "orange-cloudavenue/cloudavenue"
      version = "0.15.4"
    }
  }
}

Steps to Reproduce

Hi,

Here is the code used:

package test

import (
	"fmt"
	"os"
	"strconv"
	"testing"

	"github.com/gruntwork-io/go-commons/files"
	"github.com/gruntwork-io/terratest/modules/random"
	"github.com/gruntwork-io/terratest/modules/terraform"
	"github.com/stretchr/testify/assert"
)

// Using var.key_value_security_tags_list for security tags
func TestTerraformAll(t *testing.T) {
	// Create a unique name with dynamic suffix
	uniqueID := random.UniqueId()

	// vapp has to exists
	inputVAppName := "vapp-tnr-vm"

	// catalog has to exist
	InputCatalogName := "Orange-Linux-Internal"

	// OS template has to exist
	inputOs := "RHEL_7.9"

	// network routed of the vapp has to exist and be the same has the vapp
	inputNetworkRouted := "obsitlabiaas"

	//  Input Values
	inputVmName := fmt.Sprintf("ci-lvm-test-%s", uniqueID)
	inputVmDescription := "Vm create by Ci-tests"
	inputCpuHotAddEnabled := false
	inputCpu := 3
	inputCpuCores := 3
	inputMemory := 3
	expectedMemory := inputMemory * 1024
	inputMemoryHotAddEnabled := false
	inputVmResourceNetworksType := "org"
	inputVmResourceNetworksIpAllocationMode := "POOL"
	inputVmResourceNetworksIsPrimary := true

	inputNetwork := map[string]any{
		"type":               inputVmResourceNetworksType,
		"ip_allocation_mode": inputVmResourceNetworksIpAllocationMode,
		"is_primary":         inputVmResourceNetworksIsPrimary,
		"name":               inputNetworkRouted,
	}
	listNetworks := []any{inputNetwork}

	inputVmResourceSettingsCustomizationAllowLocalAdminPassword := false
	inputVmResourceSettingsCustomizationAutoGeneratePassword := false
	inputVmResourceSettingsCustomizationChangeSid := false
	inputVmResourceSettingsCustomizationEnabled := false
	inputVmResourceSettingsCustomizationForce := false
	inputVmResourceSettingsCustomizationHostname := fmt.Sprintf("custom-hostname-%s", uniqueID)
	inputVmResourceSettingsCustomizationJoinDomain := false
	inputVmResourceSettingsCustomizationJoinOrgDomain := false
	inputVmResourceSettingsCustomizationMustChangePasswordOnFirstLogin := false
	inputVmResourceSettingsExposeHardwareVirtualization := false
	inputPowerOn := true
	inputKeyValueSecurityTagsList := map[string]interface{}{
		"firstKey":   "firstValue",
		"secondtKey": "secondValue",
	}

	// Install the provider.tf with defered deletion
	defer os.Remove("../provider.tf")
	files.CopyFile("provider.tf", "../provider.tf")

	// retryable errors in terraform testing.
	terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
		// The path to where our Terraform code is located
		TerraformDir: "../",

		// Variables to pass to our Terraform code using -var options
		Vars: map[string]interface{}{
			"vapp_name":                 inputVAppName,
			"catalog_name":              InputCatalogName,
			"os":                        inputOs,
			"network_routed":            inputNetworkRouted,
			"vm_name":                   inputVmName,
			"vm_description":            inputVmDescription,
			"vm_cpu_hot_add_enabled":    inputCpuHotAddEnabled,
			"cpu":                       inputCpu,
			"cpu_cores":                 inputCpuCores,
			"memory":                    inputMemory,
			"vm_memory_hot_add_enabled": inputMemoryHotAddEnabled,
			"vm_resource_networks":      listNetworks,
			"vm_resource_settings_customization_allow_local_admin_password":          inputVmResourceSettingsCustomizationAllowLocalAdminPassword,
			"vm_resource_settings_customization_auto_generate_password":              inputVmResourceSettingsCustomizationAutoGeneratePassword,
			"vm_resource_settings_customization_change_sid":                          inputVmResourceSettingsCustomizationChangeSid,
			"vm_resource_settings_customization_enabled":                             inputVmResourceSettingsCustomizationEnabled,
			"vm_resource_settings_customization_force":                               inputVmResourceSettingsCustomizationForce,
			"vm_resource_settings_customization_hostname":                            inputVmResourceSettingsCustomizationHostname,
			"vm_resource_settings_customization_join_domain":                         inputVmResourceSettingsCustomizationJoinDomain,
			"vm_resource_settings_customization_join_org_domain":                     inputVmResourceSettingsCustomizationJoinOrgDomain,
			"vm_resource_settings_customization_must_change_password_on_first_login": inputVmResourceSettingsCustomizationMustChangePasswordOnFirstLogin,
			"vm_resource_settings_expose_hardware_virtualization":                    inputVmResourceSettingsExposeHardwareVirtualization,
			"key_value_security_tags_list":                                           inputKeyValueSecurityTagsList,
			"power_on":                                                               inputPowerOn,
		},
	})

	// At the end of the test, run `terraform destroy` to clean up any resources that were created.
	defer terraform.Destroy(t, terraformOptions)

	// Run `terraform init` and `terraform apply`. Fail the test if there are any errors.
	terraform.InitAndApply(t, terraformOptions)

	// Run `terraform output` to get the value of an output variable
	outputVapp := terraform.Output(t, terraformOptions, "vapp_name")
	outputOsVersion := terraform.Output(t, terraformOptions, "vm_os")
	outputVmName := terraform.Output(t, terraformOptions, "vm_name")
	outputVmDescription := terraform.Output(t, terraformOptions, "vm_description")

	outputCpuHotEnabled, _ := strconv.ParseBool(terraform.Output(t, terraformOptions, "vm_cpu_hot_add_enabled"))
	outputCpu, _ := strconv.Atoi(terraform.Output(t, terraformOptions, "vm_cpu"))
	outputCpusCores, _ := strconv.Atoi(terraform.Output(t, terraformOptions, "vm_cpus_cores"))
	outputMemory, _ := strconv.Atoi(terraform.Output(t, terraformOptions, "vm_memory"))
	outputMemoryHotAddEnabled, _ := strconv.ParseBool(terraform.Output(t, terraformOptions, "vm_memory_hot_add_enabled"))
	outputVmResourceNetworkType := terraform.Output(t, terraformOptions, "vm_resource_networks_type")
	outputVmResourceNetworkIpAllocationMode := terraform.Output(t, terraformOptions, "vm_resource_networks_ip_allocation_mode")
	outputVmResourceNetworkIsPrimary, _ := strconv.ParseBool(terraform.Output(t, terraformOptions, "vm_resource_networks_is_primary"))
	outputVmResourceSettingsCustomizationAllowLocalAdminPassword, _ := strconv.ParseBool(terraform.Output(t, terraformOptions, "vm_resource_settings_customization_allow_local_admin_password"))
	outputVmResourceSettingsCustomizationAutoGeneratePassword, _ := strconv.ParseBool(terraform.Output(t, terraformOptions, "vm_resource_settings_customization_auto_generate_password"))
	outputVmResourceSettingsCustomizationChangeSid, _ := strconv.ParseBool(terraform.Output(t, terraformOptions, "vm_resource_settings_customization_change_sid"))
	outputVmResourceSettingsCustomizationEnabled, _ := strconv.ParseBool(terraform.Output(t, terraformOptions, "vm_resource_settings_customization_enabled"))
	outputVmResourceSettingsCustomizationForce, _ := strconv.ParseBool(terraform.Output(t, terraformOptions, "vm_resource_settings_customization_force"))
	outputVmResourceSettingsCustomizationHostname := terraform.Output(t, terraformOptions, "vm_resource_settings_customization_hostname")
	outputVmResourceSettingsCustomizationJoinDomain, _ := strconv.ParseBool(terraform.Output(t, terraformOptions, "vm_resource_settings_customization_join_domain"))
	outputVmResourceSettingsCustomizationJoinOrgDomain, _ := strconv.ParseBool(terraform.Output(t, terraformOptions, "vm_resource_settings_customization_join_org_domain"))
	outputVmResourceSettingsCustomizationMustChangePasswordOnFirstLogin, _ := strconv.ParseBool(terraform.Output(t, terraformOptions, "vm_resource_settings_customization_must_change_password_on_first_login"))
	outputVmResourceSettingsExposeHardwareVirtualization, _ := strconv.ParseBool(terraform.Output(t, terraformOptions, "vm_resource_settings_expose_hardware_virtualization"))
	outputPowerOn, _ := strconv.ParseBool(terraform.Output(t, terraformOptions, "power_on"))

	// Check that the outputs match the expected values
	assert.Equal(t, inputVAppName, outputVapp)
	assert.Equal(t, inputOs, outputOsVersion)
	assert.Equal(t, inputVmName, outputVmName)
	assert.Equal(t, inputVmDescription, outputVmDescription)
	assert.Equal(t, inputCpuHotAddEnabled, outputCpuHotEnabled)
	assert.Equal(t, inputCpu, outputCpu)
	assert.Equal(t, inputCpuCores, outputCpusCores)
	assert.Equal(t, expectedMemory, outputMemory)
	assert.Equal(t, inputMemoryHotAddEnabled, outputMemoryHotAddEnabled)
	assert.Equal(t, inputVmResourceNetworksType, outputVmResourceNetworkType)
	assert.Equal(t, inputVmResourceNetworksIpAllocationMode, outputVmResourceNetworkIpAllocationMode)
	assert.Equal(t, inputVmResourceNetworksIsPrimary, outputVmResourceNetworkIsPrimary)
	assert.Equal(t, inputVmResourceSettingsCustomizationAllowLocalAdminPassword, outputVmResourceSettingsCustomizationAllowLocalAdminPassword)
	assert.Equal(t, inputVmResourceSettingsCustomizationAutoGeneratePassword, outputVmResourceSettingsCustomizationAutoGeneratePassword)
	assert.Equal(t, inputVmResourceSettingsCustomizationChangeSid, outputVmResourceSettingsCustomizationChangeSid)
	assert.Equal(t, inputVmResourceSettingsCustomizationEnabled, outputVmResourceSettingsCustomizationEnabled)
	assert.Equal(t, inputVmResourceSettingsCustomizationForce, outputVmResourceSettingsCustomizationForce)
	assert.Equal(t, inputVmResourceSettingsCustomizationHostname, outputVmResourceSettingsCustomizationHostname)
	assert.Equal(t, inputVmResourceSettingsCustomizationJoinDomain, outputVmResourceSettingsCustomizationJoinDomain)
	assert.Equal(t, inputVmResourceSettingsCustomizationJoinOrgDomain, outputVmResourceSettingsCustomizationJoinOrgDomain)
	assert.Equal(t, inputVmResourceSettingsCustomizationMustChangePasswordOnFirstLogin, outputVmResourceSettingsCustomizationMustChangePasswordOnFirstLogin)
	assert.Equal(t, inputVmResourceSettingsExposeHardwareVirtualization, outputVmResourceSettingsExposeHardwareVirtualization)
	assert.Equal(t, inputPowerOn, outputPowerOn)
}

Debug Output

Hi,
Due to the character limit, I'm attaching screenshots here. I can grant you access to the relevant project if you'd like.

Here are the results for a CI executed on February 1st, 2024 :
image
image
image
image
image
image
image

Here are the results for a CI executed on February 28, 2024 :
image
image
image
image
image
image
image

Panic Output

No response

Important Factoids

Hi ,

For both executions of our CI, the context remains unchanged :

image hashicorp/terraform:1.5.7
go version go1.20.11 linux/amd64
All go libraries were checked.

Installing orange-cloudavenue/cloudavenue v0.15.4


Resume :

Same CI executed on February 1st and 28, 2024.
Only the one from the 28th presents the following error during VM creation:
image

References

No response

Would you like to implement a fix?

None

@ValentinPhB ValentinPhB added the bug Something isn't working label Feb 28, 2024
@azrod
Copy link
Member

azrod commented May 21, 2024

Hi @ValentinPhB,

I'm found your problem. The customization settings are editable only if Guest Customization is enabled.

The settings Auto Generate Password is enabled in your vapp template but the guest customization is disabled.
So the parameter auto_generate_password = false in your terraform configuration is not applied.

If you do not know the state of the fields provided by the vapp template, it's recommended that you configure terraform implicity because this attribute is "Optional and Compute". If you define no configuration for this field the provider call API and get the value.

Regards

@dmicheneau dmicheneau linked a pull request May 21, 2024 that will close this issue
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working community
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants