Skip to content

Commit 9e2c83a

Browse files
Terraform Team AutomationMeharwadeDivya
authored andcommitted
Bug Fix - trigger recreation while change subnet_id for endpoint config and ignore order in configurations for addons
1 parent 345d3f5 commit 9e2c83a

File tree

7 files changed

+114
-71
lines changed

7 files changed

+114
-71
lines changed

examples/container_engine/addons/main.tf

Lines changed: 62 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,39 @@
11
// Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
22
// Licensed under the Mozilla Public License v2.0
3-
4-
variable "tenancy_ocid" {
3+
variable "user_ocid" {
54
}
65

7-
variable "cluster_id" {
8-
6+
variable "fingerprint" {
97
}
108

11-
variable "kubernetes_version" {
12-
9+
variable "private_key_path" {
1310
}
1411

15-
variable "compartment_ocid" {
12+
variable "region" {
13+
default = "us-ashburn-1"
1614
}
1715

18-
variable "image_id" {
1916

17+
variable "tenancy_ocid" {
2018
}
2119

22-
data "oci_containerengine_addon_options" "all" {
23-
#Required
24-
kubernetes_version = var.kubernetes_version
25-
}
20+
variable "cluster_id" {
2621

27-
data "oci_containerengine_addon_options" "name_filter_example" {
28-
#Required
29-
kubernetes_version = var.kubernetes_version
30-
#Optional, a name uniquely identifies an add-on, see all supported add-on names in data.oci_containerengine_addon_options.all.addon_options
31-
addon_name = "KubernetesDashboard"
3222
}
3323

34-
resource "oci_containerengine_addon" "addon_resource_example" {
35-
#Required, a name uniquely identifies an add-on, see all supported add-on names in data.oci_containerengine_addon_options.all.addon_options
36-
addon_name = "KubernetesDashboard"
37-
#Required
38-
cluster_id = var.cluster_id
39-
#Required, false values keeps installed resources of the addon on deletion. Set to true to fully remove resources
40-
remove_addon_resources_on_delete = true
41-
42-
/*
43-
configurations that are supported by the add-on specified by the addon_name, see all supported configurations in in data.oci_containerengine_addon_options.all.addon_options.
44-
Unless required by a specific add-on, most of add-ons only have optional configurations that allow customization.
45-
*/
46-
configurations {
24+
variable "kubernetes_version" {
4725

48-
}
49-
/*
50-
Optional, see all supported version in in data.oci_containerengine_addon_options.all.addon_options.
51-
It is highly recommended to not set this field to let service choose and manage addon version.
52-
*/
53-
version = "v1.0.0"
5426
}
5527

56-
data "oci_containerengine_addons" "addon_addon_data_source_list_example" {
57-
#Required
58-
cluster_id = var.cluster_id
28+
variable "compartment_ocid" {
5929
}
6030

61-
data "oci_containerengine_addon" "addon_data_source_singular_example" {
62-
#Required
63-
cluster_id = var.cluster_id
64-
#Required, a name uniquely identifies an add-on, see all supported add-on names in data.oci_containerengine_addon_options.all.addon_options
65-
addon_name = "KubernetesDashboard"
31+
provider "oci" {
32+
region = var.region
33+
tenancy_ocid = var.tenancy_ocid
34+
user_ocid = var.user_ocid
35+
fingerprint = var.fingerprint
36+
private_key_path = var.private_key_path
6637
}
6738

6839
/*
@@ -113,7 +84,7 @@ resource "oci_core_subnet" "nodePool_Subnet_1" {
11384
resource "oci_containerengine_cluster" "test_cluster" {
11485
#Required
11586
compartment_id = var.compartment_ocid
116-
kubernetes_version = var.kubernetes_version
87+
kubernetes_version = reverse(data.oci_containerengine_cluster_option.test_cluster_option.kubernetes_versions)[0]
11788
name = "tfTestCluster"
11889
vcn_id = oci_core_vcn.test_vcn.id
11990
type = "ENHANCED_CLUSTER"
@@ -126,13 +97,21 @@ resource "oci_containerengine_addon" "dashboard" {
12697
cluster_id = oci_containerengine_cluster.test_cluster.id
12798
#Required, remove the resource on addon deletion
12899
remove_addon_resources_on_delete = true
100+
dynamic configurations {
101+
for_each = local.addon_mappings
102+
103+
content {
104+
key =configurations.value.key
105+
value = configurations.value.value
106+
}
107+
}
129108
}
130109

131110
resource "oci_containerengine_node_pool" "test_node_pool" {
132111
#Required
133112
cluster_id = oci_containerengine_cluster.test_cluster.id
134113
compartment_id = var.compartment_ocid
135-
kubernetes_version = var.kubernetes_version
114+
kubernetes_version = reverse(data.oci_containerengine_cluster_option.test_cluster_option.kubernetes_versions)[0]
136115
name = "tfPool"
137116
node_shape = "VM.Standard2.1"
138117

@@ -146,7 +125,7 @@ resource "oci_containerengine_node_pool" "test_node_pool" {
146125

147126
node_source_details {
148127
#Required
149-
image_id = var.image_id
128+
image_id = local.image_id
150129
source_type = "IMAGE"
151130

152131
#Optional
@@ -155,4 +134,40 @@ resource "oci_containerengine_node_pool" "test_node_pool" {
155134

156135
//use terraform depends_on to enforce cluster->add-on->node pool DAG
157136
depends_on = [oci_containerengine_addon.dashboard]
137+
}
138+
139+
data "oci_containerengine_cluster_option" "test_cluster_option" {
140+
cluster_option_id = "all"
141+
}
142+
143+
data "oci_containerengine_node_pool_option" "test_node_pool_option" {
144+
node_pool_option_id = "all"
145+
}
146+
147+
data "oci_core_images" "shape_specific_images" {
148+
#Required
149+
compartment_id = var.tenancy_ocid
150+
shape = "VM.Standard2.1"
151+
}
152+
153+
locals {
154+
all_images = "${data.oci_core_images.shape_specific_images.images}"
155+
all_sources = "${data.oci_containerengine_node_pool_option.test_node_pool_option.sources}"
156+
157+
compartment_images = [for image in local.all_images : image.id if length(regexall("Oracle-Linux-[0-9]*.[0-9]*-20[0-9]*",image.display_name)) > 0 ]
158+
159+
oracle_linux_images = [for source in local.all_sources : source.image_id if length(regexall("Oracle-Linux-[0-9]*.[0-9]*-20[0-9]*",source.source_name)) > 0]
160+
161+
image_id = tolist(setintersection( toset(local.compartment_images), toset(local.oracle_linux_images)))[0]
162+
163+
addon_mappings = {
164+
mapping1 = {
165+
key = "numOfReplicas"
166+
value = "1"
167+
}
168+
mapping2 = {
169+
key = "nodeSelectors"
170+
value = "{\"pool\":\"system\"}"
171+
}
172+
}
158173
}

examples/container_engine/main.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ resource "oci_core_subnet" "nodePool_Subnet_2" {
166166
resource "oci_containerengine_cluster" "test_cluster" {
167167
#Required
168168
compartment_id = var.compartment_ocid
169-
kubernetes_version = data.oci_containerengine_cluster_option.test_cluster_option.kubernetes_versions[0]
169+
kubernetes_version = reverse(data.oci_containerengine_cluster_option.test_cluster_option.kubernetes_versions)[0]
170170
name = "tfTestCluster"
171171
vcn_id = oci_core_vcn.test_vcn.id
172172

internal/integrationtest/containerengine_cluster_test.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,12 @@ func TestContainerengineClusterResource_basic(t *testing.T) {
131131
resource.TestCheckResourceAttrSet(resourceName, "kubernetes_version"),
132132
resource.TestCheckResourceAttr(resourceName, "name", "name"),
133133
resource.TestCheckResourceAttrSet(resourceName, "vcn_id"),
134-
135134
func(s *terraform.State) (err error) {
136135
resId, err = acctest.FromInstanceState(s, resourceName, "id")
137136
return err
138137
},
139138
),
140139
},
141-
142140
// delete before next Create
143141
{
144142
Config: config + compartmentIdVariableStr + ContainerengineClusterResourceDependencies,

internal/service/containerengine/containerengine_addon_resource.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,10 @@ func ContainerengineAddonResource() *schema.Resource {
5151

5252
// Optional
5353
"configurations": {
54-
Type: schema.TypeList,
55-
Optional: true,
56-
Computed: true,
54+
Type: schema.TypeList,
55+
Optional: true,
56+
Computed: true,
57+
DiffSuppressFunc: tfresource.ListOfMapEqualIgnoreOrderSuppressDiff,
5758
Elem: &schema.Resource{
5859
Schema: map[string]*schema.Schema{
5960
// Required

internal/service/containerengine/containerengine_cluster_resource.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ func ContainerengineClusterResource() *schema.Resource {
9696
"subnet_id": {
9797
Type: schema.TypeString,
9898
Required: true,
99+
ForceNew: true,
99100
},
100101

101102
// Optional

internal/tfresource/crud_helpers.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,52 @@ func listEqualIgnoreOrderSuppressDiff(key string, d schemaResourceData) bool {
560560
return true
561561
}
562562

563+
func ListOfMapEqualIgnoreOrderSuppressDiff(key string, old string, new string, d *schema.ResourceData) bool {
564+
return listOfMapEqualIgnoreOrderSuppressDiff(key, d)
565+
}
566+
567+
func listOfMapEqualIgnoreOrderSuppressDiff(key string, d schemaResourceData) bool {
568+
// Take only the field name, key might be field.#
569+
oldRaw, newRaw := d.GetChange(strings.Split(key, ".")[0])
570+
if newRaw == nil || oldRaw == nil {
571+
return false
572+
}
573+
oldList := oldRaw.([]interface{})
574+
newList := newRaw.([]interface{})
575+
576+
if len(oldList) != len(newList) {
577+
return false
578+
}
579+
tmp1 := make([]string, len(oldList))
580+
tmp2 := make([]string, len(newList))
581+
582+
for i := range oldList {
583+
map1 := oldList[i].(map[string]interface{})
584+
jsonMap := GenericMapToJsonMap(map1)
585+
s1, err := json.Marshal(jsonMap)
586+
if err != nil {
587+
return false
588+
}
589+
tmp1[i] = string(s1)
590+
591+
map2 := oldList[i].(map[string]interface{})
592+
jsonMap2 := GenericMapToJsonMap(map2)
593+
s2, err := json.Marshal(jsonMap2)
594+
if err != nil {
595+
return false
596+
}
597+
tmp2[i] = string(s2)
598+
}
599+
sort.Strings(tmp1)
600+
sort.Strings(tmp2)
601+
for i := range oldList {
602+
if tmp1[i] != tmp2[i] {
603+
return false
604+
}
605+
}
606+
return true
607+
}
608+
563609
func FieldDeprecatedAndAvoidReferences(deprecatedFieldName string) string {
564610
return fmt.Sprintf("The '%s' field has been deprecated and may be removed in a future version. Do not use this field.", deprecatedFieldName)
565611
}

website/docs/d/containerengine_node_pools.html.markdown

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -102,24 +102,6 @@ The following attributes are exported:
102102
* `boot_volume_size_in_gbs` - The size of the boot volume in GBs. Minimum value is 50 GB. See [here](https://docs.cloud.oracle.com/en-us/iaas/Content/Block/Concepts/bootvolumes.htm) for max custom boot volume sizing and OS-specific requirements.
103103
* `image_id` - The OCID of the image used to boot the node.
104104
* `source_type` - The source type for the node. Use `IMAGE` when specifying an OCID of an image.
105-
* `nodes` - The nodes in the node pool.
106-
* `availability_domain` - The name of the availability domain in which this node is placed.
107-
* `defined_tags` - Defined tags for this resource. Each key is predefined and scoped to a namespace. For more information, see [Resource Tags](https://docs.cloud.oracle.com/iaas/Content/General/Concepts/resourcetags.htm). Example: `{"Operations.CostCenter": "42"}`
108-
* `error` - An error that may be associated with the node.
109-
* `code` - A short error code that defines the upstream error, meant for programmatic parsing. See [API Errors](https://docs.cloud.oracle.com/iaas/Content/API/References/apierrors.htm).
110-
* `message` - A human-readable error string of the upstream error.
111-
* `status` - The status of the HTTP response encountered in the upstream error.
112-
* `fault_domain` - The fault domain of this node.
113-
* `freeform_tags` - Free-form tags for this resource. Each tag is a simple key-value pair with no predefined name, type, or namespace. For more information, see [Resource Tags](https://docs.cloud.oracle.com/iaas/Content/General/Concepts/resourcetags.htm). Example: `{"Department": "Finance"}`
114-
* `id` - The OCID of the compute instance backing this node.
115-
* `kubernetes_version` - The version of Kubernetes this node is running.
116-
* `lifecycle_details` - Details about the state of the node.
117-
* `name` - The name of the node.
118-
* `node_pool_id` - The OCID of the node pool to which this node belongs.
119-
* `private_ip` - The private IP address of this node.
120-
* `public_ip` - The public IP address of this node.
121-
* `state` - The state of the node.
122-
* `subnet_id` - The OCID of the subnet in which this node is placed.
123105
* `quantity_per_subnet` - The number of nodes in each subnet.
124106
* `ssh_public_key` - The SSH public key on each node in the node pool on launch.
125107
* `state` - The state of the nodepool.

0 commit comments

Comments
 (0)