From 8e104609397a7ed861b20ccbbf0c4b486ff90c75 Mon Sep 17 00:00:00 2001 From: Clouddude Date: Sun, 24 Nov 2024 02:41:40 -0500 Subject: [PATCH] Initial load --- .../oke-quickstartz/VERSION | 1 + .../oke-quickstartz/cluster-tools.tf | 141 +++ .../oke-quickstartz/datasources.tf | 28 + .../oke-quickstartz/defaults.tf | 111 +++ .../oke-quickstartz/env-vars | 0 .../oke-quickstartz/main.tf | 705 +++++++++++++ .../modules/cluster-tools/cert-manager.tf | 21 + .../modules/cluster-tools/cluster-tools.tf | 39 + .../modules/cluster-tools/grafana.tf | 234 +++++ .../modules/cluster-tools/ingress-nginx.tf | 146 +++ .../modules/cluster-tools/jaeger.tf | 0 .../modules/cluster-tools/keycloak.tf | 0 .../modules/cluster-tools/metrics-server.tf | 28 + .../modules/cert-manager/issuers/Chart.yaml | 7 + .../cert-manager/issuers/templates/NOTES.txt | 3 + .../issuers/templates/_helpers.tpl | 3 + .../issuers/templates/clusterissuers.yaml | 46 + .../modules/cert-manager/issuers/values.yaml | 4 + .../modules/cert-manager/main.tf | 102 ++ .../modules/cert-manager/providers.tf | 24 + .../modules/cert-manager/test.yaml | 29 + .../modules/cert-manager/variables.tf | 18 + .../cluster-tools/modules/verrazzano/main.tf | 17 + .../modules/verrazzano/providers.tf | 24 + .../modules/verrazzano/variables.tf | 18 + .../modules/cluster-tools/postgresql.tf | 0 .../modules/cluster-tools/prometheus.tf | 39 + .../modules/cluster-tools/providers.tf | 34 + .../modules/cluster-tools/redis.tf | 0 .../modules/oci-networking/README.md | 3 + .../oci-networking/gateway/datasources.tf | 12 + .../modules/oci-networking/gateway/main.tf | 61 ++ .../modules/oci-networking/gateway/outputs.tf | 20 + .../oci-networking/gateway/providers.tf | 19 + .../oci-networking/gateway/variables.tf | 78 ++ .../oci-networking/route_table/main.tf | 23 + .../oci-networking/route_table/outputs.tf | 8 + .../oci-networking/route_table/providers.tf | 19 + .../oci-networking/route_table/variables.tf | 28 + .../oci-networking/security_list/main.tf | 111 +++ .../oci-networking/security_list/outputs.tf | 12 + .../oci-networking/security_list/providers.tf | 20 + .../oci-networking/security_list/variables.tf | 142 +++ .../modules/oci-networking/subnet/main.tf | 21 + .../modules/oci-networking/subnet/outputs.tf | 12 + .../oci-networking/subnet/providers.tf | 19 + .../oci-networking/subnet/variables.tf | 52 + .../modules/oci-networking/vcn/datasources.tf | 7 + .../modules/oci-networking/vcn/main.tf | 16 + .../modules/oci-networking/vcn/outputs.tf | 40 + .../modules/oci-networking/vcn/providers.tf | 19 + .../modules/oci-networking/vcn/variables.tf | 38 + .../modules/oci-policies/main.tf | 35 + .../modules/oci-policies/outputs.tf | 13 + .../modules/oci-policies/variables.tf | 73 ++ .../modules/oci-policies/versions.tf | 20 + .../modules/oci-vault-kms/main.tf | 47 + .../modules/oci-vault-kms/outputs.tf | 7 + .../modules/oci-vault-kms/policies.tf | 75 ++ .../modules/oci-vault-kms/providers.tf | 20 + .../modules/oci-vault-kms/variables.tf | 58 ++ .../oke-cluster-autoscaler/datasources.tf | 8 + .../modules/oke-cluster-autoscaler/main.tf | 280 ++++++ .../oke-cluster-autoscaler/variables.tf | 64 ++ .../oke-cluster-autoscaler/versions.tf | 24 + .../modules/oke-node-pool/datasources.tf | 55 ++ .../modules/oke-node-pool/main.tf | 102 ++ .../modules/oke-node-pool/outputs.tf | 22 + .../modules/oke-node-pool/variables.tf | 145 +++ .../modules/oke-node-pool/versions.tf | 19 + .../oke-quickstartz/modules/oke/LICENSE | 27 + .../oke-quickstartz/modules/oke/README.md | 53 + .../modules/oke/datasources.tf | 20 + .../oke-quickstartz/modules/oke/main.tf | 73 ++ .../modules/oke/oke-orm-private-endpoint.tf | 28 + .../oke-quickstartz/modules/oke/outputs.tf | 41 + .../oke-quickstartz/modules/oke/variables.tf | 139 +++ .../oke-quickstartz/modules/oke/versions.tf | 19 + .../oke-quickstartz/oci-networking.tf | 157 +++ .../oke-quickstartz/outputs.tf | 56 ++ .../oke-quickstartz/policies.tf | 62 ++ .../oke-quickstartz/providers.tf | 69 ++ .../oke-quickstartz/schema.yaml | 927 ++++++++++++++++++ .../oke-quickstartz/terraform.tfvars | 12 + .../oke-quickstartz/variables.tf | 354 +++++++ .../oke-quickstartz/versions.tf | 40 + 86 files changed, 5746 insertions(+) create mode 100644 terraform-provider-oci/oke-quickstartz/VERSION create mode 100644 terraform-provider-oci/oke-quickstartz/cluster-tools.tf create mode 100644 terraform-provider-oci/oke-quickstartz/datasources.tf create mode 100644 terraform-provider-oci/oke-quickstartz/defaults.tf create mode 100644 terraform-provider-oci/oke-quickstartz/env-vars create mode 100644 terraform-provider-oci/oke-quickstartz/main.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/cert-manager.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/cluster-tools.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/grafana.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/ingress-nginx.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/jaeger.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/keycloak.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/metrics-server.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/modules/cert-manager/issuers/Chart.yaml create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/modules/cert-manager/issuers/templates/NOTES.txt create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/modules/cert-manager/issuers/templates/_helpers.tpl create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/modules/cert-manager/issuers/templates/clusterissuers.yaml create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/modules/cert-manager/issuers/values.yaml create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/modules/cert-manager/main.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/modules/cert-manager/providers.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/modules/cert-manager/test.yaml create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/modules/cert-manager/variables.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/modules/verrazzano/main.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/modules/verrazzano/providers.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/modules/verrazzano/variables.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/postgresql.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/prometheus.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/providers.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/cluster-tools/redis.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/README.md create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/gateway/datasources.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/gateway/main.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/gateway/outputs.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/gateway/providers.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/gateway/variables.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/route_table/main.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/route_table/outputs.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/route_table/providers.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/route_table/variables.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/security_list/main.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/security_list/outputs.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/security_list/providers.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/security_list/variables.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/subnet/main.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/subnet/outputs.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/subnet/providers.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/subnet/variables.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/vcn/datasources.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/vcn/main.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/vcn/outputs.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/vcn/providers.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-networking/vcn/variables.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-policies/main.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-policies/outputs.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-policies/variables.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-policies/versions.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-vault-kms/main.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-vault-kms/outputs.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-vault-kms/policies.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-vault-kms/providers.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oci-vault-kms/variables.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oke-cluster-autoscaler/datasources.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oke-cluster-autoscaler/main.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oke-cluster-autoscaler/variables.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oke-cluster-autoscaler/versions.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oke-node-pool/datasources.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oke-node-pool/main.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oke-node-pool/outputs.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oke-node-pool/variables.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oke-node-pool/versions.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oke/LICENSE create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oke/README.md create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oke/datasources.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oke/main.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oke/oke-orm-private-endpoint.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oke/outputs.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oke/variables.tf create mode 100644 terraform-provider-oci/oke-quickstartz/modules/oke/versions.tf create mode 100644 terraform-provider-oci/oke-quickstartz/oci-networking.tf create mode 100644 terraform-provider-oci/oke-quickstartz/outputs.tf create mode 100644 terraform-provider-oci/oke-quickstartz/policies.tf create mode 100644 terraform-provider-oci/oke-quickstartz/providers.tf create mode 100644 terraform-provider-oci/oke-quickstartz/schema.yaml create mode 100644 terraform-provider-oci/oke-quickstartz/terraform.tfvars create mode 100644 terraform-provider-oci/oke-quickstartz/variables.tf create mode 100644 terraform-provider-oci/oke-quickstartz/versions.tf diff --git a/terraform-provider-oci/oke-quickstartz/VERSION b/terraform-provider-oci/oke-quickstartz/VERSION new file mode 100644 index 0000000..f76f913 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/VERSION @@ -0,0 +1 @@ +0.9.2 \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/cluster-tools.tf b/terraform-provider-oci/oke-quickstartz/cluster-tools.tf new file mode 100644 index 0000000..793e13b --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/cluster-tools.tf @@ -0,0 +1,141 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +################################################################################ +# Module: Kubernetes Cluster Tools +################################################################################ +module "cluster-tools" { + source = "./modules/cluster-tools" + + # Oracle Cloud Infrastructure Tenancy and Compartment OCID + tenancy_ocid = var.tenancy_ocid + # compartment_ocid = var.compartment_ocid + region = var.region + + # Deployment Tags + Freeform Tags + Defined Tags + oci_tag_values = local.oci_tag_values + + # Cluster Tools + ## Namespace + cluster_tools_namespace = "cluster-tools" + + ## Ingress Controller + ingress_nginx_enabled = var.ingress_nginx_enabled + ingress_load_balancer_shape = var.ingress_load_balancer_shape + ingress_load_balancer_shape_flex_min = var.ingress_load_balancer_shape_flex_min + ingress_load_balancer_shape_flex_max = var.ingress_load_balancer_shape_flex_max + + ## Ingress + ingress_hosts = var.ingress_hosts + ingress_tls = var.ingress_tls + ingress_cluster_issuer = var.ingress_cluster_issuer + ingress_email_issuer = var.ingress_email_issuer + ingress_hosts_include_nip_io = var.ingress_hosts_include_nip_io + nip_io_domain = var.nip_io_domain + + ## Cert Manager + cert_manager_enabled = var.cert_manager_enabled + + ## Metrics Server + metrics_server_enabled = var.metrics_server_enabled + + ## Prometheus + prometheus_enabled = var.prometheus_enabled + + ## Grafana + grafana_enabled = var.grafana_enabled + + depends_on = [module.oke, module.oke_node_pools, module.oke_cluster_autoscaler] +} + +# Kubernetes Cluster Tools +## IngressController/LoadBalancer +variable "ingress_nginx_enabled" { + default = false + description = "Enable Ingress Nginx for Kubernetes Services (This option provision a Load Balancer)" +} +variable "ingress_load_balancer_shape" { + default = "flexible" # Flexible, 10Mbps, 100Mbps, 400Mbps or 8000Mps + description = "Shape that will be included on the Ingress annotation for the OCI Load Balancer creation" +} +variable "ingress_load_balancer_shape_flex_min" { + default = "10" + description = "Enter the minimum size of the flexible shape." +} +variable "ingress_load_balancer_shape_flex_max" { + default = "100" # From 10 to 8000. Cannot be lower than ingress_load_balancer_shape_flex_min + description = "Enter the maximum size of the flexible shape (Should be bigger than minimum size). The maximum service limit is set by your tenancy limits." +} +## Ingresses +variable "ingress_hosts" { + default = "" + description = "Enter a valid full qualified domain name (FQDN). You will need to map the domain name to the EXTERNAL-IP address on your DNS provider (DNS Registry type - A). If you have multiple domain names, include separated by comma. e.g.: mushop.example.com,catshop.com" +} +variable "ingress_hosts_include_nip_io" { + default = true + description = "Include app_name.HEXXX.nip.io on the ingress hosts. e.g.: mushop.HEXXX.nip.io" +} +variable "nip_io_domain" { + default = "nip.io" + description = "Dynamic wildcard DNS for the application hostname. Should support hex notation. e.g.: nip.io" +} +variable "ingress_tls" { + default = false + description = "If enabled, will generate SSL certificates to enable HTTPS for the ingress using the Certificate Issuer" +} +variable "ingress_cluster_issuer" { + default = "letsencrypt-prod" + description = "Certificate issuer type. Currently supports the free Let's Encrypt and Self-Signed. Only *letsencrypt-prod* generates valid certificates" +} +variable "ingress_email_issuer" { + default = "no-reply@example.cloud" + description = "You must replace this email address with your own. The certificate provider will use this to contact you about expiring certificates, and issues related to your account." +} + +## Cert Manager +variable "cert_manager_enabled" { + default = false + description = "Enable x509 Certificate Management" +} + +## Metrics Server +variable "metrics_server_enabled" { + default = true + description = "Enable Metrics Server for Metrics, HPA, VPA and Cluster Autoscaler" +} + +## Prometheus +variable "prometheus_enabled" { + default = false + description = "Enable Prometheus" +} + +## Grafana +variable "grafana_enabled" { + default = false + description = "Enable Grafana Dashboards. Includes example dashboards and Prometheus, OCI Logging and OCI Metrics datasources" +} + +# Cluster Tools Outputs +## grafana +output "grafana_admin_password" { + value = module.cluster-tools.grafana_admin_password + sensitive = true +} + +## Ingress Controller +locals { + app_domain = module.cluster-tools.ingress_controller_load_balancer_hostname + url_protocol = module.cluster-tools.url_protocol +} + +output "grafana_url" { + value = (var.grafana_enabled && var.ingress_nginx_enabled) ? format("${local.url_protocol}://%s/grafana", local.app_domain) : null + description = "Grafana Dashboards URL" +} + +output "app_url" { + value = (var.ingress_nginx_enabled) ? format("${local.url_protocol}://%s", local.app_domain) : null + description = "Application URL" +} diff --git a/terraform-provider-oci/oke-quickstartz/datasources.tf b/terraform-provider-oci/oke-quickstartz/datasources.tf new file mode 100644 index 0000000..54f03ff --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/datasources.tf @@ -0,0 +1,28 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +# # Gets home and current regions +# data "oci_identity_tenancy" "tenant_details" { +# tenancy_id = var.tenancy_ocid + +# provider = oci.current_region +# } + +# data "oci_identity_regions" "home_region" { +# filter { +# name = "key" +# values = [data.oci_identity_tenancy.tenant_details.home_region_key] +# } + +# provider = oci.current_region +# } + +# Available OCI Services +data "oci_core_services" "all_services_network" { + filter { + name = "name" + values = ["All .* Services In Oracle Services Network"] + regex = true + } +} diff --git a/terraform-provider-oci/oke-quickstartz/defaults.tf b/terraform-provider-oci/oke-quickstartz/defaults.tf new file mode 100644 index 0000000..a9e0dbd --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/defaults.tf @@ -0,0 +1,111 @@ +# Copyright (c) 2022-2023 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +# File Version: 0.1.0 + +# Dependencies: +# - terraform-oci-networking module + +################################################################################ +# If you have extra configurations to add, you can add them here. +# It's supported to include: +# - Extra Node Pools and their configurations +# - Extra subnets +# - Extra route tables and security lists +################################################################################ + +################################################################################ +# Deployment Defaults +################################################################################ +locals { + deploy_id = random_string.deploy_id.result + deploy_tags = { "DeploymentID" = local.deploy_id, "AppName" = local.app_name, "Quickstart" = "terraform-oci-oke-quickstart", "OKEclusterName" = "${local.app_name} (${local.deploy_id})" } + oci_tag_values = { + "freeformTags" = merge(var.tag_values.freeformTags, local.deploy_tags), + "definedTags" = var.tag_values.definedTags + } + app_name = var.app_name + app_name_normalized = substr(replace(lower(local.app_name), " ", "-"), 0, 6) + app_name_for_dns = substr(lower(replace(local.app_name, "/\\W|_|\\s/", "")), 0, 6) +} + +resource "random_string" "deploy_id" { + length = 4 + special = false +} + +################################################################################ +# Required locals for the oci-networking and oke modules +################################################################################ +locals { + node_pools = concat(local.node_pool_1, local.extra_node_pools, var.extra_node_pools) + create_new_vcn = (var.create_new_oke_cluster && var.create_new_vcn) ? true : false + vcn_display_name = "[${local.app_name}] VCN for OKE (${local.deploy_id})" + create_subnets = (var.create_subnets) ? true : false + subnets = concat(local.subnets_oke, local.extra_subnets, var.extra_subnets) + route_tables = concat(local.route_tables_oke, var.extra_route_tables) + security_lists = concat(local.security_lists_oke, var.extra_security_lists) + resolved_vcn_compartment_ocid = (var.create_new_compartment_for_oke ? local.oke_compartment_ocid : var.compartment_ocid) + pre_vcn_cidr_blocks = split(",", var.vcn_cidr_blocks) + vcn_cidr_blocks = contains(module.vcn.cidr_blocks, local.pre_vcn_cidr_blocks[0]) ? distinct(concat([local.pre_vcn_cidr_blocks[0]], module.vcn.cidr_blocks)) : module.vcn.cidr_blocks + network_cidrs = { + VCN-MAIN-CIDR = local.vcn_cidr_blocks[0] # e.g.: "10.20.0.0/16" = 65536 usable IPs + ENDPOINT-REGIONAL-SUBNET-CIDR = cidrsubnet(local.vcn_cidr_blocks[0], 12, 0) # e.g.: "10.20.0.0/28" = 15 usable IPs + NODES-REGIONAL-SUBNET-CIDR = cidrsubnet(local.vcn_cidr_blocks[0], 6, 3) # e.g.: "10.20.12.0/22" = 1021 usable IPs (10.20.12.0 - 10.20.15.255) + LB-REGIONAL-SUBNET-CIDR = cidrsubnet(local.vcn_cidr_blocks[0], 6, 4) # e.g.: "10.20.16.0/22" = 1021 usable IPs (10.20.16.0 - 10.20.19.255) + FSS-MOUNT-TARGETS-REGIONAL-SUBNET-CIDR = cidrsubnet(local.vcn_cidr_blocks[0], 10, 81) # e.g.: "10.20.20.64/26" = 62 usable IPs (10.20.20.64 - 10.20.20.255) + APIGW-FN-REGIONAL-SUBNET-CIDR = cidrsubnet(local.vcn_cidr_blocks[0], 8, 30) # e.g.: "10.20.30.0/24" = 254 usable IPs (10.20.30.0 - 10.20.30.255) + VCN-NATIVE-POD-NETWORKING-REGIONAL-SUBNET-CIDR = cidrsubnet(local.vcn_cidr_blocks[0], 1, 1) # e.g.: "10.20.128.0/17" = 32766 usable IPs (10.20.128.0 - 10.20.255.255) + BASTION-REGIONAL-SUBNET-CIDR = cidrsubnet(local.vcn_cidr_blocks[0], 12, 32) # e.g.: "10.20.2.0/28" = 15 usable IPs (10.20.2.0 - 10.20.2.15) + PODS-CIDR = "10.244.0.0/16" + KUBERNETES-SERVICE-CIDR = "10.96.0.0/16" + ALL-CIDR = "0.0.0.0/0" + } +} + +################################################################################ +# Extra OKE node pools +# Example commented out below +################################################################################ +locals { + extra_node_pools = [ + # { + # node_pool_name = "GPU" # Must be unique + # node_pool_autoscaler_enabled = false + # node_pool_min_nodes = 1 + # node_pool_max_nodes = 2 + # node_k8s_version = var.k8s_version + # node_pool_shape = "BM.GPU.A10.4" + # node_pool_shape_specific_ad = 3 # Optional, if not provided or set = 0, will be randomly assigned + # node_pool_node_shape_config_ocpus = 1 + # node_pool_node_shape_config_memory_in_gbs = 1 + # node_pool_boot_volume_size_in_gbs = "100" + # existent_oke_nodepool_id_for_autoscaler = null + # node_pool_alternative_subnet = null # Optional, name of previously created subnet + # image_operating_system = null + # image_operating_system_version = null + # extra_initial_node_labels = [{ key = "app.pixel/gpu", value = "true" }] + # cni_type = "FLANNEL_OVERLAY" # "FLANNEL_OVERLAY" or "OCI_VCN_IP_NATIVE" + # }, + ] +} + +locals { + extra_subnets = [ + # { + # subnet_name = "opensearch_subnet" + # cidr_block = cidrsubnet(local.vcn_cidr_blocks[0], 8, 35) # e.g.: "10.20.35.0/24" = 254 usable IPs (10.20.35.0 - 10.20.35.255) + # display_name = "OCI OpenSearch Service subnet (${local.deploy_id})" # If null, is autogenerated + # dns_label = "opensearch${local.deploy_id}" # If null, disable dns label + # prohibit_public_ip_on_vnic = false + # prohibit_internet_ingress = false + # route_table_id = module.route_tables["public"].route_table_id # If null, the VCN's default route table is used + # alternative_route_table_name = null # Optional, Name of the previously created route table + # dhcp_options_id = module.vcn.default_dhcp_options_id # If null, the VCN's default set of DHCP options is used + # security_list_ids = [module.security_lists["opensearch_security_list"].security_list_id] # If null, the VCN's default security list is used + # extra_security_list_names = [] # Optional, Names of the previously created security lists + # ipv6cidr_block = null # If null, no IPv6 CIDR block is assigned + # }, + ] +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/env-vars b/terraform-provider-oci/oke-quickstartz/env-vars new file mode 100644 index 0000000..e69de29 diff --git a/terraform-provider-oci/oke-quickstartz/main.tf b/terraform-provider-oci/oke-quickstartz/main.tf new file mode 100644 index 0000000..52fb5da --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/main.tf @@ -0,0 +1,705 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +# File Version: 0.8.0 + +################################################################################ +# +# *** Note: Normally, you should not need to edit this file. *** +# +################################################################################ + +################################################################################ +# Module: OCI Vault (KMS) - Key Management Service to use with OKE +################################################################################ +module "vault" { + source = "./modules/oci-vault-kms" + + providers = { + oci = oci + oci.home_region = oci.home_region + } + + # Oracle Cloud Infrastructure Tenancy and Compartment OCID + tenancy_ocid = var.tenancy_ocid + + # Deployment Tags + Freeform Tags + Defined Tags + oci_tag_values = local.oci_tag_values + + # Encryption (OCI Vault/Key Management/KMS) + use_encryption_from_oci_vault = var.use_encryption_from_oci_vault + create_new_encryption_key = var.create_new_encryption_key + existent_encryption_key_id = var.existent_encryption_key_id + + # OKE Cluster Details + oke_cluster_compartment_ocid = local.oke_compartment_ocid + + ## Create Dynamic group and Policies for OCI Vault (Key Management/KMS) + create_dynamic_group_for_nodes_in_compartment = var.create_dynamic_group_for_nodes_in_compartment + create_compartment_policies = var.create_compartment_policies + create_vault_policies_for_group = var.create_vault_policies_for_group +} + +################################################################################ +# Module: Oracle Container Engine for Kubernetes (OKE) Cluster +################################################################################ +module "oke" { + source = "./modules/oke" + + # providers = { + # oci = oci + # oci.home_region = oci.home_region + # } + + # Oracle Cloud Infrastructure Tenancy and Compartment OCID + tenancy_ocid = var.tenancy_ocid + compartment_ocid = local.oke_compartment_ocid + region = var.region + cluster_type = var.cluster_type + # Deployment Tags + Freeform Tags + Defined Tags + cluster_tags = local.oci_tag_values + load_balancers_tags = local.oci_tag_values + block_volumes_tags = local.oci_tag_values + + # OKE Cluster + ## create_new_oke_cluster + create_new_oke_cluster = var.create_new_oke_cluster + existent_oke_cluster_id = var.existent_oke_cluster_id + + ## Network Details + vcn_id = module.vcn.vcn_id + network_cidrs = local.network_cidrs + k8s_endpoint_subnet_id = local.create_subnets ? module.subnets["oke_k8s_endpoint_subnet"].subnet_id : var.existent_oke_k8s_endpoint_subnet_ocid + lb_subnet_id = local.create_subnets ? module.subnets["oke_lb_subnet"].subnet_id : var.existent_oke_load_balancer_subnet_ocid + cni_type = local.cni_type + ### Cluster Workers visibility + cluster_workers_visibility = var.cluster_workers_visibility + ### Cluster API Endpoint visibility + cluster_endpoint_visibility = var.cluster_endpoint_visibility + + ## Control Plane Kubernetes Version + k8s_version = var.k8s_version + + ## Create Dynamic group and Policies for Autoscaler and OCI Metrics and Logging + # create_dynamic_group_for_nodes_in_compartment = var.create_dynamic_group_for_nodes_in_compartment + # create_compartment_policies = var.create_compartment_policies + + ## Encryption (OCI Vault/Key Management/KMS) + oci_vault_key_id_oke_secrets = module.vault.oci_vault_key_id + oci_vault_key_id_oke_image_policy = module.vault.oci_vault_key_id +} + +################################################################################ +# Module: OKE Node Pool +################################################################################ +module "oke_node_pools" { + for_each = { for map in local.node_pools : map.node_pool_name => map } + source = "./modules/oke-node-pool" + + # Deployment Tags + Freeform Tags + node_pools_tags = local.oci_tag_values + worker_nodes_tags = local.oci_tag_values + + # Oracle Cloud Infrastructure Tenancy and Compartment OCID + tenancy_ocid = var.tenancy_ocid + + # OKE Cluster Details + oke_cluster_ocid = module.oke.oke_cluster_ocid + oke_cluster_compartment_ocid = local.oke_compartment_ocid + create_new_node_pool = var.create_new_oke_cluster + + # OKE Worker Nodes (Compute) + node_pool_name = try(each.value.node_pool_name, "no_pool_name") + node_pool_min_nodes = try(each.value.node_pool_min_nodes, 1) + node_pool_max_nodes = try(each.value.node_pool_max_nodes, 3) + node_k8s_version = try(each.value.node_k8s_version, var.k8s_version) + node_pool_shape = each.value.node_pool_shape + node_pool_shape_specific_ad = try(each.value.node_pool_shape_specific_ad, 0) + node_pool_node_shape_config_ocpus = try(each.value.node_pool_node_shape_config_ocpus, 4) + node_pool_boot_volume_size_in_gbs = try(each.value.node_pool_boot_volume_size_in_gbs, 80) + node_pool_node_shape_config_memory_in_gbs = try(each.value.node_pool_node_shape_config_memory_in_gbs, 48) + existent_oke_nodepool_id_for_autoscaler = try(each.value.existent_oke_nodepool_id_for_autoscaler, null) + node_pool_autoscaler_enabled = try(each.value.node_pool_autoscaler_enabled, true) + node_pool_oke_init_params = try(each.value.node_pool_oke_init_params, "") + node_pool_cloud_init_parts = try(each.value.node_pool_cloud_init_parts, []) + public_ssh_key = try(local.workers_public_ssh_key, "") + image_operating_system = try(each.value.image_operating_system, "Oracle Linux") + image_operating_system_version = try(each.value.image_operating_system_version, "8") + extra_initial_node_labels = try(each.value.extra_initial_node_labels, {}) + cni_type = try(each.value.cni_type, "FLANNEL_OVERLAY") + + # OKE Network Details + # nodes_subnet_id = local.create_subnets ? module.subnets["oke_nodes_subnet"].subnet_id : var.existent_oke_nodes_subnet_ocid + nodes_subnet_id = (local.create_subnets ? (anytrue([(each.value.node_pool_alternative_subnet == ""), (each.value.node_pool_alternative_subnet == null)]) + ? module.subnets["oke_nodes_subnet"].subnet_id : module.subnets[each.value.node_pool_alternative_subnet].subnet_id) + : var.existent_oke_nodes_subnet_ocid) + vcn_native_pod_networking_subnet_ocid = each.value.cni_type == "OCI_VCN_IP_NATIVE" ? (local.create_subnets ? module.subnets["oke_pods_network_subnet"].subnet_id : var.existent_oke_vcn_native_pod_networking_subnet_ocid) : null + + # Encryption (OCI Vault/Key Management/KMS) + oci_vault_key_id_oke_node_boot_volume = module.vault.oci_vault_key_id +} +locals { + node_pool_1 = [ + { + node_pool_name = var.node_pool_name_1 != "" ? var.node_pool_name_1 : "pool1" # Must be unique + node_pool_min_nodes = var.node_pool_initial_num_worker_nodes_1 + node_pool_max_nodes = var.node_pool_max_num_worker_nodes_1 + node_pool_autoscaler_enabled = var.node_pool_autoscaler_enabled_1 + node_k8s_version = var.k8s_version # TODO: Allow to set different version for each node pool + node_pool_shape = var.node_pool_instance_shape_1.instanceShape + node_pool_shape_specific_ad = var.node_pool_shape_specific_ad_1 + node_pool_node_shape_config_ocpus = var.node_pool_instance_shape_1.ocpus + node_pool_node_shape_config_memory_in_gbs = var.node_pool_instance_shape_1.memory + node_pool_boot_volume_size_in_gbs = var.node_pool_boot_volume_size_in_gbs_1 + existent_oke_nodepool_id_for_autoscaler = var.existent_oke_nodepool_id_for_autoscaler_1 + node_pool_oke_init_params = var.node_pool_oke_init_params_1 + node_pool_cloud_init_parts = var.node_pool_cloud_init_parts_1 + node_pool_alternative_subnet = null + image_operating_system = var.image_operating_system_1 + image_operating_system_version = var.image_operating_system_version_1 + extra_initial_node_labels = var.extra_initial_node_labels_1 + cni_type = local.cni_type + }, + ] +} +# Generate ssh keys to access Worker Nodes, if generate_public_ssh_key=true, applies to the pool +resource "tls_private_key" "oke_worker_node_ssh_key" { + algorithm = "RSA" + rsa_bits = 2048 +} +locals { + workers_public_ssh_key = var.generate_public_ssh_key ? tls_private_key.oke_worker_node_ssh_key.public_key_openssh : var.public_ssh_key +} + +################################################################################ +# Module: OKE Cluster Autoscaler +################################################################################ +module "oke_cluster_autoscaler" { + source = "./modules/oke-cluster-autoscaler" + + # Oracle Cloud Infrastructure Tenancy and Compartment OCID + region = var.region + + ## Enable Cluster Autoscaler for node pools + oke_node_pools = [for node_pool in values(module.oke_node_pools) : node_pool if node_pool.node_pool_autoscaler_enabled] + + depends_on = [module.oke, module.oke_node_pools] +} + +resource "oci_identity_compartment" "oke_compartment" { + compartment_id = var.compartment_ocid + name = "${local.app_name_normalized}-${local.deploy_id}" + description = "${local.app_name} ${var.oke_compartment_description} (Deployment ${local.deploy_id})" + enable_delete = true + + count = var.create_new_compartment_for_oke ? 1 : 0 +} +locals { + oke_compartment_ocid = var.create_new_compartment_for_oke ? oci_identity_compartment.oke_compartment.0.id : var.compartment_ocid +} + +# OKE Subnets definitions +locals { + subnets_oke = concat(local.subnets_oke_standard, local.subnet_vcn_native_pod_networking, local.subnet_bastion, local.subnet_fss_mount_targets) + subnets_oke_standard = [ + { + subnet_name = "oke_k8s_endpoint_subnet" + cidr_block = lookup(local.network_cidrs, "ENDPOINT-REGIONAL-SUBNET-CIDR") + display_name = "OKE K8s Endpoint subnet (${local.deploy_id})" + dns_label = "okek8s${local.deploy_id}" + prohibit_public_ip_on_vnic = (var.cluster_endpoint_visibility == "Private") ? true : false + prohibit_internet_ingress = (var.cluster_endpoint_visibility == "Private") ? true : false + route_table_id = (var.cluster_endpoint_visibility == "Private") ? module.route_tables["private"].route_table_id : module.route_tables["public"].route_table_id + alternative_route_table_name = null + dhcp_options_id = module.vcn.default_dhcp_options_id + security_list_ids = [module.security_lists["oke_endpoint_security_list"].security_list_id] + extra_security_list_names = anytrue([(var.extra_security_list_name_for_api_endpoint == ""), (var.extra_security_list_name_for_api_endpoint == null)]) ? [] : [var.extra_security_list_name_for_api_endpoint] + ipv6cidr_block = null + }, + { + subnet_name = "oke_nodes_subnet" + cidr_block = lookup(local.network_cidrs, "NODES-REGIONAL-SUBNET-CIDR") + display_name = "OKE Nodes subnet (${local.deploy_id})" + dns_label = "okenodes${local.deploy_id}" + prohibit_public_ip_on_vnic = (var.cluster_workers_visibility == "Private") ? true : false + prohibit_internet_ingress = (var.cluster_workers_visibility == "Private") ? true : false + route_table_id = (var.cluster_workers_visibility == "Private") ? module.route_tables["private"].route_table_id : module.route_tables["public"].route_table_id + alternative_route_table_name = null + dhcp_options_id = module.vcn.default_dhcp_options_id + security_list_ids = [module.security_lists["oke_nodes_security_list"].security_list_id] + extra_security_list_names = anytrue([(var.extra_security_list_name_for_nodes == ""), (var.extra_security_list_name_for_nodes == null)]) ? [] : [var.extra_security_list_name_for_nodes] + ipv6cidr_block = null + }, + { + subnet_name = "oke_lb_subnet" + cidr_block = lookup(local.network_cidrs, "LB-REGIONAL-SUBNET-CIDR") + display_name = "OKE LoadBalancers subnet (${local.deploy_id})" + dns_label = "okelb${local.deploy_id}" + prohibit_public_ip_on_vnic = (var.cluster_load_balancer_visibility == "Private") ? true : false + prohibit_internet_ingress = (var.cluster_load_balancer_visibility == "Private") ? true : false + route_table_id = (var.cluster_load_balancer_visibility == "Private") ? module.route_tables["private"].route_table_id : module.route_tables["public"].route_table_id + alternative_route_table_name = null + dhcp_options_id = module.vcn.default_dhcp_options_id + security_list_ids = [module.security_lists["oke_lb_security_list"].security_list_id] + extra_security_list_names = [] + ipv6cidr_block = null + } + ] + subnet_vcn_native_pod_networking = (var.create_pod_network_subnet || var.cluster_cni_type == "OCI_VCN_IP_NATIVE" || var.node_pool_cni_type_1 == "OCI_VCN_IP_NATIVE") ? [ + { + subnet_name = "oke_pods_network_subnet" + cidr_block = lookup(local.network_cidrs, "VCN-NATIVE-POD-NETWORKING-REGIONAL-SUBNET-CIDR") # e.g.: 10.20.128.0/17 (1,1) = 32766 usable IPs (10.20.128.0 - 10.20.255.255) + display_name = "OKE PODs Network subnet (${local.deploy_id})" + dns_label = "okenpn${local.deploy_id}" + prohibit_public_ip_on_vnic = (var.pods_network_visibility == "Private") ? true : false + prohibit_internet_ingress = (var.pods_network_visibility == "Private") ? true : false + route_table_id = (var.pods_network_visibility == "Private") ? module.route_tables["private"].route_table_id : module.route_tables["public"].route_table_id + alternative_route_table_name = null + dhcp_options_id = module.vcn.default_dhcp_options_id + security_list_ids = [module.security_lists["oke_pod_network_security_list"].security_list_id] + extra_security_list_names = anytrue([(var.extra_security_list_name_for_vcn_native_pod_networking == ""), (var.extra_security_list_name_for_vcn_native_pod_networking == null)]) ? [] : [var.extra_security_list_name_for_vcn_native_pod_networking] + ipv6cidr_block = null + }] : [] + subnet_bastion = [] # 10.20.2.0/28 (12,32) = 15 usable IPs (10.20.2.0 - 10.20.2.15) + subnet_fss_mount_targets = [] # 10.20.20.64/26 (10,81) = 62 usable IPs (10.20.20.64 - 10.20.20.255) +} + +# OKE Route Tables definitions +locals { + route_tables_oke = [ + { + route_table_name = "private" + display_name = "OKE Private Route Table (${local.deploy_id})" + route_rules = [ + { + description = "Traffic to the internet" + destination = lookup(local.network_cidrs, "ALL-CIDR") + destination_type = "CIDR_BLOCK" + network_entity_id = module.gateways.nat_gateway_id + }, + { + description = "Traffic to OCI services" + destination = lookup(data.oci_core_services.all_services_network.services[0], "cidr_block") + destination_type = "SERVICE_CIDR_BLOCK" + network_entity_id = module.gateways.service_gateway_id + }] + + }, + { + route_table_name = "public" + display_name = "OKE Public Route Table (${local.deploy_id})" + route_rules = [ + { + description = "Traffic to/from internet" + destination = lookup(local.network_cidrs, "ALL-CIDR") + destination_type = "CIDR_BLOCK" + network_entity_id = module.gateways.internet_gateway_id + }] + }] +} + +# OKE Security Lists definitions +locals { + security_lists_oke = [ + { + security_list_name = "oke_nodes_security_list" + display_name = "OKE Node Workers Security List (${local.deploy_id})" + egress_security_rules = [ + { + description = "Allows communication from (or to) worker nodes" + destination = lookup(local.network_cidrs, "NODES-REGIONAL-SUBNET-CIDR") + destination_type = "CIDR_BLOCK" + protocol = local.security_list_ports.all_protocols + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Allow worker nodes to communicate with pods on other worker nodes (when using VCN-native pod networking)" + destination = lookup(local.network_cidrs, "VCN-NATIVE-POD-NETWORKING-REGIONAL-SUBNET-CIDR") + destination_type = "CIDR_BLOCK" + protocol = local.security_list_ports.all_protocols + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "(optional) Allow worker nodes to communicate with internet" + destination = lookup(local.network_cidrs, "ALL-CIDR") + destination_type = "CIDR_BLOCK" + protocol = local.security_list_ports.all_protocols + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Allow nodes to communicate with OKE to ensure correct start-up and continued functioning" + destination = lookup(data.oci_core_services.all_services_network.services[0], "cidr_block") + destination_type = "SERVICE_CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "ICMP Access from Kubernetes Control Plane" + destination = lookup(local.network_cidrs, "ALL-CIDR") + destination_type = "CIDR_BLOCK" + protocol = local.security_list_ports.icmp_protocol_number + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = { type = "3", code = "4" } + }, { + description = "Access to Kubernetes API Endpoint" + destination = lookup(local.network_cidrs, "ENDPOINT-REGIONAL-SUBNET-CIDR") + destination_type = "CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number + stateless = false + tcp_options = { max = local.security_list_ports.k8s_api_endpoint_port_number, min = local.security_list_ports.k8s_api_endpoint_port_number, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Kubernetes worker to control plane communication" + destination = lookup(local.network_cidrs, "ENDPOINT-REGIONAL-SUBNET-CIDR") + destination_type = "CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number + stateless = false + tcp_options = { max = local.security_list_ports.k8s_worker_to_control_plane_port_number, min = local.security_list_ports.k8s_worker_to_control_plane_port_number, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Path discovery" + destination = lookup(local.network_cidrs, "ENDPOINT-REGIONAL-SUBNET-CIDR") + destination_type = "CIDR_BLOCK" + protocol = local.security_list_ports.icmp_protocol_number + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = { type = "3", code = "4" } + }] + ingress_security_rules = [ + { + description = "Allows communication from (or to) worker nodes" + source = lookup(local.network_cidrs, "NODES-REGIONAL-SUBNET-CIDR") + source_type = "CIDR_BLOCK" + protocol = local.security_list_ports.all_protocols + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Allow pods on one worker node to communicate with pods on other worker nodes (when using VCN-native pod networking)" + source = lookup(local.network_cidrs, "VCN-NATIVE-POD-NETWORKING-REGIONAL-SUBNET-CIDR") + source_type = "CIDR_BLOCK" + protocol = local.security_list_ports.all_protocols + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "(optional) Allow inbound SSH traffic to worker nodes" + source = lookup(local.network_cidrs, (var.cluster_workers_visibility == "Private") ? "VCN-MAIN-CIDR" : "ALL-CIDR") + source_type = "CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number + stateless = false + tcp_options = { max = local.security_list_ports.ssh_port_number, min = local.security_list_ports.ssh_port_number, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Allow control plane to communicate with worker nodes" + source = lookup(local.network_cidrs, "ENDPOINT-REGIONAL-SUBNET-CIDR") + source_type = "CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Kubernetes API endpoint to worker node communication (when using VCN-native pod networking)" + source = lookup(local.network_cidrs, "ENDPOINT-REGIONAL-SUBNET-CIDR") + source_type = "CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number + stateless = false + tcp_options = { max = local.security_list_ports.k8s_api_endpoint_to_worker_port_number, min = local.security_list_ports.k8s_api_endpoint_to_worker_port_number, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Path discovery - Kubernetes API Endpoint" + source = lookup(local.network_cidrs, "ENDPOINT-REGIONAL-SUBNET-CIDR") + source_type = "CIDR_BLOCK" + protocol = local.security_list_ports.icmp_protocol_number + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = { type = "3", code = "4" } + }, { + description = "Path discovery" + source = lookup(local.network_cidrs, "ALL-CIDR") + source_type = "CIDR_BLOCK" + protocol = local.security_list_ports.icmp_protocol_number + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = { type = "3", code = "4" } + }, { + description = "Load Balancer to Worker nodes node ports" + source = lookup(local.network_cidrs, "LB-REGIONAL-SUBNET-CIDR") + source_type = "CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number # all_protocols + stateless = false + tcp_options = { max = 32767, min = 30000, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }] + }, + { + security_list_name = "oke_lb_security_list" + display_name = "OKE Load Balancer Security List (${local.deploy_id})" + egress_security_rules = [ + { + description = "Allow traffic to worker nodes" + destination = lookup(local.network_cidrs, "ALL-CIDR") + destination_type = "CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number # all_protocols + stateless = false + tcp_options = { max = 32767, min = 30000, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }] + ingress_security_rules = [ + { + description = "Allow inbound traffic to Load Balancer" + source = lookup(local.network_cidrs, "ALL-CIDR") + source_type = "CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number + stateless = false + tcp_options = { max = local.security_list_ports.https_port_number, min = local.security_list_ports.https_port_number, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }] + }, + { + security_list_name = "oke_endpoint_security_list" + display_name = "OKE K8s API Endpoint Security List (${local.deploy_id})" + egress_security_rules = [ + { + description = "Allow Kubernetes API Endpoint to communicate with OKE" + destination = lookup(data.oci_core_services.all_services_network.services[0], "cidr_block") + destination_type = "SERVICE_CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number + stateless = false + tcp_options = { max = local.security_list_ports.https_port_number, min = local.security_list_ports.https_port_number, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Path discovery" + destination = lookup(local.network_cidrs, "NODES-REGIONAL-SUBNET-CIDR") + destination_type = "CIDR_BLOCK" + protocol = local.security_list_ports.icmp_protocol_number + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = { type = "3", code = "4" } + }, { + description = "All traffic to worker nodes (when using flannel for pod networking)" + destination = lookup(local.network_cidrs, "NODES-REGIONAL-SUBNET-CIDR") + destination_type = "CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Kubernetes API endpoint to pod communication (when using VCN-native pod networking)" + destination = lookup(local.network_cidrs, "VCN-NATIVE-POD-NETWORKING-REGIONAL-SUBNET-CIDR") + destination_type = "CIDR_BLOCK" + protocol = local.security_list_ports.all_protocols + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Kubernetes API endpoint to worker node communication (when using VCN-native pod networking)" + destination = lookup(local.network_cidrs, "NODES-REGIONAL-SUBNET-CIDR") + destination_type = "CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number + stateless = false + tcp_options = { max = local.security_list_ports.k8s_api_endpoint_to_worker_port_number, min = local.security_list_ports.k8s_api_endpoint_to_worker_port_number, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }] + ingress_security_rules = [ + { + description = "(optional) Client access to Kubernetes API endpoint" + source = lookup(local.network_cidrs, (var.cluster_endpoint_visibility == "Private") ? "VCN-MAIN-CIDR" : "ALL-CIDR") + source_type = "CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number + stateless = false + tcp_options = { max = local.security_list_ports.k8s_api_endpoint_port_number, min = local.security_list_ports.k8s_api_endpoint_port_number, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Kubernetes worker to Kubernetes API endpoint communication" + source = lookup(local.network_cidrs, "NODES-REGIONAL-SUBNET-CIDR") + source_type = "CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number + stateless = false + tcp_options = { max = local.security_list_ports.k8s_api_endpoint_port_number, min = local.security_list_ports.k8s_api_endpoint_port_number, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Kubernetes worker to control plane communication" + source = lookup(local.network_cidrs, "NODES-REGIONAL-SUBNET-CIDR") + source_type = "CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number + stateless = false + tcp_options = { max = local.security_list_ports.k8s_worker_to_control_plane_port_number, min = local.security_list_ports.k8s_worker_to_control_plane_port_number, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Path discovery" + source = lookup(local.network_cidrs, "NODES-REGIONAL-SUBNET-CIDR") + source_type = "CIDR_BLOCK" + protocol = local.security_list_ports.icmp_protocol_number + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = { type = "3", code = "4" } + }, { + description = "Pod to Kubernetes API endpoint communication (when using VCN-native pod networking)" + source = lookup(local.network_cidrs, "VCN-NATIVE-POD-NETWORKING-REGIONAL-SUBNET-CIDR") + source_type = "CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number + stateless = false + tcp_options = { max = local.security_list_ports.k8s_api_endpoint_port_number, min = local.security_list_ports.k8s_api_endpoint_port_number, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Pod to control plane communication (when using VCN-native pod networking)" + source = lookup(local.network_cidrs, "VCN-NATIVE-POD-NETWORKING-REGIONAL-SUBNET-CIDR") + source_type = "CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number + stateless = false + tcp_options = { max = local.security_list_ports.k8s_worker_to_control_plane_port_number, min = local.security_list_ports.k8s_worker_to_control_plane_port_number, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }] + }, + { + security_list_name = "oke_pod_network_security_list" + display_name = "OKE VCN Native Pod Networking Security List (${local.deploy_id})" + egress_security_rules = [ + { + description = "Allow pods to communicate with each other" + destination = lookup(local.network_cidrs, "VCN-NATIVE-POD-NETWORKING-REGIONAL-SUBNET-CIDR") + destination_type = "CIDR_BLOCK" + protocol = local.security_list_ports.all_protocols + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Path discovery" + destination = lookup(data.oci_core_services.all_services_network.services[0], "cidr_block") + destination_type = "SERVICE_CIDR_BLOCK" + protocol = local.security_list_ports.icmp_protocol_number + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = { type = "3", code = "4" } + }, { + description = "Allow worker nodes to communicate with OCI services" + destination = lookup(data.oci_core_services.all_services_network.services[0], "cidr_block") + destination_type = "SERVICE_CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Allow Pods to communicate with Worker Nodes" + destination = lookup(local.network_cidrs, "NODES-REGIONAL-SUBNET-CIDR") + destination_type = "CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Pod to Kubernetes API endpoint communication (when using VCN-native pod networking)" + destination = lookup(local.network_cidrs, "ENDPOINT-REGIONAL-SUBNET-CIDR") + destination_type = "CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number + stateless = false + tcp_options = { max = local.security_list_ports.k8s_api_endpoint_port_number, min = local.security_list_ports.k8s_api_endpoint_port_number, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Pod to Kubernetes API endpoint communication (when using VCN-native pod networking)" + destination = lookup(local.network_cidrs, "ENDPOINT-REGIONAL-SUBNET-CIDR") + destination_type = "CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number + stateless = false + tcp_options = { max = local.security_list_ports.k8s_worker_to_control_plane_port_number, min = local.security_list_ports.k8s_worker_to_control_plane_port_number, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "(optional) Allow pods to communicate with internet" + destination = lookup(local.network_cidrs, "ALL-CIDR") + destination_type = "CIDR_BLOCK" + protocol = local.security_list_ports.tcp_protocol_number + stateless = false + tcp_options = { max = local.security_list_ports.https_port_number, min = local.security_list_ports.https_port_number, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }] + ingress_security_rules = [ + { + description = "Kubernetes API endpoint to pod communication (when using VCN-native pod networking)" + source = lookup(local.network_cidrs, "ENDPOINT-REGIONAL-SUBNET-CIDR") + source_type = "CIDR_BLOCK" + protocol = local.security_list_ports.all_protocols + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Allow pods on one worker node to communicate with pods on other worker nodes" + source = lookup(local.network_cidrs, "NODES-REGIONAL-SUBNET-CIDR") + source_type = "CIDR_BLOCK" + protocol = local.security_list_ports.all_protocols + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }, { + description = "Allow pods to communicate with each other" + source = lookup(local.network_cidrs, "VCN-NATIVE-POD-NETWORKING-REGIONAL-SUBNET-CIDR") + source_type = "CIDR_BLOCK" + protocol = local.security_list_ports.all_protocols + stateless = false + tcp_options = { max = -1, min = -1, source_port_range = null } + udp_options = { max = -1, min = -1, source_port_range = null } + icmp_options = null + }] + } + ] + security_list_ports = { + http_port_number = 80 + https_port_number = 443 + k8s_api_endpoint_port_number = 6443 + k8s_api_endpoint_to_worker_port_number = 10250 + k8s_worker_to_control_plane_port_number = 12250 + ssh_port_number = 22 + tcp_protocol_number = "6" + icmp_protocol_number = "1" + all_protocols = "all" + } +} + +# Network locals +locals { + cni_type = (var.cluster_cni_type == "OCI_VCN_IP_NATIVE" || var.node_pool_cni_type_1 == "OCI_VCN_IP_NATIVE") ? "OCI_VCN_IP_NATIVE" : "FLANNEL_OVERLAY" +} diff --git a/terraform-provider-oci/oke-quickstartz/modules/cluster-tools/cert-manager.tf b/terraform-provider-oci/oke-quickstartz/modules/cluster-tools/cert-manager.tf new file mode 100644 index 0000000..215c208 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/cluster-tools/cert-manager.tf @@ -0,0 +1,21 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +# Cert Manager variables +variable "cert_manager_enabled" { + default = true + description = "Enable x509 Certificate Management" +} + +module "cert-manager" { + source = "./modules/cert-manager" + + # Helm Release variables + chart_namespace = kubernetes_namespace.cluster_tools.0.id + chart_repository = local.helm_repository.jetstack + chart_version = local.helm_repository.jetstack_version + ingress_email_issuer = var.ingress_email_issuer + + count = var.cert_manager_enabled ? 1 : 0 +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/cluster-tools/cluster-tools.tf b/terraform-provider-oci/oke-quickstartz/modules/cluster-tools/cluster-tools.tf new file mode 100644 index 0000000..6ce061c --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/cluster-tools/cluster-tools.tf @@ -0,0 +1,39 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +# Create namespace cluster-tools for supporting services +resource "kubernetes_namespace" "cluster_tools" { + metadata { + name = var.cluster_tools_namespace + } + + count = local.use_cluster_tools_namespace ? 1 : 0 +} + +locals { + # Helm repos + helm_repository = { + ingress_nginx = "https://kubernetes.github.io/ingress-nginx" + ingress_nginx_version = "4.6.1" + jetstack = "https://charts.jetstack.io" # cert-manager + jetstack_version = "1.12.0" # cert-manager + grafana = "https://grafana.github.io/helm-charts" + grafana_version = "6.56.5" + prometheus = "https://prometheus-community.github.io/helm-charts" + prometheus_version = "22.6.2" + metrics_server = "https://kubernetes-sigs.github.io/metrics-server" + metrics_server_version = "3.10.0" + } + use_cluster_tools_namespace = anytrue([var.grafana_enabled, var.ingress_nginx_enabled, var.cert_manager_enabled, var.prometheus_enabled]) ? true : false +} + +# OCI Provider +variable "tenancy_ocid" {} +# variable "compartment_ocid" {} +variable "region" {} + +# Namespace +variable "cluster_tools_namespace" { + default = "cluster-tools" +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/cluster-tools/grafana.tf b/terraform-provider-oci/oke-quickstartz/modules/cluster-tools/grafana.tf new file mode 100644 index 0000000..902ab13 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/cluster-tools/grafana.tf @@ -0,0 +1,234 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +# Grafana variables +variable "grafana_enabled" { + default = true + description = "Enable Grafana Dashboards. Includes example dashboards and Prometheus, OCI Logging and OCI Metrics datasources" +} + +# Grafana Helm chart +## https://github.com/grafana/helm-charts/blob/main/charts/grafana/README.md +## https://artifacthub.io/packages/helm/grafana/grafana +resource "helm_release" "grafana" { + name = "grafana" + repository = local.helm_repository.grafana + chart = "grafana" + version = local.helm_repository.grafana_version + namespace = kubernetes_namespace.cluster_tools.0.id + wait = false + + set { + name = "grafana\\.ini.server.root_url" + value = "%(protocol)s://%(domain)s:%(http_port)s/grafana" + type = "string" + } + + set { + name = "grafana\\.ini.server.serve_from_sub_path" + value = "true" + } + + values = [ + < __Warning__: Moved to [oracle-quickstart/terraform-oci-networking](https://github.com/oracle-quickstart/terraform-oci-networking). Sub modules with specific OCI Networking resource also available. example: [Virtual Cloud Network](https://github.com/oracle-quickstart/terraform-oci-networking/tree/main/modules/vcn). diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/gateway/datasources.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/gateway/datasources.tf new file mode 100644 index 0000000..e432b9c --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/gateway/datasources.tf @@ -0,0 +1,12 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +## Available Services +data "oci_core_services" "all_services" { + filter { + name = "name" + values = ["All .* Services In Oracle Services Network"] + regex = true + } +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/gateway/main.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/gateway/main.tf new file mode 100644 index 0000000..0740190 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/gateway/main.tf @@ -0,0 +1,61 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +resource "oci_core_internet_gateway" "gateway" { + compartment_id = var.compartment_ocid + display_name = var.internet_gateway_display_name + enabled = var.internet_gateway_enabled + vcn_id = var.vcn_id + route_table_id = var.internet_gateway_route_table_id + freeform_tags = var.gateways_tags.freeformTags + defined_tags = var.gateways_tags.definedTags + + count = var.create_internet_gateway ? 1 : 0 +} + +resource "oci_core_nat_gateway" "gateway" { + block_traffic = var.nat_gateway_block_traffic + compartment_id = var.compartment_ocid + display_name = var.nat_gateway_display_name + vcn_id = var.vcn_id + public_ip_id = var.nat_gateway_public_ip_id + route_table_id = var.nat_gateway_route_table_id + freeform_tags = var.gateways_tags.freeformTags + defined_tags = var.gateways_tags.definedTags + + count = var.create_nat_gateway ? 1 : 0 + lifecycle { + ignore_changes = [ + defined_tags["Oracle-Tags.CreatedBy"], + defined_tags["Oracle-Tags.CreatedOn"], + ] + } +} + +resource "oci_core_service_gateway" "gateway" { + compartment_id = var.compartment_ocid + display_name = var.service_gateway_display_name + vcn_id = var.vcn_id + route_table_id = var.service_gateway_route_table_id + freeform_tags = var.gateways_tags.freeformTags + defined_tags = var.gateways_tags.definedTags + + services { + service_id = lookup(data.oci_core_services.all_services.services[0], "id") + } + + count = var.create_service_gateway ? 1 : 0 +} + +resource "oci_core_local_peering_gateway" "gateway" { + compartment_id = var.compartment_ocid + display_name = var.local_peering_gateway_display_name + vcn_id = var.vcn_id + peer_id = var.local_peering_gateway_peer_id + route_table_id = var.local_peering_gateway_route_table_id + freeform_tags = var.gateways_tags.freeformTags + defined_tags = var.gateways_tags.definedTags + + count = var.create_local_peering_gateway ? 1 : 0 +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/gateway/outputs.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/gateway/outputs.tf new file mode 100644 index 0000000..90a2bbb --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/gateway/outputs.tf @@ -0,0 +1,20 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +output "internet_gateway_id" { + value = var.create_internet_gateway ? oci_core_internet_gateway.gateway[0].id : null + description = "The OCID of the Internet Gateway." +} +output "nat_gateway_id" { + value = var.create_nat_gateway ? oci_core_nat_gateway.gateway[0].id : null + description = "The OCID of the NAT Gateway." +} +output "service_gateway_id" { + value = var.create_service_gateway ? oci_core_service_gateway.gateway[0].id : null + description = "The OCID of the Service Gateway." +} +output "local_peering_gateway_id" { + value = var.create_local_peering_gateway ? oci_core_local_peering_gateway.gateway[0].id : null + description = "The OCID of the Local Peering Gateway." +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/gateway/providers.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/gateway/providers.tf new file mode 100644 index 0000000..bb684e3 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/gateway/providers.tf @@ -0,0 +1,19 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +terraform { + required_version = ">= 1.1" + required_providers { + oci = { + source = "oracle/oci" + version = "~> 4" + # https://registry.terraform.io/providers/oracle/oci/ + } + local = { + source = "hashicorp/local" + version = "~> 2" + # https://registry.terraform.io/providers/hashicorp/local/ + } + } +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/gateway/variables.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/gateway/variables.tf new file mode 100644 index 0000000..3042fc4 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/gateway/variables.tf @@ -0,0 +1,78 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +variable "compartment_ocid" {} +variable "vcn_id" {} +# Internet Gateway +variable "create_internet_gateway" { + default = false + description = "Create an internet gateway" +} +variable "internet_gateway_display_name" { + default = "Internet Gateway" + description = "Display name for the internet gateway" +} +variable "internet_gateway_enabled" { + default = true + description = "Whether the gateway is enabled upon creation." +} +variable "internet_gateway_route_table_id" { + default = null + description = "The OCID of the route table the internet gateway will use." +} +# NAT Gateway +variable "create_nat_gateway" { + default = false + description = "Create a NAT gateway" +} +variable "nat_gateway_display_name" { + default = "NAT Gateway" + description = "Display name for the NAT gateway" +} +variable "nat_gateway_block_traffic" { + default = false + description = "Whether the NAT gateway blocks traffic through it." +} +variable "nat_gateway_route_table_id" { + default = null + description = "The OCID of the route table the NAT gateway will use." +} +variable "nat_gateway_public_ip_id" { + default = null + description = "The OCID of the public IP the NAT gateway will use." +} +# Service Gateway +variable "create_service_gateway" { + default = false + description = "Create a service gateway" +} +variable "service_gateway_display_name" { + default = "Service Gateway" + description = "Display name for the service gateway" +} +variable "service_gateway_route_table_id" { + default = null + description = "The OCID of the route table the service gateway will use." +} +# Local Peering Gateway (LPG) +variable "create_local_peering_gateway" { + default = false + description = "Create a local peering gateway" +} +variable "local_peering_gateway_display_name" { + default = "Local Peering Gateway" + description = "Display name for the local peering gateway" +} +variable "local_peering_gateway_peer_id" { + default = null + description = "The OCID of the LPG you want to peer with." +} +variable "local_peering_gateway_route_table_id" { + default = null + description = "The OCID of the route table the local peering gateway will use." +} +# Deployment Details + Freeform Tags + Defined Tags +variable "gateways_tags" { + description = "Tags to be added to the gateway resources" +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/route_table/main.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/route_table/main.tf new file mode 100644 index 0000000..1b5dad0 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/route_table/main.tf @@ -0,0 +1,23 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +resource "oci_core_route_table" "route_table" { + compartment_id = var.compartment_ocid + vcn_id = var.vcn_id + display_name = var.display_name + freeform_tags = var.route_table_tags.freeformTags + defined_tags = var.route_table_tags.definedTags + + dynamic "route_rules" { + for_each = var.route_rules + content { + description = route_rules.value.description + destination = route_rules.value.destination + destination_type = route_rules.value.destination_type + network_entity_id = route_rules.value.network_entity_id + } + } + + count = var.create_route_table ? 1 : 0 +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/route_table/outputs.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/route_table/outputs.tf new file mode 100644 index 0000000..47b9d52 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/route_table/outputs.tf @@ -0,0 +1,8 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +output "route_table_id" { + value = var.create_route_table ? oci_core_route_table.route_table[0].id : null + description = "The OCID of the Route Table." +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/route_table/providers.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/route_table/providers.tf new file mode 100644 index 0000000..bb684e3 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/route_table/providers.tf @@ -0,0 +1,19 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +terraform { + required_version = ">= 1.1" + required_providers { + oci = { + source = "oracle/oci" + version = "~> 4" + # https://registry.terraform.io/providers/oracle/oci/ + } + local = { + source = "hashicorp/local" + version = "~> 2" + # https://registry.terraform.io/providers/hashicorp/local/ + } + } +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/route_table/variables.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/route_table/variables.tf new file mode 100644 index 0000000..6c1adc1 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/route_table/variables.tf @@ -0,0 +1,28 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +variable "compartment_ocid" {} +variable "vcn_id" {} +variable "route_table_name" {} +variable "create_route_table" { + default = false + description = "Creates a new route table. If false, bypass the creation." +} +variable "display_name" { + default = null + description = "Display name for the subnet." +} +variable "route_rules" { + type = list(object({ + description = string + destination = string + destination_type = string + network_entity_id = string + })) + default = [] +} +# Deployment Details + Freeform Tags + Defined Tags +variable "route_table_tags" { + description = "Tags to be added to the route table resources" +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/security_list/main.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/security_list/main.tf new file mode 100644 index 0000000..8346fa6 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/security_list/main.tf @@ -0,0 +1,111 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +resource "oci_core_security_list" "security_list" { + compartment_id = var.compartment_ocid + display_name = var.display_name + vcn_id = var.vcn_id + freeform_tags = var.security_list_tags.freeformTags + defined_tags = var.security_list_tags.definedTags + + dynamic "egress_security_rules" { + for_each = var.egress_security_rules + content { + description = egress_security_rules.value.description + destination = egress_security_rules.value.destination + destination_type = egress_security_rules.value.destination_type + protocol = egress_security_rules.value.protocol + stateless = egress_security_rules.value.stateless + + dynamic "tcp_options" { + for_each = (egress_security_rules.value.tcp_options.max != -1 && egress_security_rules.value.tcp_options.min != -1) ? [1] : [] + content { + max = egress_security_rules.value.tcp_options.max + min = egress_security_rules.value.tcp_options.min + dynamic "source_port_range" { + for_each = can(egress_security_rules.value.tcp_options.source_port_range.max) ? [1] : [] + content { + max = egress_security_rules.value.tcp_options.source_port_range.max + min = egress_security_rules.value.tcp_options.source_port_range.min + } + } + } + } + dynamic "udp_options" { + for_each = (egress_security_rules.value.udp_options.max != -1 && egress_security_rules.value.udp_options.min != -1) ? [1] : [] + content { + max = egress_security_rules.value.udp_options.max + min = egress_security_rules.value.udp_options.min + dynamic "source_port_range" { + for_each = can(egress_security_rules.value.udp_options.source_port_range.max) ? [1] : [] + content { + max = egress_security_rules.value.udp_options.source_port_range.max + min = egress_security_rules.value.udp_options.source_port_range.min + } + } + } + } + dynamic "icmp_options" { + for_each = can(egress_security_rules.value.icmp_options.type) ? [1] : [] + content { + type = egress_security_rules.value.icmp_options.type + code = egress_security_rules.value.icmp_options.code + } + } + } + } + + dynamic "ingress_security_rules" { + for_each = var.ingress_security_rules + content { + description = ingress_security_rules.value.description + source = ingress_security_rules.value.source + source_type = ingress_security_rules.value.source_type + protocol = ingress_security_rules.value.protocol + stateless = ingress_security_rules.value.stateless + + dynamic "tcp_options" { + for_each = (ingress_security_rules.value.tcp_options.max != -1 && ingress_security_rules.value.tcp_options.min != -1) ? [1] : [] + content { + max = ingress_security_rules.value.tcp_options.max + min = ingress_security_rules.value.tcp_options.min + dynamic "source_port_range" { + for_each = can(ingress_security_rules.value.tcp_options.source_port_range.max) ? [1] : [] + content { + max = ingress_security_rules.value.tcp_options.source_port_range.max + min = ingress_security_rules.value.tcp_options.source_port_range.min + } + } + } + } + dynamic "udp_options" { + for_each = (ingress_security_rules.value.udp_options.max != -1 && ingress_security_rules.value.udp_options.min != -1) ? [1] : [] + content { + max = ingress_security_rules.value.udp_options.max + min = ingress_security_rules.value.udp_options.min + dynamic "source_port_range" { + for_each = can(ingress_security_rules.value.udp_options.source_port_range.max) ? [1] : [] + content { + max = ingress_security_rules.value.udp_options.source_port_range.max + min = ingress_security_rules.value.udp_options.source_port_range.min + } + } + } + } + dynamic "icmp_options" { + for_each = can(ingress_security_rules.value.icmp_options.type) ? [1] : [] + content { + type = ingress_security_rules.value.icmp_options.type + code = ingress_security_rules.value.icmp_options.code + } + } + } + } + + lifecycle { + ignore_changes = [freeform_tags, defined_tags, egress_security_rules, ingress_security_rules] + } + + count = var.create_security_list ? 1 : 0 +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/security_list/outputs.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/security_list/outputs.tf new file mode 100644 index 0000000..3819f86 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/security_list/outputs.tf @@ -0,0 +1,12 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +output "security_list_id" { + value = var.create_security_list ? oci_core_security_list.security_list[0].id : null + description = "The OCID of the security list." +} +output "security_list_name" { + value = var.security_list_name + description = "The reference name of the security list. (Not the display name)" +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/security_list/providers.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/security_list/providers.tf new file mode 100644 index 0000000..45ad5c4 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/security_list/providers.tf @@ -0,0 +1,20 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +terraform { + required_version = ">= 1.1" + required_providers { + oci = { + source = "oracle/oci" + version = "~> 4" + # https://registry.terraform.io/providers/oracle/oci/ + } + local = { + source = "hashicorp/local" + version = "~> 2" + # https://registry.terraform.io/providers/hashicorp/local/ + } + } + # experiments = [module_variable_optional_attrs] +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/security_list/variables.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/security_list/variables.tf new file mode 100644 index 0000000..15dfebd --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/security_list/variables.tf @@ -0,0 +1,142 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +variable "compartment_ocid" {} +variable "vcn_id" {} +variable "security_list_name" {} +variable "create_security_list" { + default = false + description = "Creates a new security list. If false, bypass the creation." +} +variable "display_name" { + default = null + description = "Display name for the security list." +} +variable "egress_security_rules" { + type = list(object({ + description = string + destination = string + destination_type = string + protocol = string + stateless = bool + tcp_options = object({ + max = number + min = number + source_port_range = object({ + max = number + min = number + }) + }) + udp_options = object({ + max = number + min = number + source_port_range = object({ + max = number + min = number + }) + }) + icmp_options = object({ + type = number + code = number + }) + })) + default = [] +} + +variable "ingress_security_rules" { + type = list(object({ + description = string + source = string + source_type = string + protocol = string + stateless = bool + tcp_options = object({ + max = number + min = number + source_port_range = object({ + max = number + min = number + }) + }) + udp_options = object({ + max = number + min = number + source_port_range = object({ + max = number + min = number + }) + }) + icmp_options = object({ + type = number + code = number + }) + })) + default = [] +} + +# variable "egress_security_rules" { +# type = list(object({ +# description = optional(string) +# destination = string +# destination_type = optional(string) +# protocol = string +# stateless = optional(bool) +# tcp_options = optional(object({ +# max = optional(number) +# min = optional(number) +# source_port_range = optional(object({ +# max = number +# min = number +# })) +# })) +# udp_options = optional(object({ +# max = optional(number) +# min = optional(number) +# source_port_range = optional(object({ +# max = number +# min = number +# })) +# })) +# icmp_options = optional(object({ +# type = number +# code = optional(number) +# })) +# })) +# default = [] +# } +# variable "ingress_security_rules" { +# type = list(object({ +# description = optional(string) +# source = string +# source_type = optional(string) +# protocol = string +# stateless = optional(bool) +# tcp_options = optional(object({ +# max = optional(number) +# min = optional(number) +# source_port_range = optional(object({ +# max = number +# min = number +# })) +# })) +# udp_options = optional(object({ +# max = optional(number) +# min = optional(number) +# source_port_range = optional(object({ +# max = number +# min = number +# })) +# })) +# icmp_options = optional(object({ +# type = number +# code = optional(number) +# })) +# })) +# default = [] +# } + +# Deployment Details + Freeform Tags + Defined Tags +variable "security_list_tags" { + description = "Tags to be added to the security list resources" +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/subnet/main.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/subnet/main.tf new file mode 100644 index 0000000..5d5f7e5 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/subnet/main.tf @@ -0,0 +1,21 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +resource "oci_core_subnet" "subnet" { + cidr_block = var.cidr_block + compartment_id = var.compartment_ocid + display_name = var.display_name + dns_label = var.dns_label + vcn_id = var.vcn_id + prohibit_public_ip_on_vnic = var.prohibit_public_ip_on_vnic + prohibit_internet_ingress = var.prohibit_internet_ingress + route_table_id = var.route_table_id + dhcp_options_id = var.dhcp_options_id + security_list_ids = var.security_list_ids + ipv6cidr_block = var.ipv6cidr_block + freeform_tags = var.subnet_tags.freeformTags + defined_tags = var.subnet_tags.definedTags + + count = var.create_subnet ? 1 : 0 +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/subnet/outputs.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/subnet/outputs.tf new file mode 100644 index 0000000..b9f7336 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/subnet/outputs.tf @@ -0,0 +1,12 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +output "subnet_id" { + value = var.create_subnet ? oci_core_subnet.subnet[0].id : null + description = "The OCID of the subnet." +} +output "subnet_name" { + value = var.subnet_name + description = "The reference name of the subnet. (Not the display name)" +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/subnet/providers.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/subnet/providers.tf new file mode 100644 index 0000000..bb684e3 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/subnet/providers.tf @@ -0,0 +1,19 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +terraform { + required_version = ">= 1.1" + required_providers { + oci = { + source = "oracle/oci" + version = "~> 4" + # https://registry.terraform.io/providers/oracle/oci/ + } + local = { + source = "hashicorp/local" + version = "~> 2" + # https://registry.terraform.io/providers/hashicorp/local/ + } + } +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/subnet/variables.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/subnet/variables.tf new file mode 100644 index 0000000..9d77416 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/subnet/variables.tf @@ -0,0 +1,52 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +variable "compartment_ocid" {} +variable "vcn_id" {} +variable "subnet_name" {} +variable "create_subnet" { + default = true + description = "Creates a new subnet. If false, bypass the creation." +} +variable "cidr_block" { + default = ["10.20.0.0/16"] + description = "IPv4 CIDR Block for the subnet." +} +variable "display_name" { + default = null + description = "Display name for the subnet." +} +variable "dns_label" { + default = null + description = "DNS Label for subnet." +} +variable "prohibit_public_ip_on_vnic" { + default = null + description = "Whether VNICs within this subnet can have public IP addresses. Defaults to false, which means VNICs created in this subnet will automatically be assigned public IP addresses. If `prohibit_public_ip_on_vnic` is set to true, VNICs created in this subnet cannot have public IP addresses (that is, it's a private subnet)." +} +variable "prohibit_internet_ingress" { + default = null + description = "Whether to disallow ingress internet traffic to VNICs within this subnet. prohibitPublicIpOnVnic will be set to the value of prohibitInternetIngress to dictate IPv4 behavior in this subnet. Only one or the other flag should be specified." +} +variable "route_table_id" { + default = null + description = "The OCID of the route table the subnet will use. If you don't specify a route table here, the subnet will use the VCN's default route table. For information about why you would associate a route table with a subnet, see [Transit Routing: Access to Multiple VCNs in Same Region]." +} +variable "dhcp_options_id" { + default = null + description = "The OCID of the set of DHCP options the subnet will use. If you don't specify a set of options, the subnet will use the VCN's default set. For more information about DHCP options, see [Managing DHCP Options]." +} +variable "security_list_ids" { + default = null + description = "The OCID of the set of DHCP options the subnet will use. If you don't specify a set of options, the subnet will use the VCN's default set. For more information about DHCP options, see [Managing DHCP Options]." +} +variable "ipv6cidr_block" { + default = null + description = "IPv6 CIDR Block for the subnet." +} + +# Deployment Details + Freeform Tags + Defined Tags +variable "subnet_tags" { + description = "Tags to be added to the subnet resources" +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/vcn/datasources.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/vcn/datasources.tf new file mode 100644 index 0000000..d97629d --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/vcn/datasources.tf @@ -0,0 +1,7 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +data "oci_core_vcn" "main_or_existent" { + vcn_id = var.create_new_vcn ? oci_core_vcn.main[0].id : var.existent_vcn_ocid +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/vcn/main.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/vcn/main.tf new file mode 100644 index 0000000..4d921cb --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/vcn/main.tf @@ -0,0 +1,16 @@ +# Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +resource "oci_core_vcn" "main" { + cidr_blocks = var.cidr_blocks + compartment_id = var.compartment_ocid + display_name = var.display_name + dns_label = var.dns_label + freeform_tags = var.vcn_tags.freeformTags + defined_tags = var.vcn_tags.definedTags + is_ipv6enabled = var.is_ipv6enabled + ipv6private_cidr_blocks = var.ipv6private_cidr_blocks + + count = var.create_new_vcn ? 1 : 0 +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/vcn/outputs.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/vcn/outputs.tf new file mode 100644 index 0000000..c4ba473 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/vcn/outputs.tf @@ -0,0 +1,40 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +output "vcn_id" { + value = data.oci_core_vcn.main_or_existent.id +} +output "default_dhcp_options_id" { + value = data.oci_core_vcn.main_or_existent.default_dhcp_options_id +} +output "compartment_id" { + value = data.oci_core_vcn.main_or_existent.compartment_id +} +output "default_route_table_id" { + value = data.oci_core_vcn.main_or_existent.default_route_table_id +} +output "default_security_list_id" { + value = data.oci_core_vcn.main_or_existent.default_security_list_id +} +output "dns_label" { + value = data.oci_core_vcn.main_or_existent.dns_label +} +output "display_name" { + value = data.oci_core_vcn.main_or_existent.display_name +} +output "cidr_blocks" { + value = data.oci_core_vcn.main_or_existent.cidr_blocks +} +output "byoipv6cidr_blocks" { + value = data.oci_core_vcn.main_or_existent.byoipv6cidr_blocks +} +output "ipv6cidr_blocks" { + value = data.oci_core_vcn.main_or_existent.ipv6cidr_blocks +} +output "ipv6private_cidr_blocks" { + value = data.oci_core_vcn.main_or_existent.ipv6private_cidr_blocks +} +output "vcn_domain_name" { + value = data.oci_core_vcn.main_or_existent.vcn_domain_name +} diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/vcn/providers.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/vcn/providers.tf new file mode 100644 index 0000000..bb684e3 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/vcn/providers.tf @@ -0,0 +1,19 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +terraform { + required_version = ">= 1.1" + required_providers { + oci = { + source = "oracle/oci" + version = "~> 4" + # https://registry.terraform.io/providers/oracle/oci/ + } + local = { + source = "hashicorp/local" + version = "~> 2" + # https://registry.terraform.io/providers/hashicorp/local/ + } + } +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-networking/vcn/variables.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/vcn/variables.tf new file mode 100644 index 0000000..8078445 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-networking/vcn/variables.tf @@ -0,0 +1,38 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +variable "compartment_ocid" {} +variable "create_new_vcn" { + default = true + description = "Creates a new Virtual Cloud Network (VCN). If false, the VCN OCID must be provided in the variable 'existent_vcn_ocid'." +} +variable "existent_vcn_ocid" { + default = "" + description = "Using existent Virtual Cloud Network (VCN) OCID." +} +variable "cidr_blocks" { + default = ["10.20.0.0/16"] + description = "IPv4 CIDR Blocks for the Virtual Cloud Network (VCN). If use more than one block, separate them with comma. e.g.: 10.20.0.0/16,10.80.0.0/16" +} +variable "display_name" { + default = "Dev VCN 1" + description = "Display name for the Virtual Cloud Network (VCN)." +} +variable "dns_label" { + default = "vcn1" + description = "DNS Label for Virtual Cloud Network (VCN)." +} +variable "is_ipv6enabled" { + default = false + description = "Whether IPv6 is enabled for the Virtual Cloud Network (VCN)." +} +variable "ipv6private_cidr_blocks" { + default = [] + description = "The list of one or more ULA or Private IPv6 CIDR blocks for the Virtual Cloud Network (VCN)." +} + +# Deployment Details + Freeform Tags + Defined Tags +variable "vcn_tags" { + description = "Tags to be added to the VCN resources" +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-policies/main.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-policies/main.tf new file mode 100644 index 0000000..890584d --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-policies/main.tf @@ -0,0 +1,35 @@ +# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +resource "oci_identity_dynamic_group" "for_policies" { + name = "${local.app_name_normalized}-${local.dynamic_group_name_normalized}-${local.deploy_id}" + description = "${local.app_name} ${var.dynamic_group_name} (${local.deploy_id})" + compartment_id = var.tenancy_ocid + matching_rule = "${var.dynamic_group_main_condition} {${join(",", var.dynamic_group_matching_rules)}}" + freeform_tags = var.oci_tag_values.freeformTags + defined_tags = var.oci_tag_values.definedTags + + provider = oci.home_region + + count = var.create_dynamic_group ? 1 : 0 +} + +resource "oci_identity_policy" "policies" { + name = "${local.app_name_normalized}-${local.policy_name_normalized}-${local.deploy_id}" + description = "${local.app_name} ${var.policy_name} (${local.deploy_id})" + compartment_id = local.policy_compartment_ocid + statements = var.policy_statements + freeform_tags = var.oci_tag_values.freeformTags + defined_tags = var.oci_tag_values.definedTags + + depends_on = [oci_identity_dynamic_group.for_policies] + + provider = oci.home_region + + count = var.create_policy ? 1 : 0 +} + +locals { + policy_compartment_ocid = var.compartment_ocid != "" ? var.compartment_ocid : var.tenancy_ocid +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-policies/outputs.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-policies/outputs.tf new file mode 100644 index 0000000..b6fded2 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-policies/outputs.tf @@ -0,0 +1,13 @@ +# Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +output "dynamic_group_id" { + value = try(oci_identity_dynamic_group.for_policies.0.id, null) +} +output "dynamic_group_name" { + value = try(oci_identity_dynamic_group.for_policies.0.name, null) +} +output "compartment_policy_id" { + value = try(oci_identity_policy.policies.0.id, null) +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-policies/variables.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-policies/variables.tf new file mode 100644 index 0000000..d21363e --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-policies/variables.tf @@ -0,0 +1,73 @@ +# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +# Create Dynamic Group and Policies +variable "create_dynamic_group" { + default = false + description = "Creates dynamic group to use with policies. Note: You need to have proper rights on the Tenancy. If you only have rights in a compartment, uncheck and ask you administrator to create the Dynamic Group for you" +} +variable "dynamic_group_name" { + default = "Dynamic Group" + description = "Name of the dynamic group. e.g.: OKE Cluster Dynamic Group => -oke-cluster-dynamic-group-" +} +## Dynamic Group Matching Rules +variable "dynamic_group_matching_rules" { + type = list(string) + default = [] + description = "List of matching rules for the dynamic group. e.g.: [\"ALL {instance.compartment.id = 'ocid1.compartment.oc1..aaaaaaaaxxxxxxxxxxxxxxxx'}\", \"ALL {instance.id = 'ocid1.instance.oc1.phx.xxxxxxxx'}\"]" +} +variable "dynamic_group_main_condition" { + default = "ANY" + description = "Main condition for the dynamic group. e.g.: ALL, ANY" + + validation { + condition = var.dynamic_group_main_condition == "ALL" || var.dynamic_group_main_condition == "ANY" + error_message = "Sorry, but cluster visibility can only be ALL or ANY." + } +} +# Policy +variable "create_policy" { + default = false + description = "Creates policy. e.g.: Compartment Policies to support Cluster Autoscaler, OCI Logging datasource on Grafana; Tenancy Policies to support OCI Metrics datasource on Grafana" +} +variable "policy_name" { + default = "Policies" + description = "Name of the policy. e.g.: Compartment Policies => -compartment-policies-" +} +# variable "create_tenancy_policies" { +# default = false +# description = "Creates policies that need to reside on the tenancy. e.g.: Policies to support OCI Metrics datasource on Grafana" +# } +variable "compartment_ocid" { + default = "" + description = "Compartment OCID where the policies will be created. If not specified, the policies will be created on the Tenancy OCID" +} + +# Compartment Policies Statements +variable "policy_statements" { + type = list(string) + default = [] + description = "List of statements for the compartment policy. e.g.: [\"Allow dynamic-group to manage instances in compartment \", \"Allow dynamic-group to use instances in compartment where ALL {instance.compartment.id = 'ocid1.compartment.oc1..aaaaaaaaxxxxxxxxxxxxxxxx', instance.id = 'ocid1.instance.oc1.phx.xxxxxxxx'}\"]" +} + +# Deployment Details + Freeform Tags +variable "oci_tag_values" { + description = "Tags to be added to the resources" +} + +# OCI Provider +variable "tenancy_ocid" {} +# variable "region" {} +# variable "user_ocid" { default = "" } +# variable "fingerprint" { default = "" } +# variable "private_key_path" { default = "" } + +locals { + app_name_normalized = substr(replace(lower(var.oci_tag_values.freeformTags.AppName), " ", "-"), 0, 6) + app_name = var.oci_tag_values.freeformTags.AppName + deploy_id = var.oci_tag_values.freeformTags.DeploymentID + policy_compartment_OCID = var.compartment_ocid == "" ? var.tenancy_ocid : var.compartment_ocid + dynamic_group_name_normalized = substr(replace(lower(var.dynamic_group_name), " ", "-"), 0, 80) + policy_name_normalized = substr(replace(lower(var.policy_name), " ", "-"), 0, 80) +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-policies/versions.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-policies/versions.tf new file mode 100644 index 0000000..1bbfc06 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-policies/versions.tf @@ -0,0 +1,20 @@ +# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +terraform { + required_version = ">= 1.1" + required_providers { + oci = { + source = "oracle/oci" + version = "~> 4, < 5" + # https://registry.terraform.io/providers/oracle/oci/ + configuration_aliases = [oci.home_region] + } + local = { + source = "hashicorp/local" + version = "~> 2" + # https://registry.terraform.io/providers/hashicorp/local/ + } + } +} diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-vault-kms/main.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-vault-kms/main.tf new file mode 100644 index 0000000..8fedf88 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-vault-kms/main.tf @@ -0,0 +1,47 @@ +# Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +##************************************************************************** +## OCI KMS Vault +##************************************************************************** + +### OCI Vault vault +resource "oci_kms_vault" "oke_vault" { + compartment_id = var.oke_cluster_compartment_ocid + display_name = "${local.vault_display_name} - ${local.deploy_id}" + vault_type = local.vault_type[0] + freeform_tags = var.oci_tag_values.freeformTags + defined_tags = var.oci_tag_values.definedTags + + # depends_on = [oci_identity_policy.kms_user_group_compartment_policies] + + count = var.use_encryption_from_oci_vault ? (var.create_new_encryption_key ? 1 : 0) : 0 +} +### OCI Vault key +resource "oci_kms_key" "oke_key" { + compartment_id = var.oke_cluster_compartment_ocid + display_name = "${local.vault_key_display_name} - ${local.deploy_id}" + management_endpoint = oci_kms_vault.oke_vault[0].management_endpoint + protection_mode = local.vault_key_protection_mode + freeform_tags = var.oci_tag_values.freeformTags + defined_tags = var.oci_tag_values.definedTags + + key_shape { + algorithm = local.vault_key_key_shape_algorithm + length = local.vault_key_key_shape_length + } + + count = var.use_encryption_from_oci_vault ? (var.create_new_encryption_key ? 1 : 0) : 0 +} + +### Vault and Key definitions +locals { + vault_display_name = "OKE Vault" + vault_key_display_name = "OKE Key" + vault_key_key_shape_algorithm = "AES" + vault_key_key_shape_length = 32 + vault_type = ["DEFAULT", "VIRTUAL_PRIVATE"] + vault_key_protection_mode = "SOFTWARE" # HSM or SOFTWARE + oci_vault_key_id = var.use_encryption_from_oci_vault ? (var.create_new_encryption_key ? oci_kms_key.oke_key[0].id : var.existent_encryption_key_id) : "void" +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-vault-kms/outputs.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-vault-kms/outputs.tf new file mode 100644 index 0000000..4708c97 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-vault-kms/outputs.tf @@ -0,0 +1,7 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +output "oci_vault_key_id" { + value = var.use_encryption_from_oci_vault ? (var.create_new_encryption_key ? oci_kms_key.oke_key[0].id : var.existent_encryption_key_id) : null +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-vault-kms/policies.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-vault-kms/policies.tf new file mode 100644 index 0000000..1b175da --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-vault-kms/policies.tf @@ -0,0 +1,75 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +resource "oci_identity_dynamic_group" "app_dynamic_group" { + name = "${local.app_name_normalized}-kms-dg-${local.deploy_id}" + description = "${local.app_name} KMS for OKE Dynamic Group (${local.deploy_id})" + compartment_id = var.tenancy_ocid + matching_rule = "ANY {${join(",", local.dynamic_group_matching_rules)}}" + + provider = oci.home_region + + count = (var.use_encryption_from_oci_vault && var.create_dynamic_group_for_nodes_in_compartment) ? 1 : 0 +} +resource "oci_identity_policy" "app_compartment_policies" { + name = "${local.app_name_normalized}-kms-compartment-policies-${local.deploy_id}" + description = "${local.app_name} KMS for OKE Compartment Policies (${local.deploy_id})" + compartment_id = var.oke_cluster_compartment_ocid + statements = local.app_compartment_statements + + depends_on = [oci_identity_dynamic_group.app_dynamic_group] + + provider = oci.home_region + + count = (var.use_encryption_from_oci_vault && var.create_compartment_policies) ? 1 : 0 +} +resource "oci_identity_policy" "kms_user_group_compartment_policies" { + name = "${local.app_name_normalized}-kms-compartment-policies-${local.deploy_id}" + description = "${local.app_name} KMS User Group Compartment Policies (${local.deploy_id})" + compartment_id = var.oke_cluster_compartment_ocid + statements = local.kms_user_group_compartment_statements + + depends_on = [oci_identity_dynamic_group.app_dynamic_group] + + provider = oci.home_region + + count = (var.use_encryption_from_oci_vault && var.create_compartment_policies && var.create_vault_policies_for_group) ? 1 : 0 +} + +# Concat Matching Rules and Policy Statements +locals { + dynamic_group_matching_rules = concat( + local.instances_in_compartment_rule, + local.clusters_in_compartment_rule + ) + app_compartment_statements = concat( + local.allow_oke_use_oci_vault_keys_statements + ) + kms_user_group_compartment_statements = concat( + local.allow_group_manage_vault_keys_statements + ) +} + +# Individual Rules +locals { + instances_in_compartment_rule = ["ALL {instance.compartment.id = '${var.oke_cluster_compartment_ocid}'}"] + clusters_in_compartment_rule = ["ALL {resource.type = 'cluster', resource.compartment.id = '${var.oke_cluster_compartment_ocid}'}"] +} + +# Individual Policy Statements +locals { + allow_oke_use_oci_vault_keys_statements = [ + "Allow service oke to use vaults in compartment id ${var.oke_cluster_compartment_ocid}", + "Allow service oke to use keys in compartment id ${var.oke_cluster_compartment_ocid} where target.key.id = '${local.oci_vault_key_id}'", + "Allow service oke to use key-delegates in compartment id ${var.oke_cluster_compartment_ocid} where target.key.id = '${local.oci_vault_key_id}'", + "Allow service blockstorage to use keys in compartment id ${var.oke_cluster_compartment_ocid} where target.key.id = '${local.oci_vault_key_id}'", + "Allow dynamic-group ${local.app_dynamic_group} to use keys in compartment id ${var.oke_cluster_compartment_ocid} where target.key.id = '${local.oci_vault_key_id}'", + "Allow dynamic-group ${local.app_dynamic_group} to use key-delegates in compartment id ${var.oke_cluster_compartment_ocid} where target.key.id = '${local.oci_vault_key_id}'" + ] + allow_group_manage_vault_keys_statements = [ + "Allow group ${var.user_admin_group_for_vault_policy} to manage vaults in compartment id ${var.oke_cluster_compartment_ocid}", + "Allow group ${var.user_admin_group_for_vault_policy} to manage keys in compartment id ${var.oke_cluster_compartment_ocid}", + "Allow group ${var.user_admin_group_for_vault_policy} to use key-delegate in compartment id ${var.oke_cluster_compartment_ocid}" + ] +} diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-vault-kms/providers.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-vault-kms/providers.tf new file mode 100644 index 0000000..a18be62 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-vault-kms/providers.tf @@ -0,0 +1,20 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +terraform { + required_version = ">= 1.1" + required_providers { + oci = { + source = "oracle/oci" + version = "~> 4" + # https://registry.terraform.io/providers/oracle/oci/ + configuration_aliases = [oci.home_region] + } + local = { + source = "hashicorp/local" + version = "~> 2" + # https://registry.terraform.io/providers/hashicorp/local/ + } + } +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oci-vault-kms/variables.tf b/terraform-provider-oci/oke-quickstartz/modules/oci-vault-kms/variables.tf new file mode 100644 index 0000000..30cb73c --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oci-vault-kms/variables.tf @@ -0,0 +1,58 @@ +# Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +# OKE Encryption details +variable "use_encryption_from_oci_vault" { + default = false + description = "By default, Oracle manages the keys that encrypts Kubernetes Secrets at Rest in Etcd, but you can choose a key from a vault that you have access to, if you want greater control over the key's lifecycle and how it's used" +} +variable "create_new_encryption_key" { + default = false + description = "Creates new vault and key on OCI Vault/Key Management/KMS and assign to boot volume of the worker nodes" +} +variable "existent_encryption_key_id" { + default = "" + description = "Use an existent master encryption key to encrypt boot volume and object storage bucket. NOTE: If the key resides in a different compartment or in a different tenancy, make sure you have the proper policies to access, or the provision of the worker nodes will fail" +} + +# Deployment Details + Freeform Tags +variable "oci_tag_values" { + description = "Tags to be added to the resources" +} + +# OKE Variables +variable "oke_cluster_compartment_ocid" { + description = "Compartment OCID used by the OKE Cluster" + type = string +} + +# Policies variables +variable "create_vault_policies_for_group" { + default = false + description = "Creates policies to allow the user applying the stack to manage vault and keys. If you are on the Administrators group or already have the policies for a compartment, this policy is not needed. If you do not have access to allow the policy, ask your administrator to include it for you" +} +variable "user_admin_group_for_vault_policy" { + default = "Administrators" + description = "User Identity Group to allow manage vault and keys. The user running the Terraform scripts or Applying the ORM Stack need to be on this group" +} +## Create Dynamic Group and Policies +variable "create_dynamic_group_for_nodes_in_compartment" { + default = false + description = "Creates dynamic group of Nodes in the compartment. Note: You need to have proper rights on the Tenancy. If you only have rights in a compartment, uncheck and ask you administrator to create the Dynamic Group for you" +} +variable "create_compartment_policies" { + default = false + description = "Creates policies for KMS that will reside on the compartment." +} + +# OCI Provider +variable "tenancy_ocid" {} + +# Conditional locals +locals { + app_dynamic_group = (var.use_encryption_from_oci_vault && var.create_dynamic_group_for_nodes_in_compartment) ? oci_identity_dynamic_group.app_dynamic_group.0.name : "void" + app_name_normalized = substr(replace(lower(var.oci_tag_values.freeformTags.AppName), " ", "-"), 0, 6) + app_name = var.oci_tag_values.freeformTags.AppName + deploy_id = var.oci_tag_values.freeformTags.DeploymentID +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oke-cluster-autoscaler/datasources.tf b/terraform-provider-oci/oke-quickstartz/modules/oke-cluster-autoscaler/datasources.tf new file mode 100644 index 0000000..99ccee5 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oke-cluster-autoscaler/datasources.tf @@ -0,0 +1,8 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +# Gets supported Kubernetes versions for node pools +data "oci_containerengine_node_pool_option" "node_pool" { + node_pool_option_id = "all" +} diff --git a/terraform-provider-oci/oke-quickstartz/modules/oke-cluster-autoscaler/main.tf b/terraform-provider-oci/oke-quickstartz/modules/oke-cluster-autoscaler/main.tf new file mode 100644 index 0000000..cd8c7d6 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oke-cluster-autoscaler/main.tf @@ -0,0 +1,280 @@ +# Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +locals { + cluster_autoscaler_supported_k8s_versions = var.cluster_autoscaler_supported_k8s_versions # There's no API to get that list. Need to be updated manually + cluster_autoscaler_image_version = lookup(local.cluster_autoscaler_supported_k8s_versions, local.k8s_major_minor_version, reverse(values(local.cluster_autoscaler_supported_k8s_versions))[0]) + cluster_autoscaler_default_region = "us-ashburn-1" + cluster_autoscaler_image_regions = ["us-ashburn-1", "us-phoenix-1", "uk-london-1", "eu-frankfurt-1"] + cluster_autoscaler_image_region = contains(local.cluster_autoscaler_image_regions, var.region) ? var.region : local.cluster_autoscaler_default_region + cluster_autoscaler_image = var.custom_cluster_autoscaler_image != "" ? var.custom_cluster_autoscaler_image : "${local.cluster_autoscaler_image_region}.ocir.io/oracle/oci-cluster-autoscaler:${local.cluster_autoscaler_image_version}" + cluster_autoscaler_log_level_verbosity = var.cluster_autoscaler_log_level_verbosity + cluster_autoscaler_node_pools = [for map in var.oke_node_pools[*] : "--nodes=${map.node_pool_min_nodes}:${map.node_pool_max_nodes}:${map.node_pool_id}"] + cluster_autoscaler_max_node_provision_time = var.cluster_autoscaler_max_node_provision_time + cluster_autoscaler_scale_down_delay_after_add = var.cluster_autoscaler_scale_down_delay_after_add + cluster_autoscaler_scale_down_unneeded_time = var.cluster_autoscaler_scale_down_unneeded_time + cluster_autoscaler_unremovable_node_recheck_timeout = var.cluster_autoscaler_unremovable_node_recheck_timeout + cluster_autoscaler_enabled = alltrue([contains(keys(local.cluster_autoscaler_supported_k8s_versions), local.k8s_major_minor_version)]) ? anytrue(var.oke_node_pools[*].node_pool_autoscaler_enabled) : false + cluster_autoscaler_cloud_provider = local.k8s_major_minor_version < "1.24" ? "oci" : "oci-oke" + k8s_major_minor_version = regex("\\d+(?:\\.(?:\\d+|x)(?:))", try(var.oke_node_pools.0.node_k8s_version, "1.0")) +} + +# NOTE: Service Account Terraform resource is not supported with Kubernetes 1.24. +resource "kubernetes_service_account_v1" "cluster_autoscaler_sa" { + metadata { + name = "cluster-autoscaler" + namespace = "kube-system" + labels = { + k8s-addon = "cluster-autoscaler.addons.k8s.io" + k8s-app = "cluster-autoscaler" + } + } + automount_service_account_token = true # false + + count = local.cluster_autoscaler_enabled ? 1 : 0 +} +# resource "kubernetes_secret" "cluster_autoscaler_sa_secret" { +# metadata { +# name = "cluster-autoscaler-token-secret" +# namespace = "kube-system" +# annotations = { +# "kubernetes.io/service-account.name" = "cluster-autoscaler" +# "kubernetes.io/service-account.namespace" = "kube-system" +# } +# } +# type = "kubernetes.io/service-account-token" + +# depends_on = [kubernetes_service_account.cluster_autoscaler_sa] + +# count = local.cluster_autoscaler_enabled ? 1 : 0 +# } +resource "kubernetes_cluster_role" "cluster_autoscaler_cr" { + metadata { + name = "cluster-autoscaler" + labels = { + k8s-addon = "cluster-autoscaler.addons.k8s.io" + k8s-app = "cluster-autoscaler" + } + } + + rule { + api_groups = [""] + resources = ["events", "endpoints"] + verbs = ["create", "patch"] + } + rule { + api_groups = [""] + resources = ["pods/eviction"] + verbs = ["create"] + } + rule { + api_groups = [""] + resources = ["pods/status"] + verbs = ["update"] + } + rule { + api_groups = [""] + resource_names = ["cluster-autoscaler"] + resources = ["endpoints"] + verbs = ["get", "update"] + } + rule { + api_groups = [""] + resources = ["nodes"] + verbs = ["watch", "list", "get", "patch", "update"] + } + rule { + api_groups = [""] + resources = ["pods", "services", "replicationcontrollers", "persistentvolumeclaims", "persistentvolumes", "namespaces"] + verbs = ["watch", "list", "get"] + } + rule { + api_groups = ["extensions"] + resources = ["replicasets", "daemonsets"] + verbs = ["watch", "list", "get"] + } + rule { + api_groups = ["policy"] + resources = ["poddisruptionbudgets"] + verbs = ["watch", "list"] + } + rule { + api_groups = ["apps"] + resources = ["statefulsets", "replicasets", "daemonsets"] + verbs = ["watch", "list", "get"] + } + rule { + api_groups = ["storage.k8s.io"] + resources = ["storageclasses", "csinodes", "csidrivers", "csistoragecapacities"] + verbs = ["watch", "list", "get"] + } + rule { + api_groups = ["batch", "extensions"] + resources = ["jobs"] + verbs = ["get", "list", "watch", "patch"] + } + rule { + api_groups = ["coordination.k8s.io"] + resources = ["leases"] + verbs = ["create"] + } + rule { + api_groups = ["coordination.k8s.io"] + resource_names = ["cluster-autoscaler"] + resources = ["leases"] + verbs = ["get", "update"] + } + + count = local.cluster_autoscaler_enabled ? 1 : 0 +} +resource "kubernetes_role" "cluster_autoscaler_role" { + metadata { + name = "cluster-autoscaler" + namespace = "kube-system" + labels = { + k8s-addon = "cluster-autoscaler.addons.k8s.io" + k8s-app = "cluster-autoscaler" + } + } + + rule { + api_groups = [""] + resources = ["configmaps"] + verbs = ["create", "list", "watch"] + } + rule { + api_groups = [""] + resource_names = ["cluster-autoscaler-status", "cluster-autoscaler-priority-expander"] + resources = ["configmaps"] + verbs = ["delete", "get", "update", "watch"] + } + + count = local.cluster_autoscaler_enabled ? 1 : 0 +} +resource "kubernetes_cluster_role_binding" "cluster_autoscaler_crb" { + metadata { + name = "cluster-autoscaler" + labels = { + k8s-addon = "cluster-autoscaler.addons.k8s.io" + k8s-app = "cluster-autoscaler" + } + } + + role_ref { + api_group = "rbac.authorization.k8s.io" + kind = "ClusterRole" + name = "cluster-autoscaler" + } + subject { + kind = "ServiceAccount" + name = "cluster-autoscaler" + namespace = "kube-system" + } + + count = local.cluster_autoscaler_enabled ? 1 : 0 +} +resource "kubernetes_role_binding" "cluster_autoscaler_rb" { + metadata { + name = "cluster-autoscaler" + namespace = "kube-system" + labels = { + k8s-addon = "cluster-autoscaler.addons.k8s.io" + k8s-app = "cluster-autoscaler" + } + } + + role_ref { + api_group = "rbac.authorization.k8s.io" + kind = "Role" + name = "cluster-autoscaler" + } + subject { + kind = "ServiceAccount" + name = "cluster-autoscaler" + namespace = "kube-system" + } + + count = local.cluster_autoscaler_enabled ? 1 : 0 +} +resource "kubernetes_deployment" "cluster_autoscaler_deployment" { + metadata { + name = "cluster-autoscaler" + namespace = "kube-system" + labels = { + app = "cluster-autoscaler" + } + } + + spec { + replicas = var.cluster_autoscaler_num_of_replicas + + selector { + match_labels = { + app = "cluster-autoscaler" + } + } + + template { + metadata { + labels = { + app = "cluster-autoscaler" + } + annotations = { + "prometheus.io/scrape" = true + "prometheus.io/port" = 8085 + } + } + + spec { + service_account_name = "cluster-autoscaler" + + container { + image = local.cluster_autoscaler_image + name = "cluster-autoscaler" + + resources { + limits = { + cpu = "100m" + memory = "300Mi" + } + requests = { + cpu = "100m" + memory = "300Mi" + } + } + command = concat([ + "./cluster-autoscaler", + "--v=${local.cluster_autoscaler_log_level_verbosity}", + "--stderrthreshold=info", + "--cloud-provider=${local.cluster_autoscaler_cloud_provider}", + "--max-node-provision-time=${local.cluster_autoscaler_max_node_provision_time}", + "--scale-down-delay-after-add=${local.cluster_autoscaler_scale_down_delay_after_add}", + "--scale-down-unneeded-time=${local.cluster_autoscaler_scale_down_unneeded_time}", + "--unremovable-node-recheck-timeout=${local.cluster_autoscaler_unremovable_node_recheck_timeout}", + "--balance-similar-node-groups", + "--balancing-ignore-label=displayName", + "--balancing-ignore-label=hostname", + "--balancing-ignore-label=internal_addr", + "--balancing-ignore-label=oci.oraclecloud.com/fault-domain" + ], + local.cluster_autoscaler_node_pools, + var.cluster_autoscaler_extra_args) + image_pull_policy = "Always" + env { + name = "OKE_USE_INSTANCE_PRINCIPAL" + value = "true" + } + env { + name = "OCI_SDK_APPEND_USER_AGENT" + value = "oci-oke-cluster-autoscaler" + } + } + } + } + } + + wait_for_rollout = false + + count = local.cluster_autoscaler_enabled ? 1 : 0 +} diff --git a/terraform-provider-oci/oke-quickstartz/modules/oke-cluster-autoscaler/variables.tf b/terraform-provider-oci/oke-quickstartz/modules/oke-cluster-autoscaler/variables.tf new file mode 100644 index 0000000..4de2c7c --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oke-cluster-autoscaler/variables.tf @@ -0,0 +1,64 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +# OKE Variables +## OKE Autoscaler +# variable "cluster_autoscaler_enabled" { +# default = true +# description = "Enables OKE cluster autoscaler. Node pools will auto scale based on the resources usage" +# } +variable "cluster_autoscaler_supported_k8s_versions" { + type = map(string) + + default = { "1.23" = "1.23.0-4", "1.24" = "1.24.0-5", "1.25" = "1.25.0-6", "1.26" = "1.26.2-7" } # There's no API to get that list. Need to be updated manually + description = "Supported Kubernetes versions for OKE cluster autoscaler" +} +variable "custom_cluster_autoscaler_image" { + default = "" + description = "Custom Image for OKE cluster autoscaler" +} +variable "cluster_autoscaler_log_level_verbosity" { + default = 4 + description = "Log level verbosity for OKE cluster autoscaler" +} +variable "cluster_autoscaler_max_node_provision_time" { + default = "25m" + description = "Maximum time in minutes for a node to be provisioned. If the node is not ready after this time, it will be deleted and recreated" +} +variable "cluster_autoscaler_scale_down_delay_after_add" { + default = "10m" + description = "Time to wait after scale up before attempting to scale down" +} +variable "cluster_autoscaler_scale_down_unneeded_time" { + default = "10m" + description = "Time after which a node should be deleted after it has been unneeded for this long" +} +variable "cluster_autoscaler_unremovable_node_recheck_timeout" { + default = "5m" + description = "Time after which a node which failed to be removed is retried" +} +variable "cluster_autoscaler_num_of_replicas" { + default = 3 + description = "Number of replicas for OKE cluster autoscaler" +} +variable "cluster_autoscaler_extra_args" { + default = [] + description = "Extra arguments to pass to OKE cluster autoscaler" +} + +## OKE Node Pool Details +variable "oke_node_pools" { + type = list(any) + + default = [] + description = "Node pools (id, min_nodes, max_nodes, k8s_version) to use with Cluster Autoscaler" +} + +# OCI Provider +variable "region" {} + +# Get OKE options +locals { + node_pool_k8s_latest_version = reverse(sort(data.oci_containerengine_node_pool_option.node_pool.kubernetes_versions))[0] +} diff --git a/terraform-provider-oci/oke-quickstartz/modules/oke-cluster-autoscaler/versions.tf b/terraform-provider-oci/oke-quickstartz/modules/oke-cluster-autoscaler/versions.tf new file mode 100644 index 0000000..3bbc9e8 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oke-cluster-autoscaler/versions.tf @@ -0,0 +1,24 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +terraform { + required_version = ">= 1.1" + required_providers { + oci = { + source = "oracle/oci" + version = "~> 4, < 5" + # https://registry.terraform.io/providers/oracle/oci/ + } + kubernetes = { + source = "hashicorp/kubernetes" + version = "~> 2" + # https://registry.terraform.io/providers/hashicorp/kubernetes/ + } + local = { + source = "hashicorp/local" + version = "~> 2" + # https://registry.terraform.io/providers/hashicorp/local/ + } + } +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oke-node-pool/datasources.tf b/terraform-provider-oci/oke-quickstartz/modules/oke-node-pool/datasources.tf new file mode 100644 index 0000000..41e1d80 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oke-node-pool/datasources.tf @@ -0,0 +1,55 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +# Gets supported Kubernetes versions for node pools +data "oci_containerengine_node_pool_option" "node_pool" { + node_pool_option_id = "all" +} + +# Gets a list of supported images based on the shape, operating_system and operating_system_version provided +data "oci_core_images" "node_pool_images" { + compartment_id = var.oke_cluster_compartment_ocid + operating_system = var.image_operating_system + operating_system_version = var.image_operating_system_version + shape = var.node_pool_shape + sort_by = "TIMECREATED" + sort_order = "DESC" +} + +# Gets a list of Availability Domains +data "oci_identity_availability_domains" "ADs" { + compartment_id = var.tenancy_ocid +} +# Gets a specfic Availability Domain +data "oci_identity_availability_domain" "specfic" { + compartment_id = var.tenancy_ocid + ad_number = var.node_pool_shape_specific_ad + + count = (var.node_pool_shape_specific_ad > 0) ? 1 : 0 +} + +# Prepare Cloud Unit for Node Pool nodes +data "cloudinit_config" "nodes" { + gzip = true + base64_encode = true + + part { + content_type = "text/x-shellscript" + content = </var/run/oke-init.sh +bash /var/run/oke-init.sh ${var.node_pool_oke_init_params} +/usr/libexec/oci-growfs -y +EOF + } + + dynamic "part" { + for_each = var.node_pool_cloud_init_parts + content { + content_type = part.value["content_type"] + content = part.value["content"] + filename = part.value["filename"] + } + } +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oke-node-pool/main.tf b/terraform-provider-oci/oke-quickstartz/modules/oke-node-pool/main.tf new file mode 100644 index 0000000..8fe4a89 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oke-node-pool/main.tf @@ -0,0 +1,102 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +# File Version: 0.7.1 + +resource "oci_containerengine_node_pool" "oke_node_pool" { + cluster_id = var.oke_cluster_ocid + compartment_id = var.oke_cluster_compartment_ocid + kubernetes_version = local.node_k8s_version + name = var.node_pool_name + node_shape = var.node_pool_shape + ssh_public_key = var.public_ssh_key + freeform_tags = var.node_pools_tags.freeformTags + defined_tags = var.node_pools_tags.definedTags + + node_config_details { + dynamic "placement_configs" { + for_each = local.node_pool_ads # data.oci_identity_availability_domains.ADs.availability_domains + + content { + availability_domain = placement_configs.value.name + subnet_id = var.nodes_subnet_id + } + } + node_pool_pod_network_option_details { + cni_type = var.cni_type + max_pods_per_node = 0 # 31 + pod_nsg_ids = [] + pod_subnet_ids = var.vcn_native_pod_networking_subnet_ocid != null ? [var.vcn_native_pod_networking_subnet_ocid] : [] #[var.vcn_native_pod_networking_subnet_ocid] + } + # nsg_ids = [] + size = 3 # var.node_pool_min_nodes + # is_pv_encryption_in_transit_enabled = var.node_pool_node_config_details_is_pv_encryption_in_transit_enabled + kms_key_id = var.oci_vault_key_id_oke_node_boot_volume != "" ? var.oci_vault_key_id_oke_node_boot_volume : null + freeform_tags = var.worker_nodes_tags.freeformTags + defined_tags = var.worker_nodes_tags.definedTags + } + + dynamic "node_shape_config" { + for_each = local.is_flexible_node_shape ? [1] : [] + content { + ocpus = var.node_pool_node_shape_config_ocpus + memory_in_gbs = var.node_pool_node_shape_config_memory_in_gbs + } + } + + # node_source_details { + # source_type = "IMAGE" + # image_id = "ocid1.image.oc1.ca-toronto-1.aaaaaaaaeonnf55icwpffvzbzfgva7fkf5mrnd7f53ope255vjmpbufcqlna" #lookup(data.oci_core_images.node_pool_images.images[0], "id") + # boot_volume_size_in_gbs = var.node_pool_boot_volume_size_in_gbs + # } + + # node_eviction_node_pool_settings { + # eviction_grace_duration = var.node_pool_node_eviction_node_pool_settings_eviction_grace_duration #PT60M + # is_force_delete_after_grace_duration = var.node_pool_node_eviction_node_pool_settings_is_force_delete_after_grace_duration #false + # } + + node_metadata = { + user_data = anytrue([var.node_pool_oke_init_params != "", var.node_pool_cloud_init_parts != []]) ? data.cloudinit_config.nodes.rendered : null + } + + # node_pool_cycling_details { + # is_node_cycling_enabled = var.node_pool_node_pool_cycling_details_is_node_cycling_enabled + # maximum_surge = var.node_pool_node_pool_cycling_details_maximum_surge + # maximum_unavailable = var.node_pool_node_pool_cycling_details_maximum_unavailable + # } + + initial_node_labels { + key = "name" + value = var.node_pool_name + } + + dynamic "initial_node_labels" { + for_each = var.extra_initial_node_labels + + content { + key = initial_node_labels.value.key + value = initial_node_labels.value.value + } + } + + lifecycle { + ignore_changes = [ + node_config_details.0.size + ] + } + + count = var.create_new_node_pool ? 1 : 0 +} + +locals { + # Checks if is using Flexible Compute Shapes + is_flexible_node_shape = contains(split(".", var.node_pool_shape), "Flex") + + # Gets the latest Kubernetes version supported by the node pool + node_pool_k8s_latest_version = reverse(sort(data.oci_containerengine_node_pool_option.node_pool.kubernetes_versions))[0] + node_k8s_version = (var.node_k8s_version == "Latest") ? local.node_pool_k8s_latest_version : var.node_k8s_version + + # Get ADs for the shape to be used on the node pool + node_pool_ads = (var.node_pool_shape_specific_ad > 0) ? data.oci_identity_availability_domain.specfic : data.oci_identity_availability_domains.ADs.availability_domains +} diff --git a/terraform-provider-oci/oke-quickstartz/modules/oke-node-pool/outputs.tf b/terraform-provider-oci/oke-quickstartz/modules/oke-node-pool/outputs.tf new file mode 100644 index 0000000..0a983b3 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oke-node-pool/outputs.tf @@ -0,0 +1,22 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +output "node_pool_name" { + value = var.create_new_node_pool ? oci_containerengine_node_pool.oke_node_pool.0.name : var.existent_oke_nodepool_id_for_autoscaler +} +output "node_pool_min_nodes" { + value = var.node_pool_min_nodes +} +output "node_pool_max_nodes" { + value = var.node_pool_max_nodes +} +output "node_pool_id" { + value = var.create_new_node_pool ? oci_containerengine_node_pool.oke_node_pool.0.id : var.existent_oke_nodepool_id_for_autoscaler +} +output "node_k8s_version" { + value = local.node_k8s_version +} +output "node_pool_autoscaler_enabled" { + value = var.node_pool_autoscaler_enabled +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oke-node-pool/variables.tf b/terraform-provider-oci/oke-quickstartz/modules/oke-node-pool/variables.tf new file mode 100644 index 0000000..bd8d7b7 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oke-node-pool/variables.tf @@ -0,0 +1,145 @@ +# Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +# OKE Variables +variable "oke_cluster_ocid" { + description = "OKE cluster OCID" + type = string +} +variable "oke_cluster_compartment_ocid" { + description = "Compartment OCID used by the OKE Cluster" + type = string +} + +## Node Pool Variables +variable "create_new_node_pool" { + default = true + description = "Create a new node pool if true or use an existing one if false" +} +variable "node_k8s_version" { + description = "Kubernetes version installed on your worker nodes" + type = string + default = "v1.29.1" #"Latest" +} +variable "node_pool_name" { + default = "pool1" + description = "Name of the node pool" +} +variable "extra_initial_node_labels" { + default = {} + description = "Extra initial node labels to be added to the node pool" +} +variable "node_pool_min_nodes" { + default = 2 #3 + description = "The number of worker nodes in the node pool. If select Cluster Autoscaler, will assume the minimum number of nodes configured" +} +variable "node_pool_max_nodes" { + default = 2 + description = "The max number of worker nodes in the node pool if using Cluster Autoscaler." +} +variable "node_pool_shape" { + default = "VM.Standard.E4.Flex" + description = "A shape is a template that determines the number of OCPUs, amount of memory, and other resources allocated to a newly created instance for the Worker Node" +} +variable "node_pool_node_shape_config_ocpus" { + default = "2" # Only used if flex shape is selected + description = "You can customize the number of OCPUs to a flexible shape" +} +variable "node_pool_node_shape_config_memory_in_gbs" { + default = "16" # Only used if flex shape is selected + description = "You can customize the amount of memory allocated to a flexible shape" +} +variable "node_pool_shape_specific_ad" { + description = "The number of the AD to get the shape for the node pool" + type = number + default = 0 + + validation { + condition = var.node_pool_shape_specific_ad >= 0 && var.node_pool_shape_specific_ad <= 3 + error_message = "Invalid AD number, should be 0 to get all ADs or 1, 2 or 3 to be a specific AD." + } +} +variable "cni_type" { + default = "FLANNEL_OVERLAY" + description = "The CNI type to use for the cluster. Valid values are: FLANNEL_OVERLAY or OCI_VCN_IP_NATIVE" + + validation { + condition = var.cni_type == "FLANNEL_OVERLAY" || var.cni_type == "OCI_VCN_IP_NATIVE" + error_message = "Sorry, but OKE currently only supports FLANNEL_OVERLAY or OCI_VCN_IP_NATIVE CNI types." + } +} +variable "existent_oke_nodepool_id_for_autoscaler" { + default = "" + description = "Nodepool Id of the existent OKE to use with Cluster Autoscaler" +} +variable "node_pool_autoscaler_enabled" { + default = true + description = "Enable Cluster Autoscaler for the node pool" +} +variable "image_operating_system" { + default = "Oracle Linux" + description = "The OS/image installed on all nodes in the node pool." +} +variable "image_operating_system_version" { + default = "8" + description = "The OS/image version installed on all nodes in the node pool." +} +variable "node_pool_boot_volume_size_in_gbs" { + default = "50" + description = "Specify a custom boot volume size (in GB)" +} +variable "node_pool_oke_init_params" { + type = string + default = "" + description = "OKE Init params" +} +variable "node_pool_cloud_init_parts" { + type = list(object({ + content_type = string + content = string + filename = string + })) + default = [] + description = "Node Pool nodes Cloud init parts" +} +variable "public_ssh_key" { + default = "" + description = "In order to access your private nodes with a public SSH key you will need to set up a bastion host (a.k.a. jump box). If using public nodes, bastion is not needed. Left blank to not import keys." +} + +# OKE Network Variables +variable "nodes_subnet_id" { description = "Nodes Subnet OCID to deploy OKE Cluster" } +variable "vcn_native_pod_networking_subnet_ocid" { + # default = "" + description = "VCN Native Pod Networking Subnet OCID used by the OKE Cluster" + default = null + + validation { + condition = can(regex("^ocid1.subnet.oc1..*", var.vcn_native_pod_networking_subnet_ocid)) || var.vcn_native_pod_networking_subnet_ocid == null + error_message = "The subnet OCID must be a valid OCI subnet OCID or null." + } +} + +# Customer Manager Encryption Keys +variable "oci_vault_key_id_oke_node_boot_volume" { + description = "OCI Vault Key OCID used to encrypt the OKE node boot volume" + type = string + default = null +} + +# OCI Provider +variable "tenancy_ocid" {} + +# App Name Locals +locals { + app_name_normalized = substr(replace(lower(var.node_pools_tags.freeformTags.AppName), " ", "-"), 0, 6) +} + +# Deployment Details + Freeform Tags +variable "node_pools_tags" { + description = "Tags to be added to the node pools resources" +} +variable "worker_nodes_tags" { + description = "Tags to be added to the worker nodes resources" +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oke-node-pool/versions.tf b/terraform-provider-oci/oke-quickstartz/modules/oke-node-pool/versions.tf new file mode 100644 index 0000000..1c3fd8b --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oke-node-pool/versions.tf @@ -0,0 +1,19 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +terraform { + required_version = ">= 1.1" + required_providers { + oci = { + source = "oracle/oci" + version = "~> 4, < 5" + # https://registry.terraform.io/providers/oracle/oci/ + } + local = { + source = "hashicorp/local" + version = "~> 2" + # https://registry.terraform.io/providers/hashicorp/local/ + } + } +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oke/LICENSE b/terraform-provider-oci/oke-quickstartz/modules/oke/LICENSE new file mode 100644 index 0000000..bfd500d --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oke/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + +The Universal Permissive License (UPL), Version 1.0 + +Subject to the condition set forth below, permission is hereby granted to any person obtaining a copy of this +software, associated documentation and/or data (collectively the "Software"), free of charge and under any and +all copyright rights in the Software, and any and all patent rights owned or freely licensable by each licensor +hereunder covering either (i) the unmodified Software as contributed to or provided by such licensor, or +(ii) the Larger Works (as defined below), to deal in both + +(a) the Software, and +(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if one is included with the Software +(each a “Larger Work” to which the Software is contributed by such licensors), + +without restriction, including without limitation the rights to copy, create derivative works of, display, +perform, and distribute the Software and make, use, sell, offer for sale, import, export, have made, and have +sold the Software and the Larger Work(s), and to sublicense the foregoing rights on either these or other terms. + +This license is subject to the following condition: +The above copyright notice and either this complete permission notice or at a minimum a reference to the UPL must +be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/terraform-provider-oci/oke-quickstartz/modules/oke/README.md b/terraform-provider-oci/oke-quickstartz/modules/oke/README.md new file mode 100644 index 0000000..4c4812c --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oke/README.md @@ -0,0 +1,53 @@ +# Terraform OKE Submodule + +This module deploys an OKE Kubernetes cluster. + +## Usage + +```hcl +module "oke" { + source = "./modules/oke" + + providers = { + oci = oci + oci.home_region = oci.home_region + } + + # Oracle Cloud Infrastructure Tenancy and Compartment OCID + tenancy_ocid = var.tenancy_ocid + compartment_ocid = local.oke_compartment_ocid + region = var.region + + # Deployment Tags + Freeform Tags + Defined Tags + cluster_tags = local.oci_tag_values + load_balancers_tags = local.oci_tag_values + block_volumes_tags = local.oci_tag_values + + # OKE Cluster + ## create_new_oke_cluster + create_new_oke_cluster = var.create_new_oke_cluster + existent_oke_cluster_id = var.existent_oke_cluster_id + + ## Network Details + vcn_id = module.vcn.vcn_id + network_cidrs = local.network_cidrs + k8s_endpoint_subnet_id = local.create_subnets ? module.subnets["oke_k8s_endpoint_subnet"].subnet_id : var.existent_oke_k8s_endpoint_subnet_ocid + lb_subnet_id = local.create_subnets ? module.subnets["oke_lb_subnet"].subnet_id : var.existent_oke_load_balancer_subnet_ocid + cni_type = local.cni_type + ### Cluster Workers visibility + cluster_workers_visibility = var.cluster_workers_visibility + ### Cluster API Endpoint visibility + cluster_endpoint_visibility = var.cluster_endpoint_visibility + + ## Control Plane Kubernetes Version + k8s_version = var.k8s_version + + ## Create Dynamic group and Policies for Autoscaler and OCI Metrics and Logging + create_dynamic_group_for_nodes_in_compartment = var.create_dynamic_group_for_nodes_in_compartment + create_compartment_policies = var.create_compartment_policies + + ## Encryption (OCI Vault/Key Management/KMS) + oci_vault_key_id_oke_secrets = module.vault.oci_vault_key_id + oci_vault_key_id_oke_image_policy = module.vault.oci_vault_key_id +} +``` diff --git a/terraform-provider-oci/oke-quickstartz/modules/oke/datasources.tf b/terraform-provider-oci/oke-quickstartz/modules/oke/datasources.tf new file mode 100644 index 0000000..429869b --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oke/datasources.tf @@ -0,0 +1,20 @@ +# Copyright (c) 2021-2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +data "oci_containerengine_cluster_option" "oke" { + cluster_option_id = "all" +} +data "oci_containerengine_clusters" "oke" { + compartment_id = local.oke_compartment_ocid +} + +# Gets a list of Availability Domains +data "oci_identity_availability_domains" "ADs" { + compartment_id = var.tenancy_ocid +} + +# Gets kubeconfig +data "oci_containerengine_cluster_kube_config" "oke" { + cluster_id = var.create_new_oke_cluster ? oci_containerengine_cluster.oke_cluster[0].id : var.existent_oke_cluster_id +} diff --git a/terraform-provider-oci/oke-quickstartz/modules/oke/main.tf b/terraform-provider-oci/oke-quickstartz/modules/oke/main.tf new file mode 100644 index 0000000..75d18f6 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oke/main.tf @@ -0,0 +1,73 @@ +# Copyright (c) 2021-2023 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +# File Version: 0.9.2 + +resource "oci_containerengine_cluster" "oke_cluster" { + compartment_id = local.oke_compartment_ocid + kubernetes_version = (var.k8s_version == "Latest") ? local.cluster_k8s_latest_version : var.k8s_version + name = "${local.app_name} (${local.deploy_id})" + vcn_id = var.vcn_id + kms_key_id = var.oci_vault_key_id_oke_secrets != "" ? var.oci_vault_key_id_oke_secrets : null + type = var.cluster_type + freeform_tags = var.cluster_tags.freeformTags + defined_tags = var.cluster_tags.definedTags + + endpoint_config { + is_public_ip_enabled = (var.cluster_endpoint_visibility == "Private") ? false : true + subnet_id = var.k8s_endpoint_subnet_id + nsg_ids = [] + } + options { + service_lb_subnet_ids = [var.lb_subnet_id] + add_ons { + is_kubernetes_dashboard_enabled = var.cluster_options_add_ons_is_kubernetes_dashboard_enabled + is_tiller_enabled = false # Default is false, left here for reference + } + admission_controller_options { + is_pod_security_policy_enabled = var.cluster_options_admission_controller_options_is_pod_security_policy_enabled + } + kubernetes_network_config { + services_cidr = lookup(var.network_cidrs, "KUBERNETES-SERVICE-CIDR") + pods_cidr = lookup(var.network_cidrs, "PODS-CIDR") + } + persistent_volume_config { + freeform_tags = var.block_volumes_tags.freeformTags + # defined_tags = var.block_volumes_tags.definedTags + } + service_lb_config { + freeform_tags = var.load_balancers_tags.freeformTags + # defined_tags = var.load_balancers_tags.definedTags + } + } + image_policy_config { + is_policy_enabled = false + # key_details { + # # kms_key_id = var.oci_vault_key_id_oke_image_policy != "" ? var.oci_vault_key_id_oke_image_policy : null + # } + } + cluster_pod_network_options { + cni_type = var.cni_type + } + + lifecycle { + ignore_changes = [freeform_tags, defined_tags, kubernetes_version, id] + } + + count = var.create_new_oke_cluster ? 1 : 0 +} + +# Local kubeconfig for when using Terraform locally. Not used by Oracle Resource Manager +resource "local_file" "oke_kubeconfig" { + content = data.oci_containerengine_cluster_kube_config.oke.content + filename = "${path.root}/generated/kubeconfig" + file_permission = "0644" +} + +# Get OKE options +locals { + cluster_k8s_latest_version = reverse(sort(data.oci_containerengine_cluster_option.oke.kubernetes_versions))[0] + deployed_k8s_version = var.create_new_oke_cluster ? ((var.k8s_version == "Latest") ? local.cluster_k8s_latest_version : var.k8s_version) : [ + for x in data.oci_containerengine_clusters.oke.clusters : x.kubernetes_version if x.id == var.existent_oke_cluster_id][0] +} diff --git a/terraform-provider-oci/oke-quickstartz/modules/oke/oke-orm-private-endpoint.tf b/terraform-provider-oci/oke-quickstartz/modules/oke/oke-orm-private-endpoint.tf new file mode 100644 index 0000000..1ba70d7 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oke/oke-orm-private-endpoint.tf @@ -0,0 +1,28 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +### Important Notice ### +# OCI Resource Manager Private Endpoint is only available when using Resource Manager. +# If you use local Terraform, you will need to setup an OCI Bastion for connectivity to the Private OKE. +# If using OCI CloudShell, you need to activate the OCI Private Endpoint for OCI CLoud Shell. + +resource "oci_resourcemanager_private_endpoint" "private_kubernetes_endpoint" { + compartment_id = local.oke_compartment_ocid + display_name = "Private Endpoint for OKE ${local.app_name} - ${local.deploy_id}" + description = "Resource Manager Private Endpoint for OKE for the ${local.app_name} - ${local.deploy_id}" + vcn_id = var.vcn_id + subnet_id = var.k8s_endpoint_subnet_id + freeform_tags = var.cluster_tags.freeformTags + defined_tags = var.cluster_tags.definedTags + + count = var.create_new_oke_cluster ? ((var.cluster_endpoint_visibility == "Private") ? 1 : 0) : 0 +} + +# Resolves the private IP of the customer's private endpoint to a NAT IP. +data "oci_resourcemanager_private_endpoint_reachable_ip" "private_kubernetes_endpoint" { + private_endpoint_id = var.create_new_oke_cluster ? oci_resourcemanager_private_endpoint.private_kubernetes_endpoint[0].id : var.existent_oke_cluster_private_endpoint + private_ip = trimsuffix(oci_containerengine_cluster.oke_cluster[0].endpoints.0.private_endpoint, ":6443") # TODO: Pending rule when has existent cluster + + count = (var.cluster_endpoint_visibility == "Private") ? 1 : 0 +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oke/outputs.tf b/terraform-provider-oci/oke-quickstartz/modules/oke/outputs.tf new file mode 100644 index 0000000..f8176c8 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oke/outputs.tf @@ -0,0 +1,41 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +output "comments" { + value = "The application URL will be unavailable for a few minutes after provisioning while the application is configured and deployed to Kubernetes" +} +output "deployed_oke_kubernetes_version" { + value = local.deployed_k8s_version +} +output "deployed_to_region" { + value = var.region +} +output "dev" { + value = "Made with \u2764 by Oracle Developers" +} +output "kubeconfig" { + value = data.oci_containerengine_cluster_kube_config.oke.content +} +output "kubeconfig_for_kubectl" { + value = "export KUBECONFIG=${path.root}/generated/kubeconfig" + description = "If using Terraform locally, this command set KUBECONFIG environment variable to run kubectl locally" +} +output "orm_private_endpoint_oke_api_ip_address" { + value = (var.cluster_endpoint_visibility == "Private") ? data.oci_resourcemanager_private_endpoint_reachable_ip.private_kubernetes_endpoint.0.ip_address : "" + description = "OCI Resource Manager Private Endpoint ip address for OKE Kubernetes API Private Endpoint" + + depends_on = [ + oci_resourcemanager_private_endpoint.private_kubernetes_endpoint + ] +} + +# OKE info +output "oke_cluster_ocid" { + value = var.create_new_oke_cluster ? oci_containerengine_cluster.oke_cluster[0].id : "" + description = "OKE Cluster OCID" +} +output "oke_cluster_compartment_ocid" { + value = local.oke_compartment_ocid + description = "Compartment OCID used by the OKE Cluster" +} diff --git a/terraform-provider-oci/oke-quickstartz/modules/oke/variables.tf b/terraform-provider-oci/oke-quickstartz/modules/oke/variables.tf new file mode 100644 index 0000000..c78d318 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oke/variables.tf @@ -0,0 +1,139 @@ +# Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +# OCI Provider +variable "tenancy_ocid" {} +variable "compartment_ocid" {} +variable "region" {} + +# Network Details +variable "vcn_id" { description = "VCN OCID to deploy OKE Cluster" } +variable "k8s_endpoint_subnet_id" { description = "Kubernetes Endpoint Subnet OCID to deploy OKE Cluster" } +variable "lb_subnet_id" { description = "Load Balancer Subnet OCID to deploy OKE Cluster" } +variable "cluster_workers_visibility" { + default = "Private" + description = "The Kubernetes worker nodes that are created will be hosted in public or private subnet(s)" +} +variable "cluster_endpoint_visibility" { + default = "Public" + description = "The Kubernetes cluster that is created will be hosted on a public subnet with a public IP address auto-assigned or on a private subnet. If Private, additional configuration will be necessary to run kubectl commands" +} +variable "network_cidrs" {} +variable "cni_type" { + default = "FLANNEL_OVERLAY" + description = "The CNI type to use for the cluster. Valid values are: FLANNEL_OVERLAY or OCI_VCN_IP_NATIVE" + + validation { + condition = var.cni_type == "FLANNEL_OVERLAY" || var.cni_type == "OCI_VCN_IP_NATIVE" + error_message = "Sorry, but OKE currently only supports FLANNEL_OVERLAY or OCI_VCN_IP_NATIVE CNI types." + } +} + +# OKE Variables +## OKE Cluster Details +variable "create_new_oke_cluster" { + default = false + description = "Creates a new OKE cluster and node pool" +} +variable "existent_oke_cluster_id" { + default = "" + description = "Using existent OKE Cluster. Only the application and services will be provisioned. If select cluster autoscaler feature, you need to get the node pool id and enter when required" +} +variable "cluster_type" { + default = "BASIC_CLUSTER" + description = "The type of OKE cluster to create. Valid values are: BASIC_CLUSTER or ENHANCED_CLUSTER" +} +variable "create_orm_private_endpoint" { + default = false + description = "Creates a new private endpoint for the OKE cluster" +} +variable "existent_oke_cluster_private_endpoint" { + default = "" + description = "Resource Manager Private Endpoint to access the OKE Private Cluster" +} +variable "create_new_compartment_for_oke" { + default = false + description = "Creates new compartment for OKE Nodes and OCI Services deployed. NOTE: The creation of the compartment increases the deployment time by at least 3 minutes, and can increase by 15 minutes when destroying" +} +variable "oke_compartment_description" { + default = "Compartment for OKE, Nodes and Services" +} +variable "cluster_options_add_ons_is_kubernetes_dashboard_enabled" { + default = false +} +variable "cluster_options_admission_controller_options_is_pod_security_policy_enabled" { + description = "If true: The pod security policy admission controller will use pod security policies to restrict the pods accepted into the cluster." + default = false +} + +## OKE Encryption details +variable "oci_vault_key_id_oke_secrets" { + default = null + description = "OCI Vault OCID to encrypt OKE secrets. If not provided, the secrets will be encrypted with the default key" +} +variable "oci_vault_key_id_oke_image_policy" { + default = null + description = "OCI Vault OCID for the Image Policy" +} + +variable "create_vault_policies_for_group" { + default = false + description = "Creates policies to allow the user applying the stack to manage vault and keys. If you are on the Administrators group or already have the policies for a compartment, this policy is not needed. If you do not have access to allow the policy, ask your administrator to include it for you" +} +variable "user_admin_group_for_vault_policy" { + default = "Administrators" + description = "User Identity Group to allow manage vault and keys. The user running the Terraform scripts or Applying the ORM Stack need to be on this group" +} + +variable "k8s_version" { + default = "Latest" + description = "Kubernetes version installed on your Control Plane" +} + +# Create Dynamic Group and Policies +# variable "create_dynamic_group_for_nodes_in_compartment" { +# default = false # TODO: true +# description = "Creates dynamic group of Nodes in the compartment. Note: You need to have proper rights on the Tenancy. If you only have rights in a compartment, uncheck and ask you administrator to create the Dynamic Group for you" +# } +# variable "existent_dynamic_group_for_nodes_in_compartment" { +# default = "" +# description = "Enter previous created Dynamic Group for the policies" +# } +# variable "create_compartment_policies" { +# default = false # TODO: true +# description = "Creates policies that will reside on the compartment. e.g.: Policies to support Cluster Autoscaler, OCI Logging datasource on Grafana" +# } +# variable "create_tenancy_policies" { +# default = false # TODO: true +# description = "Creates policies that need to reside on the tenancy. e.g.: Policies to support OCI Metrics datasource on Grafana" +# } + +# ORM Schema visual control variables +variable "show_advanced" { + default = false +} + +# App Name Locals +locals { + app_name = var.cluster_tags.freeformTags.AppName + deploy_id = var.cluster_tags.freeformTags.DeploymentID + app_name_normalized = substr(replace(lower(var.cluster_tags.freeformTags.AppName), " ", "-"), 0, 6) + app_name_for_dns = substr(lower(replace(var.cluster_tags.freeformTags.AppName, "/\\W|_|\\s/", "")), 0, 6) +} + +# OKE Compartment +locals { + oke_compartment_ocid = var.compartment_ocid +} + +# Deployment Details + Freeform Tags +variable "cluster_tags" { + description = "Tags to be added to the cluster resources" +} +variable "load_balancers_tags" { + description = "Tags to be added to the load balancers resources" +} +variable "block_volumes_tags" { + description = "Tags to be added to the block volumes resources" +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/modules/oke/versions.tf b/terraform-provider-oci/oke-quickstartz/modules/oke/versions.tf new file mode 100644 index 0000000..dcf32b0 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/modules/oke/versions.tf @@ -0,0 +1,19 @@ +# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +terraform { + required_version = ">= 1.1" + required_providers { + oci = { + source = "oracle/oci" + version = "~> 4, < 5" + # https://registry.terraform.io/providers/oracle/oci/ + } + local = { + source = "hashicorp/local" + version = "~> 2" + # https://registry.terraform.io/providers/hashicorp/local/ + } + } +} diff --git a/terraform-provider-oci/oke-quickstartz/oci-networking.tf b/terraform-provider-oci/oke-quickstartz/oci-networking.tf new file mode 100644 index 0000000..583eb39 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/oci-networking.tf @@ -0,0 +1,157 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +# File Version: 0.9.0 + +# Dependencies: +# - defaults.tf file +# - local.create_new_vcn +# - local.create_subnets +# - local.resolved_vcn_compartment_ocid +# - local.subnets +# - local.route_tables +# - local.security_lists +# - terraform-oci-networking module + +################################################################################ +# +# *** Note: Normally, you should not need to edit this file. *** +# +################################################################################ +## MODIFICATIONS: +## +## Date Name Description +## (DD/MM/YYYY) +## ---------- ------------------------ -------------------------------------- +## 28/05/2024 Kosseila HD (CLoudDude) repatriated networtking modules back to the repo +## from :github.com/oracle-quickstart/terraform-oci-networking//modules/*?ref=0.2.0 +############################################################################################ +################################################################################ +# Module: Virtual Cloud Network (VCN) +################################################################################ +module "vcn" { + source = "./modules/oci-networking/vcn" + # Oracle Cloud Infrastructure Tenancy and Compartment OCID + compartment_ocid = local.vcn_compartment_ocid + # Deployment Tags + Freeform Tags + Defined Tags + vcn_tags = local.oci_tag_values + # Virtual Cloud Network (VCN) arguments + create_new_vcn = local.create_new_vcn + existent_vcn_ocid = var.existent_vcn_ocid + cidr_blocks = local.pre_vcn_cidr_blocks + display_name = local.vcn_display_name + dns_label = "${local.app_name_for_dns}${local.deploy_id}" + is_ipv6enabled = var.is_ipv6enabled + ipv6private_cidr_blocks = var.ipv6private_cidr_blocks +} + +################################################################################ +# Module: Subnets +################################################################################ +module "subnets" { + for_each = { for map in local.subnets : map.subnet_name => map } + source = "./modules/oci-networking/subnet" + # Oracle Cloud Infrastructure Tenancy and Compartment OCID + compartment_ocid = local.vcn_compartment_ocid + vcn_id = module.vcn.vcn_id + # Deployment Tags + Freeform Tags + Defined Tags + subnet_tags = local.oci_tag_values + # Subnet arguments + create_subnet = local.create_subnets + subnet_name = each.value.subnet_name + cidr_block = each.value.cidr_block + display_name = each.value.display_name # If null, is autogenerated + dns_label = each.value.dns_label # If null, is autogenerated + prohibit_public_ip_on_vnic = each.value.prohibit_public_ip_on_vnic + prohibit_internet_ingress = each.value.prohibit_internet_ingress + route_table_id = (anytrue([(each.value.alternative_route_table_name == ""), (each.value.alternative_route_table_name == null)]) + ? each.value.route_table_id + : module.route_tables[each.value.alternative_route_table_name].route_table_id) # If null, the VCN's default route table is used + dhcp_options_id = each.value.dhcp_options_id # If null, the VCN's default set of DHCP options is used + security_list_ids = concat(each.value.security_list_ids, [for v in each.value.extra_security_list_names : module.security_lists[v].security_list_id]) # If null, the VCN's default security list is used + ipv6cidr_block = each.value.ipv6cidr_block # If null, no IPv6 CIDR block is assigned + # security_list_ids = (anytrue([(each.value.alternative_security_list == ""), (each.value.alternative_security_list == null)]) # If null, the VCN's default security list is used + # ? each.value.security_list_ids + # : [module.security_lists[each.value.alternative_security_list].security_list_id]) +} + +################################################################################ +# Module: Gateways +################################################################################ +module "gateways" { + source = "./modules/oci-networking/gateway" + + # Oracle Cloud Infrastructure Tenancy and Compartment OCID + compartment_ocid = local.vcn_compartment_ocid + vcn_id = module.vcn.vcn_id + + # Deployment Tags + Freeform Tags + Defined Tags + gateways_tags = local.oci_tag_values + + # Internet Gateway + create_internet_gateway = local.create_subnets + internet_gateway_display_name = "Internet Gateway (${local.deploy_id})" + internet_gateway_enabled = true + + # NAT Gateway + create_nat_gateway = local.create_subnets + nat_gateway_display_name = "NAT Gateway (${local.deploy_id})" + nat_gateway_public_ip_id = null + + # Service Gateway + create_service_gateway = local.create_subnets + service_gateway_display_name = "Service Gateway (${local.deploy_id})" + + # Local Peering Gateway (LPG) + create_local_peering_gateway = false + local_peering_gateway_display_name = "Local Peering Gateway (${local.deploy_id})" + local_peering_gateway_peer_id = null +} + +################################################################################ +# Module: Route Tables +################################################################################ +module "route_tables" { + for_each = { for map in local.route_tables : map.route_table_name => map } + source = "./modules/oci-networking/route_table" + + # Oracle Cloud Infrastructure Tenancy and Compartment OCID + compartment_ocid = local.vcn_compartment_ocid + vcn_id = module.vcn.vcn_id + + # Deployment Tags + Freeform Tags + Defined Tags + route_table_tags = local.oci_tag_values + + # Route Table attributes + create_route_table = local.create_subnets + route_table_name = each.value.route_table_name + display_name = each.value.display_name + route_rules = each.value.route_rules +} + +################################################################################ +# Module: Security Lists +################################################################################ +module "security_lists" { + for_each = { for map in local.security_lists : map.security_list_name => map } + source = "./modules/oci-networking/security_list" + + # Oracle Cloud Infrastructure Tenancy and Compartment OCID + compartment_ocid = local.vcn_compartment_ocid + vcn_id = module.vcn.vcn_id + + # Deployment Tags + Freeform Tags + Defined Tags + security_list_tags = local.oci_tag_values + + # Security List attributes + create_security_list = local.create_subnets + security_list_name = each.value.security_list_name + display_name = each.value.display_name + egress_security_rules = each.value.egress_security_rules + ingress_security_rules = each.value.ingress_security_rules +} + +locals { + vcn_compartment_ocid = var.create_new_vcn ? local.resolved_vcn_compartment_ocid : var.existent_vcn_compartment_ocid +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/outputs.tf b/terraform-provider-oci/oke-quickstartz/outputs.tf new file mode 100644 index 0000000..2872d64 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/outputs.tf @@ -0,0 +1,56 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +# Deployment outputs +output "stack_version" { + value = file("${path.module}/VERSION") +} +output "deploy_id" { + value = local.deploy_id +} + +# OKE Outputs +output "comments" { + value = module.oke.comments +} +output "deployed_oke_kubernetes_version" { + value = module.oke.deployed_oke_kubernetes_version +} +output "deployed_to_region" { + value = module.oke.deployed_to_region +} +output "kubeconfig" { + value = module.oke.kubeconfig + sensitive = true +} +output "kubeconfig_for_kubectl" { + value = module.oke.kubeconfig_for_kubectl + description = "If using Terraform locally, this command set KUBECONFIG environment variable to run kubectl locally" +} +output "oke_cluster_ocid" { + value = module.oke.oke_cluster_ocid +} +output "oke_node_pools" { + value = module.oke_node_pools +} +output "subnets" { + value = module.subnets +} + +output "dev" { + value = module.oke.dev +} +### Important Security Notice ### +# The private key generated by this resource will be stored unencrypted in your Terraform state file. +# Use of this resource for production deployments is not recommended. +# Instead, generate a private key file outside of Terraform and distribute it securely to the system where Terraform will be run. +output "generated_private_key_pem" { + value = var.generate_public_ssh_key ? tls_private_key.oke_worker_node_ssh_key.private_key_pem : "No Keys Auto Generated" + sensitive = true +} + + +output "cluster_type_value" { + value = var.cluster_type +} diff --git a/terraform-provider-oci/oke-quickstartz/policies.tf b/terraform-provider-oci/oke-quickstartz/policies.tf new file mode 100644 index 0000000..9bf2d6f --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/policies.tf @@ -0,0 +1,62 @@ +# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +module "cluster-dynamic-group" { + source = "./modules/oci-policies" + + providers = { + oci = oci + oci.home_region = oci.home_region + } + + # Oracle Cloud Infrastructure Tenancy + tenancy_ocid = var.tenancy_ocid + + # Deployment Tags + Freeform Tags + Defined Tags + oci_tag_values = local.oci_tag_values + + create_dynamic_group = true + dynamic_group_name = "OKE Cluster Nodes" + dynamic_group_matching_rules = [ + "ALL {instance.compartment.id = '${local.oke_compartment_ocid}'}", + "ALL {resource.type = 'cluster', resource.compartment.id = '${local.oke_compartment_ocid}'}" + ] + + count = var.create_dynamic_group_for_nodes_in_compartment ? 1 : 0 +} + +module "cluster-compartment-policies" { + source = "./modules/oci-policies" + + providers = { + oci = oci + oci.home_region = oci.home_region + } + + # Oracle Cloud Infrastructure Tenancy and Compartment OCID + tenancy_ocid = var.tenancy_ocid + compartment_ocid = local.oke_compartment_ocid + + oci_tag_values = local.oci_tag_values + + create_policy = true + policy_name = "OKE Cluster Compartment Policies" + policy_statements = [ + "Allow dynamic-group ${local.dynamic_group_name} to manage cluster-node-pools in compartment id ${local.oke_compartment_ocid}", + "Allow dynamic-group ${local.dynamic_group_name} to manage instance-family in compartment id ${local.oke_compartment_ocid}", + "Allow dynamic-group ${local.dynamic_group_name} to use subnets in compartment id ${local.oke_compartment_ocid}", + "Allow dynamic-group ${local.dynamic_group_name} to read virtual-network-family in compartment id ${local.oke_compartment_ocid}", + "Allow dynamic-group ${local.dynamic_group_name} to use vnics in compartment id ${local.oke_compartment_ocid}", + "Allow dynamic-group ${local.dynamic_group_name} to inspect compartments in compartment id ${local.oke_compartment_ocid}", + "Allow dynamic-group ${local.dynamic_group_name} to use network-security-groups in compartment id ${local.oke_compartment_ocid}", + "Allow dynamic-group ${local.dynamic_group_name} to use private-ips in compartment id ${local.oke_compartment_ocid}", + "Allow dynamic-group ${local.dynamic_group_name} to manage public-ips in compartment id ${local.oke_compartment_ocid}" + ] + + count = var.create_compartment_policies ? 1 : 0 +} + +locals { + dynamic_group_name = var.create_dynamic_group_for_nodes_in_compartment ? module.cluster-dynamic-group.0.dynamic_group_name : var.existent_dynamic_group_for_nodes_in_compartment +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/providers.tf b/terraform-provider-oci/oke-quickstartz/providers.tf new file mode 100644 index 0000000..160758b --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/providers.tf @@ -0,0 +1,69 @@ +# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +provider "oci" { + tenancy_ocid = var.tenancy_ocid + region = var.region +} + +provider "oci" { + alias = "home_region" + tenancy_ocid = var.tenancy_ocid + region = lookup(data.oci_identity_regions.home_region.regions[0], "name") + + user_ocid = var.user_ocid + fingerprint = var.fingerprint + private_key_path = var.private_key_path +} + +# New configuration to avoid Terraform Kubernetes provider interpolation. https://registry.terraform.io/providers/hashicorp/kubernetes/2.2.0/docs#stacking-with-managed-kubernetes-cluster-resources +# Currently need to uncheck to refresh (--refresh=false) when destroying or else the terraform destroy will fail + +# https://docs.cloud.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengdownloadkubeconfigfile.htm#notes +provider "kubernetes" { + host = local.cluster_endpoint + cluster_ca_certificate = local.cluster_ca_certificate + insecure = local.external_private_endpoint + exec { + api_version = "client.authentication.k8s.io/v1beta1" + args = ["ce", "cluster", "generate-token", "--cluster-id", local.cluster_id, "--region", local.cluster_region] + command = "oci" + } +} + +# https://docs.cloud.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengdownloadkubeconfigfile.htm#notes +provider "helm" { + kubernetes { + host = local.cluster_endpoint + cluster_ca_certificate = local.cluster_ca_certificate + insecure = local.external_private_endpoint + exec { + api_version = "client.authentication.k8s.io/v1beta1" + args = ["ce", "cluster", "generate-token", "--cluster-id", local.cluster_id, "--region", local.cluster_region] + command = "oci" + } + } +} + +locals { + cluster_endpoint = (var.cluster_endpoint_visibility == "Private") ? ( + "https://${module.oke.orm_private_endpoint_oke_api_ip_address}:6443") : ( + yamldecode(module.oke.kubeconfig)["clusters"][0]["cluster"]["server"]) + external_private_endpoint = (var.cluster_endpoint_visibility == "Private") ? true : false + cluster_ca_certificate = base64decode(yamldecode(module.oke.kubeconfig)["clusters"][0]["cluster"]["certificate-authority-data"]) + cluster_id = yamldecode(module.oke.kubeconfig)["users"][0]["user"]["exec"]["args"][4] + cluster_region = yamldecode(module.oke.kubeconfig)["users"][0]["user"]["exec"]["args"][6] +} + +# Gets home and current regions +data "oci_identity_tenancy" "tenant_details" { + tenancy_id = var.tenancy_ocid +} + +data "oci_identity_regions" "home_region" { + filter { + name = "key" + values = [data.oci_identity_tenancy.tenant_details.home_region_key] + } +} diff --git a/terraform-provider-oci/oke-quickstartz/schema.yaml b/terraform-provider-oci/oke-quickstartz/schema.yaml new file mode 100644 index 0000000..95547f5 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/schema.yaml @@ -0,0 +1,927 @@ +# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +title: "OKE BASE Stack" +description: "OKE BASE Stack" +informationalText: "This stack deploys a new OKE Cluster with cluster tools or just the cluster tools on an existent OKE Cluster." +schemaVersion: 1.1.0 +version: "20190304" + +source: + type: quickstart + +locale: "en" +variableGroups: + - title: "Basic Hidden" + variables: + - tenancy_ocid + - region + visible: false + + - title: "General Configuration" + variables: + - app_name + - show_advanced + + - title: "OKE Cluster Configuration" + variables: + - create_new_oke_cluster + - compartment_ocid + - existent_oke_cluster_id + - k8s_version + - create_new_compartment_for_oke + - node_pool_cni_type_1 + + - title: "OKE Network Configuration" + variables: + - cluster_workers_visibility + - cluster_endpoint_visibility + - existent_oke_cluster_vcn + - create_orm_private_endpoint + - existent_oke_cluster_private_endpoint + - cluster_load_balancer_visibility + - create_new_vcn + - existent_vcn_compartment_ocid + - existent_vcn_ocid + - vcn_cidr_blocks + - create_subnets + - existent_oke_k8s_endpoint_subnet_ocid + - existent_oke_nodes_subnet_ocid + - existent_oke_load_balancer_subnet_ocid + + - title: "OKE Network - Hidden" + variables: + - is_ipv6enabled + - ipv6private_cidr_blocks + - existent_oke_vcn_native_pod_networking_subnet_ocid + - existent_oke_fss_mount_targets_subnet_ocid + visible: false + + - title: "OKE Worker Nodes" + variables: + - node_pool_autoscaler_enabled_1 + - existent_oke_nodepool_id_for_autoscaler_1 + - node_pool_initial_num_worker_nodes_1 + - node_pool_max_num_worker_nodes_1 + - node_pool_instance_shape_1 + - generate_public_ssh_key + - public_ssh_key + - image_operating_system_1 + - image_operating_system_version_1 + - node_pool_name_1 + + - title: "OKE Worker Nodes - Hidden" + variables: + - extra_node_pools + - extra_route_tables + - extra_security_list_name_for_api_endpoint + - extra_security_list_name_for_nodes + - extra_security_list_name_for_vcn_native_pod_networking + - extra_security_lists + - extra_subnets + - node_pool_oke_init_params_1 + visible: false + + - title: "Dynamic Group and Policies" + variables: + - create_dynamic_group_for_nodes_in_compartment + - existent_dynamic_group_for_nodes_in_compartment + - create_compartment_policies + + - title: "Encryption using OCI Vault (KMS)" + variables: + - use_encryption_from_oci_vault + - create_new_encryption_key + - existent_encryption_key_vault + - existent_encryption_key_id + - create_vault_policies_for_group + - user_admin_group_for_vault_policy + + - title: "Cluster Tools - Ingress Controller" + variables: + - ingress_nginx_enabled + - ingress_load_balancer_shape + - ingress_load_balancer_shape_flex_min + - ingress_load_balancer_shape_flex_max + + - title: "Cluster Tools - Ingress" + variables: + - ingress_hosts_include_nip_io + - use_custom_nip_io_domain + - nip_io_domain + - ingress_hosts + - cert_manager_enabled + - ingress_tls + - ingress_cluster_issuer + - ingress_email_issuer + + - title: "Cluster Tools" + variables: + - metrics_server_enabled + - prometheus_enabled + - grafana_enabled + + - title: "Tagging" + variables: + - tag_values + + - title: "Extras Hidden" + variables: + - user_ocid + - fingerprint + - private_key_path + - node_pool_boot_volume_size_in_gbs_1 + - oke_compartment_description + - cluster_cni_type + - create_pod_network_subnet + - extra_initial_node_labels_1 + - node_pool_shape_specific_ad_1 + - pods_network_visibility + visible: false + +variables: + # compartment_ocid: + # type: oci:identity:compartment:id + # title: "Compartment" + # description: "The compartment in which to create compute instance(s)" + # required: true + + app_name: + type: string + title: "Cluster Name Prefix" + required: true + visible: + and: + - create_new_oke_cluster + + show_advanced: + type: boolean + title: "Show advanced options?" + description: "Shows advanced options, allowing enable customer-managed encryption keys, select your ssh key, select/unselect cluster utilities, do not create policies, and other advanced options" + visible: true + + # OKE Cluster Configuration + create_new_oke_cluster: + type: boolean + title: "Create new OKE Cluster" + + compartment_ocid: + type: oci:identity:compartment:id + title: "Existent OKE Cluster Compartment" + description: "The compartment where you find the existent OKE Cluster" + required: true + visible: + not: + - create_new_oke_cluster + + existent_oke_cluster_id: + type: oci:container:cluster:id + title: "Existent OKE Cluster" + required: true + dependsOn: + compartmentId: compartment_ocid + visible: + not: + - create_new_oke_cluster + + k8s_version: + type: oci:kubernetes:versions:id + title: "Kubernetes Version" + required: false + dependsOn: + compartmentId: compartment_ocid + clusterOptionId: "all" + visible: + and: + - create_new_oke_cluster + - show_advanced + + create_new_compartment_for_oke: + type: boolean + title: "Create new Compartment" + visible: + and: + - create_new_oke_cluster + - show_advanced + + # OKE Network + cluster_workers_visibility: + type: enum + enum: + - "Private" + - "Public" + title: "Choose Worker Nodes visibility type" + required: true + visible: + and: + - create_new_oke_cluster + + cluster_endpoint_visibility: + type: enum + enum: + - "Private" + - "Public" + title: "Choose Kubernetes API Endpoint visibility type" + required: true + # visible: + # and: + # - create_new_oke_cluster + + existent_oke_cluster_vcn: + type: oci:core:vcn:id + title: "Existent OKE Cluster VCN for Private Endpoint" + required: true + dependsOn: + compartmentId: compartment_ocid + visible: + and: + - not: + - create_new_oke_cluster + - eq: + - cluster_endpoint_visibility + - "Private" + + create_orm_private_endpoint: + type: boolean + title: "Create ORM Private Endpoint for Kubernetes API Endpoint" + visible: + eq: + - cluster_endpoint_visibility + - "Private" + + existent_oke_cluster_private_endpoint: + type: oci:resourcemanager:privateendpoint:id + title: "Existent OKE Cluster ORM Private Endpoint" + required: true + dependsOn: + compartmentId: compartment_ocid + vcnId: existent_oke_cluster_vcn + visible: + and: + - not: + - create_new_oke_cluster + - create_orm_private_endpoint + - eq: + - cluster_endpoint_visibility + - "Private" + + cluster_load_balancer_visibility: + type: enum + enum: + - "Private" + - "Public" + title: "Choose Load Balancers visibility type" + required: true + visible: false + # and: + # - create_new_oke_cluster + # - show_advanced + + create_new_vcn: + type: boolean + title: "Create new Virtual Cloud Network (VCN)?" + visible: + and: + - create_new_oke_cluster + - show_advanced + + existent_vcn_compartment_ocid: + type: oci:identity:compartment:id + title: "Existent VCN Compartment" + required: true + default: compartment_ocid + visible: + and: + - and: + - create_new_oke_cluster + - show_advanced + - not: + - create_new_vcn + + existent_vcn_ocid: + type: oci:core:vcn:id + title: "Existent VCN to be used for OKE Cluster" + required: true + dependsOn: + compartmentId: existent_vcn_compartment_ocid + visible: + and: + - and: + - create_new_oke_cluster + - show_advanced + - not: + - create_new_vcn + + vcn_cidr_blocks: + type: string + title: VCN CIDR BLOCK + required: true + default: 10.20.0.0/16 + pattern: "^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\/(3[0-2]|[1-2]?[0-9])$" + visible: + and: + - create_new_oke_cluster + - create_new_vcn + - show_advanced + + create_subnets: + type: boolean + title: "Create all subnets for the OKE VCN?" + visible: + and: + - and: + - create_new_oke_cluster + - show_advanced + - not: + - create_new_vcn + + existent_oke_k8s_endpoint_subnet_ocid: + type: oci:core:subnet:id + title: "Existent subnet for Kubernetes API Endpoint" + required: true + dependsOn: + compartmentId: existent_vcn_compartment_ocid + vcnId: existent_vcn_ocid + visible: + and: + - and: + - create_new_oke_cluster + - show_advanced + - not: + - create_subnets + - not: + - create_new_vcn + + existent_oke_nodes_subnet_ocid: + type: oci:core:subnet:id + title: "Existent subnet for OKE Worker Nodes" + required: true + dependsOn: + compartmentId: existent_vcn_compartment_ocid + vcnId: existent_vcn_ocid + visible: + and: + - and: + - create_new_oke_cluster + - show_advanced + - not: + - create_subnets + - not: + - create_new_vcn + + existent_oke_load_balancer_subnet_ocid: + type: oci:core:subnet:id + title: "Existent subnet for Load Balancers created by Kubernetes" + required: true + dependsOn: + compartmentId: existent_vcn_compartment_ocid + vcnId: existent_vcn_ocid + visible: + and: + - and: + - create_new_oke_cluster + - show_advanced + - not: + - create_subnets + - not: + - create_new_vcn + + existent_oke_vcn_native_pod_networking_subnet_ocid: + type: oci:core:subnet:id + title: "(Required if using OCI_VCN_IP_NATIVE CNI) Existent subnet for VCN Native Pod Networking" + required: false + dependsOn: + compartmentId: existent_vcn_compartment_ocid + vcnId: existent_vcn_ocid + visible: + and: + - and: + - create_new_oke_cluster + - show_advanced + - eq: + - node_pool_cni_type_1 + - "OCI_VCN_IP_NATIVE" + - not: + - create_subnets + - not: + - create_new_vcn + + # OKE Worker Nodes - Node Pool + node_pool_autoscaler_enabled_1: + type: boolean + title: "Enable Cluster Autoscaler for Node Pool" + # visible: + # and: + # - create_new_oke_cluster + + node_pool_initial_num_worker_nodes_1: + type: integer + title: "Initial or min Number of Worker Nodes" + minimum: 1 + maximum: 1000 + required: true + visible: create_new_oke_cluster + + node_pool_max_num_worker_nodes_1: + type: integer + title: "Autoscaler: Maximum number of nodes" + minimum: 1 + maximum: 1000 + required: true + visible: + and: + - create_new_oke_cluster + - node_pool_autoscaler_enabled_1 + + existent_oke_nodepool_id_for_autoscaler_1: + type: string + title: "OKE Nodepool id" + required: true + visible: + and: + - and: + - node_pool_autoscaler_enabled_1 + - not: + - create_new_oke_cluster + + # node_pool_shape: + # type: oci:core:instanceshape:name + # title: "Select a shape for the Worker Nodes instances" + # required: true + # dependsOn: + # compartmentId: compartment_ocid + # visible: + # and: + # - create_new_oke_cluster + + node_pool_instance_shape_1: + type: oci:core:instanceshapewithflex:name + title: "Select a flex or fixed shape for the Worker Nodes instances" + required: true + dependsOn: + compartmentId: compartment_ocid + visible: + and: + - create_new_oke_cluster + - show_advanced + + # node_pool_node_shape_config_ocpus: + # type: integer + # minimum: 1 + # maximum: 64 + # title: "Number of OCPUs" + # visible: + # and: + # - and: + # - create_new_oke_cluster + # - or: + # - eq: + # - node_pool_shape + # - "VM.Standard.E3.Flex" + # - eq: + # - node_pool_shape + # - "VM.Standard.E4.Flex" + # - eq: + # - node_pool_shape + # - "VM.Standard.A1.Flex" + + # node_pool_node_shape_config_memory_in_gbs: + # type: integer + # minimum: 1 + # maximum: 1024 + # title: "Amount of memory (GB)" + # visible: + # and: + # - and: + # - create_new_oke_cluster + # - or: + # - eq: + # - node_pool_shape + # - "VM.Standard.E3.Flex" + # - eq: + # - node_pool_shape + # - "VM.Standard.E4.Flex" + # - eq: + # - node_pool_shape + # - "VM.Standard.A1.Flex" + + node_pool_name_1: + type: string + title: "Node Pool Name" + required: true + visible: + and: + - create_new_oke_cluster + - show_advanced + + node_pool_cni_type_1: + type: enum + title: "Cluster (and Node Pool) CNI Type" + enum: + - "FLANNEL_OVERLAY" + - "OCI_VCN_IP_NATIVE" + required: true + visible: + and: + - create_new_oke_cluster + - show_advanced + + cluster_options_add_ons_is_kubernetes_dashboard_enabled: + type: boolean + title: "Kubernetes Dashboard Enabled" + visible: false + + generate_public_ssh_key: + type: boolean + title: "Auto generate public ssh key?" + required: true + visible: + and: + - create_new_oke_cluster + - show_advanced + + public_ssh_key: + type: oci:core:ssh:publickey + title: "Import your own SSH public key" + additionalProps: + allowMultiple: true + required: false + pattern: "((^(ssh-rsa AAAAB3NzaC1yc2|ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNT|ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzOD|ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1Mj|ssh-ed25519 AAAAC3NzaC1lZDI1NTE5|ssh-dss AAAAB3NzaC1kc3)[0-9A-Za-z+\/]+[=]{0,3})( [^,]*)?)(,((ssh-rsa AAAAB3NzaC1yc2|ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNT|ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzOD|ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1Mj|ssh-ed25519 AAAAC3NzaC1lZDI1NTE5|ssh-dss AAAAB3NzaC1kc3)[0-9A-Za-z+\/]+[=]{0,3})( [^,]*)?)*$" + visible: + and: + - and: + - create_new_oke_cluster + - show_advanced + - not: + - generate_public_ssh_key + + image_operating_system_1: + type: enum + title: "Image OS" + enum: + - "Oracle Linux" + required: true + visible: + and: + - create_new_oke_cluster + - show_advanced + + image_operating_system_version_1: + type: string + title: "Image OS Version" + required: true + visible: + and: + - create_new_oke_cluster + - show_advanced + + # Dynamic Groups and Policies for Instance Principals and Autoscaler + create_dynamic_group_for_nodes_in_compartment: + type: boolean + title: "Create Dynamic Group for Worker Nodes in the Compartment" + required: true + visible: + and: + - show_advanced + + existent_dynamic_group_for_nodes_in_compartment: + type: string + title: "Existent Dynamic Group" + required: true + visible: + and: + - and: + - show_advanced + - or: + - create_compartment_policies + - not: + - create_dynamic_group_for_nodes_in_compartment + + create_compartment_policies: + type: boolean + title: "Create Compartment Policies" + required: true + visible: + and: + - show_advanced + + # Encryption options + use_encryption_from_oci_vault: + type: boolean + title: "Encrypt using Customer-Managed Encryption Keys instead of OracleManaged Encryption Keys" + visible: + and: + - create_new_oke_cluster + - show_advanced + + create_new_encryption_key: + type: boolean + title: "Create new Vault and Key" + visible: + and: + - create_new_oke_cluster + - show_advanced + - use_encryption_from_oci_vault + + existent_encryption_key_vault: + type: oci:kms:vault:id + title: "Existent Encryption Key Vault" + required: true + dependsOn: + compartmentId: compartment_ocid + visible: + and: + - and: + - create_new_oke_cluster + - show_advanced + - use_encryption_from_oci_vault + - not: + - create_new_encryption_key + + existent_encryption_key_id: + type: oci:kms:key:id + title: "Existent Encryption Key OCID" + required: true + dependsOn: + compartmentId: compartment_ocid + vaultId: existent_encryption_key_vault + visible: + and: + - and: + - create_new_oke_cluster + - show_advanced + - use_encryption_from_oci_vault + - not: + - create_new_encryption_key + + create_vault_policies_for_group: + type: boolean + title: "Create policies for the user group to manage vault and keys" + visible: + and: + - create_new_oke_cluster + - show_advanced + - use_encryption_from_oci_vault + - create_new_encryption_key + + user_admin_group_for_vault_policy: + type: string + title: "Specify your group to include the policy" + visible: + and: + - create_new_oke_cluster + - show_advanced + - use_encryption_from_oci_vault + - create_new_encryption_key + - create_vault_policies_for_group + + # Cluster Tools - Ingress + ingress_nginx_enabled: + type: boolean + title: "Ingress NGINX Controller" + + ingress_load_balancer_shape: + type: enum + enum: + - "flexible" + - "10Mbps" + - "100Mbps" + - "400Mbps" + - "8000Mbps" + title: "Select a shape for the load balancer created by the Ingress Controller" + visible: + and: + - show_advanced + - ingress_nginx_enabled + + ingress_load_balancer_shape_flex_min: + type: integer + minimum: 10 + maximum: 8000 + title: "Choose the minimum bandwidth" + required: true + visible: + and: + - and: + - show_advanced + - ingress_nginx_enabled + - eq: + - ingress_load_balancer_shape + - "flexible" + + ingress_load_balancer_shape_flex_max: + type: integer + minimum: 10 + maximum: 8000 + title: "Choose the maximum bandwidth" + required: true + visible: + and: + - and: + - show_advanced + - ingress_nginx_enabled + - eq: + - ingress_load_balancer_shape + - "flexible" + + ingress_hosts_include_nip_io: + type: boolean + title: "Optional dynamic DNS valid domain name?" + visible: + and: + - ingress_nginx_enabled + + use_custom_nip_io_domain: + type: boolean + title: "Use custom nip.io domain suffix?" + description: If you want to use a custom nip.io domain suffix, you must first deploy a nip.io service with a custom domain. + default: false + visible: + and: + - show_advanced + - ingress_nginx_enabled + - ingress_hosts_include_nip_io + + nip_io_domain: + type: string + title: "Dynamic wildcard DNS service domain" + visible: + and: + - show_advanced + - ingress_nginx_enabled + - ingress_hosts_include_nip_io + - use_custom_nip_io_domain + + ingress_hosts: + type: string + title: "Optional valid domain name" + visible: + and: + - show_advanced + - ingress_nginx_enabled + + cert_manager_enabled: + type: boolean + title: "Certificate Management" + visible: + and: + - ingress_nginx_enabled + + ingress_tls: + type: boolean + title: "Use TLS to enable HTTPS on the valid domain name" + visible: + and: + - show_advanced + - ingress_nginx_enabled + - cert_manager_enabled + + ingress_cluster_issuer: + type: enum + enum: + - "letsencrypt-prod" + - "letsencrypt-staging" + - "selfsigned" + title: "Certificate Issuer" + required: true + visible: + and: + - show_advanced + - ingress_nginx_enabled + - ingress_tls + - cert_manager_enabled + + ingress_email_issuer: + type: string + title: "Certificate Issuer Email" + required: true + visible: + and: + - show_advanced + - ingress_nginx_enabled + - ingress_tls + - cert_manager_enabled + + # Cluster Tools + metrics_server_enabled: + type: boolean + title: "Metrics Server" + + prometheus_enabled: + type: boolean + title: "Prometheus" + + grafana_enabled: + type: boolean + title: "Grafana" + + tag_values: + type: oci:identity:tag:value + title: Tag Resources + required: false + visible: show_advanced + dependsOn: + compartmentId: compartment_ocid + +outputGroups: + - title: Deployment Info + outputs: + - deploy_id + - deployed_to_region + - stack_version + + - title: Kubernetes + outputs: + - deployed_oke_kubernetes_version + - kubeconfig + + - title: Passwords and Keys + outputs: + - grafana_admin_password + - generated_private_key_pem + + - title: Comments + outputs: + - comments + + - title: Dev Notes + outputs: + - dev + +outputs: + external_ip: + type: string + title: Ingress LoadBalancer External IP + displayText: Ingress Nginx LoadBalancer External IP Address + visible: true + + grafana_url: + type: link + title: Grafana + displayText: Dashboards + visible: true + + grafana_admin_password: + type: string + title: Grafana Admin Password + displayText: Grafana Admin Password + visible: true + + deploy_id: + type: string + title: "Deployment Id" + visible: true + + deployed_to_region: + type: string + title: "Deployed using Region" + visible: true + + deployed_oke_kubernetes_version: + type: string + title: "OKE Kubernetes version deployed" + visible: true + + stack_version: + type: string + title: Stack Version + displayText: Stack Version deployed + visible: true + + generated_private_key_pem: + type: string + title: Generated Private Key + displayText: Generated Private Key + + comments: + type: string + title: Comments + displayText: Comments + visible: true + + dev: + type: string + title: dev + displayText: dev note from Oracle Developers + visible: true + + kubeconfig: + type: string + title: kubeconfig + displayText: kubeconfig for local kubectl run. Not used by ORM + visible: true + + kubeconfig_for_kubectl: + type: string + title: kubeconfig + displayText: kubeconfig for local kubectl run. Not used by ORM + visible: false + + sensitive_comments_local_tf: + type: string + title: kubeconfig + displayText: Instructions to get sensitive outputs on local Terraform. Not used by ORM + visible: false + +primaryOutputButton: mushop_url_button diff --git a/terraform-provider-oci/oke-quickstartz/terraform.tfvars b/terraform-provider-oci/oke-quickstartz/terraform.tfvars new file mode 100644 index 0000000..cec2dfd --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/terraform.tfvars @@ -0,0 +1,12 @@ +# # Oracle Cloud Infrastructure Authentication +# tenancy_ocid = "ocid1.tenancy.oc1.." # CHANGE ME +# user_ocid = "ocid1.user.oc1.." # CHANGE ME +# fingerprint = "1c:" # CHANGE ME +# private_key_path = "~/oci_api_key.pem" # CHANGE ME +# ssh_public_key = "~/id_rsa.pub" # CHANGE ME +# compartment_ocid = "ocid1.compartment.oc1." # CHANGE ME +# # Region +# region = "ca-toronto-1" # CHANGE ME +# # AD +# availability_domain = "CA-TORONTO-1-AD-1" # CHANGE ME +#cluster_type= "ENHANCED_CLUSTER" \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/variables.tf b/terraform-provider-oci/oke-quickstartz/variables.tf new file mode 100644 index 0000000..6ddf480 --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/variables.tf @@ -0,0 +1,354 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +################################################################################ +# OCI Provider Variables +################################################################################ +variable "tenancy_ocid" {} +variable "compartment_ocid" {} +variable "region" {} +variable "user_ocid" { + default = "" +} +variable "fingerprint" { + default = "" +} +variable "private_key_path" { + default = "" +} +variable "home_region" { + default = "" +} + + +################################################################################ +# App Name to identify deployment. Used for naming resources. +################################################################################ +variable "app_name" { + default = "K8s App" + type = string + description = "Application name. Will be used as prefix to identify resources, such as OKE, VCN, ATP, and others" +} +variable "tag_values" { + type = map(any) + default = { "freeformTags" = { + "Environment" = "Development", # e.g.: Demo, Sandbox, Development, QA, Stage, ... + "DeploymentType" = "generic" }, # e.g.: App Type 1, App Type 2, Red, Purple, ... + "definedTags" = {} } + description = "Use Tagging to add metadata to resources. All resources created by this stack will be tagged with the selected tag values." +} + +################################################################################ +# Variables: OCI Networking +################################################################################ +## VCN +variable "create_new_vcn" { + default = true + description = "Creates a new Virtual Cloud Network (VCN). If false, the VCN must be provided in the variable 'existent_vcn_ocid'." +} +variable "existent_vcn_ocid" { + default = "" + description = "Using existent Virtual Cloud Network (VCN) OCID." +} +variable "existent_vcn_compartment_ocid" { + default = "" + description = "Compartment OCID for existent Virtual Cloud Network (VCN)." +} +variable "vcn_cidr_blocks" { + default = "10.20.0.0/16" + description = "IPv4 CIDR Blocks for the Virtual Cloud Network (VCN). If use more than one block, separate them with comma. e.g.: 10.20.0.0/16,10.80.0.0/16. If you plan to peer this VCN with another VCN, the VCNs must not have overlapping CIDRs." +} +variable "is_ipv6enabled" { + default = false + description = "Whether IPv6 is enabled for the Virtual Cloud Network (VCN)." +} +variable "ipv6private_cidr_blocks" { + default = [] + description = "The list of one or more ULA or Private IPv6 CIDR blocks for the Virtual Cloud Network (VCN)." +} +## Subnets +variable "create_subnets" { + default = true + description = "Create subnets for OKE: Endpoint, Nodes, Load Balancers. If CNI Type OCI_VCN_IP_NATIVE, also creates the PODs VCN. If FSS Mount Targets, also creates the FSS Mount Targets Subnet" +} +variable "create_pod_network_subnet" { + default = false + description = "Create PODs Network subnet for OKE. To be used with CNI Type OCI_VCN_IP_NATIVE" +} +variable "existent_oke_k8s_endpoint_subnet_ocid" { + default = "" + description = "The OCID of the subnet where the Kubernetes cluster endpoint will be hosted" +} +variable "existent_oke_nodes_subnet_ocid" { + default = "" + description = "The OCID of the subnet where the Kubernetes worker nodes will be hosted" +} +variable "existent_oke_load_balancer_subnet_ocid" { + default = "" + description = "The OCID of the subnet where the Kubernetes load balancers will be hosted" +} +variable "existent_oke_vcn_native_pod_networking_subnet_ocid" { + default = "" + description = "The OCID of the subnet where the Kubernetes VCN Native Pod Networking will be hosted" +} +variable "existent_oke_fss_mount_targets_subnet_ocid" { + default = "" + description = "The OCID of the subnet where the Kubernetes FSS mount targets will be hosted" +} +# variable "existent_apigw_fn_subnet_ocid" { +# default = "" +# description = "The OCID of the subnet where the API Gateway and Functions will be hosted" +# } +variable "extra_subnets" { + default = [] + description = "Extra subnets to be created." +} +variable "extra_route_tables" { + default = [] + description = "Extra route tables to be created." +} +variable "extra_security_lists" { + default = [] + description = "Extra security lists to be created." +} +variable "extra_security_list_name_for_api_endpoint" { + default = null + description = "Extra security list name previosly created to be used by the K8s API Endpoint Subnet." +} +variable "extra_security_list_name_for_nodes" { + default = null + description = "Extra security list name previosly created to be used by the Nodes Subnet." +} +variable "extra_security_list_name_for_vcn_native_pod_networking" { + default = null + description = "Extra security list name previosly created to be used by the VCN Native Pod Networking Subnet." +} + +################################################################################ +# Variables: OKE Network +################################################################################ +# OKE Network Visibility (Workers, Endpoint and Load Balancers) +variable "cluster_workers_visibility" { + default = "Private" + description = "The Kubernetes worker nodes that are created will be hosted in public or private subnet(s)" + + validation { + condition = var.cluster_workers_visibility == "Private" || var.cluster_workers_visibility == "Public" + error_message = "Sorry, but cluster visibility can only be Private or Public." + } +} +variable "cluster_endpoint_visibility" { + default = "Public" + description = "The Kubernetes cluster that is created will be hosted on a public subnet with a public IP address auto-assigned or on a private subnet. If Private, additional configuration will be necessary to run kubectl commands" + + validation { + condition = var.cluster_endpoint_visibility == "Private" || var.cluster_endpoint_visibility == "Public" + error_message = "Sorry, but cluster endpoint visibility can only be Private or Public." + } +} +variable "cluster_load_balancer_visibility" { + default = "Public" + description = "The Load Balancer that is created will be hosted on a public subnet with a public IP address auto-assigned or on a private subnet. This affects the Kubernetes services, ingress controller and other load balancers resources" + + validation { + condition = var.cluster_load_balancer_visibility == "Private" || var.cluster_load_balancer_visibility == "Public" + error_message = "Sorry, but cluster load balancer visibility can only be Private or Public." + } +} +variable "pods_network_visibility" { + default = "Private" + description = "The PODs that are created will be hosted on a public subnet with a public IP address auto-assigned or on a private subnet. This affects the Kubernetes services and pods" + + validation { + condition = var.pods_network_visibility == "Private" || var.pods_network_visibility == "Public" + error_message = "Sorry, but PODs Network visibility can only be Private or Public." + } +} + +################################################################################ +# Variables: OKE Cluster +################################################################################ +## OKE Cluster Details +variable "create_new_oke_cluster" { + default = true + description = "Creates a new OKE cluster, node pool and network resources" +} +variable "existent_oke_cluster_id" { + default = "" + description = "Using existent OKE Cluster. Only the application and services will be provisioned. If select cluster autoscaler feature, you need to get the node pool id and enter when required" +} +variable "cluster_type" { + default = "ENHANCED_CLUSTER" + description = "The type of OKE cluster to create. Valid values are: BASIC_CLUSTER or ENHANCED_CLUSTER" + + validation { + condition = var.cluster_type == "BASIC_CLUSTER" || var.cluster_type == "ENHANCED_CLUSTER" + error_message = "Sorry, but cluster visibility can only be BASIC_CLUSTER or ENHANCED_CLUSTER." + } +} +variable "create_new_compartment_for_oke" { + default = false + description = "Creates new compartment for OKE Nodes and OCI Services deployed. NOTE: The creation of the compartment increases the deployment time by at least 3 minutes, and can increase by 15 minutes when destroying" +} +variable "oke_compartment_description" { + default = "Compartment for OKE, Nodes and Services" +} +variable "cluster_cni_type" { + default = "FLANNEL_OVERLAY" + description = "The CNI type to use for the cluster. Valid values are: FLANNEL_OVERLAY or OCI_VCN_IP_NATIVE" + + validation { + condition = var.cluster_cni_type == "FLANNEL_OVERLAY" || var.cluster_cni_type == "OCI_VCN_IP_NATIVE" + error_message = "Sorry, but OKE currently only supports FLANNEL_OVERLAY or OCI_VCN_IP_NATIVE CNI types." + } +} + +## OKE Encryption details +variable "use_encryption_from_oci_vault" { + default = false + description = "By default, Oracle manages the keys that encrypts Kubernetes Secrets at Rest in Etcd, but you can choose a key from a vault that you have access to, if you want greater control over the key's lifecycle and how it's used" +} +variable "create_new_encryption_key" { + default = false + description = "Creates new vault and key on OCI Vault/Key Management/KMS and assign to boot volume of the worker nodes" +} +variable "existent_encryption_key_id" { + default = "" + description = "Use an existent master encryption key to encrypt boot volume and object storage bucket. NOTE: If the key resides in a different compartment or in a different tenancy, make sure you have the proper policies to access, or the provision of the worker nodes will fail" +} +variable "create_vault_policies_for_group" { + default = false + description = "Creates policies to allow the user applying the stack to manage vault and keys. If you are on the Administrators group or already have the policies for a compartment, this policy is not needed. If you do not have access to allow the policy, ask your administrator to include it for you" +} +variable "user_admin_group_for_vault_policy" { + default = "Administrators" + description = "User Identity Group to allow manage vault and keys. The user running the Terraform scripts or Applying the ORM Stack need to be on this group" +} + +## OKE Autoscaler +variable "node_pool_autoscaler_enabled_1" { + default = true + description = "Enable Cluster Autoscaler on the node pool (pool1). Node pools will auto scale based on the resources usage and will add or remove nodes (Compute) based on the min and max number of nodes" +} +variable "node_pool_initial_num_worker_nodes_1" { + default = 2 #3 + description = "The number of worker nodes in the node pool. If enable Cluster Autoscaler, will assume the minimum number of nodes on the node pool to be scheduled by the Kubernetes (pool1)" +} +variable "node_pool_max_num_worker_nodes_1" { + default = 2 #10 + description = "Maximum number of nodes on the node pool to be scheduled by the Kubernetes (pool1)" +} +variable "existent_oke_nodepool_id_for_autoscaler_1" { + default = "" + description = "Nodepool Id of the existent OKE to use with Cluster Autoscaler (pool1)" +} + +################################################################################ +# Variables: OKE Node Pool 1 +################################################################################ +## OKE Node Pool Details +variable "k8s_version" { + default = "Latest" # "v1.29.1" + description = "Kubernetes version installed on your Control Plane and worker nodes. If not version select, will use the latest available." +} +### Node Pool 1 +variable "node_pool_name_1" { + default = "pool1" + description = "Name of the node pool 1" +} +variable "extra_initial_node_labels_1" { + default = [] + description = "Extra initial node labels to be added to the node pool 1" +} +variable "node_pool_cni_type_1" { + default = "FLANNEL_OVERLAY" + description = "The CNI type to use for the cluster. Valid values are: FLANNEL_OVERLAY or OCI_VCN_IP_NATIVE" + + validation { + condition = var.node_pool_cni_type_1 == "FLANNEL_OVERLAY" || var.node_pool_cni_type_1 == "OCI_VCN_IP_NATIVE" + error_message = "Sorry, but OKE currently only supports FLANNEL_OVERLAY or OCI_VCN_IP_NATIVE CNI types." + } +} + +#### ocpus and memory are only used if flex shape is selected +variable "node_pool_instance_shape_1" { + type = map(any) + default = { + "instanceShape" = "VM.Standard.E4.Flex" + "ocpus" = 2 + "memory" = 16 + } + description = "A shape is a template that determines the number of OCPUs, amount of memory, and other resources allocated to a newly created instance for the Worker Node. Select at least 2 OCPUs and 16GB of memory if using Flex shapes" +} +variable "node_pool_shape_specific_ad_1" { + description = "The number of the AD to get the shape for the node pool" + type = number + default = 0 + + validation { + condition = var.node_pool_shape_specific_ad_1 >= 0 && var.node_pool_shape_specific_ad_1 <= 3 + error_message = "Invalid AD number, should be 0 to get all ADs or 1, 2 or 3 to be a specific AD." + } +} +variable "node_pool_boot_volume_size_in_gbs_1" { + default = "60" + description = "Specify a custom boot volume size (in GB)" +} +variable "image_operating_system_1" { + default = "Oracle Linux" + description = "The OS/image installed on all nodes in the node pool." +} +variable "image_operating_system_version_1" { + default = "8" + description = "The OS/image version installed on all nodes in the node pool." +} +variable "node_pool_oke_init_params_1" { + type = string + default = "" + description = "OKE Init params" +} +variable "node_pool_cloud_init_parts_1" { + type = list(object({ + content_type = string + content = string + filename = string + })) + default = [] + description = "Node Pool nodes Cloud init parts" +} +variable "generate_public_ssh_key" { + default = true +} +variable "public_ssh_key" { + default = "" + description = "In order to access your private nodes with a public SSH key you will need to set up a bastion host (a.k.a. jump box). If using public nodes, bastion is not needed. Left blank to not import keys." +} +################################################################################ +# Variables: OKE Extra Node Pools +################################################################################ +variable "extra_node_pools" { + default = [] + description = "Extra node pools to be added to the cluster" +} + +################################################################################ +# Variables: Dynamic Group and Policies for OKE +################################################################################ +# Create Dynamic Group and Policies +variable "create_dynamic_group_for_nodes_in_compartment" { + default = true + description = "Creates dynamic group of Nodes in the compartment. Note: You need to have proper rights on the Tenancy. If you only have rights in a compartment, uncheck and ask you administrator to create the Dynamic Group for you" +} +variable "existent_dynamic_group_for_nodes_in_compartment" { + default = "" + description = "Enter previous created Dynamic Group for the policies" +} +variable "create_compartment_policies" { + default = true + description = "Creates policies that will reside on the compartment. e.g.: Policies to support Cluster Autoscaler, OCI Logging datasource on Grafana" +} +variable "create_tenancy_policies" { + default = false + description = "Creates policies that need to reside on the tenancy. e.g.: Policies to support OCI Metrics datasource on Grafana" +} \ No newline at end of file diff --git a/terraform-provider-oci/oke-quickstartz/versions.tf b/terraform-provider-oci/oke-quickstartz/versions.tf new file mode 100644 index 0000000..ded621e --- /dev/null +++ b/terraform-provider-oci/oke-quickstartz/versions.tf @@ -0,0 +1,40 @@ +# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. +# + +terraform { + required_version = ">= 1.1" + required_providers { + oci = { + source = "oracle/oci" + version = "~> 4, < 5" + # https://registry.terraform.io/providers/oracle/oci/ + configuration_aliases = [oci.home_region] + } + kubernetes = { + source = "hashicorp/kubernetes" + version = "~> 2" + # https://registry.terraform.io/providers/hashicorp/kubernetes/ + } + helm = { + source = "hashicorp/helm" + version = "~> 2" + # https://registry.terraform.io/providers/hashicorp/helm/ + } + tls = { + source = "hashicorp/tls" + version = "~> 4" + # https://registry.terraform.io/providers/hashicorp/tls/ + } + local = { + source = "hashicorp/local" + version = "~> 2" + # https://registry.terraform.io/providers/hashicorp/local/ + } + random = { + source = "hashicorp/random" + version = "~> 3" + # https://registry.terraform.io/providers/hashicorp/random/ + } + } +}