orange-cloudavenue / terraform-provider-cloudavenue

Terraform Cloud Avenue provider
https://registry.terraform.io/providers/orange-cloudavenue/cloudavenue
Mozilla Public License 2.0
15 stars 3 forks source link

[Bug]: Cannot use for_each in vdc creation since provider version 0.16.0 #735

Closed bobbyblues closed 2 months ago

bobbyblues commented 7 months ago

Terraform Core Version

1.5.3

Cloud Avenue Provider Version

0.16.0

Affected Resource(s)

cloudavenue_vdc

Expected Behavior

When creating VDC resources using a for_each, VDCs should be properly created.

Actual Behavior

An error is raised : Error: Service class attribute is not valid

Relevant Error/Panic Output Snippet

It seems that a validation is applied on VDC resources and this validation does not handle `for_each` statements.

Terraform Configuration Files

#.env file
export CLOUDAVENUE_ORG="cavxxxxxxxx"
export CLOUDAVENUE_USER="terraform"
export CLOUDAVENUE_USERNAME="terraform"
export CLOUDAVENUE_PASSWORD="xxxxxxxxxxxx"
export CLOUDAVENUE_URL="https://console2.cloudavenue.orange-business.com"

Steps to Reproduce

This terraform plan works:

#main.tf
terraform {
  required_providers {
    cloudavenue = {
      source  = "orange-cloudavenue/cloudavenue"
      # version = "0.16.0"
      version = "0.15.5"
    }
  }
}

provider "cloudavenue" {
}

locals {
  m_vdcs_resources = {
    "my-vdc" = {
      cpu_allocated     = 11000
      cpu_speed         = 2200
      memory            = 4
      compute_billing   = "PAYG"
      disponibility     = "ONE-ROOM"
      service_class     = "STD"
      storage_billing   = "PAYG"
      storage_profiles  = [
        {
          class   = "gold"
          default = true
          limit   = 500
        }
      ]
    }
  }
}

resource "cloudavenue_vdc" "vdcs" {
  for_each = local.m_vdcs_resources

  name                  = each.key
  cpu_allocated         = each.value.cpu_allocated
  cpu_speed_in_mhz      = each.value.cpu_speed
  memory_allocated      = each.value.memory
  billing_model         = each.value.compute_billing
  disponibility_class   = each.value.disponibility
  service_class         = each.value.service_class
  storage_billing_model = each.value.storage_billing
  storage_profiles      = each.value.storage_profiles
}

This one fails:

terraform {
  required_providers {
    cloudavenue = {
      source  = "orange-cloudavenue/cloudavenue"
      version = "0.16.0"
      # version = "0.15.5"
    }
  }
}

provider "cloudavenue" {
}

locals {
  m_vdcs_resources = {
    "my-vdc" = {
      cpu_allocated     = 11000
      cpu_speed         = 2200
      memory            = 4
      compute_billing   = "PAYG"
      disponibility     = "ONE-ROOM"
      service_class     = "STD"
      storage_billing   = "PAYG"
      storage_profiles  = [
        {
          class   = "gold"
          default = true
          limit   = 500
        }
      ]
    }
  }
}

resource "cloudavenue_vdc" "vdcs" {
  for_each = local.m_vdcs_resources

  name                  = each.key
  cpu_allocated         = each.value.cpu_allocated
  cpu_speed_in_mhz      = each.value.cpu_speed
  memory_allocated      = each.value.memory
  billing_model         = each.value.compute_billing
  disponibility_class   = each.value.disponibility
  service_class         = each.value.service_class
  storage_billing_model = each.value.storage_billing
  storage_profiles      = each.value.storage_profiles
}

Only the provider version changes.

Debug Output

No response

Panic Output

No response

Important Factoids

No response

References

No response

Would you like to implement a fix?

None

azrod commented 7 months ago

Hello ✋ @bobbyblues,

You are using an older version of the terraform client and cloudavenue provider. Please update to the latest version and try again. The for_each is not supported in the provider. The bug is probably in the terraform client.

Best

bobbyblues commented 7 months ago

Regarding the cloudavenue provider : The error is here even on the latest version (0.18.2), but I submitted the bug for the first version where it appeared.

Regarding the terraform client version : The latest terraform version seems to have an issue with using Cloud Avenue's S3 as a backend, but once again, it has no impact on the issue.

$ terraform plan
╷
│ Error: Service class attribute is not valid
│ 
│   with cloudavenue_vdc.vdcs,
│   on main.tf line 49, in resource "cloudavenue_vdc" "vdcs":
│   49:   service_class         = each.value.service_class
│ 
│ service class not found
╵
$ terraform -v                                                                                                                                                                                                                            ↵ 1
Terraform v1.7.4
on linux_amd64
+ provider registry.terraform.io/orange-cloudavenue/cloudavenue v0.18.2

It really does seem the issue was introduced by the provider. Could it be you introduced a check to validate the validity of the vDC parameters, and that check fails when the resource uses a for_each ?

