Skip to content

Commit 7f0ae99

Browse files
authored
Merge pull request #669 from terraform-providers/release
Release 3.10.0
2 parents be59f79 + 8348537 commit 7f0ae99

13 files changed

+480
-44
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
## 3.9.1 (Unreleased)
1+
## 3.10.0 (Unreleased)
2+
3+
### Added
4+
- Support for attaching Route Table to Subnet. Issue [#270](https://github.com/terraform-providers/terraform-provider-oci/issues/270)
5+
6+
27
## 3.9.0 (December 04, 2018)
38

49
### Added
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
### Use Route Table Attachment to avoid cyclic dependency between Subnet and Route Table
2+
3+
This example uses the `oci_core_route_table_attachment` resource to resolve this dependency cycle problem:
4+
* oci_core_vnic_attachment.ExampleVnicAttachment
5+
* oci_core_private_ip.TFPrivateIP
6+
* oci_core_route_table.ExampleRouteTable
7+
* oci_core_subnet.ExampleSubnet
8+
* oci_core_instance.ExampleInstance
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
variable "tenancy_ocid" {}
2+
variable "user_ocid" {}
3+
variable "fingerprint" {}
4+
variable "private_key_path" {}
5+
variable "compartment_ocid" {}
6+
variable "region" {}
7+
8+
variable "instance_image_ocid" {
9+
type = "map"
10+
11+
default = {
12+
// See https://docs.us-phoenix-1.oraclecloud.com/images/
13+
// Oracle-provided image "Oracle-Linux-7.4-2018.02.21-1"
14+
us-phoenix-1 = "ocid1.image.oc1.phx.aaaaaaaaupbfz5f5hdvejulmalhyb6goieolullgkpumorbvxlwkaowglslq"
15+
16+
us-ashburn-1 = "ocid1.image.oc1.iad.aaaaaaaajlw3xfie2t5t52uegyhiq2npx7bqyu4uvi2zyu3w3mqayc2bxmaa"
17+
eu-frankfurt-1 = "ocid1.image.oc1.eu-frankfurt-1.aaaaaaaa7d3fsb6272srnftyi4dphdgfjf6gurxqhmv6ileds7ba3m2gltxq"
18+
uk-london-1 = "ocid1.image.oc1.uk-london-1.aaaaaaaaa6h6gj6v4n56mqrbgnosskq63blyv2752g36zerymy63cfkojiiq"
19+
}
20+
}
21+
22+
variable "availability_domain" {
23+
default = 3
24+
}
25+
26+
data "oci_identity_availability_domains" "ADs" {
27+
compartment_id = "${var.tenancy_ocid}"
28+
}
29+
30+
variable "instance_shape" {
31+
default = "VM.Standard1.8"
32+
}
33+
34+
provider "oci" {
35+
tenancy_ocid = "${var.tenancy_ocid}"
36+
user_ocid = "${var.user_ocid}"
37+
fingerprint = "${var.fingerprint}"
38+
private_key_path = "${var.private_key_path}"
39+
region = "${var.region}"
40+
}
41+
42+
resource "oci_core_virtual_network" "ExampleVCN" {
43+
cidr_block = "10.1.0.0/16"
44+
compartment_id = "${var.compartment_ocid}"
45+
display_name = "TFExampleVCN"
46+
dns_label = "tfexamplevcn"
47+
}
48+
49+
resource "oci_core_subnet" "ExampleSubnet" {
50+
availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
51+
cidr_block = "10.1.20.0/24"
52+
display_name = "TFExampleSubnet"
53+
dns_label = "tfexamplesubnet"
54+
55+
compartment_id = "${var.compartment_ocid}"
56+
vcn_id = "${oci_core_virtual_network.ExampleVCN.id}"
57+
}
58+
59+
resource "oci_core_route_table_attachment" "ExampleRouteTableAttachment" {
60+
subnet_id = "${oci_core_subnet.ExampleSubnet.id}"
61+
route_table_id = "${oci_core_route_table.ExampleRouteTable.id}"
62+
}
63+
64+
resource "oci_core_private_ip" "TFPrivateIP" {
65+
vnic_id = "${oci_core_vnic_attachment.ExampleVnicAttachment.vnic_id}"
66+
display_name = "someDisplayName"
67+
hostname_label = "somehostnamelabel"
68+
}
69+
70+
resource "oci_core_route_table" "ExampleRouteTable" {
71+
compartment_id = "${var.compartment_ocid}"
72+
vcn_id = "${oci_core_virtual_network.ExampleVCN.id}"
73+
display_name = "TFExampleRouteTable"
74+
75+
route_rules {
76+
destination = "0.0.0.0/0"
77+
destination_type = "CIDR_BLOCK"
78+
network_entity_id = "${oci_core_private_ip.TFPrivateIP.id}"
79+
}
80+
}
81+
82+
resource "oci_core_vnic_attachment" "ExampleVnicAttachment" {
83+
create_vnic_details {
84+
subnet_id = "${oci_core_subnet.ExampleSubnet.id}"
85+
skip_source_dest_check = true
86+
}
87+
88+
instance_id = "${oci_core_instance.ExampleInstance.id}"
89+
}
90+
91+
# Create Instance
92+
resource "oci_core_instance" "ExampleInstance" {
93+
availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
94+
compartment_id = "${var.compartment_ocid}"
95+
display_name = "TFInstance"
96+
hostname_label = "instance"
97+
image = "${var.instance_image_ocid[var.region]}"
98+
shape = "${var.instance_shape}"
99+
100+
create_vnic_details {
101+
subnet_id = "${oci_core_subnet.ExampleSubnet.id}"
102+
skip_source_dest_check = true
103+
assign_public_ip = true
104+
}
105+
}

oci/core_image_test.go

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,35 +18,23 @@ var (
1818
generateResourceFromRepresentationMap("oci_core_image", "test_image", Required, Create, imageRepresentation)
1919

2020
imageDataSourceRepresentation = map[string]interface{}{
21-
"compartment_id": Representation{repType: Required, create: `${var.compartment_id}`},
22-
"display_name": Representation{repType: Optional, create: `MyCustomImage`, update: `displayName2`},
23-
"operating_system": Representation{repType: Optional, create: `operatingSystem`},
24-
"operating_system_version": Representation{repType: Optional, create: `operatingSystemVersion`},
25-
"shape": Representation{repType: Optional, create: `shape`},
26-
"state": Representation{repType: Optional, create: `AVAILABLE`},
27-
"filter": RepresentationGroup{Required, imageDataSourceFilterRepresentation}}
21+
"compartment_id": Representation{repType: Required, create: `${var.compartment_id}`},
22+
"display_name": Representation{repType: Optional, create: `MyCustomImage`, update: `displayName2`},
23+
"state": Representation{repType: Optional, create: `AVAILABLE`},
24+
"filter": RepresentationGroup{Required, imageDataSourceFilterRepresentation}}
2825
imageDataSourceFilterRepresentation = map[string]interface{}{
2926
"name": Representation{repType: Required, create: `id`},
3027
"values": Representation{repType: Required, create: []string{`${oci_core_image.test_image.id}`}},
3128
}
3229

3330
imageRepresentation = map[string]interface{}{
34-
"compartment_id": Representation{repType: Required, create: `${var.compartment_id}`},
35-
"defined_tags": Representation{repType: Optional, create: `${map("${oci_identity_tag_namespace.tag-namespace1.name}.${oci_identity_tag.tag1.name}", "value")}`, update: `${map("${oci_identity_tag_namespace.tag-namespace1.name}.${oci_identity_tag.tag1.name}", "updatedValue")}`},
36-
"display_name": Representation{repType: Optional, create: `MyCustomImage`, update: `displayName2`},
37-
"freeform_tags": Representation{repType: Optional, create: map[string]string{"Department": "Finance"}, update: map[string]string{"Department": "Accounting"}},
38-
"image_source_details": RepresentationGroup{Optional, imageImageSourceDetailsRepresentation},
39-
"instance_id": Representation{repType: Required, create: `${oci_core_instance.test_instance.id}`},
40-
"launch_mode": Representation{repType: Optional, create: `NATIVE`},
41-
"timeouts": RepresentationGroup{Required, timeoutsRepresentation},
42-
}
43-
imageImageSourceDetailsRepresentation = map[string]interface{}{
44-
"source_type": Representation{repType: Required, create: `objectStorageTuple`},
45-
"bucket_name": Representation{repType: Optional, create: `MyBucket`},
46-
"namespace_name": Representation{repType: Optional, create: `MyNamespace`},
47-
"object_name": Representation{repType: Optional, create: `image-to-import.qcow2`},
48-
"source_image_type": Representation{repType: Optional, create: `QCOW2`},
49-
"source_uri": Representation{repType: Optional, create: `https://objectstorage.us-phoenix-1.oraclecloud.com/n/MyNamespace/b/MyBucket/o/image-to-import.qcow2`},
31+
"compartment_id": Representation{repType: Required, create: `${var.compartment_id}`},
32+
"defined_tags": Representation{repType: Optional, create: `${map("${oci_identity_tag_namespace.tag-namespace1.name}.${oci_identity_tag.tag1.name}", "value")}`, update: `${map("${oci_identity_tag_namespace.tag-namespace1.name}.${oci_identity_tag.tag1.name}", "updatedValue")}`},
33+
"display_name": Representation{repType: Optional, create: `MyCustomImage`, update: `displayName2`},
34+
"freeform_tags": Representation{repType: Optional, create: map[string]string{"Department": "Finance"}, update: map[string]string{"Department": "Accounting"}},
35+
"instance_id": Representation{repType: Required, create: `${oci_core_instance.test_instance.id}`},
36+
"launch_mode": Representation{repType: Optional, create: `NATIVE`},
37+
"timeouts": RepresentationGroup{Required, timeoutsRepresentation},
5038
}
5139

5240
timeoutsRepresentation = map[string]interface{}{
@@ -57,7 +45,6 @@ var (
5745
)
5846

5947
func TestCoreImageResource_basic(t *testing.T) {
60-
t.Skip("Long running test")
6148
provider := testAccProvider
6249
config := testProviderConfig()
6350

@@ -106,9 +93,7 @@ func TestCoreImageResource_basic(t *testing.T) {
10693
resource.TestCheckResourceAttr(resourceName, "display_name", "MyCustomImage"),
10794
resource.TestCheckResourceAttr(resourceName, "freeform_tags.%", "1"),
10895
resource.TestCheckResourceAttrSet(resourceName, "id"),
109-
resource.TestCheckResourceAttr(resourceName, "image_source_details.#", "1"),
110-
resource.TestCheckResourceAttr(resourceName, "image_source_details.0.source_image_type", "QCOW2"),
111-
resource.TestCheckResourceAttr(resourceName, "image_source_details.0.source_type", "objectStorageTuple"),
96+
resource.TestCheckResourceAttrSet(resourceName, "instance_id"),
11297
resource.TestCheckResourceAttr(resourceName, "launch_mode", "NATIVE"),
11398
resource.TestCheckResourceAttrSet(resourceName, "operating_system"),
11499
resource.TestCheckResourceAttrSet(resourceName, "operating_system_version"),
@@ -133,9 +118,7 @@ func TestCoreImageResource_basic(t *testing.T) {
133118
resource.TestCheckResourceAttr(resourceName, "display_name", "displayName2"),
134119
resource.TestCheckResourceAttr(resourceName, "freeform_tags.%", "1"),
135120
resource.TestCheckResourceAttrSet(resourceName, "id"),
136-
resource.TestCheckResourceAttr(resourceName, "image_source_details.#", "1"),
137-
resource.TestCheckResourceAttr(resourceName, "image_source_details.0.source_image_type", "QCOW2"),
138-
resource.TestCheckResourceAttr(resourceName, "image_source_details.0.source_type", "objectStorageTuple"),
121+
resource.TestCheckResourceAttrSet(resourceName, "instance_id"),
139122
resource.TestCheckResourceAttr(resourceName, "launch_mode", "NATIVE"),
140123
resource.TestCheckResourceAttrSet(resourceName, "operating_system"),
141124
resource.TestCheckResourceAttrSet(resourceName, "operating_system_version"),

oci/core_instance_resource.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,16 @@ func (s *InstanceResourceCrud) Update() error {
557557

558558
response, err := s.Client.UpdateInstance(context.Background(), request)
559559
if err != nil {
560+
if response.RawResponse.StatusCode == 400 &&
561+
strings.Contains(err.Error(), "metadata field cannot be updated") {
562+
return fmt.Errorf(`%s
563+
564+
To change 'ssh_authorized_keys' or 'user_data' properties in the
565+
'metadata' field, the resource must be tainted and recreated.
566+
Use the terraform "taint" command to target this resource then
567+
run apply again.`, err)
568+
}
569+
560570
return err
561571
}
562572

@@ -918,7 +928,11 @@ func (s *InstanceResourceCrud) mapToInstanceSourceDetails(fieldKeyFormat string)
918928
}
919929

920930
func InstanceSourceDetailsToMap(obj *oci_core.InstanceSourceDetails, bootVolume *oci_core.BootVolume, sourceDetailsFromConfig map[string]interface{}) map[string]interface{} {
921-
result := map[string]interface{}{}
931+
// We need to use the values provided by the customer to prevent force new in case the service does not return the value
932+
result := sourceDetailsFromConfig
933+
if result == nil {
934+
result = map[string]interface{}{}
935+
}
922936
switch v := (*obj).(type) {
923937
case oci_core.InstanceSourceViaBootVolumeDetails:
924938
result["source_type"] = "bootVolume"
@@ -935,9 +949,6 @@ func InstanceSourceDetailsToMap(obj *oci_core.InstanceSourceDetails, bootVolume
935949
// The service could omit the boot volume size in the InstanceSourceViaImageDetails, so use the boot volume
936950
// SizeInGBs property if that's the case.
937951
result["boot_volume_size_in_gbs"] = strconv.FormatInt(*bootVolume.SizeInGBs, 10)
938-
} else if sourceDetailsFromConfig != nil {
939-
// Last resort. If we can't query the boot volume size from service, use the config value.
940-
result["boot_volume_size_in_gbs"] = sourceDetailsFromConfig["boot_volume_size_in_gbs"]
941952
}
942953

943954
if v.KmsKeyId != nil {

oci/core_instance_test.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ var (
3838
instanceRepresentation = map[string]interface{}{
3939
"availability_domain": Representation{repType: Required, create: `${data.oci_identity_availability_domains.test_availability_domains.availability_domains.0.name}`},
4040
"compartment_id": Representation{repType: Required, create: `${var.compartment_id}`},
41-
"shape": Representation{repType: Required, create: `VM.Standard1.8`},
41+
"shape": Representation{repType: Required, create: `VM.Standard2.1`},
4242
"create_vnic_details": RepresentationGroup{Optional, instanceCreateVnicDetailsRepresentation},
4343
"defined_tags": Representation{repType: Optional, create: `${map("${oci_identity_tag_namespace.tag-namespace1.name}.${oci_identity_tag.tag1.name}", "value")}`, update: `${map("${oci_identity_tag_namespace.tag-namespace1.name}.${oci_identity_tag.tag1.name}", "updatedValue")}`},
4444
"display_name": Representation{repType: Optional, create: `displayName`, update: `displayName2`},
@@ -98,7 +98,7 @@ func TestCoreInstanceResource_basic(t *testing.T) {
9898
provider oci {
9999
test_time_maintenance_reboot_due = "2030-01-01 00:00:00"
100100
}
101-
` + commonTestVariables()
101+
` + commonTestVariables() + KeyResourceDependencyConfig
102102

103103
compartmentId := getEnvSettingWithBlankDefault("compartment_ocid")
104104
compartmentIdVariableStr := fmt.Sprintf("variable \"compartment_id\" { default = \"%s\" }\n", compartmentId)
@@ -123,7 +123,7 @@ func TestCoreInstanceResource_basic(t *testing.T) {
123123
Check: resource.ComposeAggregateTestCheckFunc(
124124
resource.TestCheckResourceAttrSet(resourceName, "availability_domain"),
125125
resource.TestCheckResourceAttr(resourceName, "compartment_id", compartmentId),
126-
resource.TestCheckResourceAttr(resourceName, "shape", "VM.Standard1.8"),
126+
resource.TestCheckResourceAttr(resourceName, "shape", "VM.Standard2.1"),
127127
resource.TestCheckResourceAttrSet(resourceName, "subnet_id"),
128128
resource.TestCheckResourceAttr(resourceName, "time_maintenance_reboot_due", ""),
129129

@@ -165,7 +165,7 @@ func TestCoreInstanceResource_basic(t *testing.T) {
165165
resource.TestCheckResourceAttr(resourceName, "ipxe_script", "ipxeScript"),
166166
resource.TestCheckResourceAttr(resourceName, "metadata.%", "1"),
167167
resource.TestCheckResourceAttrSet(resourceName, "region"),
168-
resource.TestCheckResourceAttr(resourceName, "shape", "VM.Standard1.8"),
168+
resource.TestCheckResourceAttr(resourceName, "shape", "VM.Standard2.1"),
169169
resource.TestCheckResourceAttr(resourceName, "source_details.#", "1"),
170170
resource.TestCheckResourceAttrSet(resourceName, "source_details.0.source_id"),
171171
resource.TestCheckResourceAttr(resourceName, "source_details.0.source_type", "image"),
@@ -208,7 +208,7 @@ func TestCoreInstanceResource_basic(t *testing.T) {
208208
resource.TestCheckResourceAttr(resourceName, "ipxe_script", "ipxeScript"),
209209
resource.TestCheckResourceAttr(resourceName, "metadata.%", "2"),
210210
resource.TestCheckResourceAttrSet(resourceName, "region"),
211-
resource.TestCheckResourceAttr(resourceName, "shape", "VM.Standard1.8"),
211+
resource.TestCheckResourceAttr(resourceName, "shape", "VM.Standard2.1"),
212212
resource.TestCheckResourceAttr(resourceName, "source_details.#", "1"),
213213
resource.TestCheckResourceAttrSet(resourceName, "source_details.0.source_id"),
214214
resource.TestCheckResourceAttr(resourceName, "source_details.0.source_type", "image"),
@@ -250,7 +250,7 @@ func TestCoreInstanceResource_basic(t *testing.T) {
250250
resource.TestCheckResourceAttr(datasourceName, "instances.0.ipxe_script", "ipxeScript"),
251251
resource.TestCheckResourceAttr(datasourceName, "instances.0.metadata.%", "2"),
252252
resource.TestCheckResourceAttrSet(datasourceName, "instances.0.region"),
253-
resource.TestCheckResourceAttr(datasourceName, "instances.0.shape", "VM.Standard1.8"),
253+
resource.TestCheckResourceAttr(datasourceName, "instances.0.shape", "VM.Standard2.1"),
254254
resource.TestCheckResourceAttr(datasourceName, "instances.0.source_details.#", "1"),
255255
resource.TestCheckResourceAttrSet(datasourceName, "instances.0.source_details.0.source_id"),
256256
resource.TestCheckResourceAttr(datasourceName, "instances.0.source_details.0.source_type", "image"),
@@ -279,7 +279,7 @@ func TestCoreInstanceResource_basic(t *testing.T) {
279279
resource.TestCheckResourceAttr(singularDatasourceName, "ipxe_script", "ipxeScript"),
280280
resource.TestCheckResourceAttr(singularDatasourceName, "metadata.%", "2"),
281281
resource.TestCheckResourceAttrSet(singularDatasourceName, "region"),
282-
resource.TestCheckResourceAttr(singularDatasourceName, "shape", "VM.Standard1.8"),
282+
resource.TestCheckResourceAttr(singularDatasourceName, "shape", "VM.Standard2.1"),
283283
resource.TestCheckResourceAttr(singularDatasourceName, "source_details.#", "1"),
284284
resource.TestCheckResourceAttr(singularDatasourceName, "source_details.0.source_type", "image"),
285285
resource.TestCheckResourceAttrSet(singularDatasourceName, "state"),
@@ -306,6 +306,7 @@ func TestCoreInstanceResource_basic(t *testing.T) {
306306
"extended_metadata",
307307
"hostname_label",
308308
"subnet_id",
309+
"source_details.0.kms_key_id", //TODO: Service is not returning this value, remove when the service returns it. COM-26394
309310
},
310311
ResourceName: resourceName,
311312
},

0 commit comments

Comments
 (0)