oracle / terraform-provider-oci

Terraform Oracle Cloud Infrastructure provider
https://www.terraform.io/docs/providers/oci/
Mozilla Public License 2.0
758 stars 676 forks source link

DBaaS State File Stores/Provisions Incorrect CPU Core Count #539

Closed HJeon139 closed 6 years ago

HJeon139 commented 6 years ago

Terraform Version 0.11.7

$ terraform -v Terraform v0.11.7

OCI Provider Version

$ /terraform-provider-oci_v2.1.10

Description

Summary

OCI Provider stores incorrect value in state file or provisions with an incorrect value for cpu count.

Details

Validation on OCI has been updated to check if the cpu count is outside the limits for the requested shape. https://docs.us-phoenix-1.oraclecloud.com/Content/Database/Concepts/overview.htm Because of this, we are passing in cpu count as 4 and the shape as VM.Instance1.4. However, the provider stores the cpu count as 8. As a result, any following runs will force a new resource, forcing the process to destroy any configured db and delay builds by the OCI DBaaS Provisioning time (~90 mins).

Steps to reproduce

  1. Build DB by running terraform apply

  2. Check state file to compare input and saved values for oci_database_db_system.database.*.cpu_core_count.

Expected behavior

This value should be the same as the input.

Bug behavior

This value is different from the input.

  1. run terraform apply again
Expected behavior

Terraform recognizes there has been no changes and does nothing.

Bug behavior

Terraform reads that the state file has cpu_core_count=8 but configuration has cpu_core_count=4. Terrraform forces new resource to apply change.

Terraform Plan

Database Resource and Outputs

resource "oci_database_db_system" "database" {
  count                   = "1"

  availability_domain     = "${var.availability_domain}"
  compartment_id          = "${var.compartment_ocid}"
  cpu_core_count          = "${var.cpu_core_count}"
  database_edition        = "ENTERPRISE_EDITION_EXTREME_PERFORMANCE"
  db_home {
    database {
      "admin_password"    = "${var.password}"
      "db_name"           = "${var.db_name}"
      "character_set"     = "AL32UTF8"
      "ncharacter_set"    = "AL16UTF16"
      "db_workload"       = "OLTP"
    }
    db_version            = "12.1.0.2"
  }

  hostname                = "oracle-db"
  shape                   = "VM.Standard1.4"
  ssh_public_keys         = ["${file("${var.ssh_public_key}")}"]
  subnet_id               = "${var.subnet_id}"

  cluster_name            = "DB"
  data_storage_size_in_gb = "256"
  disk_redundancy         = "HIGH"
  display_name            = "Test-Oracle-DB"
  node_count              = "${var.node_count}"
  license_model           = "LICENSE_INCLUDED"
}

output "input_cpu_core_count" {
  value = "${var.cpu_core_count}"
}

output "output_cpu_core_count" {
  value = "${oci_database_db_system.database.*.cpu_core_count}"
}

Plan

terraform plan log

