From 5b0c5c4c465e8d2f471cd17b3c7cd497ac27b242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=87etin=20ARDAL?= <6201562+kral2@users.noreply.github.com> Date: Mon, 20 Sep 2021 15:41:09 +0200 Subject: [PATCH] feat: add reserved public ip (#71) - var.public_ip and var.public_ip_display_name are added to control this new feature - var.public_ip accept a string with value NONE, RESERVED or EPHEMERAL. each keyword does what it says. - var.assign_public_ip becomes deprecated - rename terraform resources from to more meaningful name fix #55 --- CHANGELOG.adoc | 5 +- README.md | 19 ++- docs/terraformoptions.adoc | 33 ++++- examples/instances_fixed_shape/README.md | 5 +- examples/instances_fixed_shape/main.tf | 12 +- examples/instances_fixed_shape/variables.tf | 6 + examples/instances_flex_shape/README.md | 5 +- examples/instances_flex_shape/main.tf | 10 +- examples/instances_flex_shape/variables.tf | 8 +- .../instances_reserved_public_ip/README.md | 39 ++++++ examples/instances_reserved_public_ip/main.tf | 49 +++++++ .../terraform.tfvars.example | 34 +++++ .../instances_reserved_public_ip/variables.tf | 131 ++++++++++++++++++ main.tf | 59 ++++++-- outputs.tf | 45 +++++- variables.tf | 20 ++- 16 files changed, 426 insertions(+), 54 deletions(-) create mode 100644 examples/instances_reserved_public_ip/README.md create mode 100644 examples/instances_reserved_public_ip/main.tf create mode 100644 examples/instances_reserved_public_ip/terraform.tfvars.example create mode 100644 examples/instances_reserved_public_ip/variables.tf diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index ea34bda..51bc506 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -19,12 +19,16 @@ Given a version number MAJOR.MINOR.PATCH: === Deprecated * `var.ssh_authorized_keys` is deprecated. Use `var.ssh_public_keys`. +* `var.assign_public_ip` is deprecated. Use `var.public_ip` with the predefined keywords instead. === New features * Add support for freeform and defined tags for instances, vnics and block volumes (Fix #10, #11, #12, #13, #18, #20) * Add "module watermark" freeform tags: module defined and user defined freeform tags are merged on the final resource * Add support to provide the `ssh_authorized_keys` argument as a string or as a file (Fix #67 #70) +* Add support for reserved Public IP on instance first VNIC (fix #55) +* [ ] Define a backup policy for boot volume and additional block volumes (fix #64) +* Add new outputs for each provisioned resources: "all_attributes" outputs have full provider coverage and are auto-updating. === Documentation @@ -47,7 +51,6 @@ Given a version number MAJOR.MINOR.PATCH: * Outputs produces unnecessarily multidimensional objects (Issue #31) * Repo maintenance: ** add .gitattributes for consistent line ending and tab -** add pre-commit configuration file == 2.0.4 - 2021-02-13 diff --git a/README.md b/README.md index a72a469..70925f9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Oracle Cloud Infrastructure Terraform Module for Compute Instance -This Module provides an easy way to launch compute instances with advanced settings and good practices embedded. +This module provides an easy way to launch compute instances with advanced settings and good practices embedded. On top of the compute instance capabilities, this module can also provision and attach additional Block Volumes to the instances. @@ -10,24 +10,20 @@ On top of the compute instance capabilities, this module can also provision and > > Oracle recommends that you do not use custom images without these rules unless you understand the security risks. See [Compute Best Practices](https://docs.cloud.oracle.com/iaas/Content/Compute/References/bestpracticescompute.htm#two) for recommendations on how to manage instances. -## Maintainers - -This module is maintained by Oracle. - ## Requirements The diagram below summarizes the required components and their respective versions to use this module. ![versions](https://github.com/oracle-terraform-modules/terraform-oci-compute-instance/blob/main/docs/diagrams/versions.svg?raw=true&sanitize=true) -To enforce versions compatibility of both Terraform and the OCI provider, your root configuration should ideally include this block in `main.tf` for version pinning: +To enforce versions compatibility of both Terraform and the OCI provider, your root configuration should ideally include this block for version pinning: ```HCL terraform { - required_version = ">= 0.12" + required_version = ">= 0.12.6" required_providers { oci = { - version = ">= 3.27" + version = ">= 4.0.0" } } } @@ -59,11 +55,11 @@ module "instance" { ## What's coming next for this module? -The current focus is to get back in close the gap between this module and the provider's capabilities. We started with a complete code base update for [HCL2 syntax compatibility](https://github.com/oracle-terraform-modules/terraform-oci-compute-instance/releases/tag/v2.0.2), then adding support for [Regional Subnets](https://github.com/oracle-terraform-modules/terraform-oci-compute-instance/releases/tag/v2.0.4) and now [Flexible Shapes](https://github.com/oracle-terraform-modules/terraform-oci-compute-instance/pull/49). +The current focus is to close the gap between this module and the provider's capabilities. We started with a complete codebase update for [HCL2 syntax compatibility](https://github.com/oracle-terraform-modules/terraform-oci-compute-instance/releases/tag/v2.0.2), then adding support for [Regional Subnets](https://github.com/oracle-terraform-modules/terraform-oci-compute-instance/releases/tag/v2.0.4) and lastly [Flexible Shapes](https://github.com/oracle-terraform-modules/terraform-oci-compute-instance/pull/49). We will continue to push in that direction with the goal of [feature parity with the provider's capabilities](https://github.com/oracle-terraform-modules/terraform-oci-compute-instance/projects/4), as well as adding more features and integration points with other OCI services: Block Volume Backups, Secondary VNICs and IPs, etc ... -Compute Instances are also a perfect place to illustrate [module composition principles](https://www.terraform.io/docs/language/modules/develop/composition.html) reusing the other existing official Terraform OCI Modules +Given the dependency to Network and Storage for Compute Instances,it is a perfect place to illustrate [module composition principles](https://www.terraform.io/docs/language/modules/develop/composition.html) and how to reuse the other official Terraform OCI modules. ## Configuring iSCSI volume attachments @@ -73,7 +69,8 @@ Compute Instances are also a perfect place to illustrate [module composition pri ## Contributing -This project is open source. Oracle appreciates any contributions that are made by the open source community: raising issues, improving documentation, fixing bugs, or adding new features. +This project is open source and maintained by Oracle. +Oracle appreciates any contributions that are made by the open source community: raising issues, improving documentation, fixing bugs, or adding new features. Learn how to [contribute](https://github.com/oracle-terraform-modules/terraform-oci-compute-instance/blob/main/CONTRIBUTING.adoc). diff --git a/docs/terraformoptions.adoc b/docs/terraformoptions.adoc index 441b70d..84c093a 100644 --- a/docs/terraformoptions.adoc +++ b/docs/terraformoptions.adoc @@ -24,12 +24,15 @@ No modules. [cols="a,a",options="header,autowidth"] |=== |Name |Type -|https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/core_instance[oci_core_instance.this] |resource -|https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/core_volume[oci_core_volume.this] |resource -|https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/core_volume_attachment[oci_core_volume_attachment.this] |resource -|https://registry.terraform.io/providers/hashicorp/oci/latest/docs/data-sources/core_instance_credentials[oci_core_instance_credentials.this] |data source +|https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/core_instance[oci_core_instance.instance] |resource +|https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/core_public_ip[oci_core_public_ip.public_ip] |resource +|https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/core_volume[oci_core_volume.volume] |resource +|https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/core_volume_attachment[oci_core_volume_attachment.volume_attachment] |resource +|https://registry.terraform.io/providers/hashicorp/oci/latest/docs/data-sources/core_instance_credentials[oci_core_instance_credentials.credential] |data source +|https://registry.terraform.io/providers/hashicorp/oci/latest/docs/data-sources/core_private_ips[oci_core_private_ips.private_ips] |data source |https://registry.terraform.io/providers/hashicorp/oci/latest/docs/data-sources/core_shapes[oci_core_shapes.ad1] |data source -|https://registry.terraform.io/providers/hashicorp/oci/latest/docs/data-sources/core_subnet[oci_core_subnet.this] |data source +|https://registry.terraform.io/providers/hashicorp/oci/latest/docs/data-sources/core_subnet[oci_core_subnet.instance_subnet] |data source +|https://registry.terraform.io/providers/hashicorp/oci/latest/docs/data-sources/core_vnic_attachments[oci_core_vnic_attachments.vnic_attachment] |data source |https://registry.terraform.io/providers/hashicorp/oci/latest/docs/data-sources/identity_availability_domains[oci_identity_availability_domains.ad] |data source |=== @@ -45,7 +48,7 @@ No modules. |no |[[input_assign_public_ip]] <> -|Whether the VNIC should be assigned a public IP address. +|Deprecated: use `var.public_ip` instead. Whether the VNIC should be assigned a public IP address (Always EPHEMERAL). |`bool` |`false` |no @@ -146,6 +149,18 @@ No modules. |`[]` |no +|[[input_public_ip]] <> +|Whether to create a Public IP to attach to primary vnic and which lifetime. Valid values are NONE, RESERVED or EPHEMERAL. +|`string` +|`"NONE"` +|no + +|[[input_public_ip_display_name]] <> +|(Updatable) A user-friendly name. Does not have to be unique, and it's changeable. +|`string` +|`null` +|no + |[[input_resource_platform]] <> |Platform to create resources in. |`string` @@ -219,10 +234,16 @@ No modules. [cols="a,a",options="header,autowidth"] |=== |Name |Description +|[[output_instance_all_attributes]] <> |all attributes of created instance |[[output_instance_id]] <> |ocid of created instances. |[[output_instance_password]] <> |Passwords to login to Windows instance. |[[output_instance_username]] <> |Usernames to login to Windows instance. |[[output_instances_summary]] <> |Private and Public IPs for each instance. |[[output_private_ip]] <> |Private IPs of created instances. +|[[output_private_ips_all_attributes]] <> |all attributes of created private ips |[[output_public_ip]] <> |Public IPs of created instances. +|[[output_public_ip_all_attributes]] <> |all attributes of created public ip +|[[output_vnic_attachment_all_attributes]] <> |all attributes of created vnic attachments +|[[output_volume_all_attributes]] <> |all attributes of created volumes +|[[output_volume_attachment_all_attributes]] <> |all attributes of created volumes attachments |=== \ No newline at end of file diff --git a/examples/instances_fixed_shape/README.md b/examples/instances_fixed_shape/README.md index 52b4a20..b6b72f4 100644 --- a/examples/instances_fixed_shape/README.md +++ b/examples/instances_fixed_shape/README.md @@ -13,7 +13,8 @@ You will need to collect the following information before you start: 1. your OCI provider authentication values 2. a compartment OCID in which the instances will be created -3. a subnet OCID to which the instance's primary VNICs will be attached +3. a source OCID to deploy the instance, usually an image ocid from [OCI Platform Images list] +4. a subnet OCID to which the instance's primary VNICs will be attached For detailed instructions, see [docs/prerequisites.adoc] @@ -33,3 +34,5 @@ Then apply the example using the following commands: [Terraform Variable Definition file]:https://www.terraform.io/docs/language/values/variables.html#variable-definitions-tfvars-files [docs/prerequisites.adoc]:https://github.com/oracle-terraform-modules/terraform-oci-compute-instance/blob/main/docs/prerequisites.adoc +[Provisioning Infrastructure with Terraform]:https://www.terraform.io/docs/cli/run/index.html +[OCI Platform Images list]:https://docs.oracle.com/en-us/iaas/images/ diff --git a/examples/instances_fixed_shape/main.tf b/examples/instances_fixed_shape/main.tf index 3249e03..58f8276 100644 --- a/examples/instances_fixed_shape/main.tf +++ b/examples/instances_fixed_shape/main.tf @@ -1,10 +1,10 @@ // Copyright (c) 2018, 2021 Oracle and/or its affiliates. terraform { - required_version = ">= 0.12" // terraform version below 0.12 is not tested/supported with this module + required_version = ">= 0.13" // terraform version below 0.12 is not tested/supported with this module required_providers { oci = { - version = ">= 3.27" // force downloading oci-provider compatible with terraform v0.12 + version = ">= 4.0.0" // force downloading oci-provider compatible with terraform v0.12 } } } @@ -34,8 +34,8 @@ module "instance_nonflex" { # operating system parameters ssh_public_keys = var.ssh_public_keys # networking parameters - assign_public_ip = var.assign_public_ip - subnet_ocids = var.subnet_ocids + public_ip = var.public_ip # NONE, RESERVED or EPHEMERAL + subnet_ocids = var.subnet_ocids # storage parameters block_storage_sizes_in_gbs = var.block_storage_sizes_in_gbs } @@ -65,8 +65,8 @@ module "instance_nonflex_custom" { # operating system parameters ssh_public_keys = var.ssh_public_keys # networking parameters - assign_public_ip = var.assign_public_ip - subnet_ocids = var.subnet_ocids + public_ip = var.public_ip # NONE, RESERVED or EPHEMERAL + subnet_ocids = var.subnet_ocids # storage parameters block_storage_sizes_in_gbs = [] # no block volume will be created } diff --git a/examples/instances_fixed_shape/variables.tf b/examples/instances_fixed_shape/variables.tf index eb26b6f..4dc132b 100644 --- a/examples/instances_fixed_shape/variables.tf +++ b/examples/instances_fixed_shape/variables.tf @@ -118,6 +118,12 @@ variable "assign_public_ip" { default = false } +variable "public_ip" { + description = "Whether to create a Public IP to attach to primary vnic and which lifetime. Valid values are NONE, RESERVED or EPHEMERAL." + type = string + default = "NONE" +} + variable "subnet_ocids" { description = "The unique identifiers (OCIDs) of the subnets in which the instance primary VNICs are created." type = list(string) diff --git a/examples/instances_flex_shape/README.md b/examples/instances_flex_shape/README.md index ea26d95..8e3e449 100644 --- a/examples/instances_flex_shape/README.md +++ b/examples/instances_flex_shape/README.md @@ -13,7 +13,8 @@ You will need to collect the following information before you start: 1. your OCI provider authentication values 2. a compartment OCID in which the instances will be created -3. a subnet OCID to which the instance's primary VNICs will be attached +3. a source OCID to deploy the instance, usually an image ocid from [OCI Platform Images list] +4. a subnet OCID to which the instance's primary VNICs will be attached For detailed instructions, see [docs/prerequisites.adoc] @@ -33,3 +34,5 @@ Then apply the example using the following commands: [Terraform Variable Definition file]:https://www.terraform.io/docs/language/values/variables.html#variable-definitions-tfvars-files [docs/prerequisites.adoc]:https://github.com/oracle-terraform-modules/terraform-oci-compute-instance/blob/main/docs/prerequisites.adoc +[Provisioning Infrastructure with Terraform]:https://www.terraform.io/docs/cli/run/index.html +[OCI Platform Images list]:https://docs.oracle.com/en-us/iaas/images/ diff --git a/examples/instances_flex_shape/main.tf b/examples/instances_flex_shape/main.tf index 9317bf6..ff70bfb 100644 --- a/examples/instances_flex_shape/main.tf +++ b/examples/instances_flex_shape/main.tf @@ -1,10 +1,10 @@ // Copyright (c) 2018, 2021 Oracle and/or its affiliates. terraform { - required_version = ">= 0.12" // terraform version below 0.12 is not tested/supported with this module + required_version = ">= 0.13" // terraform version below 0.12 is not tested/supported with this module required_providers { oci = { - version = ">= 3.27" // force downloading oci-provider compatible with terraform v0.12 + version = ">= 4.0.0" // force downloading oci-provider compatible with terraform v0.12 } } } @@ -37,8 +37,8 @@ module "instance_flex" { # operating system parameters ssh_public_keys = var.ssh_public_keys # networking parameters - assign_public_ip = var.assign_public_ip - subnet_ocids = var.subnet_ocids + public_ip = var.public_ip # NONE, RESERVED or EPHEMERAL + subnet_ocids = var.subnet_ocids # storage parameters block_storage_sizes_in_gbs = var.block_storage_sizes_in_gbs } @@ -67,7 +67,7 @@ output "instance_flex" { # # operating system parameters # ssh_public_key = var.ssh_public_key # # networking parameters -# assign_public_ip = var.assign_public_ip +# public_ip = var.public_ip # NONE, RESERVED or EPHEMERAL # subnet_ocids = var.subnet_ocids # # storage parameters # block_storage_sizes_in_gbs = [] # no block volume will be created diff --git a/examples/instances_flex_shape/variables.tf b/examples/instances_flex_shape/variables.tf index eba6943..15cad80 100644 --- a/examples/instances_flex_shape/variables.tf +++ b/examples/instances_flex_shape/variables.tf @@ -119,10 +119,10 @@ variable "ssh_public_keys" { # networking parameters -variable "assign_public_ip" { - description = "Whether the VNIC should be assigned a public IP address." - type = bool - default = false +variable "public_ip" { + description = "Whether to create a Public IP to attach to primary vnic and which lifetime. Valid values are NONE, RESERVED or EPHEMERAL." + type = string + default = "NONE" } variable "subnet_ocids" { diff --git a/examples/instances_reserved_public_ip/README.md b/examples/instances_reserved_public_ip/README.md new file mode 100644 index 0000000..eedd888 --- /dev/null +++ b/examples/instances_reserved_public_ip/README.md @@ -0,0 +1,39 @@ +# Creating Compute Instances using Flex shape + +This example illustrates how to use this module to creates compute instances with a reserved public IP. + +One modules will be configured: + +- 1 instance (1 OCPU, 1GB RAM) with a reserved public IP associated with the Primary IP of the primary VNIC. + +## Prerequisites + +You will need to collect the following information before you start: + +1. your OCI provider authentication values +2. a compartment OCID in which the instances will be created +3. a source OCID to deploy the instance, usually an image ocid from [OCI Platform Images list] +4. a subnet OCID to which the instance's primary VNICs will be attached + +For detailed instructions, see [docs/prerequisites.adoc] + +## Using this example with Terraform cli + +Prepare one [Terraform Variable Definition file] named `terraform.tfvars` with the required authentication information. + +*TIP: You can rename and configure `terraform.tfvars.example` from this example's folder.* + +Then apply the example using the following commands: + +```shell +> terraform init +> terraform plan +> terraform apply +``` + +See [Provisioning Infrastructure with Terraform] for more details about Terraform CLI and the available subcommands. + +[Terraform Variable Definition file]:https://www.terraform.io/docs/language/values/variables.html#variable-definitions-tfvars-files +[docs/prerequisites.adoc]:https://github.com/oracle-terraform-modules/terraform-oci-compute-instance/blob/main/docs/prerequisites.adoc +[Provisioning Infrastructure with Terraform]:https://www.terraform.io/docs/cli/run/index.html +[OCI Platform Images list]:https://docs.oracle.com/en-us/iaas/images/ diff --git a/examples/instances_reserved_public_ip/main.tf b/examples/instances_reserved_public_ip/main.tf new file mode 100644 index 0000000..331a591 --- /dev/null +++ b/examples/instances_reserved_public_ip/main.tf @@ -0,0 +1,49 @@ +// Copyright (c) 2018, 2021 Oracle and/or its affiliates. + +terraform { + required_version = ">= 0.13" // terraform version below 0.12 is not tested/supported with this module + required_providers { + oci = { + version = ">= 4.0.0" // force downloading oci-provider compatible with terraform v0.12 + } + } +} + +provider "oci" { + tenancy_ocid = var.tenancy_ocid + user_ocid = var.user_ocid + fingerprint = var.fingerprint + private_key_path = var.private_key_path + region = var.region +} + +# # * This module will create 1 Flex Compute Instances, with a reserved public IP +module "instance_reserved_ip" { + source = "oracle-terraform-modules/compute-instance/oci" + # general oci parameters + compartment_ocid = var.compartment_ocid + freeform_tags = var.freeform_tags + defined_tags = var.defined_tags + # compute instance parameters + ad_number = null + instance_count = 1 + instance_display_name = "instance_reserved_ip" + shape = var.shape + source_ocid = var.source_ocid + source_type = var.source_type + instance_flex_memory_in_gbs = 1 # only used if shape is Flex type + instance_flex_ocpus = 1 # only used if shape is Flex type + # operating system parameters + ssh_authorized_keys = var.ssh_authorized_keys + # networking parameters + public_ip = var.public_ip # NONE, RESERVED or EPHEMERAL + subnet_ocids = var.subnet_ocids + # storage parameters + block_storage_sizes_in_gbs = [] # no block volume will be created + preserve_boot_volume = false +} + +output "instance_reserved_ip" { + description = "IP information of the instances provisioned by this module." + value = module.instance_reserved_ip.instances_summary +} diff --git a/examples/instances_reserved_public_ip/terraform.tfvars.example b/examples/instances_reserved_public_ip/terraform.tfvars.example new file mode 100644 index 0000000..3093452 --- /dev/null +++ b/examples/instances_reserved_public_ip/terraform.tfvars.example @@ -0,0 +1,34 @@ +# Copyright (c) 2019, 2020 Oracle Corporation and/or affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +/*---------------------------------------------------------------------------- +HOW TO USE THIS FILE + +1. keep this file in the same folder as your terraform *.tf files +2. If your terraform config is managed with Git, add the tfvars file to your .gitignore. +3. Keep your RSA private key outside of your terraform work folder! +----------------------------------------------------------------------------*/ + +# provider identity parameters + +tenancy_ocid = "" +user_ocid = "" +fingerprint = "" +region = "" +private_key_path = "" + +# general oci parameters + +compartment_ocid = "" + +# compute instance parameters + +source_ocid = "" + +# operating system parameters + +ssh_authorized_keys = "" + +# networking parameters + +subnet_ocids = [""] diff --git a/examples/instances_reserved_public_ip/variables.tf b/examples/instances_reserved_public_ip/variables.tf new file mode 100644 index 0000000..eba0514 --- /dev/null +++ b/examples/instances_reserved_public_ip/variables.tf @@ -0,0 +1,131 @@ +# Copyright (c) 2019, 2021, Oracle Corporation and/or affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl + +# provider identity parameters +variable "fingerprint" { + description = "fingerprint of oci api private key" + type = string + # no default value, asking user to explicitly set this variable's value. see codingconventions.adoc +} + +variable "private_key_path" { + description = "path to oci api private key used" + type = string + # no default value, asking user to explicitly set this variable's value. see codingconventions.adoc +} + +variable "region" { + description = "the oci region where resources will be created" + type = string + # no default value, asking user to explicitly set this variable's value. see codingconventions.adoc + # List of regions: https://docs.cloud.oracle.com/iaas/Content/General/Concepts/regions.htm#ServiceAvailabilityAcrossRegions +} + +variable "tenancy_ocid" { + description = "tenancy ocid where to create the sources" + type = string + # no default value, asking user to explicitly set this variable's value. see codingconventions.adoc +} + +variable "user_ocid" { + description = "ocid of user that terraform will use to create the resources" + type = string + # no default value, asking user to explicitly set this variable's value. see codingconventions.adoc +} + +# general oci parameters + +variable "compartment_ocid" { + description = "compartment ocid where to create all resources" + type = string + # no default value, asking user to explicitly set this variable's value. see codingconventions.adoc +} + +variable "freeform_tags" { + description = "simple key-value pairs to tag the resources created using freeform tags." + type = map(string) + default = null +} + +variable "defined_tags" { + description = "predefined and scoped to a namespace to tag the resources created using defined tags." + type = map(string) + default = null +} + +# compute instance parameters + +variable "instance_ad_number" { + description = "The availability domain number of the instance. If none is provided, it will start with AD-1 and continue in round-robin." + type = number + default = 1 +} + +variable "instance_count" { + description = "Number of identical instances to launch from a single module." + type = number + default = 1 +} + +variable "instance_display_name" { + description = "(Updatable) A user-friendly name for the instance. Does not have to be unique, and it's changeable." + type = string + default = "module_instance_flex" +} + +variable "instance_flex_memory_in_gbs" { + type = number + description = "(Updatable) The total amount of memory available to the instance, in gigabytes." + default = null +} + +variable "instance_flex_ocpus" { + type = number + description = "(Updatable) The total number of OCPUs available to the instance." + default = null +} + +variable "shape" { + description = "The shape of an instance." + type = string + default = "VM.Standard.E3.Flex" +} + +variable "source_ocid" { + description = "The OCID of an image or a boot volume to use, depending on the value of source_type." + type = string +} + +variable "source_type" { + description = "The source type for the instance." + type = string + default = "image" +} + +# operating system parameters + +variable "ssh_authorized_keys" { + description = "Public SSH keys path to be included in the ~/.ssh/authorized_keys file for the default user on the instance." + type = string +} + +# networking parameters + +variable "public_ip" { + description = "Whether to create a Public IP to attach to primary vnic and which lifetime. Valid values are NONE, RESERVED or EPHEMERAL." + type = string + default = "NONE" +} + +variable "subnet_ocids" { + description = "The unique identifiers (OCIDs) of the subnets in which the instance primary VNICs are created." + type = list(string) +} + +# storage parameters + +variable "block_storage_sizes_in_gbs" { + description = "Sizes of volumes to create and attach to each instance." + type = list(string) + default = [50] +} diff --git a/main.tf b/main.tf index ed50fdb..2f5009b 100644 --- a/main.tf +++ b/main.tf @@ -24,7 +24,7 @@ locals { #################### # Subnet Datasource #################### -data "oci_core_subnet" "this" { +data "oci_core_subnet" "instance_subnet" { count = length(var.subnet_ocids) subnet_id = element(var.subnet_ocids, count.index) } @@ -56,7 +56,7 @@ locals { ############ # Instance ############ -resource "oci_core_instance" "this" { +resource "oci_core_instance" "instance" { count = var.instance_count // If no explicit AD number, spread instances on all ADs in round-robin. Looping to the first when last AD is reached availability_domain = var.ad_number == null ? element(local.ADs, count.index) : element(local.ADs, var.ad_number - 1) @@ -74,7 +74,7 @@ resource "oci_core_instance" "this" { } create_vnic_details { - assign_public_ip = var.assign_public_ip + assign_public_ip = var.public_ip == "NONE" ? var.assign_public_ip : false display_name = var.vnic_name == "" ? "" : var.instance_count != "1" ? "${var.vnic_name}_${count.index + 1}" : var.vnic_name hostname_label = var.hostname_label == "" ? "" : var.instance_count != "1" ? "${var.hostname_label}-${count.index + 1}" : var.hostname_label private_ip = element( @@ -83,7 +83,7 @@ resource "oci_core_instance" "this" { ) skip_source_dest_check = var.skip_source_dest_check // Current implementation requires providing a list of subnets when using ad-specific subnets - subnet_id = data.oci_core_subnet.this[count.index % length(data.oci_core_subnet.this.*.id)].id + subnet_id = data.oci_core_subnet.instance_subnet[count.index % length(data.oci_core_subnet.instance_subnet.*.id)].id freeform_tags = local.merged_freeform_tags defined_tags = var.defined_tags @@ -111,19 +111,19 @@ resource "oci_core_instance" "this" { ################################## # Instance Credentials Datasource ################################## -data "oci_core_instance_credentials" "this" { +data "oci_core_instance_credentials" "credential" { count = var.resource_platform != "linux" ? var.instance_count : 0 - instance_id = oci_core_instance.this[count.index].id + instance_id = oci_core_instance.instance[count.index].id } ######### # Volume ######### -resource "oci_core_volume" "this" { +resource "oci_core_volume" "volume" { count = var.instance_count * length(var.block_storage_sizes_in_gbs) - availability_domain = oci_core_instance.this[count.index % var.instance_count].availability_domain + availability_domain = oci_core_instance.instance[count.index % var.instance_count].availability_domain compartment_id = var.compartment_ocid - display_name = "${oci_core_instance.this[count.index % var.instance_count].display_name}_volume${floor(count.index / var.instance_count)}" + display_name = "${oci_core_instance.instance[count.index % var.instance_count].display_name}_volume${floor(count.index / var.instance_count)}" size_in_gbs = element( var.block_storage_sizes_in_gbs, floor(count.index / var.instance_count), @@ -135,11 +135,46 @@ resource "oci_core_volume" "this" { #################### # Volume Attachment #################### -resource "oci_core_volume_attachment" "this" { +resource "oci_core_volume_attachment" "volume_attachment" { count = var.instance_count * length(var.block_storage_sizes_in_gbs) attachment_type = var.attachment_type - instance_id = oci_core_instance.this[count.index % var.instance_count].id - volume_id = oci_core_volume.this[count.index].id + instance_id = oci_core_instance.instance[count.index % var.instance_count].id + volume_id = oci_core_volume.volume[count.index].id use_chap = var.use_chap } +#################### +# Networking +#################### + +data "oci_core_vnic_attachments" "vnic_attachment" { + count = var.instance_count + compartment_id = var.compartment_ocid + instance_id = oci_core_instance.instance[count.index].id + + depends_on = [ + oci_core_instance.instance + ] +} + +data "oci_core_private_ips" "private_ips" { + count = var.instance_count + vnic_id = data.oci_core_vnic_attachments.vnic_attachment[count.index].vnic_attachments[0].vnic_id + + depends_on = [ + oci_core_instance.instance + ] +} + +resource "oci_core_public_ip" "public_ip" { + count = var.public_ip == "NONE" ? 0 : var.instance_count + compartment_id = var.compartment_ocid + lifetime = var.public_ip + + display_name = var.public_ip_display_name != null ? var.public_ip_display_name : oci_core_instance.instance[count.index].display_name + private_ip_id = data.oci_core_private_ips.private_ips[count.index].private_ips[0].id + # public_ip_pool_id = oci_core_public_ip_pool.test_public_ip_pool.id # * (BYOIP CIDR Blocks) are not supported yet by this module. + + freeform_tags = local.merged_freeform_tags + defined_tags = var.defined_tags +} diff --git a/outputs.tf b/outputs.tf index 8568744..ba46a49 100644 --- a/outputs.tf +++ b/outputs.tf @@ -3,7 +3,7 @@ locals { instances_details = [ // display name, Primary VNIC Public/Private IP for each instance - for i in oci_core_instance.this : < v } +} + +output "public_ip_all_attributes" { + description = "all attributes of created public ip" + value = { for k, v in oci_core_public_ip.public_ip : k => v } +} + +output "private_ips_all_attributes" { + description = "all attributes of created private ips" + value = { for k, v in data.oci_core_private_ips.private_ips : k => v } +} + +output "vnic_attachment_all_attributes" { + description = "all attributes of created vnic attachments" + value = { for k, v in data.oci_core_vnic_attachments.vnic_attachment : k => v } +} + +output "volume_all_attributes" { + description = "all attributes of created volumes" + value = { for k, v in oci_core_volume.volume : k => v } +} + +output "volume_attachment_all_attributes" { + description = "all attributes of created volumes attachments" + value = { for k, v in oci_core_volume_attachment.volume_attachment : k => v } } diff --git a/variables.tf b/variables.tf index f0abd49..5411b26 100644 --- a/variables.tf +++ b/variables.tf @@ -126,7 +126,8 @@ variable "user_data" { # networking parameters variable "assign_public_ip" { - description = "Whether the VNIC should be assigned a public IP address." + #! Deprecation notice: will be removed at next major release. Use `var.public_ip` instead. + description = "Deprecated: use `var.public_ip` instead. Whether the VNIC should be assigned a public IP address (Always EPHEMERAL)." type = bool default = false } @@ -149,6 +150,23 @@ variable "private_ips" { default = [] } +variable "public_ip" { + description = "Whether to create a Public IP to attach to primary vnic and which lifetime. Valid values are NONE, RESERVED or EPHEMERAL." + type = string + default = "NONE" + + validation { + condition = contains(["NONE", "RESERVED", "EPHEMERAL"], var.public_ip) + error_message = "Accepted values are NONE, RESERVED or EPHEMERAL." + } +} + +variable "public_ip_display_name" { + description = "(Updatable) A user-friendly name. Does not have to be unique, and it's changeable." + type = string + default = null +} + variable "skip_source_dest_check" { description = "Whether the source/destination check is disabled on the VNIC." type = bool