matmb-cld commented 3 months ago

Hello,

I've tried to create a module to create vdc and call this module as a workaround for for_each issue. But in fact the issue is still present:

variable "vdcs" {
  type = map(any)
  default = {}
}

module "hosting_zone_vdc" {
  source = "./modules/vdc"
  vdcs = var.vdcs
}

But the issue is still present:

terraform validate
╷
│ Error: Service class attribute is not valid
│ 
│   with module.hosting_zone_vdc.cloudavenue_vdc.hosting_zone,
│   on modules/vdc/vdcs.tf line 11, in resource "cloudavenue_vdc" "hosting_zone":
│   11:   service_class         = each.value.service_class
│ 
│ service class not found
jcnaud commented 2 months ago

Hi,

We still have this issue.

The error is also present in the last version "0.18.4".

This error is triggered in line internal/provider/vdc/vdc_resource.go: line 117

case errors.Is(err, rules.ErrServiceClassNotFound):
    resp.Diagnostics.AddAttributeError(path.Root("service_class"), "Service class attribute is not valid", err.Error())

So the issue appear during the validation. I don't find how to resolve this issue.

I'm not comfortable with Go and even less comfortable with the Go Terrafrom libraries to make the fix.

Can you help us with it ?

Regards

azrod commented 2 months ago

Hi,

We still have this issue.

The error is also present in the last version "0.18.4".

This error is triggered in line internal/provider/vdc/vdc_resource.go: line 117

case errors.Is(err, rules.ErrServiceClassNotFound):
  resp.Diagnostics.AddAttributeError(path.Root("service_class"), "Service class attribute is not valid", err.Error())

So the issue appear during the validation. I don't find how to resolve this issue.

I'm not comfortable with Go and even less comfortable with the Go Terrafrom libraries to make the fix.

Can you help us with it ?

Regards

Hi @jcnaud,

Thanks for your help. The problem is not in the providers. Cloud Avenue use the latest terraform framework for build the provider. In this framework we can operate in the different terraform sequences

validate -> plan -> apply

In the VDC resource we use ValidateConfig func which occurs in the terraform validate sequence. But there seems to be a bug if the values ​​come from a terraform module. We tried to work around the problem by retaining the functionality but it didn't work.

As this validation function is only there for the comfort of users, we have just proposed a workaround to explicitly bypass this validation. (PR in progress)

jcnaud commented 2 months ago

Hi,

Thanks, I don't know how to make a works around.

I use this, very little example with the last provider version "0.18.5" delivered today (31/07/2024):

#.env file
export CLOUDAVENUE_ORG="cavxxxxxxxx"
export CLOUDAVENUE_USER="terraform"
export CLOUDAVENUE_USERNAME="terraform"
export CLOUDAVENUE_PASSWORD="xxxxxxxxxxxx"
export CLOUDAVENUE_URL="https://console2.cloudavenue.orange-business.com"
# main.tf file
terraform {
  required_providers {
    cloudavenue = {
      source  = "orange-cloudavenue/cloudavenue"
      version = "0.18.5" # Last version (31/07/2024)
    }
  }
}

provider "cloudavenue" {
}

locals {
  m_vdcs_resources = {
  }
}

resource "cloudavenue_vdc" "vdcs" {
  for_each = local.m_vdcs_resources # In this example, local.m_vdcs_resources equal "{}"

  name                  = each.key
  cpu_allocated         = each.value.cpu_allocated
  cpu_speed_in_mhz      = each.value.cpu_speed
  memory_allocated      = each.value.memory
  billing_model         = each.value.compute_billing
  disponibility_class   = each.value.disponibility
  service_class         = each.value.service_class
  storage_billing_model = each.value.storage_billing
  storage_profiles      = each.value.storage_profiles
}

After, i run theses commands in bash console :

# Load env vars
. .env

# Download provider cloud avenue
terraform init

# Plan
terraform plan

Normally, with empty for_each, no resource will be created with no error.

But, since the version 0.16.0 to "0.18.5"(31/07/2024), we obtain this bug:

│ Error: Service class attribute is not valid
│ 
│   with cloudavenue_vdc.vdcs,
│   on main.tf line 28, in resource "cloudavenue_vdc" "vdcs":
│   28:   service_class         = each.value.service_class
│ 
│ service class not found

We have the same error with the command terraform apply because apply make also a plan.

I don't know how to pass trough this bug.

In another part, if we remove the for_each, we kill the model of yours other terraform deployment.

Regards.

jcnaud commented 2 months ago

I just see you make a merge request with adding a new env CLOUDAVENUE_VDC_VALIDATION var to disable vdc resource validation.

I will test this workaround with the next release if the next release implement your code modification.

#.env file
export CLOUDAVENUE_VDC_VALIDATION=false

...

Regards.

jcnaud commented 1 month ago

Good !

It works with the workaround and the last version "0.19.0".

Regards.