```shell Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. ------------------------------------------------------------------------ An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create ~ update in-place <= read (data resources) Terraform will perform the following actions: ~ data.oci_core_vnic.database_node_vnics[0] id: "" => availability_domain: "" => compartment_id: "" => display_name: "" => hostname_label: "" => is_primary: "" => mac_address: "" => private_ip_address: "" => public_ip_address: "" => skip_source_dest_check: "" => state: "" => subnet_id: "" => time_created: "" => vnic_id: "" => "[REDACTED]" ~ data.oci_core_vnic.database_node_vnics[1] id: "" => availability_domain: "" => compartment_id: "" => display_name: "" => hostname_label: "" => is_primary: "" => mac_address: "" => private_ip_address: "" => public_ip_address: "" => skip_source_dest_check: "" => state: "" => subnet_id: "" => time_created: "" => vnic_id: "" => "[REDACTED]" <= data.oci_database_databases.databases id: compartment_id: "[REDACTED]" databases.#: db_home_id: "[REDACTED]" <= data.oci_database_db_homes.database_homes id: compartment_id: "[REDACTED]" db_homes.#: db_system_id: "[REDACTED]" <= data.oci_database_db_nodes.database_nodes id: compartment_id: "[REDACTED]" db_nodes.#: db_system_id: "[REDACTED]" + oci_database_db_system.database id: availability_domain: "[REDACTED]" backup_subnet_id: cluster_name: "DB" compartment_id: "[REDACTED]" cpu_core_count: "4" data_storage_percentage: data_storage_size_in_gb: "256" database_edition: "ENTERPRISE_EDITION_EXTREME_PERFORMANCE" db_home.#: "1" db_home.0.database.#: "1" db_home.0.database.0.admin_password: db_home.0.database.0.character_set: "AL32UTF8" db_home.0.database.0.db_backup_config.#: db_home.0.database.0.db_name: "DB" db_home.0.database.0.db_workload: "OLTP" db_home.0.database.0.ncharacter_set: "AL16UTF16" db_home.0.database.0.pdb_name: db_home.0.db_version: "12.1.0.2" db_home.0.display_name: disk_redundancy: "HIGH" display_name: "Test-Oracle-DB" domain: hostname: "oracle-db" last_patch_history_entry_id: license_model: "LICENSE_INCLUDED" lifecycle_details: listener_port: node_count: "2" reco_storage_size_in_gb: scan_dns_record_id: scan_ip_ids.#: shape: "VM.Standard1.4" ssh_public_keys.#: "1" ssh_public_keys.0: "[REDACTED]" state: subnet_id: "[REDACTED]" time_created: version: vip_ids.#: Plan: 1 to add, 2 to change, 0 to destroy. ------------------------------------------------------------------------ Note: You didn't specify an "-out" parameter to save this plan, so Terraform can't guarantee that exactly these actions will be performed if "terraform apply" is subsequently run. ```

Apply log

terraform apply log

