diff --git a/examples/ibm-db2/README.md b/examples/ibm-db2/README.md new file mode 100644 index 0000000000..f8022a8290 --- /dev/null +++ b/examples/ibm-db2/README.md @@ -0,0 +1,49 @@ +# This example shows how to create an instance of IBM Db2 SaaS on IBM Cloud and configure connectivity from a VSI + +This sample provisions an IBM Db2 SaaS instance on IBM Cloud. + +## Costs + +This sample uses chargable services and **will** incur costs for the time the services are deployed. Execution of `terraform destroy` will result in deletion of all resources including the Db2 SaaS service instance. Billing for Db2 SaaS will terminate on the hour. + + +## Dependencies + +- User has IAM permissions to create and configure an IBM Db2 SaaS for IBM Cloud Instance in the resource group specified. + +## Configuration + +The terraform template requires you to provide values for the terraform variables. +Copy the file `variables.tfvars.example` as `variables.tfvars`. Provide appropriate values to the variables within the file. + +The following variables need to be set in the `terraform.tfvars` file before use: + +* `ibmcloud_api_key` - An API key for IBM Cloud services. If you don't have one already, go to https://cloud.ibm.com/iam/#/apikeys and create a new key. +* `region` - IBM Cloud region where your Db2 SaaS will be created. +* `resource_group` - Resource group within which Db2 SaaS will be created. + + +The example is deployed in the us-south region. The `region` parameter in main.tf must be set to the same region as the Db2 SaaS instance will be deployed in as defined by the `location` parameter on the ibm_db2 resource. + +## Outputs + +The composed connection string of Db2 SaaS Instance CRN. `crn:v1:bluemix:public:dashdb-for-transactions:us-south:a/60970f92286548d8a64cbb45bce39bc1:deae06ff-3966-4534-bfa0-4b42281e7cef::` + + +## Running the configuration +1. Initialize the terraform project to download the terraform providers and modules +```bash +$ terraform init +``` +2. Perform terraform plan with the variables. Run `terraform plan` to see the changes that will be applied to your account after you make any change to the terraform code. +```bash +$ terraform plan -var-file=./variables.tfvars +``` + +3. Perform terraform apply with the variables. Run `terraform apply` to apply the changes to the IBM Cloud after that will be applied to your account after you make any change to the terraform code. + +```bash +$ terraform apply -var-file=./variables.tfvars +``` + +Run `terraform destroy` to clean up and destroy all the resources created for the toolchain. diff --git a/examples/ibm-db2/main.tf b/examples/ibm-db2/main.tf new file mode 100644 index 0000000000..f4098ac82e --- /dev/null +++ b/examples/ibm-db2/main.tf @@ -0,0 +1,38 @@ +data "ibm_resource_group" "group" { + name = var.resource_group +} + +//Db2 SaaS Instance Creation +resource "ibm_db2" "db2_instance" { + name = "demo-db2" + service = "dashdb-for-transactions" + plan = "performance" + location = var.region + resource_group_id = data.ibm_resource_group.group.id + service_endpoints = "public-and-private" + instance_type = "bx2.4x16" + high_availability = "yes" + backup_location = "us" + + parameters_json = < 0.12 | + +## Providers + +| Name | Version | +|------|---------| +| ibm | 1.13.1 | diff --git a/examples/ibm-iam-identity-effective-account-settings/main.tf b/examples/ibm-iam-identity-effective-account-settings/main.tf new file mode 100644 index 0000000000..8ab985681d --- /dev/null +++ b/examples/ibm-iam-identity-effective-account-settings/main.tf @@ -0,0 +1,14 @@ +provider "ibm" { + ibmcloud_api_key = var.ibmcloud_api_key +} + +// Data source is not linked to a resource instance +// Uncomment if an existing data source instance exists +/* +// Create iam_effective_account_settings data source +data "ibm_iam_effective_account_settings" "iam_effective_account_settings_instance" { + account_id = var.iam_effective_account_settings_account_id + include_history = var.iam_effective_account_settings_include_history + resolve_user_mfa = var.iam_effective_account_settings_resolve_user_mfa +} +*/ diff --git a/examples/ibm-iam-identity-effective-account-settings/outputs.tf b/examples/ibm-iam-identity-effective-account-settings/outputs.tf new file mode 100644 index 0000000000..e69de29bb2 diff --git a/examples/ibm-iam-identity-effective-account-settings/variables.tf b/examples/ibm-iam-identity-effective-account-settings/variables.tf new file mode 100644 index 0000000000..e4d649688a --- /dev/null +++ b/examples/ibm-iam-identity-effective-account-settings/variables.tf @@ -0,0 +1,21 @@ +variable "ibmcloud_api_key" { + description = "IBM Cloud API key" + type = string +} + +// Data source arguments for iam_effective_account_settings +variable "iam_effective_account_settings_account_id" { + description = "Unique ID of the account." + type = string + default = "account_id" +} +variable "iam_effective_account_settings_include_history" { + description = "Defines if the entity history is included in the response." + type = bool + default = false +} +variable "iam_effective_account_settings_resolve_user_mfa" { + description = "Enrich MFA exemptions with user information." + type = bool + default = false +} diff --git a/examples/ibm-iam-identity-effective-account-settings/versions.tf b/examples/ibm-iam-identity-effective-account-settings/versions.tf new file mode 100644 index 0000000000..54c9d03e8d --- /dev/null +++ b/examples/ibm-iam-identity-effective-account-settings/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.0" + required_providers { + ibm = { + source = "IBM-Cloud/ibm" + version = "1.52.0-beta0" + } + } +} diff --git a/go.mod b/go.mod index 238fb8849e..75b56fac53 100644 --- a/go.mod +++ b/go.mod @@ -5,13 +5,13 @@ go 1.22.4 toolchain go1.22.5 require ( - github.com/IBM-Cloud/bluemix-go v0.0.0-20240926024252-81b3928fd062 + github.com/IBM-Cloud/bluemix-go v0.0.0-20241117121028-a3be206688b3 github.com/IBM-Cloud/container-services-go-sdk v0.0.0-20240725064144-454a2ae23113 github.com/IBM-Cloud/power-go-client v1.8.3 github.com/IBM/apigateway-go-sdk v0.0.0-20210714141226-a5d5d49caaca github.com/IBM/appconfiguration-go-admin-sdk v0.3.0 github.com/IBM/appid-management-go-sdk v0.0.0-20210908164609-dd0e0eaf732f - github.com/IBM/cloud-databases-go-sdk v0.7.0 + github.com/IBM/cloud-databases-go-sdk v0.7.1 github.com/IBM/cloudant-go-sdk v0.8.0 github.com/IBM/code-engine-go-sdk v0.0.0-20240808131715-b9d168602dac github.com/IBM/configuration-aggregator-go-sdk v0.0.2 @@ -40,7 +40,7 @@ require ( github.com/IBM/secrets-manager-go-sdk/v2 v2.0.7 github.com/IBM/vmware-go-sdk v0.1.2 github.com/IBM/vpc-beta-go-sdk v0.8.0 - github.com/IBM/vpc-go-sdk v0.62.0 + github.com/IBM/vpc-go-sdk v0.63.1 github.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5 github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 github.com/akamai/AkamaiOPEN-edgegrid-golang/v5 v5.0.0 diff --git a/go.sum b/go.sum index fa2621d224..9606e1ef56 100644 --- a/go.sum +++ b/go.sum @@ -113,8 +113,8 @@ github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3 github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.4.4/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/IBM-Cloud/bluemix-go v0.0.0-20240926024252-81b3928fd062 h1:VCFztsAnZBuzyVeOrpFEJFPiKDyx6tVOLe+p3VBsfWk= -github.com/IBM-Cloud/bluemix-go v0.0.0-20240926024252-81b3928fd062/go.mod h1:/7hMjdZA6fEpd/dQAOEABxKEwN0t72P3PlpEDu0Y7bE= +github.com/IBM-Cloud/bluemix-go v0.0.0-20241117121028-a3be206688b3 h1:eIa+RXJZ188p1S5q+fu3feDiL6dtp0W2IB1LM0B/plE= +github.com/IBM-Cloud/bluemix-go v0.0.0-20241117121028-a3be206688b3/go.mod h1:/7hMjdZA6fEpd/dQAOEABxKEwN0t72P3PlpEDu0Y7bE= github.com/IBM-Cloud/container-services-go-sdk v0.0.0-20240725064144-454a2ae23113 h1:f2Erqfea1dKpaTFagTJM6W/wnD3JGq/Vn9URh8nuRwk= github.com/IBM-Cloud/container-services-go-sdk v0.0.0-20240725064144-454a2ae23113/go.mod h1:xUQL9SGAjoZFd4GNjrjjtEpjpkgU7RFXRyHesbKTjiY= github.com/IBM-Cloud/ibm-cloud-cli-sdk v0.5.3/go.mod h1:RiUvKuHKTBmBApDMUQzBL14pQUGKcx/IioKQPIcRQjs= @@ -128,8 +128,8 @@ github.com/IBM/appconfiguration-go-admin-sdk v0.3.0 h1:OqFxnDxro0JiRwHBKytCcseY2 github.com/IBM/appconfiguration-go-admin-sdk v0.3.0/go.mod h1:xPxAYhr/uywUIDEo/JqWbkUdTryPdzRdYBfUpA5IjoE= github.com/IBM/appid-management-go-sdk v0.0.0-20210908164609-dd0e0eaf732f h1:4c1kqY4GqmkQ+tO03rneDb74Tv7BhTj8jDiDB1p8mdM= github.com/IBM/appid-management-go-sdk v0.0.0-20210908164609-dd0e0eaf732f/go.mod h1:d22kTYY7RYBWcQlZpqrSdshpB/lJ16viWS5Sbjtlc8s= -github.com/IBM/cloud-databases-go-sdk v0.7.0 h1:prvLebKD1kcIk81D6yRhOr/TWp1VQJGLhGAasQr7RtA= -github.com/IBM/cloud-databases-go-sdk v0.7.0/go.mod h1:JYucI1PdwqbAd8XGdDAchxzxRP7bxOh1zUnseovHKsc= +github.com/IBM/cloud-databases-go-sdk v0.7.1 h1:5kK4/3NUsGxZzmuUe+1ftajpOQbeDVh5VeemrPgROP4= +github.com/IBM/cloud-databases-go-sdk v0.7.1/go.mod h1:JYucI1PdwqbAd8XGdDAchxzxRP7bxOh1zUnseovHKsc= github.com/IBM/cloudant-go-sdk v0.8.0 h1:XzaqZFy5fm1Q9+iK52X5zRW39SHaahT9pf5SRgVTsTY= github.com/IBM/cloudant-go-sdk v0.8.0/go.mod h1:zDGBs8ideVtn9MehXbIQNI3852B68BsMtKJvq3iPn/Q= github.com/IBM/code-engine-go-sdk v0.0.0-20240808131715-b9d168602dac h1:9Y5TB9Ar2SM6JPr2kM6c9pHSdSuHMDCIcbvTa/hNTj4= @@ -196,6 +196,10 @@ github.com/IBM/vpc-beta-go-sdk v0.8.0 h1:cEPpv4iw3Ba5W2d0AWg3TIbKeJ8y1nPuUuibR5J github.com/IBM/vpc-beta-go-sdk v0.8.0/go.mod h1:hORgIyTFRzXrZIK9IohaWmCRBBlYiDRagsufi7M6akE= github.com/IBM/vpc-go-sdk v0.62.0 h1:Xga74D70ziD7nzm51ue3othHz1epMLVkGP/L6/Be+/0= github.com/IBM/vpc-go-sdk v0.62.0/go.mod h1:VBR6bAznHsNCFA89Ue4JFQpqCcFp8F5neqbCFCyks4Q= +github.com/IBM/vpc-go-sdk v0.63.0 h1:0eSG/8WLK4fW7AvPHlhCmPEe819pgWLF1OIxF0vR43A= +github.com/IBM/vpc-go-sdk v0.63.0/go.mod h1:VBR6bAznHsNCFA89Ue4JFQpqCcFp8F5neqbCFCyks4Q= +github.com/IBM/vpc-go-sdk v0.63.1 h1:HqQeq2wGI2pF4y0/m18EaPsOEEXFjyml+xwlLC9AiXE= +github.com/IBM/vpc-go-sdk v0.63.1/go.mod h1:VBR6bAznHsNCFA89Ue4JFQpqCcFp8F5neqbCFCyks4Q= github.com/Jeffail/gabs v1.1.1 h1:V0uzR08Hj22EX8+8QMhyI9sX2hwRu+/RJhJUmnwda/E= github.com/Jeffail/gabs v1.1.1/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc= github.com/Logicalis/asn1 v0.0.0-20190312173541-d60463189a56 h1:vuquMR410psHNax14XKNWa0Ae/kYgWJcXi0IFuX60N0= diff --git a/ibm/flex/structures.go b/ibm/flex/structures.go index 41c407e251..dadae9c479 100644 --- a/ibm/flex/structures.go +++ b/ibm/flex/structures.go @@ -2903,6 +2903,15 @@ func ResourceTagsCustomizeDiff(diff *schema.ResourceDiff) error { return nil } +func OnlyInUpdateDiff(resources []string, diff *schema.ResourceDiff) error { + for _, r := range resources { + if diff.HasChange(r) && diff.Id() == "" { + return fmt.Errorf("the %s can't be used at create time", r) + } + } + return nil +} + func ResourceValidateAccessTags(diff *schema.ResourceDiff, meta interface{}) error { if value, ok := diff.GetOkExists("access_tags"); ok { diff --git a/ibm/provider/provider.go b/ibm/provider/provider.go index c9bc22c434..7e30cd4daa 100644 --- a/ibm/provider/provider.go +++ b/ibm/provider/provider.go @@ -34,6 +34,7 @@ import ( "github.com/IBM-Cloud/terraform-provider-ibm/ibm/service/contextbasedrestrictions" "github.com/IBM-Cloud/terraform-provider-ibm/ibm/service/cos" "github.com/IBM-Cloud/terraform-provider-ibm/ibm/service/database" + "github.com/IBM-Cloud/terraform-provider-ibm/ibm/service/db2" "github.com/IBM-Cloud/terraform-provider-ibm/ibm/service/directlink" "github.com/IBM-Cloud/terraform-provider-ibm/ibm/service/dnsservices" "github.com/IBM-Cloud/terraform-provider-ibm/ibm/service/enterprise" @@ -319,6 +320,7 @@ func Provider() *schema.Provider { "ibm_database_tasks": database.DataSourceIBMDatabaseTasks(), "ibm_database_backup": database.DataSourceIBMDatabaseBackup(), "ibm_database_backups": database.DataSourceIBMDatabaseBackups(), + "ibm_db2": db2.DataSourceIBMDb2Instance(), "ibm_compute_bare_metal": classicinfrastructure.DataSourceIBMComputeBareMetal(), "ibm_compute_image_template": classicinfrastructure.DataSourceIBMComputeImageTemplate(), "ibm_compute_placement_group": classicinfrastructure.DataSourceIBMComputePlacementGroup(), @@ -371,6 +373,7 @@ func Provider() *schema.Provider { "ibm_iam_access_group_template_versions": iamaccessgroup.DataSourceIBMIAMAccessGroupTemplateVersions(), "ibm_iam_access_group_template_assignment": iamaccessgroup.DataSourceIBMIAMAccessGroupTemplateAssignment(), "ibm_iam_account_settings": iamidentity.DataSourceIBMIAMAccountSettings(), + "ibm_iam_effective_account_settings": iamidentity.DataSourceIBMIamEffectiveAccountSettings(), "ibm_iam_auth_token": iamidentity.DataSourceIBMIAMAuthToken(), "ibm_iam_role_actions": iampolicy.DataSourceIBMIAMRoleAction(), "ibm_iam_users": iamidentity.DataSourceIBMIAMUsers(), @@ -1033,6 +1036,7 @@ func Provider() *schema.Provider { "ibm_cis": cis.ResourceIBMCISInstance(), "ibm_database": database.ResourceIBMDatabaseInstance(), + "ibm_db2": db2.ResourceIBMDb2Instance(), "ibm_cis_domain": cis.ResourceIBMCISDomain(), "ibm_cis_domain_settings": cis.ResourceIBMCISSettings(), "ibm_cis_firewall": cis.ResourceIBMCISFirewallRecord(), diff --git a/ibm/service/database/data_source_ibm_database_connection.go b/ibm/service/database/data_source_ibm_database_connection.go index e1ef5ae65e..01e982b5cb 100644 --- a/ibm/service/database/data_source_ibm_database_connection.go +++ b/ibm/service/database/data_source_ibm_database_connection.go @@ -2226,14 +2226,3 @@ func DataSourceIBMDatabaseConnectionMySQLConnectionURIToMap(model *clouddatabase } return modelMap, nil } - -func DataSourceIBMDatabaseConnectionConnectionBundleToMap(model *clouddatabasesv5.ConnectionBundle) (map[string]interface{}, error) { - modelMap := make(map[string]interface{}) - if model.Name != nil { - modelMap["name"] = *model.Name - } - if model.BundleBase64 != nil { - modelMap["bundle_base64"] = *model.BundleBase64 - } - return modelMap, nil -} diff --git a/ibm/service/database/data_source_ibm_database_point_in_time_recovery_test.go b/ibm/service/database/data_source_ibm_database_point_in_time_recovery_test.go index 0a95020e99..78cca1f1b3 100644 --- a/ibm/service/database/data_source_ibm_database_point_in_time_recovery_test.go +++ b/ibm/service/database/data_source_ibm_database_point_in_time_recovery_test.go @@ -47,9 +47,9 @@ func testAccCheckIBMDatabaseDataSourceConfig3(name string) string { plan = "standard" location = "%[2]s" tags = ["one:two"] + service_endpoints = "private" } - - `, name, acc.Region()) + `, name, acc.Region()) } func testAccCheckIBMDatabasePitrDataSourceConfigBasic(name string) string { diff --git a/ibm/service/database/data_source_ibm_database_remotes_test.go b/ibm/service/database/data_source_ibm_database_remotes_test.go index b1cb0cd6da..1bc322cc33 100644 --- a/ibm/service/database/data_source_ibm_database_remotes_test.go +++ b/ibm/service/database/data_source_ibm_database_remotes_test.go @@ -51,6 +51,7 @@ func testAccCheckIBMDatabaseDataSourceConfig4(name string) string { plan = "standard" location = "%[2]s" tags = ["one:two"] + service_endpoints = "private" } resource "ibm_database" "db_replica" { @@ -61,6 +62,7 @@ func testAccCheckIBMDatabaseDataSourceConfig4(name string) string { plan = "standard" location = "%[2]s" tags = ["one:two"] + service_endpoints = "private" depends_on = [ ibm_database.db, diff --git a/ibm/service/database/data_source_ibm_database_test.go b/ibm/service/database/data_source_ibm_database_test.go index e7feef9a48..64ad3b1c7a 100644 --- a/ibm/service/database/data_source_ibm_database_test.go +++ b/ibm/service/database/data_source_ibm_database_test.go @@ -13,7 +13,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) -func TestAccIBMDatabaseDataSource_basic(t *testing.T) { +func TestAccIBMDatabaseDataSourceBasic(t *testing.T) { t.Parallel() databaseResourceGroup := "default" var databaseInstanceOne string @@ -36,7 +36,7 @@ func TestAccIBMDatabaseDataSource_basic(t *testing.T) { resource.TestCheckResourceAttr(dataName, "plan", "standard"), resource.TestCheckResourceAttr(dataName, "location", acc.Region()), resource.TestCheckResourceAttr(dataName, "adminuser", "admin"), - resource.TestCheckResourceAttr(dataName, "groups.0.memory.0.allocation_mb", "2048"), + resource.TestCheckResourceAttr(dataName, "groups.0.memory.0.allocation_mb", "8192"), resource.TestCheckResourceAttr(dataName, "groups.0.disk.0.allocation_mb", "10240"), resource.TestCheckResourceAttr(dataName, "allowlist.#", "0"), resource.TestCheckResourceAttr(dataName, "tags.#", "1"), @@ -65,7 +65,15 @@ func testAccCheckIBMDatabaseDataSourceConfig(databaseResourceGroup string, name location = "%[3]s" tags = ["one:two"] service_endpoints = "public" + + group { + group_id = "member" + + host_flavor { + id = "multitenant" + } + } } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } diff --git a/ibm/service/database/resource_ibm_database_edb_test.go b/ibm/service/database/resource_ibm_database_edb_test.go index bf15266c83..76d945b27f 100644 --- a/ibm/service/database/resource_ibm_database_edb_test.go +++ b/ibm/service/database/resource_ibm_database_edb_test.go @@ -37,7 +37,7 @@ func TestAccIBMEDBDatabaseInstanceBasic(t *testing.T) { resource.TestCheckResourceAttr(name, "adminuser", "admin"), resource.TestCheckResourceAttr(name, "groups.0.memory.0.allocation_mb", "49152"), resource.TestCheckResourceAttr(name, "groups.0.disk.0.allocation_mb", "61440"), - resource.TestCheckResourceAttr(name, "service_endpoints", "public"), + resource.TestCheckResourceAttr(name, "service_endpoints", "public-and-private"), resource.TestCheckResourceAttr(name, "allowlist.#", "1"), resource.TestCheckResourceAttr(name, "users.#", "1"), resource.TestCheckResourceAttr(name, "tags.#", "1"), @@ -159,6 +159,7 @@ func testAccCheckIBMDatabaseInstanceEDBMinimal(databaseResourceGroup string, nam plan = "standard" location = "%[3]s" service_endpoints = "public-and-private" + group { group_id = "member" host_flavor { diff --git a/ibm/service/database/resource_ibm_database_elasticsearch_platinum_test.go b/ibm/service/database/resource_ibm_database_elasticsearch_platinum_test.go index 3191ee5e99..de598df4df 100644 --- a/ibm/service/database/resource_ibm_database_elasticsearch_platinum_test.go +++ b/ibm/service/database/resource_ibm_database_elasticsearch_platinum_test.go @@ -248,10 +248,12 @@ func TestAccIBMDatabaseInstance_ElasticsearchPlatinum_Group(t *testing.T) { func TestAccIBMDatabaseInstanceElasticsearchPlatinumImport(t *testing.T) { t.Parallel() + databaseResourceGroup := "default" + var databaseInstanceOne string + serviceName := fmt.Sprintf("tf-Es-%d", acctest.RandIntRange(10, 100)) - //serviceName := "test_acc" resourceName := "ibm_database." + serviceName resource.Test(t, resource.TestCase{ @@ -322,7 +324,7 @@ func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumBasic(databaseResourceG delete = "15m" } } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumFullyspecified(databaseResourceGroup string, name string) string { @@ -371,7 +373,7 @@ func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumFullyspecified(database } } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumReduced(databaseResourceGroup string, name string) string { @@ -403,7 +405,7 @@ func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumReduced(databaseResourc delete = "15m" } } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumGroupMigration(databaseResourceGroup string, name string) string { @@ -439,7 +441,7 @@ func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumGroupMigration(database delete = "15m" } } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumNodeBasic(databaseResourceGroup string, name string) string { @@ -485,7 +487,7 @@ func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumNodeBasic(databaseResou delete = "15m" } } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumNodeFullyspecified(databaseResourceGroup string, name string) string { @@ -538,7 +540,7 @@ func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumNodeFullyspecified(data delete = "15m" } } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumNodeReduced(databaseResourceGroup string, name string) string { @@ -575,7 +577,7 @@ func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumNodeReduced(databaseRes delete = "15m" } } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumNodeScaleOut(databaseResourceGroup string, name string) string { @@ -612,7 +614,7 @@ func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumNodeScaleOut(databaseRe delete = "15m" } } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumGroupBasic(databaseResourceGroup string, name string) string { @@ -659,7 +661,7 @@ func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumGroupBasic(databaseReso delete = "15m" } } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumGroupFullyspecified(databaseResourceGroup string, name string) string { @@ -714,7 +716,7 @@ func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumGroupFullyspecified(dat } } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumGroupReduced(databaseResourceGroup string, name string) string { @@ -752,7 +754,7 @@ func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumGroupReduced(databaseRe delete = "15m" } } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumGroupScaleOut(databaseResourceGroup string, name string) string { @@ -789,7 +791,7 @@ func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumGroupScaleOut(databaseR delete = "15m" } } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumImport(databaseResourceGroup string, name string) string { @@ -805,7 +807,7 @@ func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumImport(databaseResource service = "databases-for-elasticsearch" plan = "platinum" location = "%[3]s" - service_endpoints = "public-and-private" + service_endpoints = "public-and-private" timeouts { create = "120m" @@ -814,5 +816,5 @@ func testAccCheckIBMDatabaseInstanceElasticsearchPlatinumImport(databaseResource } } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } diff --git a/ibm/service/database/resource_ibm_database_mongodb_enterprise_test.go b/ibm/service/database/resource_ibm_database_mongodb_enterprise_test.go index 866ab9530e..fa21b34d23 100644 --- a/ibm/service/database/resource_ibm_database_mongodb_enterprise_test.go +++ b/ibm/service/database/resource_ibm_database_mongodb_enterprise_test.go @@ -80,7 +80,7 @@ func TestAccIBMMongoDBEnterpriseDatabaseInstanceBasic(t *testing.T) { ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{ - "wait_time_minutes", "adminpassword", "group"}, + "wait_time_minutes", "adminpassword", "group", "deletion_protection"}, }, }, }) diff --git a/ibm/service/database/resource_ibm_database_mongodb_test.go b/ibm/service/database/resource_ibm_database_mongodb_test.go index 70c43725bb..58b7c59e8e 100644 --- a/ibm/service/database/resource_ibm_database_mongodb_test.go +++ b/ibm/service/database/resource_ibm_database_mongodb_test.go @@ -84,8 +84,8 @@ func TestAccIBMDatabaseInstanceMongodbImport(t *testing.T) { t.Parallel() databaseResourceGroup := "default" var databaseInstanceOne string + serviceName := fmt.Sprintf("tf-Mongo-%d", acctest.RandIntRange(10, 100)) - //serviceName := "test_acc" resourceName := "ibm_database." + serviceName resource.Test(t, resource.TestCase{ @@ -108,7 +108,7 @@ func TestAccIBMDatabaseInstanceMongodbImport(t *testing.T) { ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{ - "wait_time_minutes"}, + "wait_time_minutes", "deletion_protection"}, }, }, }) diff --git a/ibm/service/database/resource_ibm_database_postgresql_test.go b/ibm/service/database/resource_ibm_database_postgresql_test.go index 2718d3b6ba..1e1e8a8173 100644 --- a/ibm/service/database/resource_ibm_database_postgresql_test.go +++ b/ibm/service/database/resource_ibm_database_postgresql_test.go @@ -5,33 +5,12 @@ package database_test import ( "fmt" - "reflect" - "strings" "testing" - "time" - acc "github.com/IBM-Cloud/terraform-provider-ibm/ibm/acctest" - "github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns" - "github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex" - rc "github.com/IBM/platform-services-go-sdk/resourcecontrollerv2" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - - "github.com/IBM-Cloud/bluemix-go/bmxerror" - "github.com/IBM-Cloud/bluemix-go/models" -) - -const ( - databaseInstanceSuccessStatus = "active" - databaseInstanceProvisioningStatus = "provisioning" - databaseInstanceProgressStatus = "in progress" - databaseInstanceInactiveStatus = "inactive" - databaseInstanceFailStatus = "failed" - databaseInstanceRemovedStatus = "removed" - databaseInstanceReclamation = "pending_reclamation" ) func TestAccIBMDatabaseInstancePostgresBasic(t *testing.T) { @@ -83,11 +62,6 @@ func TestAccIBMDatabaseInstancePostgresBasic(t *testing.T) { resource.TestCheckResourceAttr(name, "logical_replication_slot.#", "2"), ), }, - // { - // ResourceName: name, - // ImportState: true, - // ImportStateVerify: true, - // }, }, }) } @@ -184,10 +158,12 @@ func TestAccIBMDatabaseInstancePostgresGroup(t *testing.T) { func TestAccIBMDatabaseInstancePostgresImport(t *testing.T) { t.Parallel() + databaseResourceGroup := "default" + var databaseInstanceOne string + serviceName := fmt.Sprintf("tf-Pgress-%d", acctest.RandIntRange(10, 100)) - //serviceName := "test_acc" resourceName := "ibm_database." + serviceName resource.Test(t, resource.TestCase{ @@ -218,13 +194,16 @@ func TestAccIBMDatabaseInstancePostgresImport(t *testing.T) { func TestAccIBMDatabaseInstancePostgresPITR(t *testing.T) { t.Parallel() + databaseResourceGroup := "default" + var databaseInstanceOne string var databaseInstanceTwo string + serviceName := fmt.Sprintf("tf-Pgress-%d", acctest.RandIntRange(10, 100)) - //serviceName := "test_acc" pitrServiceName := serviceName + "-pitr" - resourceName := "ibm_database." + serviceName + + sourceResource := "ibm_database." + serviceName pitrResource := "ibm_database." + pitrServiceName resource.Test(t, resource.TestCase{ @@ -235,15 +214,17 @@ func TestAccIBMDatabaseInstancePostgresPITR(t *testing.T) { { Config: testAccCheckIBMDatabaseInstancePostgresMinimal(databaseResourceGroup, serviceName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckIBMDatabaseInstanceExists(resourceName, &databaseInstanceOne), - resource.TestCheckResourceAttr(resourceName, "name", serviceName), - resource.TestCheckResourceAttr(resourceName, "service", "databases-for-postgresql"), - resource.TestCheckResourceAttr(resourceName, "plan", "standard"), - resource.TestCheckResourceAttr(resourceName, "location", acc.Region()), + testAccCheckIBMDatabaseInstanceExists(sourceResource, &databaseInstanceOne), + resource.TestCheckResourceAttr(sourceResource, "name", serviceName), + resource.TestCheckResourceAttr(sourceResource, "service", "databases-for-postgresql"), + resource.TestCheckResourceAttr(sourceResource, "plan", "standard"), + resource.TestCheckResourceAttr(sourceResource, "location", acc.Region()), ), }, { - Config: testAccCheckIBMDatabaseInstancePostgresMinimal_PITR(databaseResourceGroup, serviceName), + Config: acc.ConfigCompose( + testAccCheckIBMDatabaseInstancePostgresMinimal(databaseResourceGroup, serviceName), + testAccCheckIBMDatabaseInstancePostgresMinimal_PITR(databaseResourceGroup, serviceName)), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckIBMDatabaseInstanceExists(pitrResource, &databaseInstanceTwo), resource.TestCheckResourceAttr(pitrResource, "name", pitrServiceName), @@ -315,128 +296,6 @@ func TestAccIBMDatabaseInstancePostgresReadReplicaPromotion(t *testing.T) { }) } -func testAccCheckIBMDatabaseInstanceDestroy(s *terraform.State) error { - rsContClient, err := acc.TestAccProvider.Meta().(conns.ClientSession).ResourceControllerV2API() - if err != nil { - return err - } - for _, rs := range s.RootModule().Resources { - if rs.Type != "ibm_database" { - continue - } - - instanceID := rs.Primary.ID - - rsInst := rc.GetResourceInstanceOptions{ - ID: &instanceID, - } - instance, response, err := rsContClient.GetResourceInstance(&rsInst) - if err == nil { - if !reflect.DeepEqual(instance, models.ServiceInstance{}) && *instance.State == "active" { - return fmt.Errorf("Database still exists: %s", rs.Primary.ID) - } - } else { - if !strings.Contains(err.Error(), "404") { - return fmt.Errorf("[ERROR] Error checking if database (%s) has been destroyed: %s %s", rs.Primary.ID, err, response) - } - } - } - return nil -} - -func testAccDatabaseInstanceManuallyDelete(tfDatabaseID *string) resource.TestCheckFunc { - return func(s *terraform.State) error { - _ = testAccDatabaseInstanceManuallyDeleteUnwrapped(s, tfDatabaseID) - return nil - } -} - -func testAccDatabaseInstanceManuallyDeleteUnwrapped(s *terraform.State, tfDatabaseID *string) error { - rsConClient, err := acc.TestAccProvider.Meta().(conns.ClientSession).ResourceControllerV2API() - if err != nil { - return err - } - instance := *tfDatabaseID - var instanceID string - if strings.HasPrefix(instance, "crn") { - instanceID = instance - } else { - _, instanceID, _ = flex.ConvertTftoCisTwoVar(instance) - } - recursive := true - deleteReq := rc.DeleteResourceInstanceOptions{ - ID: &instanceID, - Recursive: &recursive, - } - response, err := rsConClient.DeleteResourceInstance(&deleteReq) - if err != nil { - return fmt.Errorf("[ERROR] Error deleting resource instance: %s %s", err, response) - } - - _ = &resource.StateChangeConf{ - Pending: []string{databaseInstanceProgressStatus, databaseInstanceInactiveStatus, databaseInstanceSuccessStatus}, - Target: []string{databaseInstanceRemovedStatus}, - Refresh: func() (interface{}, string, error) { - rsInst := rc.GetResourceInstanceOptions{ - ID: &instanceID, - } - instance, response, err := rsConClient.GetResourceInstance(&rsInst) - if err != nil { - if apiErr, ok := err.(bmxerror.RequestFailure); ok && apiErr.StatusCode() == 404 { - return instance, databaseInstanceSuccessStatus, nil - } - return nil, "", err - } - if *instance.State == databaseInstanceFailStatus { - return instance, *instance.State, fmt.Errorf("[ERROR] The resource instance %s failed to delete: %v %s", instanceID, err, response) - } - return instance, *instance.State, nil - }, - Timeout: 90 * time.Second, - Delay: 10 * time.Second, - MinTimeout: 10 * time.Second, - } - if err != nil { - return fmt.Errorf("[ERROR] Error waiting for resource instance (%s) to be deleted: %s", instanceID, err) - } - return nil -} - -func testAccCheckIBMDatabaseInstanceExists(n string, tfDatabaseID *string) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[n] - if !ok { - return fmt.Errorf("Not found: %s", n) - } - - rsContClient, err := acc.TestAccProvider.Meta().(conns.ClientSession).ResourceControllerV2API() - if err != nil { - return err - } - instanceID := rs.Primary.ID - - rsInst := rc.GetResourceInstanceOptions{ - ID: &instanceID, - } - instance, response, err := rsContClient.GetResourceInstance(&rsInst) - if err != nil { - if strings.Contains(err.Error(), "Object not found") || - strings.Contains(err.Error(), "status code: 404") { - *tfDatabaseID = "" - return nil - } - return fmt.Errorf("[ERROR] Error retrieving resource instance: %s %s", err, response) - } - if strings.Contains(*instance.State, "removed") { - *tfDatabaseID = "" - return nil - } - - *tfDatabaseID = instanceID - return nil - } -} - func testAccCheckIBMDatabaseInstancePostgresBasic(databaseResourceGroup string, name string) string { return fmt.Sprintf(` data "ibm_resource_group" "test_acc" { @@ -485,7 +344,7 @@ func testAccCheckIBMDatabaseInstancePostgresBasic(databaseResourceGroup string, plugin_type = "wal2json" } } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstancePostgresFullyspecified(databaseResourceGroup string, name string) string { @@ -556,7 +415,7 @@ func testAccCheckIBMDatabaseInstancePostgresFullyspecified(databaseResourceGroup plugin_type = "wal2json" } } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstancePostgresGroupBasic(databaseResourceGroup string, name string) string { @@ -601,7 +460,7 @@ func testAccCheckIBMDatabaseInstancePostgresGroupBasic(databaseResourceGroup str description = "desc1" } } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstancePostgresGroupFullyspecified(databaseResourceGroup string, name string) string { @@ -654,7 +513,7 @@ func testAccCheckIBMDatabaseInstancePostgresGroupFullyspecified(databaseResource description = "desc" } } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstancePostgresGroupReduced(databaseResourceGroup string, name string) string { @@ -691,7 +550,7 @@ func testAccCheckIBMDatabaseInstancePostgresGroupReduced(databaseResourceGroup s } } } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstancePostgresGroupScaleOut(databaseResourceGroup string, name string) string { @@ -728,7 +587,7 @@ func testAccCheckIBMDatabaseInstancePostgresGroupScaleOut(databaseResourceGroup service_endpoints = "public" tags = ["one:two"] } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstancePostgresImport(databaseResourceGroup string, name string) string { @@ -746,7 +605,7 @@ func testAccCheckIBMDatabaseInstancePostgresImport(databaseResourceGroup string, location = "%[3]s" service_endpoints = "public-and-private" } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstancePostgresMinimal(databaseResourceGroup string, name string) string { @@ -764,25 +623,11 @@ func testAccCheckIBMDatabaseInstancePostgresMinimal(databaseResourceGroup string location = "%[3]s" service_endpoints = "public-and-private" } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstancePostgresMinimal_PITR(databaseResourceGroup string, name string) string { return fmt.Sprintf(` - data "ibm_resource_group" "test_acc" { - is_default = true - # name = "%[1]s" - } - - resource "ibm_database" "%[2]s" { - resource_group_id = data.ibm_resource_group.test_acc.id - name = "%[2]s" - service = "databases-for-postgresql" - plan = "standard" - location = "%[3]s" - service_endpoints = "public-and-private" - } - resource "ibm_database" "%[2]s-pitr" { resource_group_id = data.ibm_resource_group.test_acc.id name = "%[2]s-pitr" @@ -793,7 +638,7 @@ func testAccCheckIBMDatabaseInstancePostgresMinimal_PITR(databaseResourceGroup s point_in_time_recovery_time = "" service_endpoints = "public-and-private" } - `, databaseResourceGroup, name, acc.Region()) + `, databaseResourceGroup, name, acc.Region()) } func testAccCheckIBMDatabaseInstancePostgresMinimal_ReadReplica(databaseResourceGroup string, name string) string { diff --git a/ibm/service/database/resource_ibm_helpers_test.go b/ibm/service/database/resource_ibm_helpers_test.go new file mode 100644 index 0000000000..ba0169385f --- /dev/null +++ b/ibm/service/database/resource_ibm_helpers_test.go @@ -0,0 +1,152 @@ +package database_test + +import ( + "fmt" + "reflect" + "strings" + + "time" + + acc "github.com/IBM-Cloud/terraform-provider-ibm/ibm/acctest" + "github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns" + "github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex" + + rc "github.com/IBM/platform-services-go-sdk/resourcecontrollerv2" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + + "github.com/IBM-Cloud/bluemix-go/bmxerror" + "github.com/IBM-Cloud/bluemix-go/models" +) + +const ( + databaseInstanceSuccessStatus = "active" + databaseInstanceProvisioningStatus = "provisioning" + databaseInstanceProgressStatus = "in progress" + databaseInstanceInactiveStatus = "inactive" + databaseInstanceFailStatus = "failed" + databaseInstanceRemovedStatus = "removed" + databaseInstanceReclamation = "pending_reclamation" +) + +func testAccCheckIBMDatabaseInstanceDestroy(s *terraform.State) error { + rsContClient, err := acc.TestAccProvider.Meta().(conns.ClientSession).ResourceControllerV2API() + if err != nil { + return err + } + for _, rs := range s.RootModule().Resources { + if rs.Type != "ibm_database" { + continue + } + + instanceID := rs.Primary.ID + + rsInst := rc.GetResourceInstanceOptions{ + ID: &instanceID, + } + instance, response, err := rsContClient.GetResourceInstance(&rsInst) + if err == nil { + if !reflect.DeepEqual(instance, models.ServiceInstance{}) && *instance.State == "active" { + return fmt.Errorf("Database still exists: %s", rs.Primary.ID) + } + } else { + if !strings.Contains(err.Error(), "404") { + return fmt.Errorf("[ERROR] Error checking if database (%s) has been destroyed: %s %s", rs.Primary.ID, err, response) + } + } + } + return nil +} + +func testAccDatabaseInstanceManuallyDelete(tfDatabaseID *string) resource.TestCheckFunc { + return func(s *terraform.State) error { + _ = testAccDatabaseInstanceManuallyDeleteUnwrapped(s, tfDatabaseID) + return nil + } +} + +func testAccDatabaseInstanceManuallyDeleteUnwrapped(s *terraform.State, tfDatabaseID *string) error { + rsConClient, err := acc.TestAccProvider.Meta().(conns.ClientSession).ResourceControllerV2API() + if err != nil { + return err + } + instance := *tfDatabaseID + var instanceID string + if strings.HasPrefix(instance, "crn") { + instanceID = instance + } else { + _, instanceID, _ = flex.ConvertTftoCisTwoVar(instance) + } + recursive := true + deleteReq := rc.DeleteResourceInstanceOptions{ + ID: &instanceID, + Recursive: &recursive, + } + response, err := rsConClient.DeleteResourceInstance(&deleteReq) + if err != nil { + return fmt.Errorf("[ERROR] Error deleting resource instance: %s %s", err, response) + } + + _ = &resource.StateChangeConf{ + Pending: []string{databaseInstanceProgressStatus, databaseInstanceInactiveStatus, databaseInstanceSuccessStatus}, + Target: []string{databaseInstanceRemovedStatus}, + Refresh: func() (interface{}, string, error) { + rsInst := rc.GetResourceInstanceOptions{ + ID: &instanceID, + } + instance, response, err := rsConClient.GetResourceInstance(&rsInst) + if err != nil { + if apiErr, ok := err.(bmxerror.RequestFailure); ok && apiErr.StatusCode() == 404 { + return instance, databaseInstanceSuccessStatus, nil + } + return nil, "", err + } + if *instance.State == databaseInstanceFailStatus { + return instance, *instance.State, fmt.Errorf("[ERROR] The resource instance %s failed to delete: %v %s", instanceID, err, response) + } + return instance, *instance.State, nil + }, + Timeout: 90 * time.Second, + Delay: 10 * time.Second, + MinTimeout: 10 * time.Second, + } + if err != nil { + return fmt.Errorf("[ERROR] Error waiting for resource instance (%s) to be deleted: %s", instanceID, err) + } + return nil +} + +func testAccCheckIBMDatabaseInstanceExists(n string, tfDatabaseID *string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + rsContClient, err := acc.TestAccProvider.Meta().(conns.ClientSession).ResourceControllerV2API() + if err != nil { + return err + } + instanceID := rs.Primary.ID + + rsInst := rc.GetResourceInstanceOptions{ + ID: &instanceID, + } + instance, response, err := rsContClient.GetResourceInstance(&rsInst) + if err != nil { + if strings.Contains(err.Error(), "Object not found") || + strings.Contains(err.Error(), "status code: 404") { + *tfDatabaseID = "" + return nil + } + return fmt.Errorf("[ERROR] Error retrieving resource instance: %s %s", err, response) + } + if strings.Contains(*instance.State, "removed") { + *tfDatabaseID = "" + return nil + } + + *tfDatabaseID = instanceID + return nil + } +} diff --git a/ibm/service/db2/README.md b/ibm/service/db2/README.md new file mode 100644 index 0000000000..abeeb54494 --- /dev/null +++ b/ibm/service/db2/README.md @@ -0,0 +1,9 @@ +# Terraform IBM Provider + +This area is primarily for IBM provider contributors and maintainers. For information on _using_ Terraform and the IBM provider, see the links below. + + +## Handy Links +* [Find out about contributing](../../../CONTRIBUTING.md) to the IBM provider! +* IBM Provider Docs: [Home](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs) +* IBM Provider Docs: [One of the resources](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/ibm_db2_instance) \ No newline at end of file diff --git a/ibm/service/db2/data_source_ibm_db2_instance.go b/ibm/service/db2/data_source_ibm_db2_instance.go new file mode 100644 index 0000000000..009e55ed65 --- /dev/null +++ b/ibm/service/db2/data_source_ibm_db2_instance.go @@ -0,0 +1,218 @@ +// Copyright IBM Corp. 2024 All Rights Reserved. +// Licensed under the Mozilla Public License v2.0 + +package db2 + +import ( + "encoding/json" + "fmt" + "log" + "net/url" + "reflect" + + rc "github.com/IBM/platform-services-go-sdk/resourcecontrollerv2" + rg "github.com/IBM/platform-services-go-sdk/resourcemanagerv2" + + "github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns" + "github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex" + "github.com/IBM-Cloud/terraform-provider-ibm/ibm/service/resourcecontroller" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func DataSourceIBMDb2Instance() *schema.Resource { + riSchema := resourcecontroller.DataSourceIBMResourceInstance().Schema + + riSchema["high_availability"] = &schema.Schema{ + Description: "If you require high availability, please choose this option", + Optional: true, + Type: schema.TypeString, + } + + riSchema["instance_type"] = &schema.Schema{ + Description: "Available machine type flavours (default selection will assume smallest configuration)", + Optional: true, + Type: schema.TypeString, + } + + riSchema["backup_location"] = &schema.Schema{ + Description: "Cross Regional backups can be stored across multiple regions in a zone. Regional backups are stored in only specific region.", + Optional: true, + Type: schema.TypeString, + } + + return &schema.Resource{ + Read: dataSourceIBMDb2InstanceRead, + Schema: riSchema, + } +} + +func getInstancesNext(next *string) (string, error) { + if reflect.ValueOf(next).IsNil() { + return "", nil + } + u, err := url.Parse(*next) + if err != nil { + return "", err + } + q := u.Query() + return q.Get("next_url"), nil +} + +func dataSourceIBMDb2InstanceRead(d *schema.ResourceData, meta interface{}) error { + var instance rc.ResourceInstance + rsConClient, err := meta.(conns.ClientSession).ResourceControllerV2API() + if err != nil { + return err + } + rsCatClient, err := meta.(conns.ClientSession).ResourceCatalogAPI() + if err != nil { + return err + } + rsCatRepo := rsCatClient.ResourceCatalog() + if _, ok := d.GetOk("name"); ok { + name := d.Get("name").(string) + resourceInstanceListOptions := rc.ListResourceInstancesOptions{ + Name: &name, + } + + if rsGrpID, ok := d.GetOk("resource_group_id"); ok { + rg := rsGrpID.(string) + resourceInstanceListOptions.ResourceGroupID = &rg + } + + if service, ok := d.GetOk("service"); ok { + + serviceOff, err := rsCatRepo.FindByName(service.(string), true) + if err != nil { + return fmt.Errorf("[ERROR] Error retrieving service offering: %s", err) + } + resourceId := serviceOff[0].ID + resourceInstanceListOptions.ResourceID = &resourceId + } + + next_url := "" + var instances []rc.ResourceInstance + for { + if next_url != "" { + resourceInstanceListOptions.Start = &next_url + } + listInstanceResponse, resp, err := rsConClient.ListResourceInstances(&resourceInstanceListOptions) + if err != nil { + return fmt.Errorf("[ERROR] Error retrieving resource instance: %s with resp code: %s", err, resp) + } + next_url, err = getInstancesNext(listInstanceResponse.NextURL) + if err != nil { + return fmt.Errorf("[DEBUG] ListResourceInstances failed. Error occurred while parsing NextURL: %s", err) + + } + instances = append(instances, listInstanceResponse.Resources...) + if next_url == "" { + break + } + } + + var filteredInstances []rc.ResourceInstance + var location string + + if loc, ok := d.GetOk("location"); ok { + location = loc.(string) + for _, instance := range instances { + if flex.GetLocationV2(instance) == location { + filteredInstances = append(filteredInstances, instance) + } + } + } else { + filteredInstances = instances + } + + if len(filteredInstances) == 0 { + return fmt.Errorf("[ERROR] No resource instance found with name [%s]\nIf not specified please specify more filters like resource_group_id if instance doesn't exists in default group, location or service", name) + } + if len(filteredInstances) > 1 { + return fmt.Errorf("[ERROR] More than one resource instance found with name matching [%s]\nIf not specified please specify more filters like resource_group_id if instance doesn't exists in default group, location or service", name) + } + instance = filteredInstances[0] + } else if _, ok := d.GetOk("identifier"); ok { + instanceGUID := d.Get("identifier").(string) + getResourceInstanceOptions := &rc.GetResourceInstanceOptions{ + ID: &instanceGUID, + } + instances, res, err := rsConClient.GetResourceInstance(getResourceInstanceOptions) + if err != nil { + return fmt.Errorf("[ERROR] No resource instance found with id [%s\n%v]", instanceGUID, res) + } + instance = *instances + d.Set("name", instance.Name) + } + d.SetId(*instance.ID) + d.Set("status", instance.State) + d.Set("resource_group_id", instance.ResourceGroupID) + d.Set("location", instance.RegionID) + serviceOff, err := rsCatRepo.GetServiceName(*instance.ResourceID) + if err != nil { + return fmt.Errorf("[ERROR] Error retrieving service offering: %s", err) + } + + d.Set("service", serviceOff) + + d.Set(flex.ResourceName, instance.Name) + d.Set(flex.ResourceCRN, instance.CRN) + d.Set(flex.ResourceStatus, instance.State) + // ### Modifiction : Setting the onetime credientials + d.Set("onetime_credentials", instance.OnetimeCredentials) + if instance.Parameters != nil { + params, err := json.Marshal(instance.Parameters) + if err != nil { + return fmt.Errorf("[ERROR] Error marshalling instance parameters: %s", err) + } + if err = d.Set("parameters_json", string(params)); err != nil { + return fmt.Errorf("[ERROR] Error setting instance parameters json: %s", err) + } + } + rMgtClient, err := meta.(conns.ClientSession).ResourceManagerV2API() + if err != nil { + return err + } + GetResourceGroup := rg.GetResourceGroupOptions{ + ID: instance.ResourceGroupID, + } + resourceGroup, resp, err := rMgtClient.GetResourceGroup(&GetResourceGroup) + if err != nil || resourceGroup == nil { + log.Printf("[ERROR] Error retrieving resource group: %s %s", err, resp) + } + if resourceGroup != nil && resourceGroup.Name != nil { + d.Set(flex.ResourceGroupName, resourceGroup.Name) + } + d.Set("guid", instance.GUID) + if len(instance.Extensions) == 0 { + d.Set("extensions", instance.Extensions) + } else { + d.Set("extensions", flex.Flatten(instance.Extensions)) + } + + rcontroller, err := flex.GetBaseController(meta) + if err != nil { + return err + } + d.Set(flex.ResourceControllerURL, rcontroller+"/services/") + + servicePlan, err := rsCatRepo.GetServicePlanName(*instance.ResourcePlanID) + if err != nil { + return fmt.Errorf("[ERROR] Error retrieving plan: %s", err) + } + d.Set("plan", servicePlan) + d.Set("crn", instance.CRN) + tags, err := flex.GetTagsUsingCRN(meta, *instance.CRN) + if err != nil { + log.Printf( + "Error on get of resource instance tags (%s) tags: %s", d.Id(), err) + } + d.Set("tags", tags) + + d.Set("high_availability", instance.Parameters["high_availability"]) + d.Set("instance_type", instance.Parameters["instance_type"]) + d.Set("backup_location", instance.Parameters["backup_location"]) + + return nil + +} diff --git a/ibm/service/db2/resource_ibm_db2_instance.go b/ibm/service/db2/resource_ibm_db2_instance.go new file mode 100644 index 0000000000..feaae9b8ec --- /dev/null +++ b/ibm/service/db2/resource_ibm_db2_instance.go @@ -0,0 +1,261 @@ +// Copyright IBM Corp. 2024 All Rights Reserved. +// Licensed under the Mozilla Public License v2.0 + +package db2 + +import ( + "context" + "encoding/json" + "fmt" + "log" + "os" + "strconv" + "strings" + "time" + + "github.com/IBM-Cloud/bluemix-go/models" + "github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns" + "github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex" + "github.com/IBM-Cloud/terraform-provider-ibm/ibm/service/resourcecontroller" + rc "github.com/IBM/platform-services-go-sdk/resourcecontrollerv2" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +const ( + RsInstanceSuccessStatus = "active" + RsInstanceProgressStatus = "in progress" + RsInstanceProvisioningStatus = "provisioning" + RsInstanceInactiveStatus = "inactive" + RsInstanceFailStatus = "failed" + RsInstanceRemovedStatus = "removed" + RsInstanceReclamation = "pending_reclamation" + RsInstanceUpdateSuccessStatus = "succeeded" +) + +func ResourceIBMDb2Instance() *schema.Resource { + riSchema := resourcecontroller.ResourceIBMResourceInstance().Schema + + riSchema["high_availability"] = &schema.Schema{ + Description: "If you require high availability, please choose this option", + Optional: true, + Type: schema.TypeString, + } + + riSchema["instance_type"] = &schema.Schema{ + Description: "Available machine type flavours (default selection will assume smallest configuration)", + Optional: true, + Type: schema.TypeString, + } + + riSchema["backup_location"] = &schema.Schema{ + Description: "Cross Regional backups can be stored across multiple regions in a zone. Regional backups are stored in only specific region.", + Optional: true, + Type: schema.TypeString, + } + + return &schema.Resource{ + Create: resourceIBMDb2InstanceCreate, + Read: resourcecontroller.ResourceIBMResourceInstanceRead, + Update: resourcecontroller.ResourceIBMResourceInstanceUpdate, + Delete: resourcecontroller.ResourceIBMResourceInstanceDelete, + Exists: resourcecontroller.ResourceIBMResourceInstanceExists, + Importer: &schema.ResourceImporter{}, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Update: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), + }, + + CustomizeDiff: customdiff.Sequence( + func(_ context.Context, diff *schema.ResourceDiff, v interface{}) error { + return flex.ResourceTagsCustomizeDiff(diff) + }, + ), + + Schema: riSchema, + } +} + +func resourceIBMDb2InstanceCreate(d *schema.ResourceData, meta interface{}) error { + rsConClient, err := meta.(conns.ClientSession).ResourceControllerV2API() + if err != nil { + return err + } + + serviceName := d.Get("service").(string) + plan := d.Get("plan").(string) + name := d.Get("name").(string) + location := d.Get("location").(string) + + rsInst := rc.CreateResourceInstanceOptions{ + Name: &name, + } + + rsCatClient, err := meta.(conns.ClientSession).ResourceCatalogAPI() + if err != nil { + return err + } + rsCatRepo := rsCatClient.ResourceCatalog() + + serviceOff, err := rsCatRepo.FindByName(serviceName, true) + if err != nil { + return fmt.Errorf("[ERROR] Error retrieving service offering: %s", err) + } + + if metadata, ok := serviceOff[0].Metadata.(*models.ServiceResourceMetadata); ok { + if !metadata.Service.RCProvisionable { + return fmt.Errorf("%s cannot be provisioned by resource controller", serviceName) + } + } else { + return fmt.Errorf("[ERROR] Cannot create instance of resource %s\nUse 'ibm_service_instance' if the resource is a Cloud Foundry service", serviceName) + } + + servicePlan, err := rsCatRepo.GetServicePlanID(serviceOff[0], plan) + if err != nil { + return fmt.Errorf("[ERROR] Error retrieving plan: %s", err) + } + rsInst.ResourcePlanID = &servicePlan + + deployments, err := rsCatRepo.ListDeployments(servicePlan) + if err != nil { + return fmt.Errorf("[ERROR] Error retrieving deployment for plan %s : %s", plan, err) + } + if len(deployments) == 0 { + return fmt.Errorf("[ERROR] No deployment found for service plan : %s", plan) + } + deployments, supportedLocations := resourcecontroller.FilterDeployments(deployments, location) + + if len(deployments) == 0 { + locationList := make([]string, 0, len(supportedLocations)) + for l := range supportedLocations { + locationList = append(locationList, l) + } + return fmt.Errorf("[ERROR] No deployment found for service plan %s at location %s.\nValid location(s) are: %q.\nUse 'ibm_service_instance' if the service is a Cloud Foundry service", plan, location, locationList) + } + + rsInst.Target = &deployments[0].CatalogCRN + + if rsGrpID, ok := d.GetOk("resource_group_id"); ok { + rg := rsGrpID.(string) + rsInst.ResourceGroup = &rg + } else { + defaultRg, err := flex.DefaultResourceGroup(meta) + if err != nil { + return err + } + rsInst.ResourceGroup = &defaultRg + } + + params := map[string]interface{}{} + + if serviceEndpoints, ok := d.GetOk("service_endpoints"); ok { + params["service-endpoints"] = serviceEndpoints.(string) + } + if highAvailability, ok := d.GetOk("high_availability"); ok { + params["high_availability"] = highAvailability.(string) + } + if instanceType, ok := d.GetOk("instance_type"); ok { + params["instance_type"] = instanceType.(string) + } + if backupLocation, ok := d.GetOk("backup_location"); ok { + params["backup-locations"] = backupLocation.(string) + } + + if parameters, ok := d.GetOk("parameters"); ok { + temp := parameters.(map[string]interface{}) + for k, v := range temp { + if v == "true" || v == "false" { + b, _ := strconv.ParseBool(v.(string)) + params[k] = b + } else if strings.HasPrefix(v.(string), "[") && strings.HasSuffix(v.(string), "]") { + //transform v.(string) to be []string + arrayString := v.(string) + result := []string{} + trimLeft := strings.TrimLeft(arrayString, "[") + trimRight := strings.TrimRight(trimLeft, "]") + if len(trimRight) == 0 { + params[k] = result + } else { + array := strings.Split(trimRight, ",") + for _, a := range array { + result = append(result, strings.Trim(a, "\"")) + } + params[k] = result + } + } else { + params[k] = v + } + } + + } + if s, ok := d.GetOk("parameters_json"); ok { + json.Unmarshal([]byte(s.(string)), ¶ms) + } + + rsInst.Parameters = params + + //Start to create resource instance + instance, resp, err := rsConClient.CreateResourceInstance(&rsInst) + if err != nil { + log.Printf( + "Error when creating resource instance: %s, Instance info NAME->%s, LOCATION->%s, GROUP_ID->%s, PLAN_ID->%s", + err, *rsInst.Name, *rsInst.Target, *rsInst.ResourceGroup, *rsInst.ResourcePlanID) + return fmt.Errorf("[ERROR] Error when creating resource instance: %s with resp code: %s", err, resp) + } + + d.SetId(*instance.ID) + + _, err = waitForResourceInstanceCreate(d, meta) + if err != nil { + return fmt.Errorf("[ERROR] Error waiting for create resource instance (%s) to be succeeded: %s", d.Id(), err) + } + + v := os.Getenv("IC_ENV_TAGS") + if _, ok := d.GetOk("tags"); ok || v != "" { + oldList, newList := d.GetChange("tags") + err = flex.UpdateTagsUsingCRN(oldList, newList, meta, *instance.CRN) + if err != nil { + log.Printf( + "Error on create of resource instance (%s) tags: %s", d.Id(), err) + } + } + + return resourcecontroller.ResourceIBMResourceInstanceRead(d, meta) +} + +func waitForResourceInstanceCreate(d *schema.ResourceData, meta interface{}) (interface{}, error) { + rsConClient, err := meta.(conns.ClientSession).ResourceControllerV2API() + if err != nil { + return false, err + } + instanceID := d.Id() + resourceInstanceGet := rc.GetResourceInstanceOptions{ + ID: &instanceID, + } + + stateConf := &retry.StateChangeConf{ + Pending: []string{RsInstanceProgressStatus, RsInstanceInactiveStatus, RsInstanceProvisioningStatus}, + Target: []string{RsInstanceSuccessStatus}, + Refresh: func() (interface{}, string, error) { + instance, resp, err := rsConClient.GetResourceInstance(&resourceInstanceGet) + if err != nil { + if resp != nil && resp.StatusCode == 404 { + return nil, "", fmt.Errorf("[ERROR] The resource instance %s does not exist anymore: %v", d.Id(), err) + } + return nil, "", fmt.Errorf("[ERROR] Get the resource instance %s failed with resp code: %s, err: %v", d.Id(), resp, err) + } + if *instance.State == RsInstanceFailStatus { + return instance, *instance.State, fmt.Errorf("[ERROR] The resource instance '%s' creation failed: %v", d.Id(), err) + } + return instance, *instance.State, nil + }, + Timeout: d.Timeout(schema.TimeoutCreate), + Delay: 30 * time.Second, + MinTimeout: 30 * time.Second, + } + + return stateConf.WaitForStateContext(context.Background()) +} diff --git a/ibm/service/db2/resource_ibm_db2_instance_test.go b/ibm/service/db2/resource_ibm_db2_instance_test.go new file mode 100644 index 0000000000..306c024d57 --- /dev/null +++ b/ibm/service/db2/resource_ibm_db2_instance_test.go @@ -0,0 +1,155 @@ +// Copyright IBM Corp. 2024 All Rights Reserved. +// Licensed under the Mozilla Public License v2.0 + +package db2_test + +import ( + "fmt" + "strings" + "testing" + + acc "github.com/IBM-Cloud/terraform-provider-ibm/ibm/acctest" + "github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns" + + rc "github.com/IBM/platform-services-go-sdk/resourcecontrollerv2" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccIBMDb2InstanceBasic(t *testing.T) { + databaseResourceGroup := "Default" + var databaseInstanceOne string + rnd := fmt.Sprintf("tf-db2-%d", acctest.RandIntRange(10, 100)) + testName := rnd + name := "ibm_db2." + testName + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acc.TestAccPreCheck(t) }, + Providers: acc.TestAccProviders, + CheckDestroy: testAccCheckIBMDb2InstanceDestroy, + Steps: []resource.TestStep{ + { + + Config: testAccCheckIBMDb2InstanceBasic(databaseResourceGroup, testName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckIBMDb2InstanceExists(name, &databaseInstanceOne), + resource.TestCheckResourceAttr(name, "name", testName), + resource.TestCheckResourceAttr(name, "service", "dashdb-for-transactions"), + resource.TestCheckResourceAttr(name, "plan", "performance"), + resource.TestCheckResourceAttr(name, "location", "us-east"), + resource.TestCheckResourceAttr(name, "service_endpoints", "public-and-private"), + resource.TestCheckResourceAttr(name, "instance_type", ""), + resource.TestCheckResourceAttr(name, "tags.#", "1"), + ), + }, + }, + }) +} + +func testAccCheckIBMDb2InstanceDestroy(s *terraform.State) error { + rsContClient, err := acc.TestAccProvider.Meta().(conns.ClientSession).ResourceControllerV2API() + if err != nil { + return err + } + for _, rs := range s.RootModule().Resources { + if rs.Type != "ibm_db2" { + continue + } + + instanceID := rs.Primary.ID + resourceInstanceGet := rc.GetResourceInstanceOptions{ + ID: &instanceID, + } + + // Try to find the key + instance, resp, err := rsContClient.GetResourceInstance(&resourceInstanceGet) + + if err == nil { + if *instance.State == "active" { + return fmt.Errorf("Resource Instance still exists: %s", rs.Primary.ID) + } + } else { + if !strings.Contains(err.Error(), "404") { + return fmt.Errorf("[ERROR] Error checking if Resource Instance (%s) has been destroyed: %s with resp code: %s", rs.Primary.ID, err, resp) + } + } + } + + return nil +} + +func testAccCheckIBMDb2InstanceExists(n string, tfDb2ID *string) resource.TestCheckFunc { + + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + rsContClient, err := acc.TestAccProvider.Meta().(conns.ClientSession).ResourceControllerV2API() + if err != nil { + return err + } + instanceID := rs.Primary.ID + resourceInstanceGet := rc.GetResourceInstanceOptions{ + ID: &instanceID, + } + + instance, response, err := rsContClient.GetResourceInstance(&resourceInstanceGet) + + if err != nil { + if strings.Contains(err.Error(), "Object not found") || + strings.Contains(err.Error(), "status code: 404") { + *tfDb2ID = "" + return nil + } + return fmt.Errorf("[ERROR] Error retrieving resource instance: %s %s", err, response) + } + if strings.Contains(*instance.State, "removed") { + *tfDb2ID = "" + return nil + } + + *tfDb2ID = instanceID + + return nil + } +} + +func testAccCheckIBMDb2InstanceBasic(databaseResourceGroup string, testName string) string { + return fmt.Sprintf(` + + data "ibm_resource_group" "group" { + name = "%[1]s" + } + + resource "ibm_db2" "%[2]s" { + name = "%[2]s" + service = "dashdb-for-transactions" + plan = "performance" + location = "us-east" + resource_group_id = data.ibm_resource_group.group.id + service_endpoints = "public-and-private" + instance_type = "" + high_availability = "no" + backup_location = "us" + tags = ["one:two"] + + parameters_json = < 0 { + pool := poolIntf.([]interface{})[0].(map[string]interface{}) + id, okId := pool["id"] + if okId { + idStr, ok := id.(string) + if idStr != "" && ok { + var resAffPool = make([]vpcv1.ReservationIdentityIntf, 1) + resAffPool[0] = &vpcv1.ReservationIdentity{ + ID: &idStr, + } + resAffinity.Pool = resAffPool + } + } + } + options.ReservationAffinity = resAffinity + } + if primnicintf, ok := d.GetOk(isBareMetalServerPrimaryNetworkInterface); ok && len(primnicintf.([]interface{})) > 0 { primnic := primnicintf.([]interface{})[0].(map[string]interface{}) subnetintf, _ := primnic[isBareMetalServerNicSubnet] @@ -2130,6 +2298,71 @@ func bareMetalServerGet(context context.Context, d *schema.ResourceData, meta in d.Set(isBareMetalServerPrimaryNetworkInterface, primaryNicList) } + if bms.HealthReasons != nil { + healthReasonsList := make([]map[string]interface{}, 0) + for _, sr := range bms.HealthReasons { + currentSR := map[string]interface{}{} + if sr.Code != nil && sr.Message != nil { + currentSR["code"] = *sr.Code + currentSR["message"] = *sr.Message + if sr.MoreInfo != nil { + currentSR["more_info"] = *sr.Message + } + healthReasonsList = append(healthReasonsList, currentSR) + } + } + d.Set("health_reasons", healthReasonsList) + } + if err = d.Set("health_state", bms.HealthState); err != nil { + return err + } + if bms.ReservationAffinity != nil { + reservationAffinity := []map[string]interface{}{} + reservationAffinityMap := map[string]interface{}{} + + reservationAffinityMap[isReservationAffinityPolicyResp] = bms.ReservationAffinity.Policy + if bms.ReservationAffinity.Pool != nil && len(bms.ReservationAffinity.Pool) > 0 { + poolList := make([]map[string]interface{}, 0) + for _, pool := range bms.ReservationAffinity.Pool { + res := map[string]interface{}{} + + res[isReservationId] = *pool.ID + res[isReservationHref] = *pool.Href + res[isReservationName] = *pool.Name + res[isReservationCrn] = *pool.CRN + res[isReservationResourceType] = *pool.ResourceType + if pool.Deleted != nil { + deletedList := []map[string]interface{}{} + deletedMap := dataSourceReservationDeletedToMap(*pool.Deleted) + deletedList = append(deletedList, deletedMap) + res[isReservationDeleted] = deletedList + } + poolList = append(poolList, res) + } + reservationAffinityMap[isReservationAffinityPool] = poolList + } + reservationAffinity = append(reservationAffinity, reservationAffinityMap) + d.Set(isReservationAffinity, reservationAffinity) + } + resList := make([]map[string]interface{}, 0) + if bms.Reservation != nil { + res := map[string]interface{}{} + + res[isReservationId] = *bms.Reservation.ID + res[isReservationHref] = *bms.Reservation.Href + res[isReservationName] = *bms.Reservation.Name + res[isReservationCrn] = *bms.Reservation.CRN + res[isReservationResourceType] = *bms.Reservation.ResourceType + if bms.Reservation.Deleted != nil { + deletedList := []map[string]interface{}{} + deletedMap := dataSourceReservationDeletedToMap(*bms.Reservation.Deleted) + deletedList = append(deletedList, deletedMap) + res[isReservationDeleted] = deletedList + } + resList = append(resList, res) + } + d.Set(isReservation, resList) + if !core.IsNil(bms.PrimaryNetworkAttachment) { pnaId := *bms.PrimaryNetworkAttachment.ID getBareMetalServerNetworkAttachment := &vpcv1.GetBareMetalServerNetworkAttachmentOptions{ @@ -3648,8 +3881,49 @@ func bareMetalServerUpdate(context context.Context, d *schema.ResourceData, meta } bmsPatchModel.Name = &nameStr } + resPol := "reservation_affinity.0.policy" + resPool := "reservation_affinity.0.pool" + policyStr := "" + idStr := "" + + if (d.HasChange(resPol) || d.HasChange(resPool)) && !d.IsNewResource() { + flag = true + if resAffinity, ok := d.GetOk(isReservationAffinity); ok { + resAff := resAffinity.([]interface{})[0].(map[string]interface{}) + var resAffinityPatch = &vpcv1.BareMetalServerReservationAffinityPatch{} + policy, ok := resAff["policy"] + policyStr = policy.(string) + if policyStr != "" && ok { + resAffinityPatch.Policy = &policyStr + } + if d.HasChange(resPool) { + poolIntf, okPool := resAff[isReservationAffinityPool] + if okPool && poolIntf != nil && poolIntf.([]interface{}) != nil && len(poolIntf.([]interface{})) > 0 { + pool := poolIntf.([]interface{})[0].(map[string]interface{}) + id, okId := pool["id"] + if okId { + idStr, ok = id.(string) + if idStr != "" && ok { + var resAffPool = make([]vpcv1.ReservationIdentityIntf, 1) + resAffPool[0] = &vpcv1.ReservationIdentity{ + ID: &idStr, + } + resAffinityPatch.Pool = resAffPool + } + } + + } + } + } + } if flag { bmsPatch, err := bmsPatchModel.AsPatch() + //Detaching the reservation from the reserved bare metal server + if policyStr == "disabled" && idStr == "" { + resAffMap := bmsPatch["reservation_affinity"].(map[string]interface{}) + resAffMap["pool"] = nil + bmsPatch["reservation_affinity"] = resAffMap + } if err != nil { return fmt.Errorf("[ERROR] Error calling asPatch for BareMetalServerPatch: %s", err) } @@ -3675,7 +3949,7 @@ func bareMetalServerUpdate(context context.Context, d *schema.ResourceData, meta } if flag || isServerStopped { - isServerStopped, err = resourceStartServerIfStopped(id, "hard", d, context, sess, isServerStopped) + _, err = resourceStartServerIfStopped(id, "hard", d, context, sess, isServerStopped) if err != nil { return err } diff --git a/ibm/service/vpc/resource_ibm_is_bare_metal_server_test.go b/ibm/service/vpc/resource_ibm_is_bare_metal_server_test.go index 3a96f58756..3a5fbadad1 100644 --- a/ibm/service/vpc/resource_ibm_is_bare_metal_server_test.go +++ b/ibm/service/vpc/resource_ibm_is_bare_metal_server_test.go @@ -482,6 +482,77 @@ ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCKVmnMOlHKcZK8tpt3MP1lqOLAcqcJzhsvJcjscgVE }) } +func TestAccIBMISBareMetalServer_reservation(t *testing.T) { + var server string + vpcname := fmt.Sprintf("tf-vpc-%d", acctest.RandIntRange(10, 100)) + name := fmt.Sprintf("tf-server-%d", acctest.RandIntRange(10, 100)) + subnetname := fmt.Sprintf("tfip-subnet-%d", acctest.RandIntRange(10, 100)) + publicKey := strings.TrimSpace(` +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCKVmnMOlHKcZK8tpt3MP1lqOLAcqcJzhsvJcjscgVERRN7/9484SOBJ3HSKxxNG5JN8owAjy5f9yYwcUg+JaUVuytn5Pv3aeYROHGGg+5G346xaq3DAwX6Y5ykr2fvjObgncQBnuU5KHWCECO/4h8uWuwh/kfniXPVjFToc+gnkqA+3RKpAecZhFXwfalQ9mMuYGFxn+fwn8cYEApsJbsEmb0iJwPiZ5hjFC8wREuiTlhPHDgkBLOiycd20op2nXzDbHfCHInquEe/gYxEitALONxm0swBOwJZwlTDOB7C6y2dzlrtxr1L59m7pCkWI4EtTRLvleehBoj3u7jB4usR +`) + sshname := fmt.Sprintf("tf-sshname-%d", acctest.RandIntRange(10, 100)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acc.TestAccPreCheck(t) }, + Providers: acc.TestAccProviders, + CheckDestroy: testAccCheckIBMISBareMetalServerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckIBMISBareMetalServerReservationConfig(vpcname, subnetname, sshname, publicKey, name), + Check: resource.ComposeTestCheckFunc( + testAccCheckIBMISBareMetalServerExists("ibm_is_bare_metal_server.testacc_bms", server), + resource.TestCheckResourceAttr( + "ibm_is_bare_metal_server.testacc_bms", "name", name), + resource.TestCheckResourceAttr( + "ibm_is_bare_metal_server.testacc_bms", "zone", acc.ISZoneName), + resource.TestCheckResourceAttr( + "ibm_is_bare_metal_server.testacc_bms", "reservation_affinity.0.policy", "manual"), + resource.TestCheckResourceAttrSet( + "ibm_is_bare_metal_server.testacc_bms", "reservation_affinity.0.pool"), + ), + }, + }, + }) +} + +func testAccCheckIBMISBareMetalServerReservationConfig(vpcname, subnetname, sshname, publicKey, name string) string { + return fmt.Sprintf(` + resource "ibm_is_vpc" "testacc_vpc" { + name = "%s" + } + + resource "ibm_is_subnet" "testacc_subnet" { + name = "%s" + vpc = ibm_is_vpc.testacc_vpc.id + zone = "%s" + total_ipv4_address_count = 16 + } + + resource "ibm_is_ssh_key" "testacc_sshkey" { + name = "%s" + public_key = "%s" + } + + resource "ibm_is_bare_metal_server" "testacc_bms" { + profile = "%s" + name = "%s" + image = "%s" + zone = "%s" + keys = [ibm_is_ssh_key.testacc_sshkey.id] + primary_network_interface { + subnet = ibm_is_subnet.testacc_subnet.id + } + vpc = ibm_is_vpc.testacc_vpc.id + reservation_affinity { + policy = "manual" + pool { + id = "0735-b4a78f50-33bd-44f9-a3ff-4c33f444459d" + } + } + } +`, vpcname, subnetname, acc.ISZoneName, sshname, publicKey, acc.IsBareMetalServerProfileName, name, acc.IsBareMetalServerImage, acc.ISZoneName) +} + func testAccCheckIBMISBareMetalServerDestroy(s *terraform.State) error { sess, _ := acc.TestAccProvider.Meta().(conns.ClientSession).VpcV1API() diff --git a/ibm/service/vpc/resource_ibm_is_instance.go b/ibm/service/vpc/resource_ibm_is_instance.go index 389296b46a..2ed6729b89 100644 --- a/ibm/service/vpc/resource_ibm_is_instance.go +++ b/ibm/service/vpc/resource_ibm_is_instance.go @@ -1629,6 +1629,35 @@ func ResourceIBMISInstance() *schema.Resource { }, }, }, + "health_reasons": { + Type: schema.TypeList, + Computed: true, + Description: "The reasons for the current health_state (if any).", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "code": { + Type: schema.TypeString, + Computed: true, + Description: "A snake case string succinctly identifying the reason for this health state.", + }, + "message": { + Type: schema.TypeString, + Computed: true, + Description: "An explanation of the reason for this health state.", + }, + "more_info": { + Type: schema.TypeString, + Computed: true, + Description: "Link to documentation about the reason for this health state.", + }, + }, + }, + }, + "health_state": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "The health of this resource", + }, isInstanceReservation: { Type: schema.TypeList, Computed: true, @@ -2096,7 +2125,7 @@ func instanceCreateByImage(d *schema.ResourceData, meta interface{}, profile, na resAffinity.Policy = &policyStr } poolIntf, okPool := resAff[isReservationAffinityPool] - if okPool { + if okPool && poolIntf != nil && poolIntf.([]interface{}) != nil && len(poolIntf.([]interface{})) > 0 { pool := poolIntf.([]interface{})[0].(map[string]interface{}) id, okId := pool["id"] if okId { @@ -2631,7 +2660,7 @@ func instanceCreateByCatalogOffering(d *schema.ResourceData, meta interface{}, p resAffinity.Policy = &policyStr } poolIntf, okPool := resAff[isReservationAffinityPool] - if okPool { + if okPool && poolIntf != nil && poolIntf.([]interface{}) != nil && len(poolIntf.([]interface{})) > 0 { pool := poolIntf.([]interface{})[0].(map[string]interface{}) id, okId := pool["id"] if okId { @@ -3146,7 +3175,7 @@ func instanceCreateByTemplate(d *schema.ResourceData, meta interface{}, profile, resAffinity.Policy = &policyStr } poolIntf, okPool := resAff[isReservationAffinityPool] - if okPool { + if okPool && poolIntf != nil && poolIntf.([]interface{}) != nil && len(poolIntf.([]interface{})) > 0 { pool := poolIntf.([]interface{})[0].(map[string]interface{}) id, okId := pool["id"] if okId { @@ -3635,7 +3664,7 @@ func instanceCreateBySnapshot(d *schema.ResourceData, meta interface{}, profile, resAffinity.Policy = &policyStr } poolIntf, okPool := resAff[isReservationAffinityPool] - if okPool { + if okPool && poolIntf != nil && poolIntf.([]interface{}) != nil && len(poolIntf.([]interface{})) > 0 { pool := poolIntf.([]interface{})[0].(map[string]interface{}) id, okId := pool["id"] if okId { @@ -4113,7 +4142,7 @@ func instanceCreateByVolume(d *schema.ResourceData, meta interface{}, profile, n resAffinity.Policy = &policyStr } poolIntf, okPool := resAff[isReservationAffinityPool] - if okPool { + if okPool && poolIntf != nil && poolIntf.([]interface{}) != nil && len(poolIntf.([]interface{})) > 0 { pool := poolIntf.([]interface{})[0].(map[string]interface{}) id, okId := pool["id"] if okId { @@ -4812,6 +4841,24 @@ func instanceGet(d *schema.ResourceData, meta interface{}, id string) error { primaryNicList = append(primaryNicList, currentPrimNic) d.Set(isInstancePrimaryNetworkInterface, primaryNicList) } + if instance.HealthReasons != nil { + healthReasonsList := make([]map[string]interface{}, 0) + for _, sr := range instance.HealthReasons { + currentSR := map[string]interface{}{} + if sr.Code != nil && sr.Message != nil { + currentSR["code"] = *sr.Code + currentSR["message"] = *sr.Message + if sr.MoreInfo != nil { + currentSR["more_info"] = *sr.Message + } + healthReasonsList = append(healthReasonsList, currentSR) + } + } + d.Set("health_reasons", healthReasonsList) + } + if err = d.Set("health_state", instance.HealthState); err != nil { + return err + } if instance.ReservationAffinity != nil { reservationAffinity := []map[string]interface{}{} reservationAffinityMap := map[string]interface{}{} @@ -4829,7 +4876,7 @@ func instanceGet(d *schema.ResourceData, meta interface{}, id string) error { res[isReservationResourceType] = *pool.ResourceType if pool.Deleted != nil { deletedList := []map[string]interface{}{} - deletedMap := dataSourceInstanceReservationDeletedToMap(*pool.Deleted) + deletedMap := dataSourceReservationDeletedToMap(*pool.Deleted) deletedList = append(deletedList, deletedMap) res[isReservationDeleted] = deletedList } @@ -4851,7 +4898,7 @@ func instanceGet(d *schema.ResourceData, meta interface{}, id string) error { res[isReservationResourceType] = *instance.Reservation.ResourceType if instance.Reservation.Deleted != nil { deletedList := []map[string]interface{}{} - deletedMap := dataSourceInstanceReservationDeletedToMap(*instance.Reservation.Deleted) + deletedMap := dataSourceReservationDeletedToMap(*instance.Reservation.Deleted) deletedList = append(deletedList, deletedMap) res[isReservationDeleted] = deletedList } @@ -5641,7 +5688,7 @@ func instanceUpdate(d *schema.ResourceData, meta interface{}) error { } if d.HasChange(resPool) { poolIntf, okPool := resAff[isReservationAffinityPool] - if okPool { + if okPool && poolIntf != nil && poolIntf.([]interface{}) != nil && len(poolIntf.([]interface{})) > 0 { pool := poolIntf.([]interface{})[0].(map[string]interface{}) id, okId := pool["id"] if okId { @@ -6915,15 +6962,6 @@ func resourceIbmIsInstanceInstancePlacementToMap(instancePlacement vpcv1.Instanc return instancePlacementMap } -func resourceIbmIsInstanceReservationAffinityPoolToMap(reservationPool vpcv1.ReservationReference) map[string]interface{} { - resAffPoolMap := map[string]interface{}{} - - resAffPoolMap["crn"] = reservationPool.CRN - resAffPoolMap["href"] = reservationPool.Href - resAffPoolMap["id"] = reservationPool.ID - return resAffPoolMap -} - func resourceIbmIsInstanceDedicatedHostGroupReferenceDeletedToMap(dedicatedHostGroupReferenceDeleted vpcv1.Deleted) map[string]interface{} { dedicatedHostGroupReferenceDeletedMap := map[string]interface{}{} diff --git a/ibm/service/vpc/resource_ibm_is_instance_template.go b/ibm/service/vpc/resource_ibm_is_instance_template.go index 7a0b0ac2de..4fd13aab33 100644 --- a/ibm/service/vpc/resource_ibm_is_instance_template.go +++ b/ibm/service/vpc/resource_ibm_is_instance_template.go @@ -1860,7 +1860,7 @@ func instanceTemplateCreate(d *schema.ResourceData, meta interface{}, profile, n resAffinity.Policy = &policyStr } poolIntf, okPool := resAff[isReservationAffinityPool] - if okPool { + if okPool && poolIntf != nil && poolIntf.([]interface{}) != nil && len(poolIntf.([]interface{})) > 0 { pool := poolIntf.([]interface{})[0].(map[string]interface{}) id, okId := pool["id"] if okId { diff --git a/ibm/service/vpc/resource_ibm_is_reservation.go b/ibm/service/vpc/resource_ibm_is_reservation.go index 0d98ac3520..d9835590e5 100644 --- a/ibm/service/vpc/resource_ibm_is_reservation.go +++ b/ibm/service/vpc/resource_ibm_is_reservation.go @@ -264,9 +264,9 @@ func ResourceIBMISReservation() *schema.Resource { func ResourceIBMISReservationValidator() *validate.ResourceValidator { validateSchema := make([]validate.ValidateSchema, 0) - affinityPolicy := "restricted" - term := "one_year,three_year" - resourceType := "instance_profile" + affinityPolicy := "automatic, restricted" + term := "one_year, three_year" + resourceType := "bare_metal_server_profile, instance_profile" validateSchema = append(validateSchema, validate.ValidateSchema{ @@ -504,7 +504,7 @@ func resourceIBMISReservationRead(d *schema.ResourceData, meta interface{}) erro profileMap := []map[string]interface{}{} finalList := map[string]interface{}{} - profileItem := reservation.Profile + profileItem := reservation.Profile.(*vpcv1.ReservationProfile) if profileItem.Href != nil { finalList[isReservationProfileHref] = profileItem.Href @@ -576,6 +576,7 @@ func resourceIBMISReservationUpdate(d *schema.ResourceData, meta interface{}) er } hasChanged := false name := "" + affPol := "" reservationPatchModel := &vpcv1.ReservationPatch{} if d.HasChange(isReservationName) { @@ -585,6 +586,13 @@ func resourceIBMISReservationUpdate(d *schema.ResourceData, meta interface{}) er hasChanged = true } } + if d.HasChange(isReservationAffinityPolicy) { + affPol = d.Get(isReservationAffinityPolicy).(string) + if affPol != "" { + reservationPatchModel.AffinityPolicy = &affPol + hasChanged = true + } + } if d.HasChange(isReservationCapacity) { capacityIntf := d.Get(isReservationCapacity) capacityMap := capacityIntf.([]interface{})[0].(map[string]interface{}) @@ -593,6 +601,7 @@ func resourceIBMISReservationUpdate(d *schema.ResourceData, meta interface{}) er reservationPatchModel.Capacity = &vpcv1.ReservationCapacityPatch{ Total: core.Int64Ptr(int64(totalIntf.(int))), } + hasChanged = true } } } @@ -605,12 +614,14 @@ func resourceIBMISReservationUpdate(d *schema.ResourceData, meta interface{}) er if expPolIntf.(string) != "" { cuPatch.ExpirationPolicy = core.StringPtr(string(expPolIntf.(string))) } + hasChanged = true } } if d.HasChange(isReservationCommittedUse + ".0." + isReservationComittedUseTerm) { if termIntf, ok := committedUseMap[isReservationComittedUseTerm]; ok { cuPatch.Term = core.StringPtr(string(termIntf.(string))) } + hasChanged = true } reservationPatchModel.CommittedUse = cuPatch } @@ -623,6 +634,7 @@ func resourceIBMISReservationUpdate(d *schema.ResourceData, meta interface{}) er if profNameIntf.(string) != "" { profPatch.Name = core.StringPtr(string(profNameIntf.(string))) } + hasChanged = true } } if d.HasChange(isReservationProfile + ".0." + isReservationProfileResourceType) { @@ -630,6 +642,7 @@ func resourceIBMISReservationUpdate(d *schema.ResourceData, meta interface{}) er if resTypeIntf.(string) != "" { profPatch.ResourceType = core.StringPtr(string(resTypeIntf.(string))) } + hasChanged = true } } reservationPatchModel.Profile = profPatch diff --git a/ibm/service/vpc/resource_ibm_is_reservation_activate.go b/ibm/service/vpc/resource_ibm_is_reservation_activate.go index 96ac3c4753..8379f63eb8 100644 --- a/ibm/service/vpc/resource_ibm_is_reservation_activate.go +++ b/ibm/service/vpc/resource_ibm_is_reservation_activate.go @@ -350,7 +350,7 @@ func resourceIBMISReservationActivateRead(d *schema.ResourceData, meta interface profileMap := []map[string]interface{}{} finalList := map[string]interface{}{} - profileItem := reservation.Profile + profileItem := reservation.Profile.(*vpcv1.ReservationProfile) if profileItem.Href != nil { finalList[isReservationProfileHref] = profileItem.Href diff --git a/metadata/provider_metadata.json b/metadata/provider_metadata.json index 60f5eb3285..63805d34fb 100644 --- a/metadata/provider_metadata.json +++ b/metadata/provider_metadata.json @@ -107426,6 +107426,13 @@ "description": "Allow outbound connections to public destinations", "default_value": false, "optional": true + }, + { + "name": "enable_secure_by_default", + "type": "TypeBool", + "description": "Enable Secure-by-default security group configuration on existing cluster", + "default_value": false, + "optional": true } ], "ibm_container_vpc_worker": [ diff --git a/website/allowed-subcategories.txt b/website/allowed-subcategories.txt index 74a627221c..b9178368c2 100644 --- a/website/allowed-subcategories.txt +++ b/website/allowed-subcategories.txt @@ -12,6 +12,7 @@ Container Registry Configuration Aggregator Context Based Restrictions CD Tekton Pipeline +Db2 SaaS Direct Link Gateway DNS Services Enterprise Management diff --git a/website/docs/d/db2_instance.html.markdown b/website/docs/d/db2_instance.html.markdown new file mode 100644 index 0000000000..9d668dba85 --- /dev/null +++ b/website/docs/d/db2_instance.html.markdown @@ -0,0 +1,50 @@ +--- +subcategory: "Db2 SaaS" +layout: "ibm" +page_title: "IBM : ibm_db2" +description: |- + Get Information about IBM Db2 SaaS instance. +--- + +# ibm_db2 + +Retrieve information about an existing [IBM Db2 SaaS Instance](https://cloud.ibm.com/docs/Db2onCloud). + +**Note** +Configuration of an IBM Db2 SaaS on IBM Cloud Instance `data_source` requires that the `region` parameter is set for the IBM provider in the `provider.tf`. The region must be the same as the `location` that the IBM Cloud Databases instance is deployed into.A `terraform refresh` of the `data_source` fails if the region and the location differ. + +## Example usage +The following example retrieves information about the `db2_instance` instance in `us-south`. + +```terraform +data "ibm_db2" "db2_instance" { + name = "" + resource_group_id = data.ibm_resource_group.group.id + location = "us-south" + service = "dashdb-for-transactions" +} +``` + +## Argument reference +Review the argument reference that you can specify for your data source. + +- `name` - (Required, String) The name of the IBM Db2 SaaS on IBM Cloud instance. IBM Cloud does not enforce that service names are unique and it is possible that duplicate service names exist. The first located service instance is used by Terraform. The name must not include spaces. +- `location` - (Optional, String) The location where the IBM Db2 SaaS on IBM Cloud instance is deployed into. +- `resource_group_id`- (Optional, String) The ID of the resource group where the IBM Db2 SaaS on IBM Cloud instance is deployed into. The default is `default`. +- `service` - (Optional, String) The service type of the instance. To retrieve this value, run `ibmcloud catalog service-marketplace` or `ibmcloud catalog search`. + +## Attribute reference +In addition to all argument references list, you can access the following attribute references after your data source is created. + +- `guid` - (String) The unique identifier of the IBM Db2 SaaS on IBM Cloud instance. +- `resource_crn` - (String) The unique identifier(CRN) of the IBM Db2 SaaS on IBM Cloud instance. +- `plan` - (String) The service plan of the IBM Db2 SaaS on IBM Cloud instance. +- `location` - (String) The location where the IBM Db2 SaaS on IBM Cloud instance is deployed into. +- `status` - (String) The status of the IBM Db2 SaaS on IBM Cloud instance. +- `version` - (String) The database version. +- `platform_options`- (String) The CRN of key protect key. + + Nested scheme for `platform_options`: + - `disk_encryption_key_crn`- (String) The CRN of disk encryption key. + - `backup_encryption_key_crn`- (String) The CRN of backup encryption key. + diff --git a/website/docs/d/iam_effective_account_settings.html.markdown b/website/docs/d/iam_effective_account_settings.html.markdown new file mode 100644 index 0000000000..03c39018f4 --- /dev/null +++ b/website/docs/d/iam_effective_account_settings.html.markdown @@ -0,0 +1,142 @@ +--- +layout: "ibm" +page_title: "IBM : ibm_iam_effective_account_settings" +description: |- + Get information about iam_effective_account_settings +subcategory: "IAM Identity Services" +--- + +# ibm_iam_effective_account_settings + +Provides a read-only data source to retrieve information about iam_effective_account_settings. You can then reference the fields of the data source in other resources within the same configuration by using interpolation syntax. + +## Example Usage + +```hcl +data "ibm_iam_effective_account_settings" "iam_effective_account_settings" { + account_id = "account_id" +} +``` + +## Argument Reference + +You can specify the following arguments for this data source. + +* `account_id` - (Required, Forces new resource, String) Unique ID of the account. +* `include_history` - (Optional, Boolean) Defines if the entity history is included in the response. + * Constraints: The default value is `false`. +* `resolve_user_mfa` - (Optional, Boolean) Enrich MFA exemptions with user information. + * Constraints: The default value is `false`. + +## Attribute Reference + +After your data source is created, you can read values from the following attributes. + +* `id` - The unique identifier of the iam_effective_account_settings. +* `account` - (List) +Nested schema for **account**: + * `account_id` - (String) Unique ID of the account. + * `allowed_ip_addresses` - (String) Defines the IP addresses and subnets from which IAM tokens can be created for the account. + * `history` - (List) History of the Account Settings. + Nested schema for **history**: + * `action` - (String) Action of the history entry. + * `iam_id` - (String) IAM ID of the identity which triggered the action. + * `iam_id_account` - (String) Account of the identity which triggered the action. + * `message` - (String) Message which summarizes the executed action. + * `params` - (List) Params of the history entry. + * `timestamp` - (String) Timestamp when the action was triggered. + * `max_sessions_per_identity` - (String) Defines the max allowed sessions per identity required by the account. Valid values: * Any whole number greater than 0 * NOT_SET - To unset account setting and use service default. + * `mfa` - (String) Defines the MFA requirement for the user. Valid values: * NONE - No MFA trait set * NONE_NO_ROPC- No MFA, disable CLI logins with only a password * TOTP - For all non-federated IBMId users * TOTP4ALL - For all users * LEVEL1 - Email-based MFA for all users * LEVEL2 - TOTP-based MFA for all users * LEVEL3 - U2F MFA for all users. + * Constraints: Allowable values are: `NONE`, `NONE_NO_ROPC`, `TOTP`, `TOTP4ALL`, `LEVEL1`, `LEVEL2`, `LEVEL3`. + * `restrict_create_platform_apikey` - (String) Defines whether or not creating platform API keys is access controlled. Valid values: * RESTRICTED - to apply access control * NOT_RESTRICTED - to remove access control * NOT_SET - to 'unset' a previous set value. + * Constraints: The default value is `NOT_SET`. Allowable values are: `RESTRICTED`, `NOT_RESTRICTED`, `NOT_SET`. + * `restrict_create_service_id` - (String) Defines whether or not creating a service ID is access controlled. Valid values: * RESTRICTED - only users assigned the 'Service ID creator' role on the IAM Identity Service can create service IDs, including the account owner * NOT_RESTRICTED - all members of an account can create service IDs * NOT_SET - to 'unset' a previous set value. + * Constraints: The default value is `NOT_SET`. Allowable values are: `RESTRICTED`, `NOT_RESTRICTED`, `NOT_SET`. + * `session_expiration_in_seconds` - (String) Defines the session expiration in seconds for the account. Valid values: * Any whole number between between '900' and '86400' * NOT_SET - To unset account setting and use service default. + * Constraints: The default value is `86400`. + * `session_invalidation_in_seconds` - (String) Defines the period of time in seconds in which a session will be invalidated due to inactivity. Valid values: * Any whole number between '900' and '7200' * NOT_SET - To unset account setting and use service default. + * Constraints: The default value is `7200`. + * `system_access_token_expiration_in_seconds` - (String) Defines the access token expiration in seconds. Valid values: * Any whole number between '900' and '3600' * NOT_SET - To unset account setting and use service default. + * Constraints: The default value is `3600`. + * `system_refresh_token_expiration_in_seconds` - (String) Defines the refresh token expiration in seconds. Valid values: * Any whole number between '900' and '259200' * NOT_SET - To unset account setting and use service default. + * Constraints: The default value is `259200`. + * `user_mfa` - (List) List of users that are exempted from the MFA requirement of the account. + Nested schema for **user_mfa**: + * `description` - (String) optional description. + * `email` - (String) email of the user. + * `iam_id` - (String) The iam_id of the user. + * `mfa` - (String) Defines the MFA requirement for the user. Valid values: * NONE - No MFA trait set * NONE_NO_ROPC- No MFA, disable CLI logins with only a password * TOTP - For all non-federated IBMId users * TOTP4ALL - For all users * LEVEL1 - Email-based MFA for all users * LEVEL2 - TOTP-based MFA for all users * LEVEL3 - U2F MFA for all users. + * Constraints: Allowable values are: `NONE`, `NONE_NO_ROPC`, `TOTP`, `TOTP4ALL`, `LEVEL1`, `LEVEL2`, `LEVEL3`. + * `name` - (String) name of the user account. + * `user_name` - (String) userName of the user. +* `assigned_templates` - (List) assigned template section. +Nested schema for **assigned_templates**: + * `allowed_ip_addresses` - (String) Defines the IP addresses and subnets from which IAM tokens can be created for the account. + * `max_sessions_per_identity` - (String) Defines the max allowed sessions per identity required by the account. Valid values: * Any whole number greater than 0 * NOT_SET - To unset account setting and use service default. + * `mfa` - (String) Defines the MFA requirement for the user. Valid values: * NONE - No MFA trait set * NONE_NO_ROPC- No MFA, disable CLI logins with only a password * TOTP - For all non-federated IBMId users * TOTP4ALL - For all users * LEVEL1 - Email-based MFA for all users * LEVEL2 - TOTP-based MFA for all users * LEVEL3 - U2F MFA for all users. + * Constraints: Allowable values are: `NONE`, `NONE_NO_ROPC`, `TOTP`, `TOTP4ALL`, `LEVEL1`, `LEVEL2`, `LEVEL3`. + * `restrict_create_platform_apikey` - (String) Defines whether or not creating platform API keys is access controlled. Valid values: * RESTRICTED - to apply access control * NOT_RESTRICTED - to remove access control * NOT_SET - to 'unset' a previous set value. + * Constraints: The default value is `NOT_SET`. Allowable values are: `RESTRICTED`, `NOT_RESTRICTED`, `NOT_SET`. + * `restrict_create_service_id` - (String) Defines whether or not creating a service ID is access controlled. Valid values: * RESTRICTED - only users assigned the 'Service ID creator' role on the IAM Identity Service can create service IDs, including the account owner * NOT_RESTRICTED - all members of an account can create service IDs * NOT_SET - to 'unset' a previous set value. + * Constraints: The default value is `NOT_SET`. Allowable values are: `RESTRICTED`, `NOT_RESTRICTED`, `NOT_SET`. + * `session_expiration_in_seconds` - (String) Defines the session expiration in seconds for the account. Valid values: * Any whole number between between '900' and '86400' * NOT_SET - To unset account setting and use service default. + * Constraints: The default value is `86400`. + * `session_invalidation_in_seconds` - (String) Defines the period of time in seconds in which a session will be invalidated due to inactivity. Valid values: * Any whole number between '900' and '7200' * NOT_SET - To unset account setting and use service default. + * Constraints: The default value is `7200`. + * `system_access_token_expiration_in_seconds` - (String) Defines the access token expiration in seconds. Valid values: * Any whole number between '900' and '3600' * NOT_SET - To unset account setting and use service default. + * Constraints: The default value is `3600`. + * `system_refresh_token_expiration_in_seconds` - (String) Defines the refresh token expiration in seconds. Valid values: * Any whole number between '900' and '259200' * NOT_SET - To unset account setting and use service default. + * Constraints: The default value is `259200`. + * `template_id` - (String) Template Id. + * `template_name` - (String) Template name. + * `template_version` - (Integer) Template version. + * `user_mfa` - (List) List of users that are exempted from the MFA requirement of the account. + Nested schema for **user_mfa**: + * `description` - (String) optional description. + * `email` - (String) email of the user. + * `iam_id` - (String) The iam_id of the user. + * `mfa` - (String) Defines the MFA requirement for the user. Valid values: * NONE - No MFA trait set * NONE_NO_ROPC- No MFA, disable CLI logins with only a password * TOTP - For all non-federated IBMId users * TOTP4ALL - For all users * LEVEL1 - Email-based MFA for all users * LEVEL2 - TOTP-based MFA for all users * LEVEL3 - U2F MFA for all users. + * Constraints: Allowable values are: `NONE`, `NONE_NO_ROPC`, `TOTP`, `TOTP4ALL`, `LEVEL1`, `LEVEL2`, `LEVEL3`. + * `name` - (String) name of the user account. + * `user_name` - (String) userName of the user. +* `context` - (List) Context with key properties for problem determination. +Nested schema for **context**: + * `cluster_name` - (String) The cluster name. + * `elapsed_time` - (String) The elapsed time in msec. + * `end_time` - (String) The finish time of the request. + * `host` - (String) The host of the server instance processing the request. + * `instance_id` - (String) The instance ID of the server instance processing the request. + * `operation` - (String) The operation of the inbound REST request. + * `start_time` - (String) The start time of the request. + * `thread_id` - (String) The thread ID of the server instance processing the request. + * `transaction_id` - (String) The transaction ID of the inbound REST request. + * `url` - (String) The URL of that cluster. + * `user_agent` - (String) The user agent of the inbound REST request. +* `effective` - (List) +Nested schema for **effective**: + * `allowed_ip_addresses` - (String) Defines the IP addresses and subnets from which IAM tokens can be created for the account. + * `max_sessions_per_identity` - (String) Defines the max allowed sessions per identity required by the account. Valid values: * Any whole number greater than 0 * NOT_SET - To unset account setting and use service default. + * `mfa` - (String) Defines the MFA requirement for the user. Valid values: * NONE - No MFA trait set * NONE_NO_ROPC- No MFA, disable CLI logins with only a password * TOTP - For all non-federated IBMId users * TOTP4ALL - For all users * LEVEL1 - Email-based MFA for all users * LEVEL2 - TOTP-based MFA for all users * LEVEL3 - U2F MFA for all users. + * Constraints: Allowable values are: `NONE`, `NONE_NO_ROPC`, `TOTP`, `TOTP4ALL`, `LEVEL1`, `LEVEL2`, `LEVEL3`. + * `restrict_create_platform_apikey` - (String) Defines whether or not creating platform API keys is access controlled. Valid values: * RESTRICTED - to apply access control * NOT_RESTRICTED - to remove access control * NOT_SET - to 'unset' a previous set value. + * Constraints: The default value is `NOT_SET`. Allowable values are: `RESTRICTED`, `NOT_RESTRICTED`, `NOT_SET`. + * `restrict_create_service_id` - (String) Defines whether or not creating a service ID is access controlled. Valid values: * RESTRICTED - only users assigned the 'Service ID creator' role on the IAM Identity Service can create service IDs, including the account owner * NOT_RESTRICTED - all members of an account can create service IDs * NOT_SET - to 'unset' a previous set value. + * Constraints: The default value is `NOT_SET`. Allowable values are: `RESTRICTED`, `NOT_RESTRICTED`, `NOT_SET`. + * `session_expiration_in_seconds` - (String) Defines the session expiration in seconds for the account. Valid values: * Any whole number between between '900' and '86400' * NOT_SET - To unset account setting and use service default. + * Constraints: The default value is `86400`. + * `session_invalidation_in_seconds` - (String) Defines the period of time in seconds in which a session will be invalidated due to inactivity. Valid values: * Any whole number between '900' and '7200' * NOT_SET - To unset account setting and use service default. + * Constraints: The default value is `7200`. + * `system_access_token_expiration_in_seconds` - (String) Defines the access token expiration in seconds. Valid values: * Any whole number between '900' and '3600' * NOT_SET - To unset account setting and use service default. + * Constraints: The default value is `3600`. + * `system_refresh_token_expiration_in_seconds` - (String) Defines the refresh token expiration in seconds. Valid values: * Any whole number between '900' and '259200' * NOT_SET - To unset account setting and use service default. + * Constraints: The default value is `259200`. + * `user_mfa` - (List) List of users that are exempted from the MFA requirement of the account. + Nested schema for **user_mfa**: + * `description` - (String) optional description. + * `email` - (String) email of the user. + * `iam_id` - (String) The iam_id of the user. + * `mfa` - (String) Defines the MFA requirement for the user. Valid values: * NONE - No MFA trait set * NONE_NO_ROPC- No MFA, disable CLI logins with only a password * TOTP - For all non-federated IBMId users * TOTP4ALL - For all users * LEVEL1 - Email-based MFA for all users * LEVEL2 - TOTP-based MFA for all users * LEVEL3 - U2F MFA for all users. + * Constraints: Allowable values are: `NONE`, `NONE_NO_ROPC`, `TOTP`, `TOTP4ALL`, `LEVEL1`, `LEVEL2`, `LEVEL3`. + * `name` - (String) name of the user account. + * `user_name` - (String) userName of the user. + diff --git a/website/docs/d/is_bare_metal_server.markdown b/website/docs/d/is_bare_metal_server.markdown index b0a118b2a0..1612f89eb0 100644 --- a/website/docs/d/is_bare_metal_server.markdown +++ b/website/docs/d/is_bare_metal_server.markdown @@ -6,7 +6,7 @@ description: |- Manages IBM Cloud Bare Metal Server. --- -# ibm\_is_bare_metal_server +# ibm_is_bare_metal_server Import the details of an existing IBM Cloud Bare Metal Server as a read-only data source. You can then reference the fields of the data source in other resources within the same configuration using interpolation syntax. For more information, about bare metal servers, see [About Bare Metal Servers for VPC](https://cloud.ibm.com/docs/vpc?topic=vpc-about-bare-metal-servers). @@ -70,6 +70,13 @@ In addition to all argument reference list, you can access the following attribu - `resource_type` - (String) The resource type - `size` - (Integer) The size of the disk in GB (gigabytes) - `enable_secure_boot` - (Boolean) Indicates whether secure boot is enabled. If enabled, the image must support secure boot or the server will fail to boot. +- `health_reasons` - (List) The reasons for the current health_state (if any). + + Nested scheme for `health_reasons`: + - `code` - (String) A snake case string succinctly identifying the reason for this health state. + - `message` - (String) An explanation of the reason for this health state. + - `more_info` - (String) Link to documentation about the reason for this health state. +- `health_state` - (String) The health of this resource. - `href` - (String) The URL for this bare metal server - `id` - (String) The unique identifier for this bare metal server - `image` - (String) Image used in the bare metal server. @@ -95,8 +102,35 @@ In addition to all argument reference list, you can access the following attribu - `name` - (String) The name for this reserved IP. The name is unique across all reserved IPs in a subnet. - `resource_type` - (String) The resource type. + - `reservation`- (List) The reservation used by this bare metal server. + Nested scheme for `reservation`: + - `crn` - (String) The CRN for this reservation. + - `deleted` - (List) If present, this property indicates the referenced resource has been deleted, and provides some supplementary information. + + Nested `deleted` blocks have the following structure: + - `more_info` - (String) Link to documentation about deleted resources. + - `href` - (String) The URL for this reservation. + - `id` - (String) The unique identifier for this reservation. + - `name` - (string) The name for this reservation. The name is unique across all reservations in the region. + - `resource_type` - (string) The resource type. + - `reservation_affinity`- (List) The bare metal server reservation affinity. + + Nested scheme for `reservation_affinity`: + - `policy` - (String) The reservation affinity policy to use for this bare metal server. + - `pool` - (List) The pool of reservations available for use by this bare metal server. + + Nested `pool` blocks have the following structure: + - `crn` - (String) The CRN for this reservation. + - `deleted` - (List) If present, this property indicates the referenced resource has been deleted, and provides some supplementary information. + + Nested `deleted` blocks have the following structure: + - `more_info` - (String) Link to documentation about deleted resources. + - `href` - (String) The URL for this reservation. + - `id` - (String) The unique identifier for this reservation. + - `name` - (string) The name for this reservation. The name is unique across all reservations in the region. + - `resource_type` - (string) The resource type. - `resource_type` - (String) The resource type. - - `subnet` - (List) The subnet of the virtual network interface for the network attachment. + - `subnet` - (List) The subnet of the virtual network interface for the network attachment. Nested schema for **subnet**: - `crn` - (String) The CRN for this subnet. - `deleted` - (List) If present, this property indicates the referenced resource has been deleted, and providessome supplementary information. diff --git a/website/docs/d/is_bare_metal_server_network_interface_floating_ip.markdown b/website/docs/d/is_bare_metal_server_network_interface_floating_ip.markdown index 3ebf3f5077..a640d64ccc 100644 --- a/website/docs/d/is_bare_metal_server_network_interface_floating_ip.markdown +++ b/website/docs/d/is_bare_metal_server_network_interface_floating_ip.markdown @@ -24,7 +24,7 @@ provider "ibm" { ```terraform - data "is_bare_metal_server_network_interface_floating_ip" "test" { + data "ibm_is_bare_metal_server_network_interface_floating_ip" "test" { bare_metal_server = ibm_is_bare_metal_server.example.id floating_ip = ibm_is_floating_ip.example.id network_interface = ibm_is_bare_metal_server_network_interface.example.id diff --git a/website/docs/d/is_bare_metal_server_network_interface_floating_ips.markdown b/website/docs/d/is_bare_metal_server_network_interface_floating_ips.markdown index dfc69fe6d7..8c459150ac 100644 --- a/website/docs/d/is_bare_metal_server_network_interface_floating_ips.markdown +++ b/website/docs/d/is_bare_metal_server_network_interface_floating_ips.markdown @@ -24,7 +24,7 @@ provider "ibm" { ```terraform - data "is_bare_metal_server_network_interface_floating_ips" "test" { + data "ibm_is_bare_metal_server_network_interface_floating_ips" "test" { bare_metal_server = "xxxx-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx" network_interface = "xxxx-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx" } diff --git a/website/docs/d/is_bare_metal_servers.markdown b/website/docs/d/is_bare_metal_servers.markdown index 037c5fd49a..6b73c612b3 100644 --- a/website/docs/d/is_bare_metal_servers.markdown +++ b/website/docs/d/is_bare_metal_servers.markdown @@ -6,7 +6,7 @@ description: |- Manages IBM Cloud Bare Metal Servers. --- -# ibm\_is_bare_metal_servers +# ibm_is_bare_metal_servers Import the details of an existing IBM Cloud vBare Metal Server collection as a read-only data source. You can then reference the fields of the data source in other resources within the same configuration using interpolation syntax. For more information, about bare metal servers, see [About Bare Metal Servers for VPC](https://cloud.ibm.com/docs/vpc?topic=vpc-about-bare-metal-servers). @@ -62,6 +62,13 @@ Review the attribute references that you can access after you retrieve your data - `resource_type` - (String) The resource type - `size` - (Integer) The size of the disk in GB (gigabytes) - `enable_secure_boot` - (Boolean) Indicates whether secure boot is enabled. If enabled, the image must support secure boot or the server will fail to boot. + - `health_reasons` - (List) The reasons for the current health_state (if any). + + Nested scheme for `health_reasons`: + - `code` - (String) A snake case string succinctly identifying the reason for this health state. + - `message` - (String) An explanation of the reason for this health state. + - `more_info` - (String) Link to documentation about the reason for this health state. + - `health_state` - (String) The health of this resource. - `href` - (String) The URL for this bare metal server - `id` - (String) The unique identifier for this bare metal server - `image` - (String) Image used in the bare metal server. @@ -180,6 +187,33 @@ Review the attribute references that you can access after you retrieve your data - `security_groups` - (Array) List of security groups. - `subnet` - (String) ID of the subnet. - `profile` - (String) The name for this bare metal server profile + - `reservation`- (List) The reservation used by this bare metal server. + Nested scheme for `reservation`: + - `crn` - (String) The CRN for this reservation. + - `deleted` - (List) If present, this property indicates the referenced resource has been deleted, and provides some supplementary information. + + Nested `deleted` blocks have the following structure: + - `more_info` - (String) Link to documentation about deleted resources. + - `href` - (String) The URL for this reservation. + - `id` - (String) The unique identifier for this reservation. + - `name` - (string) The name for this reservation. The name is unique across all reservations in the region. + - `resource_type` - (string) The resource type. + - `reservation_affinity`- (List) The bare metal server reservation affinity. + + Nested scheme for `reservation_affinity`: + - `policy` - (String) The reservation affinity policy to use for this bare metal server. + - `pool` - (List) The pool of reservations available for use by this bare metal server. + + Nested `pool` blocks have the following structure: + - `crn` - (String) The CRN for this reservation. + - `deleted` - (List) If present, this property indicates the referenced resource has been deleted, and provides some supplementary information. + + Nested `deleted` blocks have the following structure: + - `more_info` - (String) Link to documentation about deleted resources. + - `href` - (String) The URL for this reservation. + - `id` - (String) The unique identifier for this reservation. + - `name` - (string) The name for this reservation. The name is unique across all reservations in the region. + - `resource_type` - (string) The resource type. - `resource_group` - (String) resource group id of the bare metal server. - `resource_type` - (String) The type of resource referenced - `firmware_update_type_available` - (String) The firmware update type available for the bare metal server. diff --git a/website/docs/d/is_instance.html.markdown b/website/docs/d/is_instance.html.markdown index 952a3cfe23..8cacbc87cb 100644 --- a/website/docs/d/is_instance.html.markdown +++ b/website/docs/d/is_instance.html.markdown @@ -148,6 +148,13 @@ In addition to all argument reference list, you can access the following attribu - `manufacture` - (String) The manufacturer of the GPU. - `memory`- (Integer) The amount of memory that was allocated to the GPU. - `model` - (String) The model of the GPU. +- `health_reasons` - (List) The reasons for the current health_state (if any). + + Nested scheme for `health_reasons`: + - `code` - (String) A snake case string succinctly identifying the reason for this health state. + - `message` - (String) An explanation of the reason for this health state. + - `more_info` - (String) Link to documentation about the reason for this health state. +- `health_state` - (String) The health of this resource. - `id` - (String) The ID that was assigned to the Virtual Servers for VPC instance. - `image` - (String) The ID of the virtual server image that is used in the instance. - `keys`- (List) A list of SSH keys that were added to the instance during creation. diff --git a/website/docs/d/is_instance_disk.html.markdown b/website/docs/d/is_instance_disk.html.markdown index 6128307a04..e0e0623212 100644 --- a/website/docs/d/is_instance_disk.html.markdown +++ b/website/docs/d/is_instance_disk.html.markdown @@ -73,7 +73,7 @@ data "ibm_is_instance" "example" { passphrase = "" } -data "is_instance_disk" "example" { +data "ibm_is_instance_disk" "example" { instance = data.ibm_is_instance.example.id disk = data.ibm_is_instance.example.disks.0.id } diff --git a/website/docs/d/is_instance_disks.html.markdown b/website/docs/d/is_instance_disks.html.markdown index e33036b748..70fb72a1a5 100644 --- a/website/docs/d/is_instance_disks.html.markdown +++ b/website/docs/d/is_instance_disks.html.markdown @@ -72,7 +72,7 @@ data "ibm_is_instance" "example" { passphrase = "" } -data "is_instance_disks" "example" { +data "ibm_is_instance_disks" "example" { instance = data.ibm_is_instance.example.id } ``` diff --git a/website/docs/d/is_instances.html.markdown b/website/docs/d/is_instances.html.markdown index effd99dcc0..7c3ca0f75f 100644 --- a/website/docs/d/is_instances.html.markdown +++ b/website/docs/d/is_instances.html.markdown @@ -97,6 +97,13 @@ In addition to all argument reference list, you can access the following attribu - `manufacture` - Manufacture of the gpu. - `memory` - Memory of the gpu. - `model` - Model of the gpu. + - `health_reasons` - (List) The reasons for the current health_state (if any). + + Nested scheme for `health_reasons`: + - `code` - (String) A snake case string succinctly identifying the reason for this health state. + - `message` - (String) An explanation of the reason for this health state. + - `more_info` - (String) Link to documentation about the reason for this health state. + - `health_state` - (String) The health of this resource. - `id` - (String) The ID that was assigned to the Virtual Servers for VPC instance. - `image` - (String) The ID of the virtual server image that is used in the instance. - `lifecycle_reasons`- (List) The reasons for the current lifecycle_state (if any). diff --git a/website/docs/d/is_placement_group.html.markdown b/website/docs/d/is_placement_group.html.markdown index 39c9b164b0..87e485c27b 100644 --- a/website/docs/d/is_placement_group.html.markdown +++ b/website/docs/d/is_placement_group.html.markdown @@ -23,7 +23,7 @@ provider "ibm" { ## Example usage ```terraform -data "is_placement_group" "example" { +data "ibm_is_placement_group" "example" { name = ibm_is_placement_group.example.name } ``` diff --git a/website/docs/d/is_placement_groups.html.markdown b/website/docs/d/is_placement_groups.html.markdown index c53561d56d..bd02dad3bf 100644 --- a/website/docs/d/is_placement_groups.html.markdown +++ b/website/docs/d/is_placement_groups.html.markdown @@ -24,7 +24,7 @@ provider "ibm" { ## Example usage ```terraform -data "is_placement_groups" "example" { +data "ibm_is_placement_groups" "example" { } ``` diff --git a/website/docs/r/container_vpc_cluster.html.markdown b/website/docs/r/container_vpc_cluster.html.markdown index a5b2832faa..d421edd2c3 100644 --- a/website/docs/r/container_vpc_cluster.html.markdown +++ b/website/docs/r/container_vpc_cluster.html.markdown @@ -220,6 +220,7 @@ Review the argument references that you can specify for your resource. - `kms_account_id` - (Optional, String) Account ID for boot volume encryption, if other account is providing the kms. - `security_groups` - (Optional, List) Enables users to define specific security groups for their workers. - `disable_outbound_traffic_protection` - (Optional, Bool) Include this option to allow public outbound access from the cluster workers. By default, public outbound access is blocked in OpenShift versions 4.15 and later and Kubernetes versions 1.30 and later. This option is usable only from OpenShift versions 4.15 and later and Kubernetes versions 1.30 and later. +- `enable_secure_by_default` - (Optional, Bool) Enables Secure-by-default security group configuration. Once the upgrade begins, it cannot be undone. During the upgrade, network traffic to your cluster may temporarily be blocked. This option is usable only from OpenShift versions 4.15 and later and Kubernetes versions 1.30 and later. **Note** diff --git a/website/docs/r/database.html.markdown b/website/docs/r/database.html.markdown index ae9bd98c39..cb0bddec4a 100644 --- a/website/docs/r/database.html.markdown +++ b/website/docs/r/database.html.markdown @@ -733,6 +733,7 @@ Import requires a minimal Terraform config file to allow importing. ```terraform resource "ibm_database" "" { name = "" +} ``` Run `terraform state show ibm_database.` after import to retrieve the more values to be included in the resource config file. Observe the ICD exports the admin userid. It does not export any more user IDs and passwords that are configured on the instance. These values must be retrieved from an alternative source. If new passwords need to be configured or the connection string that is retrieved to use the service, a new users block must be defined to create new users. This limitation is due to a lack of ICD functionality. diff --git a/website/docs/r/db2_instance.html.markdown b/website/docs/r/db2_instance.html.markdown new file mode 100644 index 0000000000..854359b7b5 --- /dev/null +++ b/website/docs/r/db2_instance.html.markdown @@ -0,0 +1,135 @@ +--- +subcategory: "Db2 SaaS" +layout: "ibm" +page_title: "IBM : ibm_db2" +description: |- + Manages IBM Db2 SaaS instance. +--- + +# ibm_db2 + +Create or delete an IBM Db2 SaaS on IBM Cloud instance. The `ibmcloud_api_key` that are used by Terraform should grant IAM rights to create and modify IBM Cloud Db2 Databases and have access to the resource group the Db2 SaaS instance is associated with. For more information, see [documentation](https://cloud.ibm.com/docs/Db2onCloud?topic=Db2onCloud-getting-started) to manage Db2 SaaS instances. + + +Configuration of an Db2 SaaS resource requires that the `region` parameter is set for the IBM provider in the `provider.tf` to be the same as the target Db2 SaaS `location/region`. If the Terraform configuration needs to deploy resources into multiple regions, provider alias can be used. For more information, see [Terraform provider configuration](https://www.terraform.io/docs/configuration/providers.html#multiple-provider-instances). + + +## Example usage +To find an example for provisioning and configuring a Db2 SaaS instance , see [here](https://github.com/IBM-Cloud/terraform-provider-ibm/tree/master/examples/ibm-db2). + +```terraform +data "ibm_resource_group" "group" { + name = "" +} + +resource "ibm_db2" "" { + name = "" + service = "dashdb-for-transactions" + plan = "performance" + location = "us-south" + resource_group_id = data.ibm_resource_group.group.id + service_endpoints = "public-and-private" + instance_type = "bx2.4x16" + high_availability = "yes" + backup_location = "us" + + parameters_json = <:key:`. `backup_encryption_key_crn` can be added only at the time of creation and no update support are available. + + +## Attribute reference +In addition to all argument references list, you can access the following attribute references after your resource is created. + +- `id` - (String) The CRN of the database instance. +- `status` - (String) The status of the instance. +- `version` - (String) The database version. + +## Import +The database instance can be imported by using the ID, that is formed from the CRN. To import the resource, you must specify the `region` parameter in the `provider` block of your Terraform configuration file. If the region is not specified, `us-south` is used by default. An Terraform refresh or apply fails, if the database instance is not in the same region as configured in the provider or its alias. + +CRN is a 120 digit character string of the form - `crn:v1:bluemix:public:dashdb-for-transactions:us-south:a/60970f92286548d8a64cbb45bce39bc1:deae06ff-3966-4534-bfa0-4b42281e7cef::` + +**Syntax** + +``` +$ terraform import ibm_db2.my_db +``` + +**Example** + +``` +$ terraform import ibm_db2.my_db crn:v1:bluemix:public:dashdb-for-transactions:us-south:a/60970f92286548d8a64cbb45bce39bc1:deae06ff-3966-4534-bfa0-4b42281e7cef:: +``` + +Import requires a minimal Terraform config file to allow importing. + +```terraform +resource "ibm_db2" "" { + name = "" +} +``` + +Run `terraform state show ibm_db2.` after import to retrieve the more values to be included in the resource config file. It does not export any more user IDs and passwords that are configured on the instance. These values must be retrieved from an alternative source. \ No newline at end of file diff --git a/website/docs/r/is_bare_metal_server.markdown b/website/docs/r/is_bare_metal_server.markdown index 0d5ae468d1..e999bf4e9d 100644 --- a/website/docs/r/is_bare_metal_server.markdown +++ b/website/docs/r/is_bare_metal_server.markdown @@ -56,6 +56,53 @@ resource "ibm_is_bare_metal_server" "example" { } vpc = ibm_is_vpc.example.id } +``` +### Reservation Example +```terraform +resource "ibm_is_reservation" "example" { + capacity { + total = 5 + } + committed_use { + term = "one_year" + } + profile { + name = "mx2d-metal-32x192" + resource_type = "bare_metal_server_profile" + } + zone = "us-east-3" + name = "reservation-name" +} +resource "ibm_is_vpc" "example" { + name = "example-vpc" +} +resource "ibm_is_subnet" "example" { + name = "example-subnet" + vpc = ibm_is_vpc.vpc.id + zone = "us-south-3" + ipv4_cidr_block = "10.240.129.0/24" +} +resource "ibm_is_ssh_key" "example" { + name = "example-ssh" + public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCKVmnMOlHKcZK8tpt3MP1lqOLAcqcJzhsvJcjscgVERRN7/9484SOBJ3HSKxxNG5JN8owAjy5f9yYwcUg+JaUVuytn5Pv3aeYROHGGg+5G346xaq3DAwX6Y5ykr2fvjObgncQBnuU5KHWCECO/4h8uWuwh/kfniXPVjFToc+gnkqA+3RKpAecZhFXwfalQ9mMuYGFxn+fwn8cYEApsJbsEmb0iJwPiZ5hjFC8wREuiTlhPHDgkBLOiycd20op2nXzDbHfCHInquEe/gYxEitALONxm0swBOwJZwlTDOB7C6y2dzlrtxr1L59m7pCkWI4EtTRLvleehBoj3u7jB4usR" +} +resource "ibm_is_bare_metal_server" "example" { + profile = "mx2d-metal-32x192" + name = "example-bms" + image = "r134-31c8ca90-2623-48d7-8cf7-737be6fc4c3e" + zone = "us-south-3" + keys = [ibm_is_ssh_key.example.id] + primary_network_interface { + subnet = ibm_is_subnet.example.id + } + reservation_affinity { + policy = "manual" + pool { + id = ibm_is_reservation.example.id + } + } + vpc = ibm_is_vpc.example.id +} ``` ### Reserved ip example @@ -141,6 +188,13 @@ Review the argument references that you can specify for your resource. - `bandwidth` - (Integer) The total bandwidth (in megabits per second) shared across the bare metal server's network interfaces. The specified value must match one of the bandwidth values in the bare metal server's profile. - `delete_type` - (Optional, String) Type of deletion on destroy. **soft** signals running operating system to quiesce and shutdown cleanly, **hard** immediately stop the server. By default its `hard`. - `enable_secure_boot` - (Optional, Boolean) Indicates whether secure boot is enabled. If enabled, the image must support secure boot or the server will fail to boot. Updating `enable_secure_boot` requires the server to be stopped and then it would be started. +- `health_reasons` - (List) The reasons for the current health_state (if any). + + Nested scheme for `health_reasons`: + - `code` - (String) A snake case string succinctly identifying the reason for this health state. + - `message` - (String) An explanation of the reason for this health state. + - `more_info` - (String) Link to documentation about the reason for this health state. +- `health_state` - (String) The health of this resource. - `image` - (Required, String) ID of the image. ( On update of `image`, server will be [reinitialized](https://cloud.ibm.com/apidocs/vpc/latest#replace-bare-metal-server-initialization) if server is in stopped state, else server will be stopped and restarted during update ) -> **NOTE:** @@ -288,6 +342,31 @@ Review the argument references that you can specify for your resource. - `subnet` - (Required, String) ID of the subnet to associate with. - `profile` - (Required, Forces new resource, String) The name the profile to use for this bare metal server. +- `reservation`- (List) The reservation used by this bare metal server. + Nested scheme for `reservation`: + - `crn` - (String) The CRN for this reservation. + - `deleted` - (List) If present, this property indicates the referenced resource has been deleted, and provides some supplementary information. + + Nested `deleted` blocks have the following structure: + - `more_info` - (String) Link to documentation about deleted resources. + - `href` - (String) The URL for this reservation. + - `id` - (String) The unique identifier for this reservation. + - `name` - (string) The name for this reservation. The name is unique across all reservations in the region. + - `resource_type` - (string) The resource type. +- `reservation_affinity`- (List) The bare metal server reservation affinity. + + Nested scheme for `reservation_affinity`: + - `policy` - (String) The reservation affinity policy to use for this bare metal server. + - `pool` - (List) The pool of reservations available for use by this bare metal server. + Nested `pool` blocks have the following structure: + - `crn` - (String) The CRN for this reservation. + - `deleted` - (List) If present, this property indicates the referenced resource has been deleted, and provides some supplementary information. + Nested `deleted` blocks have the following structure: + - `more_info` - (String) Link to documentation about deleted resources. + - `href` - (String) The URL for this reservation. + - `id` - (String) The unique identifier for this reservation. + - `name` - (string) The name for this reservation. The name is unique across all reservations in the region. + - `resource_type` - (string) The resource type. - `resource_group` - (Optional, Forces new resource, String) The resource group ID for this bare metal server. - `trusted_platform_module` - (Optional, List) trusted platform module (TPM) configuration for the bare metals server @@ -339,6 +418,16 @@ In addition to all argument reference list, you can access the following attribu - `subnet` - (String) ID of the subnet to associate with. - `vlan` - (Integer) Indicates the 802.1Q VLAN ID tag that must be used for all traffic on this interface. [ conflicts with `allowed_vlans`] +- `reservation_affinity` - (Optional, List) The reservation affinity for the bare metal server + Nested scheme for `reservation_affinity`: + - `policy` - (Optional, String) The reservation affinity policy to use for this bare metal server. + + ->**policy** + • disabled: Reservations will not be used +
• manual: Reservations in pool will be available for use + - `pool` - (Optional, String) The pool of reservations available for use by this bare metal server. Specified reservations must have a status of active, and have the same profile and zone as this bare metal server. The pool must be empty if policy is disabled, and must not be empty if policy is manual. + Nested scheme for `pool`: + - `id` - The unique identifier for this reservation - `resource_type` - (String) The type of resource. - `firmware_update_type_available` - (String) The firmware update type available for the bare metal server. -> **Supported firmware update types**
• none
• optional
• required diff --git a/website/docs/r/is_instance.html.markdown b/website/docs/r/is_instance.html.markdown index 7dee54d74d..0fa9ef40e1 100644 --- a/website/docs/r/is_instance.html.markdown +++ b/website/docs/r/is_instance.html.markdown @@ -787,6 +787,13 @@ In addition to all argument reference list, you can access the following attribu - `manufacture` - (String) The manufacturer of the GPU. - `memory`- (Integer) The amount of memory of the GPU in gigabytes. - `model` - (String) The model of the GPU. +- `health_reasons` - (List) The reasons for the current health_state (if any). + + Nested scheme for `health_reasons`: + - `code` - (String) A snake case string succinctly identifying the reason for this health state. + - `message` - (String) An explanation of the reason for this health state. + - `more_info` - (String) Link to documentation about the reason for this health state. +- `health_state` - (String) The health of this resource. - `placement_target` - The placement restrictions for the virtual server instance. - `crn` - The CRN of the placement target - `deleted` - If present, this property indicates the referenced resource has been deleted and providessome supplementary information. diff --git a/website/docs/r/is_instance_disk_management.html.markdown b/website/docs/r/is_instance_disk_management.html.markdown index 8995116656..978ab1aa6e 100644 --- a/website/docs/r/is_instance_disk_management.html.markdown +++ b/website/docs/r/is_instance_disk_management.html.markdown @@ -63,7 +63,7 @@ data "ibm_is_instance" "example" { passphrase = "" } -data "is_instance_disk" "example" { +data "ibm_is_instance_disk" "example" { instance = data.ibm_is_instance.example.id disk = data.ibm_is_instance.example.disks.0.id } diff --git a/website/docs/r/resource_instance.html.markdown b/website/docs/r/resource_instance.html.markdown index 234f336a8f..50bc6eb113 100644 --- a/website/docs/r/resource_instance.html.markdown +++ b/website/docs/r/resource_instance.html.markdown @@ -20,7 +20,7 @@ data "ibm_resource_group" "group" { resource "ibm_resource_instance" "resource_instance" { name = "test" service = "cloud-object-storage" - plan = "lite" + plan = "standard" location = "global" resource_group_id = data.ibm_resource_group.group.id tags = ["tag1", "tag2"]