```shell An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create ~ update in-place <= read (data resources) Terraform will perform the following actions: ~ data.oci_core_vnic.database_node_vnics[0] id: "" => availability_domain: "" => compartment_id: "" => display_name: "" => hostname_label: "" => is_primary: "" => mac_address: "" => private_ip_address: "" => public_ip_address: "" => skip_source_dest_check: "" => state: "" => subnet_id: "" => time_created: "" => vnic_id: "" => "[REDACTED]" ~ data.oci_core_vnic.database_node_vnics[1] id: "" => availability_domain: "" => compartment_id: "" => display_name: "" => hostname_label: "" => is_primary: "" => mac_address: "" => private_ip_address: "" => public_ip_address: "" => skip_source_dest_check: "" => state: "" => subnet_id: "" => time_created: "" => vnic_id: "" => "[REDACTED]" <= data.oci_database_databases.databases id: compartment_id: "[REDACTED]" databases.#: db_home_id: "[REDACTED]" <= data.oci_database_db_homes.database_homes id: compartment_id: "[REDACTED]" db_homes.#: db_system_id: "[REDACTED]" <= data.oci_database_db_nodes.database_nodes id: compartment_id: "[REDACTED]" db_nodes.#: db_system_id: "[REDACTED]" + oci_database_db_system.database id: availability_domain: "[REDACTED]" backup_subnet_id: cluster_name: "DB" compartment_id: "[REDACTED]" cpu_core_count: "4" data_storage_percentage: data_storage_size_in_gb: "256" database_edition: "ENTERPRISE_EDITION_EXTREME_PERFORMANCE" db_home.#: "1" db_home.0.database.#: "1" db_home.0.database.0.admin_password: db_home.0.database.0.character_set: "AL32UTF8" db_home.0.database.0.db_backup_config.#: db_home.0.database.0.db_name: "DB" db_home.0.database.0.db_workload: "OLTP" db_home.0.database.0.ncharacter_set: "AL16UTF16" db_home.0.database.0.pdb_name: db_home.0.db_version: "12.1.0.2" db_home.0.display_name: disk_redundancy: "HIGH" display_name: "Test-Oracle-DB" domain: hostname: "oracle-db" last_patch_history_entry_id: license_model: "LICENSE_INCLUDED" lifecycle_details: listener_port: node_count: "2" reco_storage_size_in_gb: scan_dns_record_id: scan_ip_ids.#: shape: "VM.Standard1.4" ssh_public_keys.#: "1" ssh_public_keys.0: "[REDACTED]" state: subnet_id: "[REDACTED]" time_created: version: vip_ids.#: Plan: 1 to add, 2 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes oci_database_db_system.database: Creating... availability_domain: "" => "[REDACTED]" backup_subnet_id: "" => "" cluster_name: "" => "DB" compartment_id: "" => "[REDACTED]" cpu_core_count: "" => "4" data_storage_percentage: "" => "" data_storage_size_in_gb: "" => "256" database_edition: "" => "ENTERPRISE_EDITION_EXTREME_PERFORMANCE" db_home.#: "" => "1" db_home.0.database.#: "" => "1" db_home.0.database.0.admin_password: "" => "" db_home.0.database.0.character_set: "" => "AL32UTF8" db_home.0.database.0.db_backup_config.#: "" => "" db_home.0.database.0.db_name: "" => "DB" db_home.0.database.0.db_workload: "" => "OLTP" db_home.0.database.0.ncharacter_set: "" => "AL16UTF16" db_home.0.database.0.pdb_name: "" => "" db_home.0.db_version: "" => "12.1.0.2" db_home.0.display_name: "" => "" disk_redundancy: "" => "HIGH" display_name: "" => "Test-Oracle-DB" domain: "" => "" hostname: "" => "oracle-db" last_patch_history_entry_id: "" => "" license_model: "" => "LICENSE_INCLUDED" lifecycle_details: "" => "" listener_port: "" => "" node_count: "" => "2" reco_storage_size_in_gb: "" => "" scan_dns_record_id: "" => "" scan_ip_ids.#: "" => "" shape: "" => "VM.Standard1.4" ssh_public_keys.#: "" => "1" ssh_public_keys.0: "" => "[REDACTED]" state: "" => "" subnet_id: "" => "[REDACTED]" time_created: "" => "" version: "" => "" vip_ids.#: "" => "" oci_database_db_system.database: Still creating... (10s elapsed) oci_database_db_system.database: Still creating... (20s elapsed) oci_database_db_system.database: Still creating... (30s elapsed) . . . oci_database_db_system.database: Still creating... (1h39m31s elapsed) oci_database_db_system.database: Creation complete after 1h39m37s (ID: [REDACTED]) data.oci_database_db_nodes.database_nodes: Refreshing state... data.oci_database_db_homes.database_homes: Refreshing state... data.oci_core_vnic.database_node_vnics[0]: Refreshing state... data.oci_core_vnic.database_node_vnics[1]: Refreshing state... data.oci_database_databases.databases: Refreshing state... Apply complete! Resources: 1 added, 0 changed, 0 destroyed. Outputs: input_cpu_core_count = 4 output_cpu_core_count = [ 8 ] ```

2nd apply (to show force new resource)

terraform 2nd apply log

```shell oci_database_db_system.database: Refreshing state... (ID: ocid1.dbsystem.oc1.iad.abuwcljsbkpmy4cz...bij4etsboxbw6aldcmsayzo4budg7byczbk3wq) data.oci_database_db_homes.database_homes: Refreshing state... data.oci_database_db_nodes.database_nodes: Refreshing state... data.oci_core_vnic.database_node_vnics[0]: Refreshing state... data.oci_core_vnic.database_node_vnics[1]: Refreshing state... data.oci_database_databases.databases: Refreshing state... An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: ~ update in-place -/+ destroy and then create replacement <= read (data resources) Terraform will perform the following actions: ~ data.oci_core_vnic.database_node_vnics[0] id: "" => availability_domain: "" => compartment_id: "" => display_name: "" => hostname_label: "" => is_primary: "" => mac_address: "" => private_ip_address: "" => public_ip_address: "" => skip_source_dest_check: "" => state: "" => subnet_id: "" => time_created: "" => vnic_id: "" => "[REDACTED]" ~ data.oci_core_vnic.database_node_vnics[1] id: "" => availability_domain: "" => compartment_id: "" => display_name: "" => hostname_label: "" => is_primary: "" => mac_address: "" => private_ip_address: "" => public_ip_address: "" => skip_source_dest_check: "" => state: "" => subnet_id: "" => time_created: "" => vnic_id: "" => "[REDACTED]" <= data.oci_database_databases.databases id: compartment_id: "[REDACTED]" databases.#: db_home_id: "[REDACTED]" <= data.oci_database_db_homes.database_homes id: compartment_id: "[REDACTED]" db_homes.#: db_system_id: "[REDACTED]" <= data.oci_database_db_nodes.database_nodes id: compartment_id: "[REDACTED]" db_nodes.#: db_system_id: "[REDACTED]" -/+ oci_database_db_system.database (new resource required) id: "[REDACTED]" => (forces new resource) availability_domain: "[REDACTED]" => "[REDACTED]" backup_subnet_id: "" => cluster_name: "DB" => "DB" compartment_id: "[REDACTED]" => "[REDACTED]" cpu_core_count: "8" => "4" (forces new resource) data_storage_percentage: "80" => data_storage_size_in_gb: "256" => "256" database_edition: "ENTERPRISE_EDITION_EXTREME_PERFORMANCE" => "ENTERPRISE_EDITION_EXTREME_PERFORMANCE" db_home.#: "1" => "1" db_home.0.database.#: "1" => "1" db_home.0.database.0.admin_password: => (attribute changed) db_home.0.database.0.character_set: "AL32UTF8" => "AL32UTF8" db_home.0.database.0.db_backup_config.#: "0" => db_home.0.database.0.db_name: "DB" => "DB" db_home.0.database.0.db_workload: "OLTP" => "OLTP" db_home.0.database.0.ncharacter_set: "AL16UTF16" => "AL16UTF16" db_home.0.database.0.pdb_name: "" => db_home.0.db_version: "12.1.0.2" => "12.1.0.2" db_home.0.display_name: "" => disk_redundancy: "HIGH" => "HIGH" display_name: "Test-Oracle-DB" => "Test-Oracle-DB" domain: "[REDACTED]" => hostname: "oracle-db" => "oracle-db" last_patch_history_entry_id: "" => license_model: "LICENSE_INCLUDED" => "LICENSE_INCLUDED" lifecycle_details: "" => listener_port: "1521" => node_count: "2" => "2" reco_storage_size_in_gb: "256" => scan_dns_record_id: "[REDACTED]" => scan_ip_ids.#: "3" => shape: "VM.Standard1.4" => "VM.Standard1.4" ssh_public_keys.#: "1" => "1" ssh_public_keys.0: "[REDACTED]" (forces new resource) state: "AVAILABLE" => subnet_id: "[REDACTED]" => "[REDACTED]" time_created: "2018-06-01 18:39:16.419 +0000 UTC" => version: "12.2.0.1.180116" => vip_ids.#: "2" => Plan: 1 to add, 2 to change, 1 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: no Error: Apply cancelled. ```

HJeon139 commented 6 years ago

It appears that the cpu core count is no longer being used and is instead calculated based on the shape. So cpu count for a 2 node DB is 8 when using shape VM.Instance1.4.

Perhaps the fix would be to make the field not required and not force new resource as mentioned in the other issue:

https://github.com/oracle/terraform-provider-oci/issues/517

drauba commented 6 years ago

It appears that the cpu core count is no longer being used and is instead calculated based on the shape. So cpu count for a 2 node DB is 8 when using shape VM.Instance1.4.

This is only true for Database Systems with a VM node. CPU Core Count is used for Database Systems running on Baremetal shapes.

rcohenma commented 6 years ago

From the documentation:

To solve your issue we will make cpu_core_count Optional rather than Required so that you can avoid specifying it when using VM shapes.

While we work on this fix you can change your config to match the value in the statefile (the value returned by the service). This will avoid unnecessary diffs on subsequent applies.

HJeon139 commented 6 years ago

The issue we had where OCI would not set it to the calculated value (node count * cpu per node) is now resolved. We are able to spin up db systems by using the calculated value. (e.g. in the example above we can now put in shape 1.4 and node count 2 with cpu core count 8).

codycushing commented 6 years ago

Hello, this has been addressed in release 2.1.13