[
  {
    "path": ".github/ISSUE_TEMPLATE/Bug_Report.md",
    "content": "---\nname: 🐛 Bug Report\nabout: If something isn't working as expected 🤔.\nlabels: bug\n---\n\n<!---\nPlease note the following potential times when an issue might be in Terraform core:\n\n* [Configuration Language](https://www.terraform.io/docs/configuration/index.html) or resource ordering issues\n* [State](https://www.terraform.io/docs/state/index.html) and [State Backend](https://www.terraform.io/docs/backends/index.html) issues\n* [Provisioner](https://www.terraform.io/docs/provisioners/index.html) issues\n* [Registry](https://registry.terraform.io/) issues\n* Spans resources across multiple providers\n\nIf you are running into one of these scenarios, we recommend opening an issue in the [Terraform core repository](https://github.com/hashicorp/terraform/) instead.\n--->\n\n<!--- Please keep this note for the community --->\n\n### Community Note\n\n* Please vote on this issue by adding a 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to the original issue to help the community and maintainers prioritize this request\n* Please do not leave \"+1\" or \"me too\" comments, they generate extra noise for issue followers and do not help prioritize the request\n* If you are interested in working on this issue or have submitted a pull request, please leave a comment\n\n<!--- Thank you for keeping this note for the community --->\n\n### Terraform Version and Provider Version\n\n<!--- Please run `terraform -v` to show the Terraform core version and provider version(s). \nIf you are using a local copy of the Terraform Oracle Cloud Infrastructure Provider, run the plugin directly to get the version: `<path-to-plugin>/terraform-provider-oci`\nIf you are not running the latest version of Terraform or the provider, please upgrade because your issue may have already been fixed. [Terraform documentation on provider versioning](https://www.terraform.io/docs/configuration/providers.html#provider-versions). --->\n\n### Affected Resource(s)\n\n<!--- Please list the affected resources and data sources. For example, \"oci_core_vcn\". --->\n\n\n### Terraform Configuration Files\n\n<!--- Information about code formatting: https://help.github.com/articles/basic-writing-and-formatting-syntax/#quoting-code --->\n\n```hcl\n# Copy-paste your Terraform configurations here - for large Terraform configs,\n# please use a service like Dropbox and share a link to the ZIP file. \n# Please remove any sensitive information from configuration files before sharing them. \n```\n\n### Debug Output\n\n<!---\nPlease provide a link to a GitHub Gist containing the complete debug output. Please do NOT paste the debug output in the issue; just paste a link to the Gist.\n\nTo obtain the debug output, see the [Verbose logging for OCI Terraform Provider](https://www.terraform.io/docs/providers/oci/guides/troubleshooting.html#verbose-logging-for-oci-terraform-provider).\n\nGithub Gist: https://gist.github.com/\n--->\n\n### Panic Output\n\n<!--- \nIf Terraform produced a panic, please provide a link to a GitHub Gist containing the output of the `crash.log`. \n\nGithub Gist: https://gist.github.com/\n--->\n\n### Expected Behavior\n\n<!--- What should have happened? --->\n\n### Actual Behavior\n\n<!--- What actually happened? --->\n\n### Steps to Reproduce\n\n<!--- Please list the steps required to reproduce the issue. --->\n\n1. `terraform apply`\n\n### Important Factoids\n\n<!--- Is there anything atypical about your environment that we should know? For example: Is the issue specific to a region? --->\n\n### References\n\n<!---\nInformation about referencing Github Issues: https://help.github.com/articles/basic-writing-and-formatting-syntax/#referencing-issues-and-pull-requests\n\nAre there any other GitHub issues (open or closed) or pull requests that should be linked here? Vendor documentation? For example:\n--->"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Feature_Request.md",
    "content": "---\nname: 🚀 Feature Request\nabout: I have a suggestion (and might want to implement myself 🙂)!\nlabels: enhancement\n---\n\n<!--- Please keep this note for the community --->\n\n### Community Note\n\n* Please vote on this issue by adding a 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to the original issue to help the community and maintainers prioritize this request\n* Please do not leave \"+1\" or \"me too\" comments, they generate extra noise for issue followers and do not help prioritize the request\n* If you are interested in working on this issue or have submitted a pull request, please leave a comment\n\n<!--- Thank you for keeping this note for the community --->\n\n### Description\n\n<!--- Please leave a helpful description of the feature request here. --->\n\n### New or Affected Resource(s)\n\n<!--- Please list any new or affected resources and data sources that are part of the request. For example: \"oci_core_vcn\" --->\n\n\n### Potential Terraform Configuration\n\n<!--- Information about code formatting: https://help.github.com/articles/basic-writing-and-formatting-syntax/#quoting-code --->\n\n```hcl\n# Copy-paste any Terraform configurations for how the requested feature may be used. \n```\n\n### References\n\n<!---\nInformation about referencing Github Issues: https://help.github.com/articles/basic-writing-and-formatting-syntax/#referencing-issues-and-pull-requests\n\nAre there any other GitHub issues (open or closed) or pull requests that should be linked here? Vendor blog posts or documentation? For example:\n\n--->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Question.md",
    "content": "---\nname: 💬 Question\nabout: Questions regarding the Terraform Oracle Cloud Infrastructure OKE module\nlabels: question\n---\n\nThis Github template is intended for questions regarding the Terraform **Oracle Cloud Infrastructure** OKE module.\n\nIf you have a support request or question related to core Terraform functionality or the OCI provider, please submit them to one of these resources:\n\n* [Terraform OCI provider](https://github.com/terraform-providers/terraform-provider-oci)\n* [Terraform community resources](https://www.terraform.io/docs/extend/community/index.html)\n* [HashiCorp support](https://support.hashicorp.com) (Terraform Enterprise customers)"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "<!---\nThanks for filing an issue 😄 ! Before you submit, please read the following:\n\nCheck the other issue templates if you are trying to submit a bug report, feature request, or question\nSearch open/closed issues before submitting since someone might have asked the same thing before!\n-->"
  },
  {
    "path": ".gitignore",
    "content": "#  Local .terraform directories\n**/.terraform/*\n\nprovider.tf\n\n# .tfstate files\n*.tfstate\n*.tfstate.*\n\n# .tfvars files\n*.tfvars\n\ngenerated/**\n\n# visual code\n**/.vscode/*\n**/.metals*\n\n.terraform.lock.hcl\n\n# Generated documentation\ndocs/book\n\n.idea*\n.oca*"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\nOracle welcomes contributions to this repository from anyone.\n\nIf you want to submit a pull request to fix a bug or enhance an existing feature, please first open an issue and link to that issue when you submit your pull request.\n\nIf you have any questions about a possible submission, feel free to open an issue too.\n\n## Contributing to the terraform-oci-oke repository\n\nPull requests can be made under [The Oracle Contributor Agreement](https://oca.opensource.oracle.com/).\n\nFor pull requests to be accepted, the bottom of your commit message must have the following line using your name and e-mail address as it appears in the OCA Signatories list.\n\n```\nSigned-off-by: Your Name <you@example.org>\n```\n\nThis can be automatically added to pull requests by committing with:\n\n```\n  git commit --signoff\n```\n\nOnly pull requests from committers that can be verified as having\nsigned the OCA can be accepted.\n\n### Pull request process\n\n1. Fork this repository\n1. Create a branch in your fork to implement the changes. We recommend using the issue number as part of your branch name, e.g. `1234-fixes`\n1. Ensure that any documentation is updated with the changes that are required by your fix.\n1. Ensure that any samples are updated if the base image has been changed.\n1. Submit the pull request. *Do not leave the pull request blank*. Explain exactly what your changes are meant to do and provide simple steps on how to validate your changes. Ensure that you reference the issue you created as well. We will assign the pull request to 2-3 people for review before it is merged.\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2019 Oracle and/or its affiliates. \n\nThe Universal Permissive License (UPL), Version 1.0\n\nSubject to the condition set forth below, permission is hereby granted to any\nperson obtaining a copy of this software, associated documentation and/or data\n(collectively the \"Software\"), free of charge and under any and all copyright\nrights in the Software, and any and all patent rights owned or freely\nlicensable by each licensor hereunder covering either (i) the unmodified\nSoftware as contributed to or provided by such licensor, or (ii) the Larger\nWorks (as defined below), to deal in both\n\n(a) the Software, and\n(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if\none is included with the Software (each a \"Larger Work\" to which the Software\nis contributed by such licensors),\n\nwithout restriction, including without limitation the rights to copy, create\nderivative works of, display, perform, and distribute the Software and make,\nuse, sell, offer for sale, import, export, have made, and have sold the\nSoftware and the Larger Work(s), and to sublicense the foregoing rights on\neither these or other terms.\n\nThis license is subject to the following condition:\nThe above copyright notice and either this complete permission notice or at\na minimum a reference to the UPL must be included in all copies or\nsubstantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "Makefile",
    "content": "PROJECT_NAME := \"terraform-oci-oke\"\nSHELL = /usr/bin/env bash -o pipefail\n.SHELLFLAGS = -ec\n\n.PHONY: all\nall: build\n\n##@ General\n\n.PHONY: help\nhelp: ## Display this help.\n\t@awk 'BEGIN {FS = \":.*##\"; printf \"\\nUsage:\\n  make \\033[36m<target>\\033[0m\\n\"} /^[a-zA-Z_0-9-]+:.*?##/ { printf \"  \\033[36m%-15s\\033[0m %s\\n\", $$1, $$2 } /^##@/ { printf \"\\n\\033[1m%s\\033[0m\\n\", substr($$0, 5) } ' $(MAKEFILE_LIST)\n\n.terraform:\n\tterraform init\n\n##@ Usage\n\n.PHONY: plan\nplan: .terraform ## Run terraform plan\n\tterraform plan\n\n.PHONY: apply\napply: .terraform ## Run terraform apply\n\tterraform apply\n\n.PHONY: ssh\nssh: ## Print SSH command\n\tterraform output -json | jq -rcM '.output.value.ssh_to_operator'\n\n.PHONY: clean\nclean: ## Clear Terraform module cache\n\trm -rf ./.terraform\n\n##@ Hygiene\n\n.PHONY: fmt\nfmt: ## Run terraform fmt\n\tterraform fmt -recursive .\n\n.PHONY: validate\nvalidate: ## Run terraform validate\n\tterraform validate\n\n.PHONY: tflint\ntflint: ## Run tflint\n\ttflint --recursive .\n"
  },
  {
    "path": "README.md",
    "content": "# Terraform OKE for Oracle Cloud Infrastructure\n\n[changelog]: https://github.com/oracle-terraform-modules/terraform-oci-oke/releases\n[contributing]: https://github.com/oracle-terraform-modules/terraform-oci-oke/blob/main/CONTRIBUTING.md\n[license]: https://github.com/oracle-terraform-modules/terraform-oci-oke/blob/main/LICENSE\n[canonical_license]: https://oss.oracle.com/licenses/upl/\n\n[oci]: https://cloud.oracle.com/cloud-infrastructure\n[oci_documentation]: https://docs.oracle.com/iaas/Content/services.htm\n[oke]: https://docs.oracle.com/iaas/Content/ContEng/Concepts/contengoverview.htm\n\n[docs]: https://github.com/oracle-terraform-modules/terraform-oci-oke/tree/main/docs\n[prerequisites]: https://github.com/oracle-terraform-modules/terraform-oci-oke/blob/main/docs/prerequisites.md\n[quickstart]: https://github.com/oracle-terraform-modules/terraform-oci-oke/blob/main/docs/quickstart.md\n[diagrams]: https://github.com/oracle-terraform-modules/terraform-oci-oke/blob/main/docs/diagrams.md\n[terraform_options]: https://github.com/oracle-terraform-modules/terraform-oci-oke/blob/main/docs/terraformoptions.md\n[examples]: https://github.com/oracle-terraform-modules/terraform-oci-oke/tree/main/examples\n[repo]: https://github.com/oracle-terraform-modules/terraform-oci-oke\n[releases]: https://github.com/oracle-terraform-modules/terraform-oci-oke/releases\n[terraform]: https://www.terraform.io\n[terraform_oci]: https://registry.terraform.io/providers/oracle/oci/latest\n[terraform_oci_examples]: https://github.com/oracle/terraform-provider-oci/tree/master/examples\n[terraform_guides_examples]: https://github.com/hashicorp/terraform-guides/tree/master/infrastructure-as-code/terraform-0.12-examples\n\n[terraform_oci_bastion]: https://github.com/oracle-terraform-modules/terraform-oci-bastion\n[terraform_oci_operator]: https://github.com/oracle-terraform-modules/terraform-oci-operator\n[terraform_oci_vcn]: https://github.com/oracle-terraform-modules/terraform-oci-vcn\n\nThe [Terraform OKE Module][repo] for [Oracle Cloud Infrastructure][oci] (OCI) provides a [Terraform][terraform] module that provisions an [OCI Kubernetes Engine (OKE)][oke] cluster with supporting infrastructure.\n\nIt creates the following resources:\n\n* A Virtual Cloud Network (VCN) with public and private subnets, network security groups, and gateways (internet, NAT, service, DRG)\n* An OKE cluster (basic or enhanced) with configurable CNI, Kubernetes version, and OIDC authentication\n* Worker node pools in various modes: OKE-managed node pools, virtual node pools, self-managed instances, instance pools, cluster networks, and compute clusters\n* A bastion host for SSH access into the VCN\n* An operator host for cluster management with kubectl, Helm, and optional tools (k9s, istioctl, stern, k8sgpt)\n* IAM dynamic groups, policies, and optional tag namespaces\n* Kubernetes extensions deployed via Helm or YAML manifests\n\nThe module outputs the OKE cluster ID, endpoints, bastion and operator SSH commands, and network resource IDs. Detailed outputs such as kubeconfig are available when `output_detail = true`.\n\n## Topology\n\nThe default deployment creates a VCN with the following subnets:\n\n| Subnet | Purpose | Access |\n|--------|---------|--------|\n| bastion | Bastion host | Public |\n| operator | Operator host | Private |\n| cp | Kubernetes control plane | Private (or public) |\n| workers | Worker nodes | Private |\n| pods | Pod network (NPN CNI) | Private |\n| int_lb | Internal load balancers | Private |\n| pub_lb | Public load balancers | Public |\n\n![Default Multi-AD topology](docs/images/defaultmad-large.svg)\n\n## Worker Modes\n\nThe module supports multiple worker management modes:\n\n| Mode | Description | Use Case |\n|------|-------------|----------|\n| `node-pool` | OKE-managed node pools | General purpose workloads |\n| `virtual-node-pool` | OKE-managed virtual nodes | Serverless, burstable workloads |\n| `instance` | Self-managed compute instances | Custom node configuration |\n| `instance-pool` | Self-managed instance pools | Scalable self-managed nodes |\n| `cluster-network` | Self-managed cluster networks | HPC/GPU with RDMA networking |\n| `compute-cluster` | Shared compute clusters | Multi-nodepool HPC clusters |\n\n## Extensions\n\nThe module can deploy the following Kubernetes extensions:\n\n| Extension | Method | Purpose |\n|-----------|--------|---------|\n| Cilium | Helm | eBPF-based networking, security, and observability |\n| Multus | Daemonset | Multi-network pod interfaces |\n| SR-IOV Device Plugin | Daemonset | SR-IOV network device advertisement |\n| SR-IOV CNI Plugin | Daemonset | SR-IOV network connections |\n| RDMA CNI Plugin | Daemonset | RDMA network connections |\n| Whereabouts | Daemonset | IP address management for Multus |\n| Metrics Server | Helm | Kubernetes metrics API |\n| Cluster Autoscaler | Helm | Automatic node pool scaling |\n| Prometheus | Helm | Monitoring and alerting |\n| DCGM Exporter | Helm | GPU metrics for NVIDIA GPUs |\n| Gatekeeper | Helm | OPA policy enforcement |\n| MPI Operator | Manifest | MPI/NCCL distributed training jobs |\n| ArgoCD | Helm | GitOps continuous delivery |\n\n## [Documentation][docs]\n\n- [Prerequisites][prerequisites]\n- [Quickstart][quickstart]\n- [Diagrams][diagrams]\n- [Terraform Options][terraform_options]\n- [Examples][examples]\n\n## Related Documentation\n\n- [Oracle Cloud Infrastructure Documentation][oci_documentation]\n- [Terraform OCI Provider Documentation][terraform_oci]\n- [OCI Kubernetes Engine Documentation][oke]\n- [Terraform OCI Bastion Module][terraform_oci_bastion]\n\n## Acknowledgement\n\nCode derived and adapted from [Terraform OCI Examples][terraform_oci_examples] and HashiCorp's [Terraform 0.12 examples][terraform_guides_examples].\n\n## Contributing\n\nLearn how to [contribute][contributing].\n\n## License\n\nCopyright (c) 2017, 2025 Oracle Corporation and/or its affiliates. Licensed under the [Universal Permissive License 1.0][license] as shown at [https://oss.oracle.com/licenses/upl][canonical_license].\n"
  },
  {
    "path": "THIRD_PARTY_LICENSES.txt",
    "content": "github.com/open-policy-agent/gatekeeper\n-------- Copyrights\nCopyright 2018-2020 The Gatekeeper Authors\nCopyright 2018 The Kubernetes Authors.\nCopyright (c) 2015 Paxton Hare\nCopyright 2019 The Kubernetes Authors.\n-------- Notices\nGatekeeper\nCopyright 2018-2020 The Gatekeeper Authors\n\nThis product includes modified code from the following projects,\nas denoted by notifications in the source code headers:\n\ncontroller-runtime\nhttps://sigs.k8s.io/controller-runtime\nCopyright 2018 The Kubernetes Authors.\nLicensed under the Apache License, Version 2.0\n\n-------- License\nSPDX:Apache-2.0\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n----------------------- Dependencies Grouped by License ------------\n-------- Dependency\ngithub.com/PuerkitoBio/purell\n-------- Copyrights\nCopyright (c) 2012, Martin Angers\n\n-------- Dependencies Summary\ngithub.com/PuerkitoBio/purell\n\n-------- License used by Dependencies\nCopyright (c) 2012, Martin Angers\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n\n* Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n\n----------------------- Dependencies Grouped by License ------------\n-------- Dependency\ngithub.com/evanphx/json-patch\n-------- Copyrights\nCopyright (c) 2014, Evan Phoenix\n\n-------- Dependencies Summary\ngithub.com/evanphx/json-patch\n\n-------- License used by Dependencies\nCopyright (c) 2014, Evan Phoenix\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without \nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n* Neither the name of the Evan Phoenix nor the names of its contributors \n  may be used to endorse or promote products derived from this software \n  without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" \nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE \nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL \nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR \nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER \nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n\n----------------------- Dependencies Grouped by License ------------\n-------- Dependency\ngithub.com/pkg/errors\n-------- Copyrights\nCopyright (c) 2015, Dave Cheney <dave@cheney.net>\n\n-------- Dependencies Summary\ngithub.com/pkg/errors\n\n-------- License used by Dependencies\nCopyright (c) 2015, Dave Cheney <dave@cheney.net>\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n\n----------------------- Dependencies Grouped by License ------------\n-------- Dependency\ngithub.com/rcrowley/go-metrics\n-------- Copyrights\nCopyright 2012 Richard Crowley. All rights reserved.\n\n-------- Dependencies Summary\ngithub.com/rcrowley/go-metrics\n\n-------- License used by Dependencies\nCopyright 2012 Richard Crowley. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n    1.  Redistributions of source code must retain the above copyright\n        notice, this list of conditions and the following disclaimer.\n\n    2.  Redistributions in binary form must reproduce the above\n        copyright notice, this list of conditions and the following\n        disclaimer in the documentation and/or other materials provided\n        with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY RICHARD CROWLEY ``AS IS'' AND ANY EXPRESS\nOR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL RICHARD CROWLEY OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\nTHE POSSIBILITY OF SUCH DAMAGE.\n\nThe views and conclusions contained in the software and documentation\nare those of the authors and should not be interpreted as representing\nofficial policies, either expressed or implied, of Richard Crowley.\n\n\n----------------------- Dependencies Grouped by License ------------\n-------- Dependency\ngithub.com/hashicorp/golang-lru\n-------- Copyrights\n\n-------- Dependencies Summary\ngithub.com/hashicorp/golang-lru\n\n-------- License used by Dependencies\nMozilla Public License, version 2.0\n\n1. Definitions\n\n1.1. \"Contributor\"\n\n     means each individual or legal entity that creates, contributes to the\n     creation of, or owns Covered Software.\n\n1.2. \"Contributor Version\"\n\n     means the combination of the Contributions of others (if any) used by a\n     Contributor and that particular Contributor's Contribution.\n\n1.3. \"Contribution\"\n\n     means Covered Software of a particular Contributor.\n\n1.4. \"Covered Software\"\n\n     means Source Code Form to which the initial Contributor has attached the\n     notice in Exhibit A, the Executable Form of such Source Code Form, and\n     Modifications of such Source Code Form, in each case including portions\n     thereof.\n\n1.5. \"Incompatible With Secondary Licenses\"\n     means\n\n     a. that the initial Contributor has attached the notice described in\n        Exhibit B to the Covered Software; or\n\n     b. that the Covered Software was made available under the terms of\n        version 1.1 or earlier of the License, but not also under the terms of\n        a Secondary License.\n\n1.6. \"Executable Form\"\n\n     means any form of the work other than Source Code Form.\n\n1.7. \"Larger Work\"\n\n     means a work that combines Covered Software with other material, in a\n     separate file or files, that is not Covered Software.\n\n1.8. \"License\"\n\n     means this document.\n\n1.9. \"Licensable\"\n\n     means having the right to grant, to the maximum extent possible, whether\n     at the time of the initial grant or subsequently, any and all of the\n     rights conveyed by this License.\n\n1.10. \"Modifications\"\n\n     means any of the following:\n\n     a. any file in Source Code Form that results from an addition to,\n        deletion from, or modification of the contents of Covered Software; or\n\n     b. any new file in Source Code Form that contains any Covered Software.\n\n1.11. \"Patent Claims\" of a Contributor\n\n      means any patent claim(s), including without limitation, method,\n      process, and apparatus claims, in any patent Licensable by such\n      Contributor that would be infringed, but for the grant of the License,\n      by the making, using, selling, offering for sale, having made, import,\n      or transfer of either its Contributions or its Contributor Version.\n\n1.12. \"Secondary License\"\n\n      means either the GNU General Public License, Version 2.0, the GNU Lesser\n      General Public License, Version 2.1, the GNU Affero General Public\n      License, Version 3.0, or any later versions of those licenses.\n\n1.13. \"Source Code Form\"\n\n      means the form of the work preferred for making modifications.\n\n1.14. \"You\" (or \"Your\")\n\n      means an individual or a legal entity exercising rights under this\n      License. For legal entities, \"You\" includes any entity that controls, is\n      controlled by, or is under common control with You. For purposes of this\n      definition, \"control\" means (a) the power, direct or indirect, to cause\n      the direction or management of such entity, whether by contract or\n      otherwise, or (b) ownership of more than fifty percent (50%) of the\n      outstanding shares or beneficial ownership of such entity.\n\n\n2. License Grants and Conditions\n\n2.1. Grants\n\n     Each Contributor hereby grants You a world-wide, royalty-free,\n     non-exclusive license:\n\n     a. under intellectual property rights (other than patent or trademark)\n        Licensable by such Contributor to use, reproduce, make available,\n        modify, display, perform, distribute, and otherwise exploit its\n        Contributions, either on an unmodified basis, with Modifications, or\n        as part of a Larger Work; and\n\n     b. under Patent Claims of such Contributor to make, use, sell, offer for\n        sale, have made, import, and otherwise transfer either its\n        Contributions or its Contributor Version.\n\n2.2. Effective Date\n\n     The licenses granted in Section 2.1 with respect to any Contribution\n     become effective for each Contribution on the date the Contributor first\n     distributes such Contribution.\n\n2.3. Limitations on Grant Scope\n\n     The licenses granted in this Section 2 are the only rights granted under\n     this License. No additional rights or licenses will be implied from the\n     distribution or licensing of Covered Software under this License.\n     Notwithstanding Section 2.1(b) above, no patent license is granted by a\n     Contributor:\n\n     a. for any code that a Contributor has removed from Covered Software; or\n\n     b. for infringements caused by: (i) Your and any other third party's\n        modifications of Covered Software, or (ii) the combination of its\n        Contributions with other software (except as part of its Contributor\n        Version); or\n\n     c. under Patent Claims infringed by Covered Software in the absence of\n        its Contributions.\n\n     This License does not grant any rights in the trademarks, service marks,\n     or logos of any Contributor (except as may be necessary to comply with\n     the notice requirements in Section 3.4).\n\n2.4. Subsequent Licenses\n\n     No Contributor makes additional grants as a result of Your choice to\n     distribute the Covered Software under a subsequent version of this\n     License (see Section 10.2) or under the terms of a Secondary License (if\n     permitted under the terms of Section 3.3).\n\n2.5. Representation\n\n     Each Contributor represents that the Contributor believes its\n     Contributions are its original creation(s) or it has sufficient rights to\n     grant the rights to its Contributions conveyed by this License.\n\n2.6. Fair Use\n\n     This License is not intended to limit any rights You have under\n     applicable copyright doctrines of fair use, fair dealing, or other\n     equivalents.\n\n2.7. Conditions\n\n     Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in\n     Section 2.1.\n\n\n3. Responsibilities\n\n3.1. Distribution of Source Form\n\n     All distribution of Covered Software in Source Code Form, including any\n     Modifications that You create or to which You contribute, must be under\n     the terms of this License. You must inform recipients that the Source\n     Code Form of the Covered Software is governed by the terms of this\n     License, and how they can obtain a copy of this License. You may not\n     attempt to alter or restrict the recipients' rights in the Source Code\n     Form.\n\n3.2. Distribution of Executable Form\n\n     If You distribute Covered Software in Executable Form then:\n\n     a. such Covered Software must also be made available in Source Code Form,\n        as described in Section 3.1, and You must inform recipients of the\n        Executable Form how they can obtain a copy of such Source Code Form by\n        reasonable means in a timely manner, at a charge no more than the cost\n        of distribution to the recipient; and\n\n     b. You may distribute such Executable Form under the terms of this\n        License, or sublicense it under different terms, provided that the\n        license for the Executable Form does not attempt to limit or alter the\n        recipients' rights in the Source Code Form under this License.\n\n3.3. Distribution of a Larger Work\n\n     You may create and distribute a Larger Work under terms of Your choice,\n     provided that You also comply with the requirements of this License for\n     the Covered Software. If the Larger Work is a combination of Covered\n     Software with a work governed by one or more Secondary Licenses, and the\n     Covered Software is not Incompatible With Secondary Licenses, this\n     License permits You to additionally distribute such Covered Software\n     under the terms of such Secondary License(s), so that the recipient of\n     the Larger Work may, at their option, further distribute the Covered\n     Software under the terms of either this License or such Secondary\n     License(s).\n\n3.4. Notices\n\n     You may not remove or alter the substance of any license notices\n     (including copyright notices, patent notices, disclaimers of warranty, or\n     limitations of liability) contained within the Source Code Form of the\n     Covered Software, except that You may alter any license notices to the\n     extent required to remedy known factual inaccuracies.\n\n3.5. Application of Additional Terms\n\n     You may choose to offer, and to charge a fee for, warranty, support,\n     indemnity or liability obligations to one or more recipients of Covered\n     Software. However, You may do so only on Your own behalf, and not on\n     behalf of any Contributor. You must make it absolutely clear that any\n     such warranty, support, indemnity, or liability obligation is offered by\n     You alone, and You hereby agree to indemnify every Contributor for any\n     liability incurred by such Contributor as a result of warranty, support,\n     indemnity or liability terms You offer. You may include additional\n     disclaimers of warranty and limitations of liability specific to any\n     jurisdiction.\n\n4. Inability to Comply Due to Statute or Regulation\n\n   If it is impossible for You to comply with any of the terms of this License\n   with respect to some or all of the Covered Software due to statute,\n   judicial order, or regulation then You must: (a) comply with the terms of\n   this License to the maximum extent possible; and (b) describe the\n   limitations and the code they affect. Such description must be placed in a\n   text file included with all distributions of the Covered Software under\n   this License. Except to the extent prohibited by statute or regulation,\n   such description must be sufficiently detailed for a recipient of ordinary\n   skill to be able to understand it.\n\n5. Termination\n\n5.1. The rights granted under this License will terminate automatically if You\n     fail to comply with any of its terms. However, if You become compliant,\n     then the rights granted under this License from a particular Contributor\n     are reinstated (a) provisionally, unless and until such Contributor\n     explicitly and finally terminates Your grants, and (b) on an ongoing\n     basis, if such Contributor fails to notify You of the non-compliance by\n     some reasonable means prior to 60 days after You have come back into\n     compliance. Moreover, Your grants from a particular Contributor are\n     reinstated on an ongoing basis if such Contributor notifies You of the\n     non-compliance by some reasonable means, this is the first time You have\n     received notice of non-compliance with this License from such\n     Contributor, and You become compliant prior to 30 days after Your receipt\n     of the notice.\n\n5.2. If You initiate litigation against any entity by asserting a patent\n     infringement claim (excluding declaratory judgment actions,\n     counter-claims, and cross-claims) alleging that a Contributor Version\n     directly or indirectly infringes any patent, then the rights granted to\n     You by any and all Contributors for the Covered Software under Section\n     2.1 of this License shall terminate.\n\n5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user\n     license agreements (excluding distributors and resellers) which have been\n     validly granted by You or Your distributors under this License prior to\n     termination shall survive termination.\n\n6. Disclaimer of Warranty\n\n   Covered Software is provided under this License on an \"as is\" basis,\n   without warranty of any kind, either expressed, implied, or statutory,\n   including, without limitation, warranties that the Covered Software is free\n   of defects, merchantable, fit for a particular purpose or non-infringing.\n   The entire risk as to the quality and performance of the Covered Software\n   is with You. Should any Covered Software prove defective in any respect,\n   You (not any Contributor) assume the cost of any necessary servicing,\n   repair, or correction. This disclaimer of warranty constitutes an essential\n   part of this License. No use of  any Covered Software is authorized under\n   this License except under this disclaimer.\n\n7. Limitation of Liability\n\n   Under no circumstances and under no legal theory, whether tort (including\n   negligence), contract, or otherwise, shall any Contributor, or anyone who\n   distributes Covered Software as permitted above, be liable to You for any\n   direct, indirect, special, incidental, or consequential damages of any\n   character including, without limitation, damages for lost profits, loss of\n   goodwill, work stoppage, computer failure or malfunction, or any and all\n   other commercial damages or losses, even if such party shall have been\n   informed of the possibility of such damages. This limitation of liability\n   shall not apply to liability for death or personal injury resulting from\n   such party's negligence to the extent applicable law prohibits such\n   limitation. Some jurisdictions do not allow the exclusion or limitation of\n   incidental or consequential damages, so this exclusion and limitation may\n   not apply to You.\n\n8. Litigation\n\n   Any litigation relating to this License may be brought only in the courts\n   of a jurisdiction where the defendant maintains its principal place of\n   business and such litigation shall be governed by laws of that\n   jurisdiction, without reference to its conflict-of-law provisions. Nothing\n   in this Section shall prevent a party's ability to bring cross-claims or\n   counter-claims.\n\n9. Miscellaneous\n\n   This License represents the complete agreement concerning the subject\n   matter hereof. If any provision of this License is held to be\n   unenforceable, such provision shall be reformed only to the extent\n   necessary to make it enforceable. Any law or regulation which provides that\n   the language of a contract shall be construed against the drafter shall not\n   be used to construe this License against a Contributor.\n\n\n10. Versions of the License\n\n10.1. New Versions\n\n      Mozilla Foundation is the license steward. Except as provided in Section\n      10.3, no one other than the license steward has the right to modify or\n      publish new versions of this License. Each version will be given a\n      distinguishing version number.\n\n10.2. Effect of New Versions\n\n      You may distribute the Covered Software under the terms of the version\n      of the License under which You originally received the Covered Software,\n      or under the terms of any subsequent version published by the license\n      steward.\n\n10.3. Modified Versions\n\n      If you create software not governed by this License, and you want to\n      create a new license for such software, you may create and use a\n      modified version of this License if you rename the license and remove\n      any references to the name of the license steward (except to note that\n      such modified license differs from this License).\n\n10.4. Distributing Source Code Form that is Incompatible With Secondary\n      Licenses If You choose to distribute Source Code Form that is\n      Incompatible With Secondary Licenses under the terms of this version of\n      the License, the notice described in Exhibit B of this License must be\n      attached.\n\nExhibit A - Source Code Form License Notice\n\n      This Source Code Form is subject to the\n      terms of the Mozilla Public License, v.\n      2.0. If a copy of the MPL was not\n      distributed with this file, You can\n      obtain one at\n      http://mozilla.org/MPL/2.0/.\n\nIf it is not possible or desirable to put the notice in a particular file,\nthen You may include the notice in a location (such as a LICENSE file in a\nrelevant directory) where a recipient would be likely to look for such a\nnotice.\n\nYou may add additional accurate notices of copyright ownership.\n\nExhibit B - \"Incompatible With Secondary Licenses\" Notice\n\n      This Source Code Form is \"Incompatible\n      With Secondary Licenses\", as defined by\n      the Mozilla Public License, v. 2.0.\n\n\n----------------------- Dependencies Grouped by License ------------\n-------- Dependency\ncloud.google.com/go\n-------- Copyrights\nCopyright 2020 Google LLC\nCopyright 2019 Google LLC\nCopyright 2016 Google LLC\nCopyright (c) 1996-1998 John D. Polstra.  All rights reserved.\nCopyright (c) 2001 David E. O'Brien\nPortions Copyright 2018 Google LLC.\nCopyright 2018 Google LLC\nCopyright 2014 Google LLC\nCopyright 2017 Google LLC\nCopyright 2018 Google Inc. All Rights Reserved.\nCopyright 2020, Google LLC\nCopyright 2017, Google LLC\n\n-------- Dependency\ncontrib.go.opencensus.io/exporter/prometheus\n-------- Copyrights\nCopyright 2017, OpenCensus Authors\nCopyright 2018, OpenCensus Authors\n\n-------- Dependency\ngithub.com/OneOfOne/xxhash\n-------- Copyrights\nThe C implementation is ([Copyright](https://github.com/Cyan4973/xxHash/blob/master/LICENSE) (c) 2012-2014, Yann Collet)\n\n-------- Dependency\ngithub.com/go-logr/logr\n-------- Copyrights\nCopyright 2020 The logr Authors.\nCopyright 2019 The logr Authors.\nCopyright 2021 The logr Authors.\n\n-------- Dependency\ngithub.com/go-logr/zapr\n-------- Copyrights\nCopyright 2019 The logr Authors.\nCopyright 2018 Solly Ross\n\n-------- Dependency\ngithub.com/go-openapi/jsonpointer\n-------- Copyrights\nCopyright 2013 sigu-399 ( https://github.com/sigu-399 )\n\n-------- Dependency\ngithub.com/go-openapi/jsonreference\n-------- Copyrights\nCopyright 2013 sigu-399 ( https://github.com/sigu-399 )\n\n-------- Dependency\ngithub.com/go-openapi/spec\n-------- Copyrights\nCopyright 2015 go-swagger maintainers\nCopyright 2017 go-swagger maintainers\n\n-------- Dependency\ngithub.com/go-openapi/swag\n-------- Copyrights\nCopyright 2015 go-swagger maintainers\n\n-------- Dependency\ngithub.com/golang/glog\n-------- Copyrights\nCopyright 2013 Google Inc. All Rights Reserved.\n\n-------- Dependency\ngithub.com/golang/groupcache\n-------- Copyrights\nCopyright 2012 Google Inc.\nCopyright 2013 Google Inc.\n\n-------- Dependency\ngithub.com/google/gofuzz\n-------- Copyrights\nCopyright 2014 Google Inc. All rights reserved.\n\n-------- Dependency\ngithub.com/googleapis/gnostic\n-------- Copyrights\nCopyright 2017-2020, Google LLC.\nCopyright 2019 Google LLC. All Rights Reserved.\nCopyright 2020 Google LLC. All Rights Reserved.\nCopyright 2017 Google LLC. All Rights Reserved.\nCopyright 2018 Google LLC. All Rights Reserved.\nCopyright 2020 Google LLC. All Rights Reserved.\\n\" +\n\n-------- Dependency\ngithub.com/matttproud/golang_protobuf_extensions\n-------- Copyrights\nCopyright 2012 Matt T. Proud (matt.proud@gmail.com)\nCopyright 2013 Matt T. Proud\nCopyright 2016 Matt T. Proud\n-------- Notices\nCopyright 2012 Matt T. Proud (matt.proud@gmail.com)\n\n\n-------- Dependency\ngithub.com/modern-go/concurrent\n-------- Copyrights\n\n-------- Dependency\ngithub.com/modern-go/reflect2\n-------- Copyrights\n\n-------- Dependency\ngithub.com/open-policy-agent/cert-controller\n-------- Copyrights\nCopyright 2018-2020 The Gatekeeper Authors\n-------- Notices\ncert-controller\nCopyright 2018-2020 The Gatekeeper Authors\n\n\n\n-------- Dependency\ngithub.com/open-policy-agent/frameworks/constraint\n-------- Copyrights\nCopyright 2017 The OPA Authors.  All rights reserved.\nCopyright 2018 The OPA Authors.  All rights reserved.\n\n-------- Dependency\ngithub.com/open-policy-agent/opa\n-------- Copyrights\nCopyright 2016 The OPA Authors.  All rights reserved.\nCopyright 2017 The OPA Authors.  All rights reserved.\nCopyright 2020 The OPA Authors.  All rights reserved.\nCopyright 2019 The OPA Authors.  All rights reserved.\nCopyright 2018 The OPA Authors.  All rights reserved.\nCopyright 2021 The OPA Authors.  All rights reserved.\nCopyright (c) 2019 Jeremy Thomas\nCode copyright 2019 Jeremy Thomas. Code released under [the MIT license](https://github.com/jgthms/bulma/blob/master/LICENSE).\nCopyright 2017-2020 Authors of Cilium\n_, err := out.Write([]byte(`// Copyright 2018 The OPA Authors.  All rights reserved.\nCopyright 2015 xeipuuv\nCopyright 2018 johandorland ( https://github.com/johandorland )\nCopyright 2015 xeipuuv ( https://github.com/xeipuuv )\nCopyright 2013 MongoDB, Inc.\nCopyright 2017 johandorland ( https://github.com/johandorland )\nCopyright (c) 2015 lestrrat\nCopyright 2011 The Go Authors. All rights reserved.\nCopyright 2013-2015 CoreOS, Inc.\nCopyright The Helm Authors.\nCopyright 2012 The Gorilla Authors. All rights reserved.\nCopyright (c) 2012 Rodrigo Moraes. All rights reserved.\nCopyright 2021 icza\n\n-------- Dependency\ngithub.com/prometheus/client_golang\n-------- Copyrights\nCopyright 2018 The Prometheus Authors\nCopyright 2012-2015 The Prometheus Authors\nCopyright 2013-2015 Blake Mizerany, Björn Rabenstein\nCopyright 2010 The Go Authors\nCopyright 2013 Matt T. Proud\nCopyright 2015 The Prometheus Authors\nCopyright 2017 The Prometheus Authors\nCopyright 2019 The Prometheus Authors\nCopyright 2014 The Prometheus Authors\nCopyright 2021 The Prometheus Authors\nCopyright 2016 The Prometheus Authors\nCopyright 2020 The Prometheus Authors\nCopyright (c) 2013, The Prometheus Authors\n-------- Notices\nPrometheus instrumentation library for Go applications\nCopyright 2012-2015 The Prometheus Authors\n\nThis product includes software developed at\nSoundCloud Ltd. (http://soundcloud.com/).\n\n\nThe following components are included in this product:\n\nperks - a fork of https://github.com/bmizerany/perks\nhttps://github.com/beorn7/perks\nCopyright 2013-2015 Blake Mizerany, Björn Rabenstein\nSee https://github.com/beorn7/perks/blob/master/README.md for license details.\n\nGo support for Protocol Buffers - Google's data interchange format\nhttp://github.com/golang/protobuf/\nCopyright 2010 The Go Authors\nSee source code for license details.\n\nSupport for streaming Protocol Buffer messages for the Go language (golang).\nhttps://github.com/matttproud/golang_protobuf_extensions\nCopyright 2013 Matt T. Proud\nLicensed under the Apache License, Version 2.0\n\n\n-------- Dependency\ngithub.com/prometheus/client_model\n-------- Copyrights\nCopyright 2013 Prometheus Team\nCopyright 2012-2015 The Prometheus Authors\n-------- Notices\nData model artifacts for Prometheus.\nCopyright 2012-2015 The Prometheus Authors\n\nThis product includes software developed at\nSoundCloud Ltd. (http://soundcloud.com/).\n\n\n-------- Dependency\ngithub.com/prometheus/common\n-------- Copyrights\nCopyright 2018 The Prometheus Authors\nCopyright 2015 The Prometheus Authors\nCopyright 2016 The Prometheus Authors\nCopyright 2021 The Prometheus Authors\nCopyright 2014 The Prometheus Authors\nCopyright 2020 The Prometheus Authors\nCopyright (c) 2011, Open Knowledge Foundation Ltd.\nCopyright 2013 The Prometheus Authors\nCopyright 2019 The Prometheus Authors\nCopyright 2017 The Prometheus Authors\n-------- Notices\nCommon libraries shared by Prometheus Go components.\nCopyright 2015 The Prometheus Authors\n\nThis product includes software developed at\nSoundCloud Ltd. (http://soundcloud.com/).\n\n\n-------- Dependency\ngithub.com/prometheus/procfs\n-------- Copyrights\nCopyright 2018 The Prometheus Authors\nCopyright 2014-2015 The Prometheus Authors\nCopyright 2019 The Prometheus Authors\nCopyright 2017 The Prometheus Authors\nCopyright 2021 The Prometheus Authors\nCopyright 2020 The Prometheus Authors\nCopyright 2014 Prometheus Team\nCopyright 2017 Prometheus Team\n-------- Notices\nprocfs provides functions to retrieve system, kernel and process\nmetrics from the pseudo-filesystem proc.\n\nCopyright 2014-2015 The Prometheus Authors\n\nThis product includes software developed at\nSoundCloud Ltd. (http://soundcloud.com/).\n\n\n-------- Dependency\ngithub.com/prometheus/statsd_exporter\n-------- Copyrights\nCopyright 2013 The Prometheus Authors\nCopyright 2018 The Prometheus Authors\nCopyright 2013-2015 The Prometheus Authors\nCopyright 2020 The Prometheus Authors\nCopyright 2019 The Prometheus Authors\nCopyright 2021 The Prometheus Authors\n-------- Notices\nStatsD-to-Prometheus exporter\nCopyright 2013-2015 The Prometheus Authors\n\nThis product includes software developed at\nSoundCloud Ltd. (http://soundcloud.com/).\n\n\n-------- Dependency\ngithub.com/spf13/cobra\n-------- Copyrights\nCopyright © 2020 Steve Francia <spf@spf13.com>\nCopyright © 2015 Steve Francia <spf@spf13.com>.\nCopyright:    copyrightLine(),\nCopyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nCopyright (C) 1989, 1991 Free Software Foundation, Inc.,\nCopyright    string\ncopyright\": copyrightLine(),\nCopyright © 2013 Steve Francia <spf@spf13.com>.\nCopyright 2015 Red Hat Inc. All rights reserved.\nCopyright 2016 French Ben. All rights reserved.\n\n-------- Dependency\ngithub.com/xeipuuv/gojsonpointer\n-------- Copyrights\nCopyright 2015 xeipuuv\nCopyright 2015 xeipuuv ( https://github.com/xeipuuv )\n\n-------- Dependency\ngithub.com/xeipuuv/gojsonreference\n-------- Copyrights\nCopyright 2015 xeipuuv\nCopyright 2015 xeipuuv ( https://github.com/xeipuuv )\n\n-------- Dependency\ngithub.com/yashtewari/glob-intersection\n-------- Copyrights\n\n-------- Dependency\ngo.opencensus.io\n-------- Copyrights\nCopyright 2019, OpenCensus Authors\nCopyright 2017, OpenCensus Authors\nCopyright 2018, OpenCensus Authors\nCopyright 2020, OpenCensus Authors\n\n-------- Dependency\ngomodules.xyz/jsonpatch/v2\n-------- Copyrights\n\n-------- Dependency\ngoogle.golang.org/genproto\n-------- Copyrights\nCopyright 2020 Google LLC.\nCopyright 2020 Google LLC\nCopyright 2019 Google LLC.\nCopyright (c) 2015, Google Inc.\nCopyright 2016 Google Inc.\nCopyright 2017 Google Inc.\nCopyright 2018 Google Inc.\nCopyright 2018 Google LLC\nCopyright 2018 The Grafeas Authors. All rights reserved.\nCopyright 2019 Google LLC\n\n-------- Dependency\ngoogle.golang.org/grpc\n-------- Copyrights\nCopyright 2019 gRPC authors.\nCopyright 2017 gRPC authors.\nCopyright 2015 The gRPC Authors\nCopyright 2016 gRPC authors.\nCopyright 2018 gRPC authors.\nCopyright 2020 gRPC authors.\nCopyright 2020 The gRPC Authors\nCopyright 2014 gRPC authors.\nCopyright 2018 The gRPC Authors\nCopyright 2015 gRPC authors.\nCopyright 2019 Istio Authors. All Rights Reserved.\nCopyright 2016 The gRPC Authors\nCopyright 2015-2016 gRPC authors.\n\n-------- Dependency\ngopkg.in/yaml.v2\n-------- Copyrights\nCopyright (c) 2006 Kirill Simonov\nCopyright 2011-2016 Canonical Ltd.\n-------- Notices\nCopyright 2011-2016 Canonical Ltd.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n\n-------- Dependency\nk8s.io/api\n-------- Copyrights\nCopyright 2019 The Kubernetes Authors.\nCopyright The Kubernetes Authors.\nCopyright 2017 The Kubernetes Authors.\nCopyright 2016 The Kubernetes Authors.\nCopyright 2015 The Kubernetes Authors.\nCopyright 2018 The Kubernetes Authors.\nCopyright 2020 The Kubernetes Authors.\n\n-------- Dependency\nk8s.io/apiextensions-apiserver\n-------- Copyrights\nCopyright 2019 The Kubernetes Authors.\nCopyright 2017 The Kubernetes Authors.\nCopyright The Kubernetes Authors.\nCopyright 2018 The Kubernetes Authors.\nCopyright 2020 The Kubernetes Authors.\nCopyright 2016 The Kubernetes Authors.\n\n-------- Dependency\nk8s.io/apimachinery\n-------- Copyrights\nCopyright 2017 The Kubernetes Authors.\nCopyright 2019 The Kubernetes Authors.\nCopyright 2014 The Kubernetes Authors.\nCopyright 2020 The Kubernetes Authors.\nCopyright 2015 The Kubernetes Authors.\nCopyright 2016 The Kubernetes Authors.\nCopyright 2018 The Kubernetes Authors.\nCopyright The Kubernetes Authors.\nCopyright 2013 The Go Authors. All rights reserved.\nCopyright 2009 The Go Authors. All rights reserved.\n\n-------- Dependency\nk8s.io/apiserver\n-------- Copyrights\nCopyright 2014 The Kubernetes Authors.\nCopyright 2018 The Kubernetes Authors.\nCopyright 2015 The Kubernetes Authors.\nCopyright 2017 The Kubernetes Authors.\nCopyright 2020 The Kubernetes Authors.\nCopyright 2016 The Kubernetes Authors.\nCopyright 2019 The Kubernetes Authors.\nCopyright The Kubernetes Authors.\n\n-------- Dependency\nk8s.io/client-go\n-------- Copyrights\nCopyright 2016 The Kubernetes Authors.\nCopyright 2017 The Kubernetes Authors.\nCopyright 2019 The Kubernetes Authors.\nCopyright 2015 The Kubernetes Authors.\nCopyright 2014 The Kubernetes Authors.\nCopyright 2018 The Kubernetes Authors.\nCopyright The Kubernetes Authors.\nCopyright 2020 The Kubernetes Authors.\n\n-------- Dependency\nk8s.io/component-base\n-------- Copyrights\nCopyright 2017 The Kubernetes Authors.\nCopyright 2020 The Kubernetes Authors.\nCopyright 2014 The Kubernetes Authors.\nCopyright 2016 The Kubernetes Authors.\nCopyright 2018 The Kubernetes Authors.\nCopyright 2019 The Kubernetes Authors.\nCopyright The Kubernetes Authors.\nCopyright 2015 The Kubernetes Authors.\n\n-------- Dependency\nk8s.io/klog/v2\n-------- Copyrights\nCopyright 2013 Google Inc. All Rights Reserved.\nCopyright 2020 The Kubernetes Authors.\n\n-------- Dependency\nk8s.io/kube-openapi\n-------- Copyrights\nCopyright The Kubernetes Authors.\nCopyright 2018 The Kubernetes Authors.\nCopyright 2017 The Kubernetes Authors.\nCopyright 2019 The Kubernetes Authors.\nCopyright 2016 The Kubernetes Authors.\nCopyright 2020 The Kubernetes Authors.\nCopyright 2015 go-swagger maintainers\nCopyright (C) MongoDB, Inc. 2017-present.\nCopyright 2017 go-swagger maintainers\n\n-------- Dependency\nk8s.io/utils\n-------- Copyrights\nCopyright 2018 The Kubernetes Authors.\nCopyright 2017 The Kubernetes Authors.\nCopyright 2014 The Kubernetes Authors.\nCopyright 2015 The Kubernetes Authors.\nCopyright 2016 The Kubernetes Authors.\nCopyright 2020 The Kubernetes Authors.\nCopyright 2019 The Kubernetes Authors.\nCopyright (c) 2009 The Go Authors. All rights reserved.\nCopyright 2010 The Go Authors. All rights reserved.\nCopyright (c) 2012 The Go Authors. All rights reserved.\nCopyright 2009 The Go Authors. All rights reserved.\n\n-------- Dependency\nsigs.k8s.io/apiserver-network-proxy/konnectivity-client\n-------- Copyrights\nCopyright 2019 The Kubernetes Authors.\nCopyright The Kubernetes Authors.\n\n-------- Dependency\nsigs.k8s.io/controller-runtime\n-------- Copyrights\nCopyright 2020 The Kubernetes Authors.\nCopyright 2018 The Kubernetes Authors.\nCopyright 2019 The Kubernetes Authors.\nCopyright 2018 The Kubernetes authors.\nCopyright 2017 The Kubernetes Authors.\nCopyright 2016 The Kubernetes Authors.\nCopyright 2014 The Kubernetes Authors.\n\n-------- Dependency\nsigs.k8s.io/structured-merge-diff/v4\n-------- Copyrights\nCopyright 2018 The Kubernetes Authors.\nCopyright 2019 The Kubernetes Authors.\nCopyright 2020 The Kubernetes Authors.\n\n-------- Dependencies Summary\ncloud.google.com/go\ncontrib.go.opencensus.io/exporter/prometheus\ngithub.com/OneOfOne/xxhash\ngithub.com/go-logr/logr\ngithub.com/go-logr/zapr\ngithub.com/go-openapi/jsonpointer\ngithub.com/go-openapi/jsonreference\ngithub.com/go-openapi/spec\ngithub.com/go-openapi/swag\ngithub.com/golang/glog\ngithub.com/golang/groupcache\ngithub.com/google/gofuzz\ngithub.com/googleapis/gnostic\ngithub.com/matttproud/golang_protobuf_extensions\ngithub.com/modern-go/concurrent\ngithub.com/modern-go/reflect2\ngithub.com/open-policy-agent/cert-controller\ngithub.com/open-policy-agent/frameworks/constraint\ngithub.com/open-policy-agent/opa\ngithub.com/prometheus/client_golang\ngithub.com/prometheus/client_model\ngithub.com/prometheus/common\ngithub.com/prometheus/procfs\ngithub.com/prometheus/statsd_exporter\ngithub.com/spf13/cobra\ngithub.com/xeipuuv/gojsonpointer\ngithub.com/xeipuuv/gojsonreference\ngithub.com/yashtewari/glob-intersection\ngo.opencensus.io\ngomodules.xyz/jsonpatch/v2\ngoogle.golang.org/genproto\ngoogle.golang.org/grpc\ngopkg.in/yaml.v2\nk8s.io/api\nk8s.io/apiextensions-apiserver\nk8s.io/apimachinery\nk8s.io/apiserver\nk8s.io/client-go\nk8s.io/component-base\nk8s.io/klog/v2\nk8s.io/kube-openapi\nk8s.io/utils\nsigs.k8s.io/apiserver-network-proxy/konnectivity-client\nsigs.k8s.io/controller-runtime\nsigs.k8s.io/structured-merge-diff/v4\n\n-------- License used by Dependencies\nSPDX:Apache-2.0\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n----------------------- Dependencies Grouped by License ------------\n-------- Dependency\ngithub.com/PuerkitoBio/urlesc\n-------- Copyrights\nCopyright (c) 2012 The Go Authors. All rights reserved.\nCopyright 2009 The Go Authors. All rights reserved.\n\n-------- Dependency\ngithub.com/fsnotify/fsnotify\n-------- Copyrights\nCopyright (c) 2012 The Go Authors. All rights reserved.\nCopyright (c) 2012-2019 fsnotify Authors. All rights reserved.\nCopyright 2010 The Go Authors. All rights reserved.\nCopyright 2012 The Go Authors. All rights reserved.\nCopyright 2016 The Go Authors. All rights reserved.\nCopyright 2015 The Go Authors. All rights reserved.\nCopyright 2013 The Go Authors. All rights reserved.\nCopyright 2011 The Go Authors. All rights reserved.\n\n-------- Dependency\ngithub.com/gogo/protobuf\n-------- Copyrights\nCopyright (c) 2013, The GoGo Authors. All rights reserved.\nCopyright 2010 The Go Authors.  All rights reserved.\nCopyright 2010 The Go Authors.\nCopyright (c) 2015, The GoGo Authors. All rights reserved.\nCopyright 2016 The Go Authors.  All rights reserved.\nCopyright 2015 The Go Authors.  All rights reserved.\nCopyright 2011 The Go Authors.  All rights reserved.\nCopyright (c) 2018, The GoGo Authors. All rights reserved.\nCopyright 2018 The Go Authors.  All rights reserved.\nCopyright 2017 The Go Authors.  All rights reserved.\nCopyright (c) 2016, The GoGo Authors. All rights reserved.\nCopyright 2014 The Go Authors.  All rights reserved.\nCopyright 2012 The Go Authors.  All rights reserved.\nCopyright 2013 The Go Authors.  All rights reserved.\nCopyright (c) 2019, The GoGo Authors. All rights reserved.\nCopyright (c) 2017, The GoGo Authors. All rights reserved.\nCopyright (c) 2015, The GoGo Authors.  rights reserved.\n\n-------- Dependency\ngithub.com/golang/protobuf\n-------- Copyrights\nCopyright 2010 The Go Authors.  All rights reserved.\nCopyright 2016 The Go Authors. All rights reserved.\nCopyright 2020 The Go Authors. All rights reserved.\nCopyright 2019 The Go Authors. All rights reserved.\nCopyright 2018 The Go Authors. All rights reserved.\nCopyright 2015 The Go Authors. All rights reserved.\nCopyright 2017 The Go Authors. All rights reserved.\nCopyright 2010 The Go Authors. All rights reserved.\nCopyright 2014 The Go Authors. All rights reserved.\nCopyright 2011 The Go Authors. All rights reserved.\nCopyright 2015 The Go Authors.  All rights reserved.\n\n-------- Dependency\ngithub.com/google/go-cmp\n-------- Copyrights\nCopyright (c) 2017 The Go Authors. All rights reserved.\nCopyright 2017, The Go Authors. All rights reserved.\nCopyright 2021, The Go Authors. All rights reserved.\nCopyright 2020, The Go Authors. All rights reserved.\nCopyright 2018, The Go Authors. All rights reserved.\nCopyright 2019, The Go Authors. All rights reserved.\n\n-------- Dependency\ngithub.com/google/uuid\n-------- Copyrights\nCopyright (c) 2009,2014 Google Inc. All rights reserved.\nCopyright 2016 Google Inc.  All rights reserved.\nCopyright 2017 Google Inc.  All rights reserved.\nCopyright 2018 Google Inc.  All rights reserved.\n\n-------- Dependency\ngithub.com/imdario/mergo\n-------- Copyrights\nCopyright (c) 2013 Dario Castañé. All rights reserved.\nCopyright (c) 2012 The Go Authors. All rights reserved.\nCopyright 2013 Dario Castañé. All rights reserved.\nCopyright 2009 The Go Authors. All rights reserved.\nCopyright 2014 Dario Castañé. All rights reserved.\n\n-------- Dependency\ngithub.com/spf13/pflag\n-------- Copyrights\nCopyright (c) 2012 Alex Ogier. All rights reserved.\nCopyright (c) 2012 The Go Authors. All rights reserved.\nCopyright 2009 The Go Authors. All rights reserved.\nCopyright 2012 The Go Authors. All rights reserved.\nCopyright 2010 The Go Authors.  All rights reserved.\n\n-------- Dependency\ngolang.org/x/crypto\n-------- Copyrights\nCopyright (c) 2009 The Go Authors. All rights reserved.\nCopyright 2015 The Go Authors. All rights reserved.\nCopyright 2016 The Go Authors. All rights reserved.\nCopyright 2017 The Go Authors. All rights reserved.\nCopyright 2018 The Go Authors. All rights reserved.\nCopyright 2019 The Go Authors. All rights reserved.\nCopyright 2011 The Go Authors. All rights reserved.\nCopyright 2010 The Go Authors. All rights reserved.\nCopyright 2012 The Go Authors. All rights reserved.\nCopyright 2013 The Go Authors. All rights reserved.\nCopyright 2014 The Go Authors. All rights reserved.\nCopyright 2020 The Go Authors. All rights reserved.\nCopyright 2009 The Go Authors. All rights reserved.\n-------- Patents\nAdditional IP Rights Grant (Patents)\n\n\"This implementation\" means the copyrightable works distributed by\nGoogle as part of the Go project.\n\nGoogle hereby grants to You a perpetual, worldwide, non-exclusive,\nno-charge, royalty-free, irrevocable (except as stated in this section)\npatent license to make, have made, use, offer to sell, sell, import,\ntransfer and otherwise run, modify and propagate the contents of this\nimplementation of Go, where such license applies only to those patent\nclaims, both currently owned or controlled by Google and acquired in\nthe future, licensable by Google that are necessarily infringed by this\nimplementation of Go.  This grant does not include claims that would be\ninfringed only as a consequence of further modification of this\nimplementation.  If you or your agent or exclusive licensee institute or\norder or agree to the institution of patent litigation against any\nentity (including a cross-claim or counterclaim in a lawsuit) alleging\nthat this implementation of Go or any code incorporated within this\nimplementation of Go constitutes direct or contributory patent\ninfringement, or inducement of patent infringement, then any patent\nrights granted to you under this License for this implementation of Go\nshall terminate as of the date such litigation is filed.\n\n\n-------- Dependency\ngolang.org/x/net\n-------- Copyrights\nCopyright (c) 2009 The Go Authors. All rights reserved.\nCopyright 2016 The Go Authors. All rights reserved.\nCopyright 2017 The Go Authors. All rights reserved.\nCopyright 2014 The Go Authors. All rights reserved.\nCopyright 2015 The Go Authors. All rights reserved.\nCopyright 2010 The Go Authors. All rights reserved.\nCopyright 2009 The Go Authors. All rights reserved.\nCopyright 2012 The Go Authors. All rights reserved.\nCopyright 2013 The Go Authors. All rights reserved.\nCopyright 2011 The Go Authors. All rights reserved.\nCopyright (C) 2009 Apple Inc. All rights reserved.\nCopyright 2018 The Go Authors. All rights reserved.\nCopyright 2021 The Go Authors. All rights reserved.\nCopyright 2020 The Go Authors. All rights reserved.\nCopyright 2019 The Go Authors. All rights reserved.\n-------- Patents\nAdditional IP Rights Grant (Patents)\n\n\"This implementation\" means the copyrightable works distributed by\nGoogle as part of the Go project.\n\nGoogle hereby grants to You a perpetual, worldwide, non-exclusive,\nno-charge, royalty-free, irrevocable (except as stated in this section)\npatent license to make, have made, use, offer to sell, sell, import,\ntransfer and otherwise run, modify and propagate the contents of this\nimplementation of Go, where such license applies only to those patent\nclaims, both currently owned or controlled by Google and acquired in\nthe future, licensable by Google that are necessarily infringed by this\nimplementation of Go.  This grant does not include claims that would be\ninfringed only as a consequence of further modification of this\nimplementation.  If you or your agent or exclusive licensee institute or\norder or agree to the institution of patent litigation against any\nentity (including a cross-claim or counterclaim in a lawsuit) alleging\nthat this implementation of Go or any code incorporated within this\nimplementation of Go constitutes direct or contributory patent\ninfringement, or inducement of patent infringement, then any patent\nrights granted to you under this License for this implementation of Go\nshall terminate as of the date such litigation is filed.\n\n\n-------- Dependency\ngolang.org/x/oauth2\n-------- Copyrights\nCopyright (c) 2009 The Go Authors. All rights reserved.\nCopyright 2017 The oauth2 Authors. All rights reserved.\nCopyright 2021 The Go Authors. All rights reserved.\nCopyright 2015 The oauth2 Authors. All rights reserved.\nCopyright 2018 The Go Authors. All rights reserved.\nCopyright 2014 The Go Authors. All rights reserved.\nCopyright 2019 The Go Authors. All rights reserved.\nCopyright 2015 The Go Authors. All rights reserved.\nCopyright 2016 The Go Authors. All rights reserved.\nCopyright 2020 The Go Authors. All rights reserved.\nCopyright 2017 The Go Authors. All rights reserved.\nCopyright 2018 The oauth2 Authors. All rights reserved.\n\n-------- Dependency\ngolang.org/x/sync\n-------- Copyrights\nCopyright (c) 2009 The Go Authors. All rights reserved.\nCopyright 2016 The Go Authors. All rights reserved.\nCopyright 2017 The Go Authors. All rights reserved.\nCopyright 2013 The Go Authors. All rights reserved.\nCopyright 2019 The Go Authors. All rights reserved.\n-------- Patents\nAdditional IP Rights Grant (Patents)\n\n\"This implementation\" means the copyrightable works distributed by\nGoogle as part of the Go project.\n\nGoogle hereby grants to You a perpetual, worldwide, non-exclusive,\nno-charge, royalty-free, irrevocable (except as stated in this section)\npatent license to make, have made, use, offer to sell, sell, import,\ntransfer and otherwise run, modify and propagate the contents of this\nimplementation of Go, where such license applies only to those patent\nclaims, both currently owned or controlled by Google and acquired in\nthe future, licensable by Google that are necessarily infringed by this\nimplementation of Go.  This grant does not include claims that would be\ninfringed only as a consequence of further modification of this\nimplementation.  If you or your agent or exclusive licensee institute or\norder or agree to the institution of patent litigation against any\nentity (including a cross-claim or counterclaim in a lawsuit) alleging\nthat this implementation of Go or any code incorporated within this\nimplementation of Go constitutes direct or contributory patent\ninfringement, or inducement of patent infringement, then any patent\nrights granted to you under this License for this implementation of Go\nshall terminate as of the date such litigation is filed.\n\n\n-------- Dependency\ngolang.org/x/sys\n-------- Copyrights\nCopyright (c) 2009 The Go Authors. All rights reserved.\nCopyright 2019 The Go Authors. All rights reserved.\nCopyright 2018 The Go Authors. All rights reserved.\nCopyright 2020 The Go Authors. All rights reserved.\nCopyright 2012 The Go Authors. All rights reserved.\nCopyright 2011 The Go Authors. All rights reserved.\nCopyright 2015 The Go Authors. All rights reserved.\nCopyright 2009 The Go Authors. All rights reserved.\nCopyright 2013 The Go Authors. All rights reserved.\nCopyright 2016 The Go Authors. All rights reserved.\nCopyright 2017 The Go Authors. All rights reserved.\nCopyright 2010 The Go Authors. All rights reserved.\nCopyright 2014 The Go Authors. All rights reserved.\nCopyright 2021 The Go Authors. All rights reserved.\nCopyright 2009,2010 The Go Authors. All rights reserved.\nCopyright 2017 The Go Authors. All right reserved.\n-------- Patents\nAdditional IP Rights Grant (Patents)\n\n\"This implementation\" means the copyrightable works distributed by\nGoogle as part of the Go project.\n\nGoogle hereby grants to You a perpetual, worldwide, non-exclusive,\nno-charge, royalty-free, irrevocable (except as stated in this section)\npatent license to make, have made, use, offer to sell, sell, import,\ntransfer and otherwise run, modify and propagate the contents of this\nimplementation of Go, where such license applies only to those patent\nclaims, both currently owned or controlled by Google and acquired in\nthe future, licensable by Google that are necessarily infringed by this\nimplementation of Go.  This grant does not include claims that would be\ninfringed only as a consequence of further modification of this\nimplementation.  If you or your agent or exclusive licensee institute or\norder or agree to the institution of patent litigation against any\nentity (including a cross-claim or counterclaim in a lawsuit) alleging\nthat this implementation of Go or any code incorporated within this\nimplementation of Go constitutes direct or contributory patent\ninfringement, or inducement of patent infringement, then any patent\nrights granted to you under this License for this implementation of Go\nshall terminate as of the date such litigation is filed.\n\n\n-------- Dependency\ngolang.org/x/term\n-------- Copyrights\nCopyright (c) 2009 The Go Authors. All rights reserved.\nCopyright 2019 The Go Authors. All rights reserved.\nCopyright 2013 The Go Authors. All rights reserved.\nCopyright 2020 The Go Authors. All rights reserved.\nCopyright 2011 The Go Authors. All rights reserved.\n-------- Patents\nAdditional IP Rights Grant (Patents)\n\n\"This implementation\" means the copyrightable works distributed by\nGoogle as part of the Go project.\n\nGoogle hereby grants to You a perpetual, worldwide, non-exclusive,\nno-charge, royalty-free, irrevocable (except as stated in this section)\npatent license to make, have made, use, offer to sell, sell, import,\ntransfer and otherwise run, modify and propagate the contents of this\nimplementation of Go, where such license applies only to those patent\nclaims, both currently owned or controlled by Google and acquired in\nthe future, licensable by Google that are necessarily infringed by this\nimplementation of Go.  This grant does not include claims that would be\ninfringed only as a consequence of further modification of this\nimplementation.  If you or your agent or exclusive licensee institute or\norder or agree to the institution of patent litigation against any\nentity (including a cross-claim or counterclaim in a lawsuit) alleging\nthat this implementation of Go or any code incorporated within this\nimplementation of Go constitutes direct or contributory patent\ninfringement, or inducement of patent infringement, then any patent\nrights granted to you under this License for this implementation of Go\nshall terminate as of the date such litigation is filed.\n\n\n-------- Dependency\ngolang.org/x/text\n-------- Copyrights\nCopyright (c) 2009 The Go Authors. All rights reserved.\nCopyright 2014 The Go Authors. All rights reserved.\nCopyright 2016 The Go Authors. All rights reserved.\nCopyright 2015 The Go Authors. All rights reserved.\nCopyright 2017 The Go Authors. All rights reserved.\nCopyright 2012 The Go Authors. All rights reserved.\nCopyright 2013 The Go Authors. All rights reserved.\nCopyright 2019 The Go Authors. All rights reserved.\nCopyright 2018 The Go Authors. All rights reserved.\nCopyright 2009 The Go Authors. All rights reserved.\nCopyright 2011 The Go Authors. All rights reserved.\n-------- Patents\nAdditional IP Rights Grant (Patents)\n\n\"This implementation\" means the copyrightable works distributed by\nGoogle as part of the Go project.\n\nGoogle hereby grants to You a perpetual, worldwide, non-exclusive,\nno-charge, royalty-free, irrevocable (except as stated in this section)\npatent license to make, have made, use, offer to sell, sell, import,\ntransfer and otherwise run, modify and propagate the contents of this\nimplementation of Go, where such license applies only to those patent\nclaims, both currently owned or controlled by Google and acquired in\nthe future, licensable by Google that are necessarily infringed by this\nimplementation of Go.  This grant does not include claims that would be\ninfringed only as a consequence of further modification of this\nimplementation.  If you or your agent or exclusive licensee institute or\norder or agree to the institution of patent litigation against any\nentity (including a cross-claim or counterclaim in a lawsuit) alleging\nthat this implementation of Go or any code incorporated within this\nimplementation of Go constitutes direct or contributory patent\ninfringement, or inducement of patent infringement, then any patent\nrights granted to you under this License for this implementation of Go\nshall terminate as of the date such litigation is filed.\n\n\n-------- Dependency\ngolang.org/x/time\n-------- Copyrights\nCopyright (c) 2009 The Go Authors. All rights reserved.\nCopyright 2015 The Go Authors. All rights reserved.\n-------- Patents\nAdditional IP Rights Grant (Patents)\n\n\"This implementation\" means the copyrightable works distributed by\nGoogle as part of the Go project.\n\nGoogle hereby grants to You a perpetual, worldwide, non-exclusive,\nno-charge, royalty-free, irrevocable (except as stated in this section)\npatent license to make, have made, use, offer to sell, sell, import,\ntransfer and otherwise run, modify and propagate the contents of this\nimplementation of Go, where such license applies only to those patent\nclaims, both currently owned or controlled by Google and acquired in\nthe future, licensable by Google that are necessarily infringed by this\nimplementation of Go.  This grant does not include claims that would be\ninfringed only as a consequence of further modification of this\nimplementation.  If you or your agent or exclusive licensee institute or\norder or agree to the institution of patent litigation against any\nentity (including a cross-claim or counterclaim in a lawsuit) alleging\nthat this implementation of Go or any code incorporated within this\nimplementation of Go constitutes direct or contributory patent\ninfringement, or inducement of patent infringement, then any patent\nrights granted to you under this License for this implementation of Go\nshall terminate as of the date such litigation is filed.\n\n\n-------- Dependency\ngoogle.golang.org/protobuf\n-------- Copyrights\nCopyright (c) 2018 The Go Authors. All rights reserved.\nCopyright 2018 The Go Authors. All rights reserved.\nCopyright 2019 The Go Authors. All rights reserved.\nCopyright 2020 The Go Authors. All rights reserved.\nCopyright 2019 The Go Authors. All rights reserved.\",\nCopyright 2018 The Go Authors. All rights reserved.\",\nCopyright 2008 Google Inc.  All rights reserved.\nCopyright 2021 The Go Authors. All rights reserved.\n-------- Patents\nAdditional IP Rights Grant (Patents)\n\n\"This implementation\" means the copyrightable works distributed by\nGoogle as part of the Go project.\n\nGoogle hereby grants to You a perpetual, worldwide, non-exclusive,\nno-charge, royalty-free, irrevocable (except as stated in this section)\npatent license to make, have made, use, offer to sell, sell, import,\ntransfer and otherwise run, modify and propagate the contents of this\nimplementation of Go, where such license applies only to those patent\nclaims, both currently owned or controlled by Google and acquired in\nthe future, licensable by Google that are necessarily infringed by this\nimplementation of Go.  This grant does not include claims that would be\ninfringed only as a consequence of further modification of this\nimplementation.  If you or your agent or exclusive licensee institute or\norder or agree to the institution of patent litigation against any\nentity (including a cross-claim or counterclaim in a lawsuit) alleging\nthat this implementation of Go or any code incorporated within this\nimplementation of Go constitutes direct or contributory patent\ninfringement, or inducement of patent infringement, then any patent\nrights granted to you under this License for this implementation of Go\nshall terminate as of the date such litigation is filed.\n\n\n-------- Dependency\ngopkg.in/inf.v0\n-------- Copyrights\nCopyright (c) 2012 Péter Surányi. Portions Copyright (c) 2009 The Go\n\n-------- Dependencies Summary\ngithub.com/PuerkitoBio/urlesc\ngithub.com/fsnotify/fsnotify\ngithub.com/gogo/protobuf\ngithub.com/golang/protobuf\ngithub.com/google/go-cmp\ngithub.com/google/uuid\ngithub.com/imdario/mergo\ngithub.com/spf13/pflag\ngolang.org/x/crypto\ngolang.org/x/net\ngolang.org/x/oauth2\ngolang.org/x/sync\ngolang.org/x/sys\ngolang.org/x/term\ngolang.org/x/text\ngolang.org/x/time\ngoogle.golang.org/protobuf\ngopkg.in/inf.v0\n\n-------- License used by Dependencies\nSPDX:BSD-3-Clause--modified-by-Google\nRedistribution and use in source and binary forms, with \nor without modification, are permitted provided that the following conditions\nare met:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n----------------------- Dependencies Grouped by License ------------\n-------- Dependency\ngithub.com/davecgh/go-spew\n-------- Copyrights\nCopyright (c) 2012-2016 Dave Collins <dave@davec.name>\nCopyright (c) 2015-2016 Dave Collins <dave@davec.name>\nCopyright (c) 2013-2016 Dave Collins <dave@davec.name>\nCopyright (c) 2013 Dave Collins <dave@davec.name>\n\n-------- Dependencies Summary\ngithub.com/davecgh/go-spew\n\n-------- License used by Dependencies\nSPDX:ISC\nPermission to use, copy, modify, and/or distribute this \nsoftware for any purpose with or without fee is hereby granted, provided that \nthe above copyright notice and this permission notice appear in all copies.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH \nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY \nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, \nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM \nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR \nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR \nPERFORMANCE OF THIS SOFTWARE.\n\n----------------------- Dependencies Grouped by License ------------\n-------- Dependency\ngithub.com/asaskevich/govalidator\n-------- Copyrights\nCopyright (c) 2014-2020 Alex Saskevich\n\n-------- Dependency\ngithub.com/beorn7/perks\n-------- Copyrights\nCopyright (C) 2013 Blake Mizerany\n\n-------- Dependency\ngithub.com/blang/semver\n-------- Copyrights\nCopyright (c) 2014 Benedikt Lang <github at benediktlang.de>\n\n-------- Dependency\ngithub.com/cespare/xxhash/v2\n-------- Copyrights\nCopyright (c) 2016 Caleb Spare\n\n-------- Dependency\ngithub.com/go-kit/log\n-------- Copyrights\nCopyright (c) 2021 Go kit\nCopyright (c) 2014 Simon Eskildsen\nCopyright 2013 The Go Authors. All rights reserved.\nCopyright 2011 The Go Authors. All rights reserved.\n\n-------- Dependency\ngithub.com/go-logfmt/logfmt\n-------- Copyrights\nCopyright (c) 2015 go-logfmt\nCopyright 2010 The Go Authors. All rights reserved.\n\n-------- Dependency\ngithub.com/gobwas/glob\n-------- Copyrights\nCopyright (c) 2016 Sergey Kamardin\n\n-------- Dependency\ngithub.com/josharian/intern\n-------- Copyrights\nCopyright (c) 2019 Josh Bleecher Snyder\n\n-------- Dependency\ngithub.com/json-iterator/go\n-------- Copyrights\nCopyright (c) 2016 json-iterator\n\n-------- Dependency\ngithub.com/mailru/easyjson\n-------- Copyrights\nCopyright (c) 2016 Mail.Ru Group\nCopyright (c) 2009 The Go Authors. All rights reserved.\n\n-------- Dependency\ngithub.com/mitchellh/mapstructure\n-------- Copyrights\nCopyright (c) 2013 Mitchell Hashimoto\n\n-------- Dependency\ngo.uber.org/atomic\n-------- Copyrights\nCopyright (c) 2016 Uber Technologies, Inc.\nCopyright (c) 2019 Uber Technologies, Inc.\n\n-------- Dependency\ngo.uber.org/multierr\n-------- Copyrights\nCopyright (c) 2017 Uber Technologies, Inc.\nCopyright (c) 2019 Uber Technologies, Inc.\n\n-------- Dependency\ngo.uber.org/zap\n-------- Copyrights\nCopyright (c) 2016-2017 Uber Technologies, Inc.\nCopyright (c) 2016 Uber Technologies, Inc.\nCopyright (c) \"*\" Uber Technologies, Inc.\")\nCopyright (c) 2017 Uber Technologies, Inc.\nCopyright (c) 2019 Uber Technologies, Inc.\nCopyright (c) 2020 Uber Technologies, Inc.\nCopyright (c) 2016, 2017 Uber Technologies, Inc.\nCopyright (c) 2018 Uber Technologies, Inc.\n\n-------- Dependency\ngopkg.in/yaml.v3\n-------- Copyrights\ncopyright staring in 2011 when the project was ported over:\nCopyright (c) 2006-2010 Kirill Simonov\nCopyright (c) 2006-2011 Kirill Simonov\nCopyright (c) 2011-2019 Canonical Ltd\nCopyright 2011-2016 Canonical Ltd.\n-------- Notices\nCopyright 2011-2016 Canonical Ltd.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n\n-------- Dependencies Summary\ngithub.com/asaskevich/govalidator\ngithub.com/beorn7/perks\ngithub.com/blang/semver\ngithub.com/cespare/xxhash/v2\ngithub.com/go-kit/log\ngithub.com/go-logfmt/logfmt\ngithub.com/gobwas/glob\ngithub.com/josharian/intern\ngithub.com/json-iterator/go\ngithub.com/mailru/easyjson\ngithub.com/mitchellh/mapstructure\ngo.uber.org/atomic\ngo.uber.org/multierr\ngo.uber.org/zap\ngopkg.in/yaml.v3\n\n-------- License used by Dependencies\nSPDX:MIT\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation files\n(the \"Software\"), to deal in the Software without restriction, including without\nlimitation the rights to use, copy, modify, merge, publish, distribute,\nsublicense, and/or sell copies of the Software, and to permit persons to whom\nthe Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR \nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n----------------------- Dependencies Grouped by License ------------\n-------- Dependency\ngithub.com/ghodss/yaml\n-------- Copyrights\nCopyright (c) 2014 Sam Ghods\nCopyright (c) 2012 The Go Authors. All rights reserved.\nCopyright 2013 The Go Authors. All rights reserved.\n\n-------- Dependency\nsigs.k8s.io/yaml\n-------- Copyrights\nCopyright (c) 2014 Sam Ghods\nCopyright (c) 2012 The Go Authors. All rights reserved.\nCopyright 2013 The Go Authors. All rights reserved.\n\n-------- Dependencies Summary\ngithub.com/ghodss/yaml\nsigs.k8s.io/yaml\n\n-------- License used by Dependencies\nThe MIT License (MIT)\n\nCopyright (c) 2014 Sam Ghods\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n\nCopyright (c) 2012 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n\nATTRIBUTION-HELPER-GENERATED:\nLicense file based on go.mod with md5 sum: 8e6c0582e13472356e90672b8842731d\n"
  },
  {
    "path": "data-common.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  state_id = coalesce(var.state_id, random_string.state_id.id)\n}\n\nresource \"random_string\" \"state_id\" {\n  length  = 6\n  lower   = true\n  numeric = false\n  special = false\n  upper   = false\n}\n\noutput \"state_id\" {\n  value = local.state_id\n}\n"
  },
  {
    "path": "data-images.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# Used to retrieve available worker node images, k8s versions, shapes...\ndata \"oci_containerengine_node_pool_option\" \"oke\" {\n  count               = local.cluster_enabled ? 1 : 0\n  node_pool_option_id = \"all\"\n  compartment_id      = local.compartment_id\n}\n\nlocals {\n  k8s_versions      = toset(concat([var.kubernetes_version], [for k, v in var.worker_pools : lookup(v, \"kubernetes_version\", \"\") if lookup(v, \"kubernetes_version\", \"\") != \"\"]))\n  k8s_versions_only = [for k8_version in local.k8s_versions : trimprefix(lower(k8_version), \"v\")]\n\n  # OKE managed node pool images\n  node_pool_images = try(one(data.oci_containerengine_node_pool_option.oke[*].sources), [])\n\n  # Parse platform/operating system information from node pool image names\n  indexed_images = try({\n    for k, v in local.node_pool_images : v.image_id => merge(\n      try(element(regexall(\"OKE-(?P<k8s_version>[0-9\\\\.]+)-(?P<build>[0-9]+)\", v.source_name), 0), { k8s_version = \"none\" }),\n      {\n        arch        = length(regexall(\"aarch64\", v.source_name)) > 0 ? \"aarch64\" : \"x86_64\"\n        image_type  = length(regexall(\"OKE\", v.source_name)) > 0 ? \"oke\" : \"platform\"\n        is_gpu      = length(regexall(\"GPU\", v.source_name)) > 0\n        os          = trimspace(replace(element(regexall(\"^[a-zA-Z-]+\", v.source_name), 0), \"-\", \" \"))\n        os_version  = element(regexall(\"[0-9\\\\.]+\", v.source_name), 0)\n        sort_key    = replace(try(join(\".\", regex(\"-([0-9]{4}\\\\.[01][0-9].[0-9]{1,2}).*?-([0-9]+)$\", v.source_name)), v.source_name), \".\", \"\")\n        source_name = v.source_name\n      },\n    )\n  }, {})\n\n  # Create non-exclusive groupings of image IDs for intersection when selecting based on config and instance shape\n  image_ids = try(merge({\n    x86_64   = [for k, v in local.indexed_images : k if v.arch == \"x86_64\"]\n    aarch64  = [for k, v in local.indexed_images : k if v.arch == \"aarch64\"]\n    oke      = [for k, v in local.indexed_images : k if v.image_type == \"oke\" && contains(local.k8s_versions_only, v.k8s_version)]\n    platform = [for k, v in local.indexed_images : k if v.image_type == \"platform\"]\n    gpu      = [for k, v in local.indexed_images : k if v.is_gpu]\n    nongpu   = [for k, v in local.indexed_images : k if !v.is_gpu]\n    }, {\n    # Include groups for OS name and major version\n    # https://developer.hashicorp.com/terraform/language/expressions/for#grouping-results\n    for k, v in local.indexed_images : format(\"%v %v\", v.os, split(\".\", v.os_version)[0]) => k...\n    }, {\n    # Include groups for referenced Kubernetes versions\n    for k, v in local.indexed_images : format(\"%v\", v.k8s_version) => k... if contains(local.k8s_versions_only, v.k8s_version)\n  }), {})\n}\n"
  },
  {
    "path": "docs/diagrams.md",
    "content": "# Diagrams\n\nThis page collects the currently relevant architecture diagrams for the module.\n\n## Default topologies\n\n### Default Multi-AD topology\n\n![Default Multi-AD topology](./images/defaultmad-large.svg)\n\nShows the default regional deployment spread across multiple availability domains. The control plane, worker nodes, bastion, operator, and load balancer subnets are separated so the module can provide both public entry points and private east-west traffic paths.\n\n### Default Single-AD topology\n\n![Default Single-AD topology](./images/defaultsad-large.svg)\n\nShows the same baseline layout constrained to a single availability domain. This is the simpler topology when multi-AD placement is not required or not available in the target region.\n\n## Network and access\n\n### Network layout\n\n![Network layout](./images/networking-large.svg)\n\nIllustrates how the module divides the VCN into functional subnets and NSG boundaries. Use it to understand where the control plane, workers, pods, and load balancers live and how traffic is expected to flow between them.\n\n### Load balancer layout\n\n![Load balancer layout](./images/loadbalancers-large.svg)\n\nHighlights the public and internal load balancer subnet choices. This is the diagram to consult when deciding how to set `load_balancers`, `preferred_load_balancer`, and the related service exposure model.\n\n### Bastion access layout\n\n![Bastion access layout](./images/bastion-large.svg)\n\nShows the administrative access path into the VCN through the bastion host. It is useful when validating SSH reachability to private resources such as the operator or worker nodes.\n\n## Exposure variants\n\n### Public control plane topology\n\n![Public control plane topology](./images/publiccluster-large.svg)\n\nShows the variant where the Kubernetes API endpoint is reachable through a public address. This is the most direct management model, but it also requires tighter control of the allowed CIDR ranges.\n\n### Private control plane topology\n\n![Private control plane topology](./images/privatecluster-large.svg)\n\nShows the variant where the Kubernetes API endpoint stays private inside the VCN. This is the preferred layout when cluster administration should happen from the bastion, operator, or connected private networks only.\n\n### Public workers topology\n\n![Public workers topology](./images/publicworkers-large.svg)\n\nShows worker nodes with public IPs and direct outbound reachability. This can simplify bootstrap and troubleshooting, but it expands the exposed surface compared with private workers.\n\n### Private workers topology\n\n![Private workers topology](./images/privateworkers-large.svg)\n\nShows worker nodes kept on private addresses behind the VCN gateways. This is the more typical production posture when outbound access is routed through NAT or service gateways instead of direct public addressing.\n\n## Identity\n\n### OIDC discovery flow\n\n![OIDC discovery flow](./images/oidc-discovery.png)\n\nExplains the OIDC discovery integration exposed by the cluster. Use it when enabling `oidc_discovery_enabled` or documenting how external identity providers and token validation interact with the OKE API server.\n"
  },
  {
    "path": "docs/prerequisites.md",
    "content": "# Pre-requisites\n\n[Quick Start guide](https://github.com/oracle-terraform-modules/terraform-oci-oke/blob/main/docs/quickstart.md)\n\nThis section will guide you through the pre-requisites before you can use this project.\n\nYou can proceed to the [Quick Start guide](https://github.com/oracle-terraform-modules/terraform-oci-oke/blob/main/docs/quickstart.md) if you have already done these.\n\n1. [Install Terraform](#install-terraform)\n2. [Generate and upload your OCI API keys](#generate-and-upload-your-oci-api-keys)\n3. [Create an OCI compartment](#create-an-oci-compartment)\n4. [Obtain the necessary OCIDs](#obtain-the-necessary-ocids)\n5. [Generate an SSH key pair](#generate-an-ssh-key-pair)\n6. [Identity and Access Management Rights](#identity-and-access-management-rights)\n\n### Install Terraform\n\nStart by installing Terraform and configuring your path. You need version 1.3.0+.\n\n#### Installing Terraform on Oracle Linux\n\n```bash\nyum -y install oraclelinux-developer-release-el7 && yum -y install terraform\n```\n\n#### Installing Terraform on macOS\n\n```bash\nbrew install terraform\n```\n\n#### Manual Installation\n\n1. Open your browser and navigate to the [Terraform download page](https://www.terraform.io/downloads.html). You need version 1.3.0+.\n2. Download the appropriate version for your operating system.\n3. Extract the contents of the compressed file and copy the `terraform` binary to a location that is in your path.\n\n##### Configure path on Linux/macOS\n\n```bash\nsudo mv /path/to/terraform /usr/local/bin\n```\n\n##### Configure path on Windows\n\n1. Click on `Start`, type `Control Panel` and open it.\n2. Select `System > Advanced System Settings > Environment Variables`.\n3. Select `System variables > PATH` and click `Edit`.\n4. Click `New` and paste the location of the directory where you extracted `terraform.exe`.\n5. Close all open windows by clicking `OK`.\n6. Open a new terminal and verify Terraform has been properly installed.\n\n#### Testing Terraform installation\n\n```bash\nterraform -v\nTerraform v1.x.x\n```\n\n### Generate and upload your OCI API keys\n\nFollow the documentation for [generating and uploading your API keys](https://docs.cloud.oracle.com/iaas/Content/API/Concepts/apisigningkey.htm#two).\n\nNote the key fingerprint.\n\n### Create an OCI compartment\n\nFollow the documentation for [creating a compartment](https://docs.cloud.oracle.com/iaas/Content/Identity/Tasks/managingcompartments.htm#two).\n\n### Obtain the necessary OCIDs\n\nThe following OCIDs are required:\n\n1. Compartment OCID\n2. Tenancy OCID\n3. User OCID\n\nFollow the documentation for [obtaining the tenancy and user OCIDs](https://docs.cloud.oracle.com/iaas/Content/API/Concepts/apisigningkey.htm#five).\n\nTo obtain the compartment OCID:\n\n1. Navigate to `Identity > Compartments`.\n2. Click on your compartment.\n3. Locate `OCID` on the page and click `Copy`.\n\n### Generate an SSH key pair\n\nAn SSH key pair is required for access to the bastion and operator hosts. Generate one if you don't have one:\n\n```bash\nssh-keygen -t rsa -b 4096 -f ~/.ssh/oke_key\n```\n\nThis creates `~/.ssh/oke_key` (private key) and `~/.ssh/oke_key.pub` (public key).\n\n### Identity and Access Management Rights\n\nThe user or group running Terraform needs the following permissions:\n\n| Permission | Purpose |\n|------------|---------|\n| `manage all-resources in compartment` | Full management of all OKE resources |\n| `manage instance-family in compartment` | Create and manage compute instances |\n| `manage virtual-network-family in compartment` | Create and manage VCN, subnets, NSGs |\n| `manage cluster-family in compartment` | Create and manage OKE clusters |\n| `manage volume-family in compartment` | Create and manage block volumes |\n| `manage dynamic-groups in tenancy` | Create IAM dynamic groups (if `create_iam_resources = true`) |\n| `manage policies in tenancy` | Create IAM policies (if `create_iam_resources = true`) |\n\nFor a least-privilege setup, set `create_iam_resources = true` and the module will create the required dynamic groups and policies automatically.\n"
  },
  {
    "path": "docs/quickstart.md",
    "content": "# Quickstart\n\n1. [Assumptions](#assumptions)\n2. [Pre-requisites](#pre-requisites)\n3. [Instructions](#instructions)\n4. [Connect to the cluster](#connect-to-the-cluster)\n5. [Update the cluster](#update-the-cluster)\n6. [Destroy the cluster](#destroy-the-cluster)\n7. [Related documentation](#related-documentation)\n\n### Assumptions\n\n1. You have set up the [required API keys](https://docs.cloud.oracle.com/iaas/Content/API/Concepts/apisigningkey.htm).\n2. You know the [required OCIDs](https://docs.cloud.oracle.com/iaas/Content/API/Concepts/apisigningkey.htm#five).\n3. You have the necessary [permissions](./prerequisites.md#identity-and-access-management-rights).\n4. You have an SSH key pair available.\n\n### Pre-requisites\n\n1. `git` is installed.\n2. An SSH client is installed.\n3. Terraform 1.3.0+ is installed.\n\nSee [Pre-requisites](./prerequisites.md) for detailed setup instructions.\n\n### Instructions\n\n#### Provisioning using this git repo\n\n1. Clone the repo:\n\n```bash\ngit clone https://github.com/oracle-terraform-modules/terraform-oci-oke.git tfoke\n\ncd tfoke\n```\n\nCreate a `terraform.tfvars` file for your environment. This repository does not ship a generic root `terraform.tfvars.example`.\n\n2. Create a `provider.tf` file and add the following:\n\n```hcl\nterraform {\n  required_providers {\n    oci = {\n      source  = \"oracle/oci\"\n      version = \">= 7.30.0\"\n    }\n  }\n}\n\nprovider \"oci\" {\n  tenancy_ocid     = var.tenancy_id\n  user_ocid        = var.user_id\n  fingerprint      = var.api_fingerprint\n  private_key_path = var.api_private_key_path\n  region           = var.region\n}\n\nprovider \"oci\" {\n  alias            = \"home\"\n  tenancy_ocid     = var.tenancy_id\n  user_ocid        = var.user_id\n  fingerprint      = var.api_fingerprint\n  private_key_path = var.api_private_key_path\n  region           = coalesce(var.home_region, var.region)\n}\n```\n\nProvider credentials are intentionally configured in `provider.tf`, not in `terraform.tfvars`.\n\n3. Set mandatory provider parameters:\n\n- `api_fingerprint`\n- `api_private_key_path`\n- `region`\n- `tenancy_id`\n- `user_id`\n\n4. Set other required parameters:\n\n- `compartment_id`\n- One of `ssh_public_key` or `ssh_public_key_path`\n\n5. Set cluster and worker parameters. At minimum, configure:\n\n```hcl\n# Cluster\ncreate_cluster     = true\ncluster_name       = \"oke-cluster\"\nkubernetes_version = \"v1.34.2\"\n\n# Workers\nworker_pool_mode = \"node-pool\"\nworker_pool_size = 1\n\nworker_pools = {\n  np1 = {\n    size  = 1\n  }\n}\n```\n\n6. Optional parameters to override (see [Terraform Options](./terraformoptions.md) for the full list):\n\n- Cluster: `cluster_type`, `cni_type`, `control_plane_is_public`, `pods_cidr`, `services_cidr`\n- Workers: `worker_shape`, `worker_image_type`, `worker_image_os`, `worker_image_os_version`\n- Network: `vcn_cidrs`, `subnets`, `nsgs`, `load_balancers`\n- Bastion: `create_bastion`, `bastion_shape`, `bastion_allowed_cidrs`\n- Operator: `create_operator`, `operator_shape`, `operator_upgrade`\n\n7. Run Terraform:\n\n```bash\nterraform init\nterraform plan\nterraform apply\n```\n\n8. Retrieve the cluster and access information:\n\n```bash\nterraform output cluster_id\nterraform output cluster_endpoints\nterraform output ssh_to_bastion\nterraform output ssh_to_operator\n```\n\nIf you want Terraform to emit `cluster_kubeconfig`, also set:\n\n```hcl\noutput_detail = true\n```\n\n### Connect to the cluster\n\n#### Via the operator host\n\n1. SSH to the operator through the bastion:\n\n```bash\n# Use the output from terraform output ssh_to_operator\nssh -o ProxyCommand='ssh -W %h:%p -i ~/.ssh/oke_key opc@<bastion_ip>' -i ~/.ssh/oke_key opc@<operator_ip>\n```\n\n2. Verify connectivity:\n\n```bash\nkubectl get nodes\n```\n\n#### Via kubeconfig\n\n1. Retrieve the kubeconfig:\n\n```bash\nterraform output -raw cluster_kubeconfig > ~/.kube/config-oke\nexport KUBECONFIG=~/.kube/config-oke\n```\n\n`cluster_kubeconfig` is only populated when `output_detail = true`.\n\n2. Verify connectivity:\n\n```bash\nkubectl get nodes\n```\n\n### Update the cluster\n\nTo update the infrastructure:\n\n```bash\n# Modify terraform.tfvars as needed\nterraform plan\nterraform apply\n```\n\nCommon updates:\n- **Kubernetes version**: Change `kubernetes_version` and run `terraform apply`\n- **Worker pool size**: Adjust `worker_pool_size` or individual pool `size`\n- **Add worker pools**: Add entries to the `worker_pools` map\n- **Extensions**: Enable extensions by setting `<extension>_install = true`\n\n### Destroy the cluster\n\n```bash\nterraform destroy\n```\n\n### Related documentation\n\n- [All Terraform configuration options](./terraformoptions.md) for this module\n- [Example configurations](https://github.com/oracle-terraform-modules/terraform-oci-oke/tree/main/examples)\n- [Pre-requisites](./prerequisites.md)\n"
  },
  {
    "path": "docs/terraformoptions.md",
    "content": "# Terraform Options\n\nConfiguration Terraform Options:\n\n1. [General](#general)\n2. [Identity and Access Management](#identity-and-access-management)\n3. [Network](#network)\n4. [Cluster](#cluster)\n5. [Cluster Add-ons](#cluster-add-ons)\n6. [Workers](#workers)\n7. [Bastion](#bastion)\n8. [Operator](#operator)\n9. [Extensions](#extensions)\n   - [Cilium](#cilium)\n   - [Multus](#multus)\n   - [SR-IOV Device Plugin](#sr-iov-device-plugin)\n   - [SR-IOV CNI Plugin](#sr-iov-cni-plugin)\n   - [RDMA CNI Plugin](#rdma-cni-plugin)\n   - [Whereabouts](#whereabouts)\n   - [Metrics Server](#metrics-server)\n   - [Cluster Autoscaler](#cluster-autoscaler)\n   - [Prometheus](#prometheus)\n   - [DCGM Exporter](#dcgm-exporter)\n   - [Gatekeeper](#gatekeeper)\n   - [MPI Operator](#mpi-operator)\n   - [ArgoCD](#argocd)\n   - [Service Accounts](#service-accounts)\n10. [Utilities](#utilities)\n11. [Tagging](#tagging)\n12. [Validation Rules](#validation-rules)\n\n## General\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `state_id` | Optional Terraform state_id from an existing deployment for resource reuse. | string | `null` |\n| `output_detail` | Whether to include detailed output in the Terraform state. | `true` / `false` | `false` |\n| `timezone` | Preferred timezone for worker, operator, and bastion instances. | string (IANA timezone) | `\"Etc/UTC\"` |\n| `ssh_private_key` | SSH private key contents, optionally base64-encoded. Sensitive. | string | `null` |\n| `ssh_private_key_path` | Path to SSH private key on the machine running Terraform. | string | `null` |\n| `ssh_public_key` | SSH public key contents, optionally base64-encoded. | string | `null` |\n| `ssh_public_key_path` | Path to SSH public key. | string | `null` |\n\n## Identity and Access Management\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `tenancy_id` | Tenancy OCID. Required unless using `config_file_profile` or Resource Manager. | OCID string | `null` |\n| `tenancy_ocid` | Tenancy OCID for Resource Manager. Used as alias for `tenancy_id` in RMS. | OCID string | `null` |\n| `user_id` | User OCID for API key authentication. | OCID string | `null` |\n| `current_user_ocid` | User OCID for Resource Manager. | OCID string | `null` |\n| `compartment_id` | Compartment OCID where resources are created. Required. | OCID string | `null` |\n| `compartment_ocid` | Compartment OCID for Resource Manager. | OCID string | `null` |\n| `worker_compartment_id` | Compartment for worker resources. Defaults to `compartment_id`. | OCID string | `null` |\n| `network_compartment_id` | Compartment for network resources. Defaults to `compartment_id`. | OCID string | `null` |\n| `region` | OCI region for resource provisioning. | [OCI region identifier](https://docs.oracle.com/en-us/iaas/Content/General/Concepts/regions.htm) | `\"us-ashburn-1\"` |\n| `home_region` | Tenancy home region. Required when `create_iam_resources = true`. | OCI region identifier | `null` |\n| `api_fingerprint` | Fingerprint of the OCI API public key. | string | `null` |\n| `api_private_key` | OCI API private key contents. Sensitive. | string | `null` |\n| `api_private_key_password` | Password for the OCI API private key. Sensitive. | string | `null` |\n| `api_private_key_path` | Path to the OCI API private key file. | string | `null` |\n| `config_file_profile` | OCI CLI config file profile name for authentication. | string | `\"DEFAULT\"` |\n| `create_iam_resources` | Whether to create IAM dynamic groups and policies. | `true` / `false` | `false` |\n| `create_iam_autoscaler_policy` | Create IAM policy for cluster autoscaler. | `\"never\"` / `\"auto\"` / `\"always\"` | `\"auto\"` |\n| `create_iam_kms_policy` | Create IAM policy for KMS encryption. | `\"never\"` / `\"auto\"` / `\"always\"` | `\"auto\"` |\n| `create_iam_operator_policy` | Create IAM policy for operator instance principal. | `\"never\"` / `\"auto\"` / `\"always\"` | `\"auto\"` |\n| `create_iam_worker_policy` | Create IAM policy for worker nodes. | `\"never\"` / `\"auto\"` / `\"always\"` | `\"auto\"` |\n| `create_iam_tag_namespace` | Create IAM tag namespace and tags. | `true` / `false` | `false` |\n| `create_iam_defined_tags` | Create IAM defined tags in the tag namespace. | `true` / `false` | `false` |\n| `use_defined_tags` | Apply defined tags to created resources. | `true` / `false` | `false` |\n| `tag_namespace` | Tag namespace name for OKE defined tags. | string | `\"oke\"` |\n\n## Network\n\nRelevant diagrams:\n- [Network layout](./diagrams.md#network-layout)\n- [Load balancer layout](./diagrams.md#load-balancer-layout)\n- [Bastion access layout](./diagrams.md#bastion-access-layout)\n\n### VCN\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `create_vcn` | Whether to create a VCN. Set to `false` to use an existing VCN. | `true` / `false` | `true` |\n| `vcn_name` | Display name for the VCN. | string | `null` |\n| `vcn_id` | OCID of an existing VCN. Required when `create_vcn = false`. | OCID string | `null` |\n| `vcn_cidrs` | IPv4 CIDR blocks for the VCN. | list(string) | `[\"10.0.0.0/16\"]` |\n| `vcn_dns_label` | DNS label for the VCN. | string | `null` |\n| `vcn_enable_ipv6_gua` | Enable IPv6 Global Unicast Address. | `true` / `false` | `true` |\n| `vcn_ipv6_ula_cidrs` | IPv6 ULA CIDR blocks for the VCN. | list(string) | `[]` |\n| `assign_dns` | Whether to assign DNS records to created instances and subnet hostname labels. | `true` / `false` | `true` |\n| `lockdown_default_seclist` | Remove all default rules from the VCN default security list. | `true` / `false` | `true` |\n\n### Gateways\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `vcn_create_internet_gateway` | Create an internet gateway. | `\"auto\"` / `\"always\"` / `\"never\"` | `\"auto\"` |\n| `vcn_create_nat_gateway` | Create a NAT gateway. | `\"auto\"` / `\"always\"` / `\"never\"` | `\"auto\"` |\n| `vcn_create_service_gateway` | Create a service gateway. | `\"auto\"` / `\"always\"` / `\"never\"` | `\"always\"` |\n| `internet_gateway_id` | OCID of an existing internet gateway. | OCID string | `null` |\n| `nat_gateway_id` | OCID of an existing NAT gateway. | OCID string | `null` |\n| `nat_gateway_public_ip_id` | Reserved public IP OCID for the NAT gateway. | OCID string | `null` |\n\n### Routing\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `ig_route_table_id` | OCID of an existing internet gateway route table. | OCID string | `null` |\n| `nat_route_table_id` | OCID of an existing NAT gateway route table. | OCID string | `null` |\n| `igw_ngw_mixed_route_id` | OCID of a mixed route table (NAT GW for IPv4, IGW for IPv6). | OCID string | `null` |\n| `internet_gateway_route_rules` | Additional route rules for the internet gateway route table. | list(map(string)) | `null` |\n| `nat_gateway_route_rules` | Additional route rules for the NAT gateway route table. | list(map(string)) | `null` |\n\n### DRG\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `create_drg` | Whether to create a Dynamic Routing Gateway. | `true` / `false` | `false` |\n| `drg_display_name` | Display name for the DRG. | string | `null` |\n| `drg_id` | OCID of an existing DRG. | OCID string | `null` |\n| `drg_compartment_id` | Compartment for the DRG. Defaults to `network_compartment_id`. | OCID string | `null` |\n| `drg_attachments` | DRG attachment configurations. | map(any) | `{}` |\n| `remote_peering_connections` | Remote peering connection configurations. | map(any) | `{}` |\n| `local_peering_gateways` | Local peering gateway configurations. | map(any) | `null` |\n\n### Subnets\n\nSee [Network layout](./diagrams.md#network-layout) for the default subnet split used by the module.\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `subnets` | Configuration for standard subnets (bastion, operator, cp, int_lb, pub_lb, workers, pods). Each entry supports `create`, `id`, `cidr`, `netnum`, `newbits`, `display_name`, `dns_label`, and `ipv6_cidr`. | map(object) | Module-defined defaults for all standard subnets |\n\nExample with automatic subnet creation:\n\n```hcl\nsubnets = {\n  bastion  = { newbits = 13 }\n  operator = { newbits = 13 }\n  cp       = { newbits = 13 }\n  int_lb   = { newbits = 11 }\n  pub_lb   = { newbits = 11 }\n  workers  = { newbits = 4 }\n  pods     = { newbits = 2 }\n}\n```\n\nExample with explicit CIDRs:\n\n```hcl\nsubnets = {\n  bastion  = { cidr = \"10.0.0.0/29\" }\n  operator = { cidr = \"10.0.0.64/29\" }\n  cp       = { cidr = \"10.0.0.8/29\" }\n  int_lb   = { cidr = \"10.0.0.32/27\" }\n  pub_lb   = { cidr = \"10.0.128.0/27\" }\n  workers  = { cidr = \"10.0.144.0/20\" }\n  pods     = { cidr = \"10.0.64.0/18\" }\n}\n```\n\nExample with existing subnets:\n\n```hcl\nsubnets = {\n  operator = { id = \"ocid1.subnet...\" }\n  cp       = { id = \"ocid1.subnet...\" }\n  workers  = { id = \"ocid1.subnet...\" }\n}\n```\n\n### Network Security Groups\n\nSee [Network layout](./diagrams.md#network-layout) for how the NSG-backed subnet boundaries fit together.\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `nsgs` | Configuration for NSGs (bastion, operator, cp, int_lb, pub_lb, workers, pods, optional `fss`). Each entry supports `create` and `id`. | map(object) | Module-defined defaults for standard NSGs |\n| `allow_node_port_access` | Allow NodePort access to load balancers. | `true` / `false` | `false` |\n| `allow_worker_internet_access` | Allow worker nodes outbound internet access. | `true` / `false` | `true` |\n| `allow_pod_internet_access` | Allow pod outbound internet access. | `true` / `false` | `true` |\n| `allow_worker_ssh_access` | Allow SSH access to worker nodes. | `true` / `false` | `false` |\n| `allow_bastion_cluster_access` | Allow bastion to cluster endpoint access. | `true` / `false` | `false` |\n| `allow_rules_cp` | Additional NSG rules for the control plane. | map(any) | `{}` |\n| `allow_rules_internal_lb` | Additional NSG rules for internal load balancers. | map(any) | `{}` |\n| `allow_rules_pods` | Additional NSG rules for pods. | map(any) | `{}` |\n| `allow_rules_public_lb` | Additional NSG rules for public load balancers. | map(any) | `{}` |\n| `allow_rules_workers` | Additional NSG rules for workers. | map(any) | `{}` |\n| `control_plane_allowed_cidrs` | CIDR blocks allowed to access the control plane. | list(string) | `[]` |\n| `enable_waf` | Enable WAF monitoring for load balancers. | `true` / `false` | `false` |\n| `use_stateless_rules` | Use stateless NSG rules instead of stateful. | `true` / `false` | `false` |\n\nAdditional NSG rule example:\n\n```hcl\nallow_rules_workers = {\n  \"Allow TCP 8080 from VCN\" = {\n    protocol = 6, port = 8080, source = \"10.0.0.0/16\", source_type = \"CIDR_BLOCK\",\n  },\n}\n```\n\n## Cluster\n\nRelevant diagrams:\n- [Public control plane topology](./diagrams.md#public-control-plane-topology)\n- [Private control plane topology](./diagrams.md#private-control-plane-topology)\n- [OIDC discovery flow](./diagrams.md#oidc-discovery-flow)\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `create_cluster` | Whether to create an OKE cluster. | `true` / `false` | `true` |\n| `cluster_name` | Name of the OKE cluster. | string | `\"oke\"` |\n| `cluster_type` | Cluster type. Enhanced clusters support additional features like virtual node pools and workload identity. | `\"basic\"` / `\"enhanced\"` | `\"basic\"` |\n| `control_plane_is_public` | Whether the control plane has a public IP. | `true` / `false` | `false` |\n| `assign_public_ip_to_control_plane` | Assign a public IP to the API endpoint. | `true` / `false` | `false` |\n| `control_plane_nsg_ids` | Additional NSG IDs for the cluster endpoint. | set(string) | `[]` |\n| `backend_nsg_ids` | Additional NSG IDs for load balancer backends. Workers and pods NSGs are always included. | set(string) | `[]` |\n| `cni_type` | Container Network Interface type. | `\"flannel\"` / `\"npn\"` | `\"flannel\"` |\n| `enable_ipv6` | Create a dual-stack (IPv4 and IPv6) cluster. | `true` / `false` | `false` |\n| `oke_ip_families` | Override the `ip_families` cluster attribute. | list(string) | `[]` |\n| `pods_cidr` | CIDR range for Kubernetes pods. Must not overlap with VCN, worker, or LB subnets. | CIDR string | `\"10.244.0.0/16\"` |\n| `services_cidr` | CIDR range for Kubernetes services. Must not overlap with the VCN CIDR. | CIDR string | `\"10.96.0.0/16\"` |\n| `kubernetes_version` | Kubernetes version for the cluster. | string (e.g. `\"v1.34.2\"`) | `\"v1.34.2\"` |\n| `cluster_kms_key_id` | KMS key OCID for Kubernetes secrets encryption. | OCID string | `\"\"` |\n| `use_signed_images` | Enforce that only signed container images can be deployed. | `true` / `false` | `false` |\n| `image_signing_keys` | KMS key IDs used to verify signed images. | set(string) | `[]` |\n| `load_balancers` | Type of subnets created for load balancers. | `\"public\"` / `\"internal\"` / `\"both\"` | `\"both\"` |\n| `preferred_load_balancer` | Preferred load balancer subnet type. | `\"public\"` / `\"internal\"` | `\"public\"` |\n| `oidc_discovery_enabled` | Enable OIDC discovery for third-party token validation. Requires enhanced cluster. | `true` / `false` | `false` |\n| `oidc_token_auth_enabled` | Enable OIDC token authentication via API server flags. Requires enhanced cluster. | `true` / `false` | `false` |\n| `oidc_token_authentication_config` | OIDC token authentication configuration (client_id, issuer_url, username_claim, required_claims). | any | `{}` |\n\nBasic cluster example:\n\n```hcl\ncluster_name       = \"oke-example\"\nkubernetes_version = \"v1.34.2\"\n```\n\nEnhanced cluster example:\n\n```hcl\ncluster_name                      = \"oke\"\ncluster_type                      = \"enhanced\"\ncni_type                          = \"flannel\"\nkubernetes_version                = \"v1.34.2\"\nassign_public_ip_to_control_plane = true\n```\n\nOIDC authentication example for GitHub Actions:\n\n```hcl\ncluster_type                      = \"enhanced\"\noidc_token_auth_enabled           = true\noidc_token_authentication_config  = {\n  client_id      = \"oke-kubernetes-cluster\"\n  issuer_url     = \"https://token.actions.githubusercontent.com\"\n  username_claim = \"sub\"\n  required_claims = [\n    { key = \"repository\", value = \"GITHUB_ACCOUNT/GITHUB_REPOSITORY\" },\n    { key = \"workflow\",   value = \"oke-oidc\" },\n    { key = \"ref\",        value = \"refs/heads/main\" },\n  ]\n}\n```\n\n## Cluster Add-ons\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `cluster_addons` | Map of cluster addons to enable. Each addon supports `remove_addon_resources_on_delete`, `override_existing`, and `configurations`. | any | `{}` |\n| `cluster_addons_to_remove` | Map of cluster addons to remove. Each entry supports `remove_k8s_resources`. | any | `{}` |\n\nExample:\n\n```hcl\ncluster_addons = {\n  \"CertManager\" = {\n    remove_addon_resources_on_delete = true\n    override_existing                = true\n    configurations = [\n      { key = \"numOfReplicas\", value = \"1\" }\n    ]\n  }\n  \"NvidiaGpuPlugin\" = {\n    remove_addon_resources_on_delete = true\n  }\n}\n\ncluster_addons_to_remove = {\n  Flannel = { remove_k8s_resources = true }\n}\n```\n\n## Workers\n\nRelevant diagrams:\n- [Public workers topology](./diagrams.md#public-workers-topology)\n- [Private workers topology](./diagrams.md#private-workers-topology)\n\n### Default Pool Configuration\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `cluster_id` | Existing OKE cluster OCID. Required when `create_cluster = false`. | OCID string | `null` |\n| `cluster_ca_cert` | Base64+PEM-encoded cluster CA certificate. Required when `create_cluster = false`. | string | `null` |\n| `cluster_dns` | Cluster DNS resolver IP address. Required when `create_cluster = false`. | string | `null` |\n| `worker_pools` | Map of worker pool definitions. Key is the pool name, value is the pool configuration. | any | `{}` |\n| `worker_pool_mode` | Default management mode for worker pools. | `\"node-pool\"` / `\"virtual-node-pool\"` / `\"instance\"` / `\"instance-pool\"` / `\"cluster-network\"` / `\"compute-cluster\"` | `\"node-pool\"` |\n| `worker_pool_size` | Default size for worker pools. | number | `0` |\n| `worker_compute_clusters` | Shared compute cluster definitions for use by multiple pools. | map(any) | `{}` |\n\n### Worker Pool Defaults\n\nThese parameters set defaults for all worker pools. Individual pools can override these.\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `worker_is_public` | Provision workers with public IPs. | `true` / `false` | `false` |\n| `worker_nsg_ids` | Additional NSG IDs for all worker nodes. | list(string) | `[]` |\n| `pod_nsg_ids` | Additional NSG IDs for pods (NPN CNI). | list(string) | `[]` |\n| `kubeproxy_mode` | Kube-proxy mode. | `\"iptables\"` / `\"ipvs\"` | `\"iptables\"` |\n| `worker_block_volume_type` | Block volume attachment type for self-managed workers. | `\"paravirtualized\"` / `\"iscsi\"` | `\"paravirtualized\"` |\n| `worker_node_labels` | Default Kubernetes node labels. | map(string) | `{}` |\n| `worker_node_metadata` | Additional worker node metadata. | map(string) | `{}` |\n| `worker_image_id` | Default image OCID for worker pools. | OCID string | `null` |\n| `worker_image_type` | Default image type. `\"oke\"` uses OKE Oracle Linux images. | `\"oke\"` / `\"custom\"` / `\"platform\"` | `\"oke\"` |\n| `worker_image_os` | Default OS for platform/OKE images. | string | `\"Oracle Linux\"` |\n| `worker_image_os_version` | Default OS version for platform/OKE images. | string | `\"8\"` |\n| `worker_shape` | Default shape for worker instances. | map(any) | `{shape = \"VM.Standard.E4.Flex\", ocpus = 2, memory = 16, boot_volume_size = 50, boot_volume_vpus_per_gb = 10}` |\n| `worker_capacity_reservation_id` | Capacity reservation OCID for worker instances. | OCID string | `null` |\n| `worker_preemptible_config` | Preemptible compute configuration. | map(any) | `{}` |\n| `worker_cloud_init` | Default cloud-init MIME parts for all pools. | list(map(string)) | `[]` |\n| `worker_disable_default_cloud_init` | Disable the default OKE cloud-init. | `true` / `false` | `false` |\n| `worker_volume_kms_key_id` | KMS key OCID for boot volume encryption. | OCID string | `null` |\n| `worker_pv_transit_encryption` | Enable in-transit encryption for paravirtualized volumes. | `true` / `false` | `false` |\n| `worker_legacy_imds_endpoints_disabled` | Disable IMDSv1 endpoint on workers. | `true` / `false` | `false` |\n| `max_pods_per_node` | Maximum pods per node (1-110). Only applies with NPN CNI. | number | `31` |\n| `platform_config` | Platform configuration for self-managed pools (shielded instances). | object | `null` |\n| `agent_config` | Management agent configuration for self-managed pools. | object | `null` |\n| `allow_short_container_image_names` | Allow short container image names without full registry path. Requires Kubernetes >= 1.34.0. | `true` / `false` | `false` |\n\n### Worker Pool Entry Configuration\n\nEach entry in the `worker_pools` map supports the following attributes:\n\n| Attribute | Description | Values |\n|-----------|-------------|--------|\n| `mode` | Worker management mode. Overrides `worker_pool_mode`. | `\"node-pool\"` / `\"virtual-node-pool\"` / `\"instance\"` / `\"instance-pool\"` / `\"cluster-network\"` / `\"compute-cluster\"` |\n| `size` | Number of nodes in the pool. | number |\n| `shape` | Instance shape name. | string |\n| `ocpus` | Number of OCPUs (Flex shapes). | number |\n| `memory` | Memory in GB (Flex shapes). | number |\n| `boot_volume_size` | Boot volume size in GB. | number |\n| `boot_volume_vpus_per_gb` | Boot volume performance (10/20/30-120). Self-managed modes only. | number |\n| `description` | Pool description. | string |\n| `create` | Whether to create this pool. | `true` / `false` |\n| `image_type` | Image type for this pool. | `\"oke\"` / `\"custom\"` / `\"platform\"` |\n| `image_id` | Custom image OCID. | OCID string |\n| `os` | OS name. | string |\n| `os_version` | OS version. | string |\n| `node_labels` | Kubernetes node labels. | map(string) |\n| `subnet_id` | Custom subnet OCID for this pool. | OCID string |\n| `pod_subnet_id` | Custom pod subnet OCID (NPN CNI). | OCID string |\n| `nsg_ids` | Additional NSG IDs for this pool. | list(string) |\n| `pod_nsg_ids` | Additional pod NSG IDs for this pool (NPN CNI). | list(string) |\n| `assign_public_ip` | Assign a public IP to nodes. | `true` / `false` |\n| `cloud_init` | Pool-specific cloud-init MIME parts. | list(map(string)) |\n| `secondary_vnics` | Secondary VNIC configurations. | map(any) |\n| `autoscale` | Enable cluster autoscaler for this pool. | `true` / `false` |\n| `min_size` | Minimum pool size for autoscaling. | number |\n| `max_size` | Maximum pool size for autoscaling. | number |\n| `allow_autoscaler` | Allow cluster autoscaler to manage this pool. | `true` / `false` |\n| `ignore_initial_pool_size` | Ignore initial pool size when autoscaling. | `true` / `false` |\n| `drain` | Mark pool for draining (disables scheduling, drains through operator). | `true` / `false` |\n| `placement_ads` | List of AD numbers for placement. | list(number) |\n| `compute_cluster` | Name of a shared compute cluster (compute-cluster mode). | string |\n| `instance_ids` | Instance IDs in compute cluster. | list(string) |\n| `platform_config` | Platform configuration (shielded instances). | object |\n| `agent_config` | Management agent configuration. | object |\n| `burst` | CPU bursting configuration for Flex shapes. | `\"BASELINE_1_8\"` / `\"BASELINE_1_2\"` |\n| `node_cycling_enabled` | Enable node cycling for updates. | `true` / `false` |\n| `node_cycling_max_surge` | Max surge during cycling (percentage or number). | string |\n| `node_cycling_max_unavailable` | Max unavailable during cycling. | number |\n| `node_cycling_mode` | Cycling mode. | `[\"instance\"]` / `[\"boot_volume\"]` |\n| `eviction_grace_duration` | Grace duration for eviction in seconds. | number |\n| `is_force_delete_after_grace_duration` | Force delete after grace duration. | `true` / `false` |\n\nBasic node pool example:\n\n```hcl\nworker_pool_mode = \"node-pool\"\nworker_pool_size = 1\n\nworker_pools = {\n  oke-vm-standard = {}\n  oke-vm-standard-large = {\n    size             = 1\n    shape            = \"VM.Standard.E4.Flex\"\n    ocpus            = 8\n    memory           = 128\n    boot_volume_size = 200\n  }\n}\n```\n\nAutoscaled node pool example:\n\n```hcl\nworker_pools = {\n  np-autoscaled = {\n    size                     = 2\n    min_size                 = 1\n    max_size                 = 3\n    autoscale                = true\n    ignore_initial_pool_size = true\n  }\n}\n```\n\nCluster network (HPC/GPU) example:\n\n```hcl\nworker_pools = {\n  oke-bm-gpu-rdma = {\n    mode          = \"cluster-network\"\n    size          = 1\n    shape         = \"BM.GPU.B4.8\"\n    placement_ads = [1]\n    image_id      = \"ocid1.image...\"\n    secondary_vnics = {\n      \"vnic-display-name\" = {\n        nic_index = 1\n        subnet_id = \"ocid1.subnet...\"\n      }\n    }\n  }\n}\n```\n\n## Bastion\n\nThe bastion instance provides a public SSH entrypoint into the VCN.\n\nSee [Bastion access layout](./diagrams.md#bastion-access-layout) for the administrative access path.\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `create_bastion` | Whether to create a bastion host. | `true` / `false` | `true` |\n| `bastion_public_ip` | IP address of an existing bastion. Ignored when `create_bastion = true`. | string | `null` |\n| `bastion_allowed_cidrs` | List of CIDR blocks allowed SSH access to the bastion. Set to `[\"0.0.0.0/0\"]` to allow from anywhere. | list(string) | `[]` |\n| `bastion_availability_domain` | Availability domain number for the bastion. Defaults to first available. | string | `null` |\n| `bastion_nsg_ids` | Additional NSG IDs for the bastion. Combined with the created NSG. | list(string) | `[]` |\n| `bastion_user` | SSH user for the bastion host. | string | `\"opc\"` |\n| `bastion_image_id` | Custom image OCID for the bastion. Ignored when `bastion_image_type = \"platform\"`. | OCID string | `null` |\n| `bastion_image_type` | Image type for the bastion. | `\"platform\"` / `\"custom\"` | `\"platform\"` |\n| `bastion_image_os` | Platform image OS name. | string | `\"Oracle Autonomous Linux\"` |\n| `bastion_image_os_version` | Platform image OS version. | string | `\"8\"` |\n| `bastion_shape` | Shape of the bastion instance. | map(any) | `{shape = \"VM.Standard.E4.Flex\", ocpus = 1, memory = 4, boot_volume_size = 50, baseline_ocpu_utilization = 100}` |\n| `bastion_is_public` | Whether the bastion is provisioned with a public IP. | `true` / `false` | `true` |\n| `bastion_upgrade` | Whether to upgrade bastion packages after provisioning. | `true` / `false` | `false` |\n| `bastion_await_cloudinit` | Block Terraform until cloud-init completes on the bastion. | `true` / `false` | `true` |\n| `bastion_volume_kms_key_id` | KMS key OCID for bastion boot volume encryption. | OCID string | `null` |\n| `bastion_legacy_imds_endpoints_disabled` | Disable IMDSv1 endpoint on the bastion. | `true` / `false` | `true` |\n\nExample:\n\n```hcl\ncreate_bastion              = true\nbastion_allowed_cidrs       = [\"0.0.0.0/0\"]\nbastion_image_type          = \"platform\"\nbastion_upgrade             = false\nbastion_user                = \"opc\"\n\nbastion_shape = {\n  shape                     = \"VM.Standard.E4.Flex\"\n  ocpus                     = 1\n  memory                    = 4\n  boot_volume_size          = 50\n  baseline_ocpu_utilization = 100\n}\n```\n\n## Operator\n\nThe operator instance provides an environment within the VCN from which the OKE cluster can be managed. It comes pre-installed with kubectl, Helm, and optional tools.\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `create_operator` | Whether to create an operator host. | `true` / `false` | `true` |\n| `operator_availability_domain` | Availability domain for the operator. Defaults to first available. | string | `null` |\n| `operator_cloud_init` | Cloud-init MIME parts for custom operator initialization. | list(map(string)) | `[]` |\n| `operator_nsg_ids` | Additional NSG IDs for the operator. | list(string) | `[]` |\n| `operator_user` | SSH user for the operator host. | string | `\"opc\"` |\n| `operator_image_id` | Custom image OCID for the operator. Ignored when `operator_image_type = \"platform\"`. | OCID string | `null` |\n| `operator_image_os` | Platform image OS name. | string | `\"Oracle Linux\"` |\n| `operator_image_os_version` | Platform image OS version. | string | `\"8\"` |\n| `operator_image_type` | Image type for the operator. | `\"platform\"` / `\"custom\"` | `\"platform\"` |\n| `operator_install_helm` | Whether to install Helm on the operator. | `true` / `false` | `true` |\n| `operator_install_helm_from_repo` | Install Helm from the package repository. | `true` / `false` | `false` |\n| `operator_install_oci_cli_from_repo` | Install OCI CLI from the package repository. | `true` / `false` | `false` |\n| `operator_install_istioctl` | Whether to install istioctl on the operator. | `true` / `false` | `false` |\n| `operator_install_k8sgpt` | Whether to install k8sgpt on the operator. | `true` / `false` | `false` |\n| `operator_install_k9s` | Whether to install k9s on the operator. | `true` / `false` | `false` |\n| `operator_install_kubectl_from_repo` | Install kubectl from the package repository. | `true` / `false` | `true` |\n| `operator_install_kubectx` | Whether to install kubectx/kubens on the operator. | `true` / `false` | `true` |\n| `operator_install_stern` | Whether to install stern on the operator. | `true` / `false` | `false` |\n| `operator_shape` | Shape of the operator instance. | map(any) | `{shape = \"VM.Standard.E4.Flex\", ocpus = 1, memory = 4, boot_volume_size = 50, baseline_ocpu_utilization = 100}` |\n| `operator_volume_kms_key_id` | KMS key OCID for operator boot volume encryption. | OCID string | `null` |\n| `operator_pv_transit_encryption` | Enable in-transit encryption for paravirtualized volumes. | `true` / `false` | `false` |\n| `operator_upgrade` | Whether to upgrade operator packages after provisioning. | `true` / `false` | `false` |\n| `operator_private_ip` | IP address of an existing operator. Ignored when `create_operator = true`. | string | `null` |\n| `operator_await_cloudinit` | Block Terraform until cloud-init completes on the operator. | `true` / `false` | `true` |\n| `operator_legacy_imds_endpoints_disabled` | Disable IMDSv1 endpoint on the operator. | `true` / `false` | `true` |\n\nExample with cloud-init:\n\n```hcl\ncreate_operator     = true\noperator_upgrade    = false\noperator_user       = \"opc\"\n\noperator_cloud_init = [\n  {\n    content      = <<-EOT\n    runcmd:\n    - echo \"Operator cloud_init using cloud-config\"\n    EOT\n    content_type = \"text/cloud-config\"\n  }\n]\n\noperator_shape = {\n  shape                     = \"VM.Standard.E4.Flex\"\n  ocpus                     = 1\n  memory                    = 4\n  boot_volume_size          = 50\n  baseline_ocpu_utilization = 100\n}\n```\n\n## Extensions\n\n### Cilium\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `cilium_install` | Whether to install Cilium. | `true` / `false` | `false` |\n| `cilium_reapply` | Reapply Cilium Helm release on every Terraform apply. | `true` / `false` | `false` |\n| `cilium_namespace` | Kubernetes namespace for Cilium. | string | `\"kube-system\"` |\n| `cilium_helm_version` | Cilium Helm chart version. | string | `\"1.16.3\"` |\n| `cilium_helm_values` | Helm values for Cilium. | any | `{}` |\n| `cilium_helm_values_files` | List of Helm values files for Cilium. | list(string) | `[]` |\n\n### Multus\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `multus_install` | Whether to install Multus CNI. | `true` / `false` | `false` |\n| `multus_namespace` | Kubernetes namespace for Multus. | string | `\"network\"` |\n| `multus_daemonset_url` | URL to the Multus daemonset manifest. Determined automatically by default. | string | `null` |\n| `multus_version` | Multus version. | string | `\"3.9.3\"` |\n\n### SR-IOV Device Plugin\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `sriov_device_plugin_install` | Whether to install the SR-IOV device plugin. | `true` / `false` | `false` |\n| `sriov_device_plugin_namespace` | Kubernetes namespace. | string | `\"network\"` |\n| `sriov_device_plugin_daemonset_url` | URL to the daemonset manifest. Determined automatically by default. | string | `null` |\n| `sriov_device_plugin_version` | SR-IOV device plugin version. | string | `\"master\"` |\n\n### SR-IOV CNI Plugin\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `sriov_cni_plugin_install` | Whether to install the SR-IOV CNI plugin. | `true` / `false` | `false` |\n| `sriov_cni_plugin_namespace` | Kubernetes namespace. | string | `\"network\"` |\n| `sriov_cni_plugin_daemonset_url` | URL to the daemonset manifest. Determined automatically by default. | string | `null` |\n| `sriov_cni_plugin_version` | SR-IOV CNI plugin version. | string | `\"master\"` |\n\n### RDMA CNI Plugin\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `rdma_cni_plugin_install` | Whether to install the RDMA CNI plugin. | `true` / `false` | `false` |\n| `rdma_cni_plugin_namespace` | Kubernetes namespace. | string | `\"network\"` |\n| `rdma_cni_plugin_daemonset_url` | URL to the daemonset manifest. Determined automatically by default. | string | `null` |\n| `rdma_cni_plugin_version` | RDMA CNI plugin version. | string | `\"master\"` |\n\n### Whereabouts\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `whereabouts_install` | Whether to install Whereabouts IPAM. | `true` / `false` | `false` |\n| `whereabouts_namespace` | Kubernetes namespace. | string | `\"default\"` |\n| `whereabouts_daemonset_url` | URL to the daemonset manifest. Determined automatically by default. | string | `null` |\n| `whereabouts_version` | Whereabouts version. | string | `\"master\"` |\n\n### Metrics Server\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `metrics_server_install` | Whether to install Metrics Server. | `true` / `false` | `false` |\n| `metrics_server_namespace` | Kubernetes namespace. | string | `\"metrics\"` |\n| `metrics_server_helm_version` | Helm chart version. | string | `\"3.8.3\"` |\n| `metrics_server_helm_values` | Helm values. | map(string) | `{}` |\n| `metrics_server_helm_values_files` | List of Helm values files. | list(string) | `[]` |\n\n### Cluster Autoscaler\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `cluster_autoscaler_install` | Whether to install the standalone Cluster Autoscaler. | `true` / `false` | `false` |\n| `cluster_autoscaler_namespace` | Kubernetes namespace. | string | `\"kube-system\"` |\n| `cluster_autoscaler_helm_version` | Helm chart version. | string | `\"9.24.0\"` |\n| `cluster_autoscaler_helm_values` | Helm values. | map(string) | `{}` |\n| `cluster_autoscaler_helm_values_files` | List of Helm values files. | list(string) | `[]` |\n\n### Prometheus\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `prometheus_install` | Whether to install Prometheus. | `true` / `false` | `false` |\n| `prometheus_reapply` | Reapply Prometheus Helm release on every apply. | `true` / `false` | `false` |\n| `prometheus_namespace` | Kubernetes namespace. | string | `\"metrics\"` |\n| `prometheus_helm_version` | Helm chart version. | string | `\"45.2.0\"` |\n| `prometheus_helm_values` | Helm values. | map(string) | `{}` |\n| `prometheus_helm_values_files` | List of Helm values files. | list(string) | `[]` |\n\n### DCGM Exporter\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `dcgm_exporter_install` | Whether to install the DCGM Exporter for GPU metrics. | `true` / `false` | `false` |\n| `dcgm_exporter_reapply` | Reapply DCGM Exporter Helm release on every apply. | `true` / `false` | `false` |\n| `dcgm_exporter_namespace` | Kubernetes namespace. | string | `\"metrics\"` |\n| `dcgm_exporter_helm_version` | Helm chart version. | string | `\"3.1.5\"` |\n| `dcgm_exporter_helm_values` | Helm values. | map(string) | `{}` |\n| `dcgm_exporter_helm_values_files` | List of Helm values files. | list(string) | `[]` |\n\n### Gatekeeper\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `gatekeeper_install` | Whether to install Gatekeeper (OPA). | `true` / `false` | `false` |\n| `gatekeeper_namespace` | Kubernetes namespace. | string | `\"kube-system\"` |\n| `gatekeeper_helm_version` | Helm chart version. | string | `\"3.11.0\"` |\n| `gatekeeper_helm_values` | Helm values. | map(string) | `{}` |\n| `gatekeeper_helm_values_files` | List of Helm values files. | list(string) | `[]` |\n\n### MPI Operator\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `mpi_operator_install` | Whether to install the MPI Operator. | `true` / `false` | `false` |\n| `mpi_operator_namespace` | Kubernetes namespace. | string | `\"default\"` |\n| `mpi_operator_deployment_url` | URL to the deployment manifest. Determined automatically by default. | string | `null` |\n| `mpi_operator_version` | MPI Operator version. | string | `\"0.4.0\"` |\n\n### ArgoCD\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `argocd_install` | Whether to install ArgoCD. | `true` / `false` | `false` |\n| `argocd_namespace` | Kubernetes namespace. | string | `\"argocd\"` |\n| `argocd_helm_version` | Helm chart version. | string | `\"8.1.2\"` |\n| `argocd_helm_values` | Helm values. | map(string) | `{}` |\n| `argocd_helm_values_files` | List of Helm values files. | list(string) | `[]` |\n\n### Service Accounts\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `create_service_account` | Whether to create Kubernetes service accounts with RBAC. | `true` / `false` | `false` |\n| `service_accounts` | Map of service account definitions. Each supports `sa_name`, `sa_namespace`, `sa_cluster_role`, `sa_cluster_role_binding`, `sa_role`, `sa_role_binding`. | map(any) | Seeded with a default `kubeconfigsa` entry |\n\nExample:\n\n```hcl\ncreate_service_account = true\n\nservice_accounts = {\n  example_cluster_role_binding = {\n    sa_name                 = \"sa1\"\n    sa_namespace            = \"kube-system\"\n    sa_cluster_role         = \"cluster-admin\"\n    sa_cluster_role_binding = \"sa1-crb\"\n  }\n}\n```\n\n## Utilities\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `await_node_readiness` | Block Terraform until nodes are ready. | `\"none\"` / `\"one\"` / `\"all\"` | `\"none\"` |\n| `ocir_email_address` | Email address for OCIR secret. | string | `null` |\n| `ocir_secret_id` | OCIR secret OCID from OCI Vault. | OCID string | `null` |\n| `ocir_secret_name` | Name of the Kubernetes Docker registry secret. | string | `\"ocirsecret\"` |\n| `ocir_secret_namespace` | Kubernetes namespace for the OCIR secret. | string | `\"default\"` |\n| `ocir_username` | Username for OCIR secret access. | string | `null` |\n| `worker_drain_ignore_daemonsets` | Ignore DaemonSet pods when draining workers. | `true` / `false` | `true` |\n| `worker_drain_delete_local_data` | Delete local data when draining workers. | `true` / `false` | `true` |\n| `worker_drain_timeout_seconds` | Timeout for worker draining in seconds. | number | `900` |\n\n## Tagging\n\n| Parameter | Description | Values | Default |\n| --- | --- | --- | --- |\n| `freeform_tags` | Freeform tags applied to all resources. | any | `{access = \"private\", environment = \"dev\", role = \"oke\", version = \"5\"}` |\n| `defined_tags` | Defined tags applied to all resources. Requires `use_defined_tags = true`. | any | `{}` |\n| `bastion_defined_tags` | Defined tags for bastion resources only. | any | `{}` |\n| `bastion_freeform_tags` | Freeform tags for bastion resources only. | any | `{}` |\n| `cluster_defined_tags` | Defined tags for cluster resources only. | any | `{}` |\n| `cluster_freeform_tags` | Freeform tags for cluster resources only. | any | `{}` |\n| `iam_defined_tags` | Defined tags for IAM resources only. | any | `{}` |\n| `iam_freeform_tags` | Freeform tags for IAM resources only. | any | `{}` |\n| `network_defined_tags` | Defined tags for network resources only. | any | `{}` |\n| `network_freeform_tags` | Freeform tags for network resources only. | any | `{}` |\n| `operator_defined_tags` | Defined tags for operator resources only. | any | `{}` |\n| `operator_freeform_tags` | Freeform tags for operator resources only. | any | `{}` |\n| `persistent_volume_defined_tags` | Defined tags for persistent volume resources only. | any | `{}` |\n| `persistent_volume_freeform_tags` | Freeform tags for persistent volume resources only. | any | `{}` |\n| `service_lb_defined_tags` | Defined tags for service load balancer resources only. | any | `{}` |\n| `service_lb_freeform_tags` | Freeform tags for service load balancer resources only. | any | `{}` |\n| `workers_defined_tags` | Defined tags for worker resources only. | any | `{}` |\n| `workers_freeform_tags` | Freeform tags for worker resources only. | any | `{}` |\n\n## Validation Rules\n\n- `compartment_id` is required.\n- Either `ssh_public_key` or `ssh_public_key_path` must be provided when creating bastion or operator.\n- `bastion_image_type = \"custom\"` requires `bastion_image_id`.\n- `operator_image_type = \"custom\"` requires `operator_image_id`.\n- `cni_type = \"npn\"` requires `cluster_type = \"enhanced\"`.\n- `oidc_discovery_enabled = true` requires `cluster_type = \"enhanced\"`.\n- `oidc_token_auth_enabled = true` requires `cluster_type = \"enhanced\"`.\n- `worker_pool_mode = \"node-pool\"` is the only mode that supports OKE-managed node pools.\n- `worker_pool_mode = \"cluster-network\"` or `\"instance-pool\"` or `\"instance\"` are self-managed modes.\n- Pods CIDR must not overlap with VCN, worker, or load balancer subnets.\n- Services CIDR must not overlap with the VCN CIDR.\n\n## Outputs\n\n| Output | Description |\n|--------|-------------|\n| `state_id` | Generated state identifier. |\n| `cluster_id` | OKE cluster OCID. |\n| `cluster_endpoints` | Cluster endpoints (public and private). |\n| `cluster_oidc_discovery_endpoint` | OIDC discovery endpoint URL. |\n| `cluster_kubeconfig` | Kubernetes kubeconfig YAML (requires `output_detail = true`). |\n| `cluster_ca_cert` | Base64-encoded cluster CA certificate. |\n| `apiserver_private_host` | Private API server hostname. |\n| `bastion_id` | Bastion instance OCID. |\n| `bastion_public_ip` | Bastion public IP address. |\n| `ssh_to_bastion` | SSH command to connect to the bastion. |\n| `operator_id` | Operator instance OCID. |\n| `operator_private_ip` | Operator private IP address. |\n| `ssh_to_operator` | SSH command to connect to the operator (via bastion). |\n| `vcn_id` | VCN OCID. |\n| `ig_route_table_id` | Internet gateway route table OCID. |\n| `nat_route_table_id` | NAT gateway route table OCID. |\n| `drg_id` | Dynamic Routing Gateway OCID (when created). |\n| `lpg_all_attributes` | Local Peering Gateway attributes. |\n| `bastion_subnet_id` | Bastion subnet OCID. |\n| `bastion_subnet_cidr` | Bastion subnet CIDR. |\n| `operator_subnet_id` | Operator subnet OCID. |\n| `operator_subnet_cidr` | Operator subnet CIDR. |\n| `control_plane_subnet_id` | Control plane subnet OCID. |\n| `control_plane_subnet_cidr` | Control plane subnet CIDR. |\n| `worker_subnet_id` | Worker subnet OCID. |\n| `worker_subnet_cidr` | Worker subnet CIDR. |\n| `pod_subnet_id` | Pod subnet OCID. |\n| `pod_subnet_cidr` | Pod subnet CIDR. |\n| `int_lb_subnet_id` | Internal load balancer subnet OCID. |\n| `int_lb_subnet_cidr` | Internal load balancer subnet CIDR. |\n| `pub_lb_subnet_id` | Public load balancer subnet OCID. |\n| `pub_lb_subnet_cidr` | Public load balancer subnet CIDR. |\n| `fss_subnet_id` | FSS subnet OCID. |\n| `fss_subnet_cidr` | FSS subnet CIDR. |\n| `bastion_nsg_id` | Bastion NSG OCID. |\n| `operator_nsg_id` | Operator NSG OCID. |\n| `control_plane_nsg_id` | Control plane NSG OCID. |\n| `int_lb_nsg_id` | Internal load balancer NSG OCID. |\n| `pub_lb_nsg_id` | Public load balancer NSG OCID. |\n| `worker_nsg_id` | Worker NSG OCID. |\n| `pod_nsg_id` | Pod NSG OCID. |\n| `fss_nsg_id` | FSS NSG OCID. |\n| `network_security_rules` | Map of all NSG security rules (requires `output_detail = true`). |\n| `availability_domains` | Map of availability domains. |\n| `dynamic_group_ids` | IAM dynamic group OCIDs. |\n| `policy_statements` | IAM policy statements. |\n| `worker_pools` | Worker pool details. |\n| `worker_instances` | Worker instance details. |\n| `worker_pool_ids` | Worker pool OCIDs. |\n| `worker_pool_ips` | Worker pool IP addresses. |\n"
  },
  {
    "path": "examples/bastion/README.md",
    "content": "# Bastion Example\n\nEnables the bastion host with a public IP for SSH access into the VCN.\n\n## Usage\n\nCopy `vars-bastion.auto.tfvars` to your root module and adjust the values as needed.\n"
  },
  {
    "path": "examples/cluster/README.md",
    "content": "# Cluster Examples\n\nExample configurations for OKE cluster creation:\n\n| File | Description |\n|------|-------------|\n| `vars-cluster-basic.auto.tfvars` | Basic cluster with default settings |\n| `vars-cluster-enhanced.auto.tfvars` | Enhanced cluster with additional features |\n| `vars-cluster-oidc-discovery.auto.tfvars` | Cluster with OIDC discovery enabled |\n| `vars-cluster-oidc-auth-single.auto.tfvars` | Cluster with single OIDC token authentication |\n| `vars-cluster-oidc-auth-multiple.auto.tfvars` | Cluster with multiple OIDC token authentication configurations |\n\n## Usage\n\nCopy the desired `.auto.tfvars` file(s) to your root module and adjust the values as needed.\n"
  },
  {
    "path": "examples/cluster-addons/README.md",
    "content": "# Cluster Add-ons Example\n\nExample configuration for enabling and configuring OKE cluster add-ons such as CertManager and NvidiaGpuPlugin.\n\n## Usage\n\nCopy `vars-cluster-addons.auto.tfvars` to your root module and adjust the values as needed.\n"
  },
  {
    "path": "examples/extensions/README.md",
    "content": "# Extension Examples\n\nExample configurations for deploying Kubernetes extensions:\n\n| File | Extension | Description |\n|------|-----------|-------------|\n| `vars-extensions-argocd.auto.tfvars` | ArgoCD | GitOps continuous delivery |\n| `vars-extensions-cilium.auto.tfvars` | Cilium | eBPF-based networking and security |\n| `vars-extensions-cluster-autoscaler.auto.tfvars` | Cluster Autoscaler | Automatic node pool scaling |\n| `vars-extensions-dcgm-exporter.auto.tfvars` | DCGM Exporter | GPU metrics for NVIDIA GPUs |\n| `vars-extensions-gatekeeper.auto.tfvars` | Gatekeeper | OPA policy enforcement |\n| `vars-extensions-metrics-server.auto.tfvars` | Metrics Server | Kubernetes metrics API |\n| `vars-extensions-mpi-operator.auto.tfvars` | MPI Operator | MPI/NCCL distributed training jobs |\n| `vars-extensions-multus.auto.tfvars` | Multus | Multi-network pod interfaces |\n| `vars-extensions-prometheus.auto.tfvars` | Prometheus | Monitoring and alerting |\n| `vars-extensions-rdma-cni.auto.tfvars` | RDMA CNI | RDMA network connections |\n| `vars-extensions-service-account.auto.tfvars` | Service Accounts | Kubernetes service accounts with RBAC |\n| `vars-extensions-sriov-cni.auto.tfvars` | SR-IOV CNI | SR-IOV network connections |\n| `vars-extensions-sriov-device.auto.tfvars` | SR-IOV Device Plugin | SR-IOV network device advertisement |\n| `vars-extensions-whereabouts.auto.tfvars` | Whereabouts | IP address management for Multus |\n\n## Usage\n\nCopy the desired `.auto.tfvars` file(s) to your root module and adjust the values as needed.\n"
  },
  {
    "path": "examples/iam/README.md",
    "content": "# IAM Examples\n\nExample configurations for IAM resources:\n\n| File | Description |\n|------|-------------|\n| `vars-iam-policies.auto.tfvars` | IAM dynamic groups and policies |\n| `vars-iam-tags.auto.tfvars` | IAM tag namespaces and defined tags |\n\n## Usage\n\nCopy the desired `.auto.tfvars` file(s) to your root module and adjust the values as needed.\n"
  },
  {
    "path": "examples/istio-mc/README.md",
    "content": "# Multi-region service mesh with Istio and OKE\n\n## Assumptions\n\n1. A pair of OKE clusters in 2 different OCI regions will be used.\n2. The OKE clusters will use private control planes.\n3. The topology model used is [Multi-Primary on different networks](https://istio.io/latest/docs/setup/install/multicluster/multi-primary_multi-network/).\n\n![Multi-primary on multiple networks](docs/assets/multi-primary%20multi-networks.png)\n4. This example uses self-signed certificates.\n\n## Create the OKE Clusters\n\n1. Copy the terraform.tfvars.example to terraform.tfvars and provide the necessary values as detailed in steps 2-6.\n\n2. Configure the provider parameters:\n\n```\n# provider\napi_fingerprint = \"\"\n\napi_private_key_path = \"~/.oci/oci_rsa.pem\"\n\nhome_region = \"ashburn\"\n\ntenancy_id = \"ocid1.tenancy.oc1..\"\n\nuser_id = \"ocid1.user.oc1..\"\n\ncompartment_id = \"ocid1.compartment.oc1..\"\n```\n\n3. Configure an ssh key pair:\n\n```\n# ssh\nssh_private_key_path = \"~/.ssh/id_rsa\"\nssh_public_key_path  = \"~/.ssh/id_rsa.pub\"\n```\n\n4. Configure your clusters' regions.\n\n```\n# clusters\nclusters = {\n  c1 = { region = \"sydney\", vcn = \"10.1.0.0/16\", pods = \"10.201.0.0/16\", services = \"10.101.0.0/16\", enabled = true }\n  c2 = { region = \"melbourne\", vcn = \"10.2.0.0/16\", pods = \"10.202.0.0/16\", services = \"10.102.0.0/16\", enabled = true }\n}\n```\n\n5. Configure additional parameters if necessary:\n\n```\nkubernetes_version = \"v1.32.1\"\n\ncluster_type = \"basic\"\n\noke_control_plane = \"private\"\n```\n\n6. Configure your node pools:\n\n```\nnodepools = {\n  np1 = {\n    shape            = \"VM.Standard.E4.Flex\",\n    ocpus            = 2,\n    memory           = 64,\n    size             = 2,\n    boot_volume_size = 150,\n  }\n}\n```\n\n7. Run terraform to create your clusters:\n\n```\nterraform apply --auto-approve\n```\n\n8. Once the Dynamic Routing Gateways (DRGs) and Remote Peering Connections (RPCs) have been created, use the OCI console to establish a connection between them.\n\n## Install Istio\n\n1. Terraform will output an ssh convenience command. Use it to ssh to the operator host:\n\n```\nssh_to_operator = \"ssh -o ProxyCommand='ssh -W %h:%p -i ~/.ssh/id_rsa opc@<bastion_ip>' -i ~/.ssh/id_rsa opc@<operator_ip>\"\n```\n\n2. Verify connectivity to both clusters:\n\n```\nfor cluster in c1 c2; do\n  ktx $cluster\n  k get nodes\ndone\n```\n\n3. Generate certs for each cluster:\n\n```\nexport ISTIO_HOME=/home/opc/istio-1.20.2\ncd $ISTIO_HOME/tools/certs \nmake -f Makefile.selfsigned.mk c1-cacerts\nmake -f Makefile.selfsigned.mk c2-cacerts\n```\n\n4. Create and label istio-system namespace in each cluster:\n\n```\nfor cluster in c1 c2; do\n  ktx $cluster\n  k create ns istio-system\n  k label namespace istio-system topology.istio.io/network=$cluster\ndone\n```\n\n5. Create a secret containing the certificates in istio-system namespace for both clusters:\n\n```\nfor cluster in c1 c2; do\n  ktx $cluster\n  kubectl create secret generic cacerts -n istio-system \\\n      --from-file=$cluster/ca-cert.pem \\\n      --from-file=$cluster/ca-key.pem \\\n      --from-file=$cluster/root-cert.pem \\\n      --from-file=$cluster/cert-chain.pem\ndone\n```\n\n6. Install Istio in both clusters:\n\n```\nfor cluster in c1 c2; do\n  ktx $cluster\n  istioctl install --set profile=default -f $HOME/$cluster.yaml\ndone\n```\n\n7. Verify the Istio installation in both clusters:\n\n```\nfor cluster in c1 c2; do\n  ktx $cluster\n  istioctl verify-install\ndone\n```\n\n8. Check if the load balancers have been properly provisioned:\n\n```\nfor cluster in c1 c2; do\n  ktx $cluster\n  k -n istio-system get svc\ndone\n```\n\n9. Check if Istio pods are running:\n\n```\nfor cluster in c1 c2; do\n  ktx $cluster\n  k -n istio-system get pods\ndone\n```\n\n10. Create an Gateway to expose all services through the eastwest ingress gateway:\n\n```\ncd $ISTIO_HOME\nfor cluster in c1 c2; do\n  ktx $cluster\n  k apply -f samples/multicluster/expose-services.yaml\ndone\n```\n\n11. Set the environment variables to verify multi-cluster connectivity:\n```\nexport CTX_CLUSTER1=c1\nexport CTX_CLUSTER2=c2\n```\n\n12. Enable endpoint discovery in each cluster by creating a remote secret:\n\n```\nistioctl create-remote-secret \\\n  --context=\"${CTX_CLUSTER1}\" \\\n  --name=\"${CTX_CLUSTER1}\" | \\\n  kubectl apply -f - --context=\"${CTX_CLUSTER2}\"\n\n\n istioctl create-remote-secret \\\n  --context=\"${CTX_CLUSTER2}\" \\\n  --name=\"${CTX_CLUSTER2}\" | \\\n  kubectl apply -f - --context=\"${CTX_CLUSTER1}\"\n```\n\n## Verify cross-cluster connectivity\n\n1. Deploy the HelloWorld Service in both clusters:\n\n```\nfor cluster in c1 c2; do\n  kubectl create --context=\"${cluster}\" namespace sample\n  kubectl label --context=\"${cluster}\" namespace sample istio-injection=enabled\n  kubectl apply --context=\"${cluster}\" -f samples/helloworld/helloworld.yaml -l service=helloworld -n sample\ndone\n```\n\n2. Deploy v1 to cluster c1:\n\n```\nkubectl apply --context=\"${CTX_CLUSTER1}\" \\\n    -f samples/helloworld/helloworld.yaml \\\n    -l version=v1 -n sample\n\nkubectl get pod --context=\"${CTX_CLUSTER1}\" -n sample -l app=helloworld\n```\n\n3. Deploy v2 to cluster c2:\n\n```\nkubectl apply --context=\"${CTX_CLUSTER2}\" \\\n    -f samples/helloworld/helloworld.yaml \\\n    -l version=v2 -n sample\n\nkubectl get pod --context=\"${CTX_CLUSTER2}\" -n sample -l app=helloworld\n```\n\n4. Deploy Sleep client pod in both clusters:\n\n```\nkubectl apply --context=\"${CTX_CLUSTER1}\" \\\n    -f samples/sleep/sleep.yaml -n sample\nkubectl apply --context=\"${CTX_CLUSTER2}\" \\\n    -f samples/sleep/sleep.yaml -n sample\n```\n\n5. Generate traffic from c1. The response should alternate between c1 (v1) and c2 (v2) regions:\n\n```\nfor i in $(seq 1 100); do\nkubectl exec --context=\"${CTX_CLUSTER1}\" -n sample -c sleep \\\n    \"$(kubectl get pod --context=\"${CTX_CLUSTER1}\" -n sample -l \\\n    app=sleep -o jsonpath='{.items[0].metadata.name}')\" \\\n    -- curl -sS helloworld.sample:5000/hello\ndone\n```\n\n6. Generate traffic from c2. The response should alternate between c1 (v1) and c2 (v2) regions:\n\n```\nfor i in $(seq 1 100); do\nkubectl exec --context=\"${CTX_CLUSTER2}\" -n sample -c sleep \\\n    \"$(kubectl get pod --context=\"${CTX_CLUSTER2}\" -n sample -l \\\n    app=sleep -o jsonpath='{.items[0].metadata.name}')\" \\\n    -- curl -sS helloworld.sample:5000/hello\ndone\n```\n\n7. Cross-cluster connectivity has been verified.\n\n"
  },
  {
    "path": "examples/istio-mc/c1.tf",
    "content": "# Copyright (c) 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nmodule \"c1\" {\n\n  source  = \"oracle-terraform-modules/oke/oci\"\n  version = \"5.2.2\"\n\n  count = lookup(lookup(var.clusters, \"c1\"), \"enabled\") ? 1 : 0\n\n  home_region = lookup(local.regions, var.home_region)\n\n  region = lookup(local.regions, lookup(lookup(var.clusters, \"c1\"), \"region\"))\n\n  tenancy_id = var.tenancy_id\n\n  # general oci parameters\n  compartment_id = var.compartment_id\n\n  # ssh keys\n  ssh_private_key_path = var.ssh_private_key_path\n  ssh_public_key_path  = var.ssh_public_key_path\n\n  # networking\n  create_drg       = var.oke_control_plane == \"private\" ? true : false\n  drg_display_name = \"c1-drg\"\n\n  remote_peering_connections = var.oke_control_plane == \"private\" ? {\n    for k, v in var.clusters : \"rpc-to-${k}\" => {} if k != \"c1\"\n  } : {}\n\n  nat_gateway_route_rules = var.oke_control_plane == \"private\" ? [\n    for k, v in var.clusters :\n    {\n      destination       = lookup(v, \"vcn\")\n      destination_type  = \"CIDR_BLOCK\"\n      network_entity_id = \"drg\"\n      description       = \"Routing to allow connectivity to ${title(k)} cluster\"\n    } if k != \"c1\"\n  ] : []\n\n  vcn_cidrs     = [lookup(lookup(var.clusters, \"c1\"), \"vcn\")]\n  vcn_dns_label = \"c1\"\n  vcn_name      = \"c1\"\n\n  #subnets\n  subnets = {\n    bastion  = { newbits = 13, netnum = 0, dns_label = \"bastion\" }\n    operator = { newbits = 13, netnum = 1, dns_label = \"operator\" }\n    cp       = { newbits = 13, netnum = 2, dns_label = \"cp\" }\n    int_lb   = { newbits = 11, netnum = 16, dns_label = \"ilb\" }\n    pub_lb   = { newbits = 11, netnum = 17, dns_label = \"plb\" }\n    workers  = { newbits = 2, netnum = 1, dns_label = \"workers\" }\n  }\n\n  # bastion host\n  create_bastion        = true\n  bastion_allowed_cidrs = [\"0.0.0.0/0\"]\n  bastion_upgrade       = false\n\n  # operator host\n  create_operator            = true\n  operator_upgrade           = false\n  create_iam_resources       = true\n  create_iam_operator_policy = \"always\"\n  operator_install_k9s       = true\n\n  # oke cluster options\n  cluster_name                = \"c1\"\n  cluster_type                = var.cluster_type\n  cni_type                    = var.preferred_cni\n  control_plane_is_public     = var.oke_control_plane == \"public\"\n  control_plane_allowed_cidrs = [local.anywhere]\n  kubernetes_version          = var.kubernetes_version\n  pods_cidr                   = lookup(lookup(var.clusters, \"c1\"), \"pods\")\n  services_cidr               = lookup(lookup(var.clusters, \"c1\"), \"services\")\n\n\n  # node pools\n  allow_worker_ssh_access = true\n  kubeproxy_mode          = \"iptables\"\n  worker_pool_mode        = \"node-pool\"\n  worker_pools            = var.nodepools\n  worker_cloud_init       = local.worker_cloud_init\n  worker_image_type       = \"oke\"\n\n  # oke load balancers\n  load_balancers          = \"both\"\n  preferred_load_balancer = \"public\"\n\n  allow_rules_internal_lb = merge({\n    for p in local.service_mesh_ports :\n    format(\"Allow ingress to port %v from cluster c2 for Istio\", p) => {\n      protocol    = local.tcp_protocol, port = p, source = lookup(lookup(var.clusters, \"c2\"), \"vcn\"),\n      source_type = local.rule_type_cidr,\n    }\n    },\n    {\n      for c in var.clusters : format(\"Allow TCP ingress from cluster %v for Cilium clustermesh\", lookup(c, \"name\")) => {\n        protocol = local.tcp_protocol, port = 2379, source = lookup(c, \"vcn\"), source_type = local.rule_type_cidr,\n      } if lookup(c, \"name\") != \"c1\"\n    },\n    {\n      for c in var.clusters :\n      format(\"Allow UDP ingress from cluster %v for cross-cluster DNS lookup via NLB for Coherence WKA\", lookup(c, \"name\"))\n      => {\n        protocol = local.udp_protocol, port = 53, source = lookup(c, \"vcn\"), source_type = local.rule_type_cidr,\n      } if lookup(c, \"name\") != \"c1\"\n    },\n  )\n\n  allow_rules_public_lb = merge({\n    for p in local.public_lb_allowed_ports :\n    format(\"Allow ingress to port %v\", p) => {\n      protocol = local.tcp_protocol, port = p, source = \"0.0.0.0/0\", source_type = local.rule_type_cidr,\n    }\n    },\n  )\n\n  allow_rules_workers = merge(\n    {\n      for c in var.clusters :\n      format(\"Allow UDP ingress to workers from cluster %v for default VXLAN\", lookup(c, \"name\")) => {\n        protocol = local.udp_protocol, port = 8472, source = lookup(c, \"vcn\"), source_type = local.rule_type_cidr,\n      } if lookup(c, \"name\") != \"c1\"\n    },\n  )\n\n  user_id = var.user_id\n\n  providers = {\n    oci      = oci.c1\n    oci.home = oci.home\n  }\n}\n"
  },
  {
    "path": "examples/istio-mc/c2.tf",
    "content": "# Copyright (c) 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nmodule \"c2\" {\n\n  source  = \"oracle-terraform-modules/oke/oci\"\n  version = \"5.2.2\"\n\n  count = lookup(lookup(var.clusters, \"c2\"), \"enabled\") ? 1 : 0\n\n  home_region = lookup(local.regions, var.home_region)\n\n  region = lookup(local.regions, lookup(lookup(var.clusters, \"c2\"), \"region\"))\n\n  tenancy_id = var.tenancy_id\n\n  # general oci parameters\n  compartment_id = var.compartment_id\n\n  # ssh keys\n  ssh_private_key_path = var.ssh_private_key_path\n  ssh_public_key_path  = var.ssh_public_key_path\n\n  # networking\n  create_drg       = var.oke_control_plane == \"private\" ? true : false\n  drg_display_name = \"c2\"\n\n  remote_peering_connections = var.oke_control_plane == \"private\" ? {\n    for k, v in var.clusters : \"rpc-to-${k}\" => {} if k != \"c2\"\n  } : {}\n\n  nat_gateway_route_rules = var.oke_control_plane == \"private\" ? [\n    for k, v in var.clusters :\n    {\n      destination       = lookup(v, \"vcn\")\n      destination_type  = \"CIDR_BLOCK\"\n      network_entity_id = \"drg\"\n      description       = \"Routing to allow connectivity to ${title(k)} cluster\"\n    } if k != \"c2\"\n  ] : []\n\n  vcn_cidrs     = [lookup(lookup(var.clusters, \"c2\"), \"vcn\")]\n  vcn_dns_label = \"c2\"\n  vcn_name      = \"c2\"\n\n  #subnets\n  subnets = {\n    cp      = { newbits = 13, netnum = 2, dns_label = \"cp\" }\n    int_lb  = { newbits = 11, netnum = 16, dns_label = \"ilb\" }\n    pub_lb  = { newbits = 11, netnum = 17, dns_label = \"plb\" }\n    workers = { newbits = 2, netnum = 1, dns_label = \"workers\" }\n  }\n\n  # bastion host\n  create_bastion        = false\n  bastion_allowed_cidrs = [\"0.0.0.0/0\"]\n  bastion_upgrade       = false\n\n  # operator host\n  create_operator            = false\n  operator_upgrade           = false\n  create_iam_resources       = true\n  create_iam_operator_policy = \"always\"\n  operator_install_k9s       = true\n\n  # oke cluster options\n  cluster_name                = \"c2\"\n  cluster_type                = var.cluster_type\n  cni_type                    = var.preferred_cni\n  control_plane_is_public     = var.oke_control_plane == \"public\"\n  control_plane_allowed_cidrs = [local.anywhere]\n  kubernetes_version          = var.kubernetes_version\n  pods_cidr                   = lookup(lookup(var.clusters, \"c2\"), \"pods\")\n  services_cidr               = lookup(lookup(var.clusters, \"c2\"), \"services\")\n\n\n  # node pools\n  kubeproxy_mode    = \"iptables\"\n  worker_pool_mode  = \"node-pool\"\n  worker_pools      = var.nodepools\n  worker_cloud_init = local.worker_cloud_init\n  worker_image_type = \"oke\"\n\n  # oke load balancers\n  load_balancers          = \"both\"\n  preferred_load_balancer = \"public\"\n\n  allow_rules_internal_lb = merge({\n    for p in local.service_mesh_ports :\n    format(\"Allow ingress to port %v  from cluster c1\", p) => {\n      protocol    = local.tcp_protocol, port = p, source = lookup(lookup(var.clusters, \"c1\"), \"vcn\"),\n      source_type = local.rule_type_cidr,\n    }\n    },\n    {\n      for c in var.clusters : format(\"Allow TCP ingress from cluster %v for Cilium clustermesh\", lookup(c, \"name\")) => {\n        protocol = local.tcp_protocol, port = 2379, source = lookup(c, \"vcn\"), source_type = local.rule_type_cidr,\n      } if lookup(c, \"name\") != \"c2\"\n    },\n    {\n      for c in var.clusters :\n      format(\"Allow UDP ingress from cluster %v for cross-cluster DNS lookup via NLB for Coherence WKA\", lookup(c, \"name\"))\n      => {\n        protocol = local.udp_protocol, port = 53, source = lookup(c, \"vcn\"), source_type = local.rule_type_cidr,\n      } if lookup(c, \"name\") != \"c2\"\n    },\n  )\n\n  allow_rules_public_lb = merge({\n    for p in local.public_lb_allowed_ports :\n    format(\"Allow ingress to port %v\", p) => {\n      protocol = local.tcp_protocol, port = p, source = \"0.0.0.0/0\", source_type = local.rule_type_cidr,\n    }\n    },\n  )\n\n  allow_rules_workers = merge(\n    {\n      for c in var.clusters :\n      format(\"Allow UDP ingress to workers from cluster %v for default VXLAN\", lookup(c, \"name\")) => {\n        protocol = local.udp_protocol, port = 8472, source = lookup(c, \"vcn\"), source_type = local.rule_type_cidr\n      } if lookup(c, \"name\") != \"c2\"\n    },\n  )\n\n  user_id = var.user_id\n\n  providers = {\n    oci      = oci.c2\n    oci.home = oci.home\n  }\n}\n"
  },
  {
    "path": "examples/istio-mc/contexts.tf",
    "content": "# Copyright (c) 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nresource \"null_resource\" \"tools\" {\n  depends_on = [module.c1]\n\n  connection {\n    host        = local.operator_ip\n    private_key = file(var.ssh_private_key_path)\n    timeout     = \"40m\"\n    type        = \"ssh\"\n    user        = \"opc\"\n\n    bastion_host        = local.bastion_ip\n    bastion_user        = \"opc\"\n    bastion_private_key = file(var.ssh_private_key_path)\n  }\n\n  provisioner \"file\" {\n    content     = local.token_helper_template\n    destination = \"/home/opc/token_helper.sh\"\n  }\n\n  provisioner \"file\" {\n    content     = local.istioctl_template\n    destination = \"/home/opc/install_istioctl.sh\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\n      \"mkdir /home/opc/bin; mv token_helper.sh /home/opc/bin; chmod +x /home/opc/bin/token_helper.sh\",\n      \"if [ -f \\\"$HOME/install_istioctl.sh\\\" ]; then bash \\\"$HOME/install_istioctl.sh\\\";fi\",\n    ]\n  }\n}\n\n\nresource \"null_resource\" \"set_contexts\" {\n  depends_on = [module.c1, module.c2]\n  for_each   = local.all_cluster_ids\n  connection {\n    host        = local.operator_ip\n    private_key = file(var.ssh_private_key_path)\n    timeout     = \"40m\"\n    type        = \"ssh\"\n    user        = \"opc\"\n\n    bastion_host        = local.bastion_ip\n    bastion_user        = \"opc\"\n    bastion_private_key = file(var.ssh_private_key_path)\n  }\n\n  provisioner \"file\" {\n    content     = lookup(local.kubeconfig_templates, each.key)\n    destination = \"/home/opc/generate_kubeconfig_${each.key}.sh\"\n  }\n\n  provisioner \"file\" {\n    content     = lookup(local.set_credentials_templates, each.key)\n    destination = \"/home/opc/kubeconfig_set_credentials_${each.key}.sh\"\n  }\n\n  provisioner \"file\" {\n    content     = lookup(local.set_alias_templates, each.key)\n    destination = \"/home/opc/set_alias_${each.key}.sh\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\n      \"if [ -f \\\"$HOME/generate_kubeconfig_${each.key}.sh\\\" ]; then bash \\\"$HOME/generate_kubeconfig_${each.key}.sh\\\";fi\",\n      \"if [ -f \\\"$HOME/kubeconfig_set_credentials_${each.key}.sh\\\" ]; then bash \\\"$HOME/kubeconfig_set_credentials_${each.key}.sh\\\";fi\",\n      \"if [ -f \\\"$HOME/set_alias_${each.key}.sh\\\" ]; then bash \\\"$HOME/set_alias_${each.key}.sh\\\";fi\",\n    ]\n  }\n\n  triggers = {\n    clusters = length(var.clusters)\n  }\n\n  lifecycle {\n    create_before_destroy = true\n  }\n\n}\n"
  },
  {
    "path": "examples/istio-mc/istio.tf",
    "content": "# Copyright (c) 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  istio_c1 = templatefile(\"${path.module}/resources/istio.template.yaml\",\n    {\n      mesh_id          = var.istio_mesh_id\n      cluster          = \"c1\"\n      mesh_network     = \"c1\"\n      pub_nsg_id       = one(element([module.c1[*].pub_lb_nsg_id], 0))\n      int_lb_subnet_id = one(element([module.c1[*].int_lb_subnet_id], 0))\n      int_nsg_id       = one(element([module.c1[*].int_lb_nsg_id], 0))\n    }\n  )\n\n  istio_c2 = templatefile(\"${path.module}/resources/istio.template.yaml\",\n    {\n      mesh_id          = var.istio_mesh_id\n      cluster          = \"c2\"\n      mesh_network     = \"c2\"\n      pub_nsg_id       = one(element([module.c2[*].pub_lb_nsg_id], 0))\n      int_lb_subnet_id = one(element([module.c2[*].int_lb_subnet_id], 0))\n      int_nsg_id       = one(element([module.c2[*].int_lb_nsg_id], 0))\n    }\n  )\n}\n\nresource \"null_resource\" \"istio\" {\n  depends_on = [module.c1, module.c2]\n\n  connection {\n    host        = local.operator_ip\n    private_key = file(var.ssh_private_key_path)\n    timeout     = \"40m\"\n    type        = \"ssh\"\n    user        = \"opc\"\n\n    bastion_host        = local.bastion_ip\n    bastion_user        = \"opc\"\n    bastion_private_key = file(var.ssh_private_key_path)\n  }\n\n  provisioner \"file\" {\n    content     = local.istio_c1\n    destination = \"/home/opc/c1.yaml\"\n  }\n\n  provisioner \"file\" {\n    content     = local.istio_c2\n    destination = \"/home/opc/c2.yaml\"\n  }\n}\n"
  },
  {
    "path": "examples/istio-mc/locals.tf",
    "content": "# Copyright (c) 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n\n  all_ports = -1\n\n  # Protocols\n  # See https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml\n  all_protocols = \"all\"\n  icmp_protocol = 1\n  tcp_protocol  = 6\n  udp_protocol  = 17\n\n  anywhere          = \"0.0.0.0/0\"\n  rule_type_nsg     = \"NETWORK_SECURITY_GROUP\"\n  rule_type_cidr    = \"CIDR_BLOCK\"\n  rule_type_service = \"SERVICE_CIDR_BLOCK\"\n\n  bastion_ip = one(element([module.c1[*].bastion_public_ip], 0))\n\n  operator_ip = one(element([module.c1[*].operator_private_ip], 0))\n\n  # TODO: check when is 15021 required for public\n  public_lb_allowed_ports = [80, 443, 15021]\n\n  # ports required to be opened for inter-cluster communication between for Istio\n  service_mesh_ports = [15012, 15017, 15021, 15443]\n\n  regions = {\n    # Africa\n    johannesburg = \"af-johannesburg-1\"\n\n    # Asia\n    chuncheon = \"ap-chuncheon-1\"\n    hyderabad = \"ap-hyderabad-1\"\n    mumbai    = \"ap-mumbai-1\"\n    osaka     = \"ap-osaka-1\"\n    seoul     = \"ap-seoul-1\"\n    singapore = \"ap-singapore-1\"\n    tokyo     = \"ap-tokyo-1\"\n\n    # Europe\n    amsterdam = \"eu-amsterdam-1\"\n    frankfurt = \"eu-frankfurt-1\"\n    london    = \"uk-london-1\"\n    madrid    = \"eu-madrid-1\"\n    marseille = \"eu-marseille-1\"\n    milan     = \"eu-milan-1\"\n    newport   = \"uk-cardiff-1\"\n    paris     = \"eu-paris-1\"\n    stockholm = \"eu-stockholm-1\"\n    zurich    = \"eu-zurich-1\"\n\n    # Middle East\n    abudhabi  = \"me-abudhabi-1\"\n    dubai     = \"me-dubai-1\"\n    jeddah    = \"me-jeddah-1\"\n    jerusalem = \"il-jerusalem-1\"\n\n    # Oceania\n    melbourne = \"ap-melbourne-1\"\n    sydney    = \"ap-sydney-1\"\n\n\n    # South America\n    bogota     = \"sa-bogota-1\"\n    santiago   = \"sa-santiago-1\"\n    saupaulo   = \"sa-saupaulo-1\"\n    valparaiso = \"sa-valparaiso-1\"\n    vinhedo    = \"sa-vinhedo-1\"\n\n    # North America\n    ashburn   = \"us-ashburn-1\"\n    chicago   = \"us-chicago-1\"\n    monterrey = \"mx-monterrey-1\"\n    montreal  = \"ca-montreal-1\"\n    phoenix   = \"us-phoenix-1\"\n    queretaro = \"mx-queretaro-1\"\n    sanjose   = \"us-sanjose-1\"\n    toronto   = \"ca-toronto-1\"\n\n    # US Gov FedRamp\n    us-gov-ashburn = \"us-langley-1\"\n    us-gov-phoenix = \"us-luke-1\"\n\n    # US Gov DISA L5\n    us-dod-east  = \"us-gov-ashburn-1\"\n    us-dod-north = \"us-gov-chicago-1\"\n    us-dod-west  = \"us-gov-phoenix-1\"\n\n    # UK Gov\n    uk-gov-south = \"uk-gov-london-1\"\n    uk-gov-west  = \"uk-gov-cardiff-1\"\n\n    # Australia Gov\n    au-gov-cbr = \"ap-dcc-canberra-1\"\n\n  }\n\n  worker_cloud_init = [\n    {\n      content      = <<-EOT\n    runcmd:\n    - 'echo \"Kernel module configuration for Istio and worker node initialization\"'\n    - 'modprobe br_netfilter'\n    - 'modprobe nf_nat'\n    - 'modprobe xt_REDIRECT'\n    - 'modprobe xt_owner'\n    - 'modprobe iptable_nat'\n    - 'modprobe iptable_mangle'\n    - 'modprobe iptable_filter'\n    - '/usr/libexec/oci-growfs -y'\n    - 'timedatectl set-timezone Australia/Sydney'\n    - 'curl --fail -H \"Authorization: Bearer Oracle\" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh'\n    - 'bash -x /var/run/oke-init.sh'\n    EOT\n      content_type = \"text/cloud-config\",\n    }\n  ]\n}\n"
  },
  {
    "path": "examples/istio-mc/outputs.tf",
    "content": "# Copyright (c) 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\noutput \"ssh_to_operator\" {\n  description = \"convenient command to ssh to the Admin operator host\"\n  value       = one(element([module.c1[*].ssh_to_operator], 0))\n}"
  },
  {
    "path": "examples/istio-mc/providers.tf",
    "content": "# Copyright (c) 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nprovider \"oci\" {\n  fingerprint         = var.api_fingerprint\n  private_key_path    = var.api_private_key_path\n  region              = lookup(local.regions, var.home_region)\n  tenancy_ocid        = var.tenancy_id\n  user_ocid           = var.user_id\n  alias               = \"home\"\n  ignore_defined_tags = [\"Oracle-Tags.CreatedBy\", \"Oracle-Tags.CreatedOn\"]\n}\n\nprovider \"oci\" {\n  fingerprint         = var.api_fingerprint\n  private_key_path    = var.api_private_key_path\n  region              = lookup(local.regions, lookup(lookup(var.clusters, \"c1\"), \"region\"))\n  tenancy_ocid        = var.tenancy_id\n  user_ocid           = var.user_id\n  alias               = \"c1\"\n  ignore_defined_tags = [\"Oracle-Tags.CreatedBy\", \"Oracle-Tags.CreatedOn\"]\n}\n\nprovider \"oci\" {\n  fingerprint         = var.api_fingerprint\n  private_key_path    = var.api_private_key_path\n  region              = lookup(local.regions, lookup(lookup(var.clusters, \"c2\"), \"region\"))\n  tenancy_ocid        = var.tenancy_id\n  user_ocid           = var.user_id\n  alias               = \"c2\"\n  ignore_defined_tags = [\"Oracle-Tags.CreatedBy\", \"Oracle-Tags.CreatedOn\"]\n}"
  },
  {
    "path": "examples/istio-mc/resources/istio.template.yaml",
    "content": "apiVersion: install.istio.io/v1alpha1\nkind: IstioOperator\nspec:\n  values:\n    global:\n      meshID: ${mesh_id}\n      multiCluster:\n        clusterName: ${cluster}\n      network: ${mesh_network}\n  components:\n    egressGateways:\n      - name: istio-egressgateway\n        enabled: true\n    ingressGateways:\n      - name: istio-ingressgateway\n        enabled: true\n        k8s:\n          serviceAnnotations:\n            service.beta.kubernetes.io/oci-load-balancer-internal: \"false\"\n            service.beta.kubernetes.io/oci-load-balancer-shape: \"flexible\"\n            service.beta.kubernetes.io/oci-load-balancer-shape-flex-min: \"50\"\n            service.beta.kubernetes.io/oci-load-balancer-shape-flex-max: \"100\"\n            service.beta.kubernetes.io/oci-load-balancer-security-list-management-mode: \"None\"\n            oci.oraclecloud.com/oci-network-security-groups: \"${pub_nsg_id}\"\n      - name: istio-eastwestgateway\n        enabled: true\n        k8s:\n          serviceAnnotations:\n            service.beta.kubernetes.io/oci-load-balancer-internal: \"true\"\n            service.beta.kubernetes.io/oci-load-balancer-shape: \"flexible\"\n            service.beta.kubernetes.io/oci-load-balancer-shape-flex-min: \"50\"\n            service.beta.kubernetes.io/oci-load-balancer-shape-flex-max: \"100\"\n            service.beta.kubernetes.io/oci-load-balancer-security-list-management-mode: \"None\"\n            service.beta.kubernetes.io/oci-load-balancer-subnet1: \"${int_lb_subnet_id}\"\n            oci.oraclecloud.com/oci-network-security-groups: \"${int_nsg_id}\"\n          env:\n          - name: ISTIO_META_REQUESTED_NETWORK_VIEW\n            value: ${mesh_network}\n          - name: ISTIO_META_ROUTER_MODE\n            value: \"sni-dnat\"\n          service:\n            ports:\n            - name: status-port\n              port: 15021\n              targetPort: 15021\n            - name: tls\n              port: 15443\n              targetPort: 15443\n            - name: tls-istiod\n              port: 15012\n              targetPort: 15012\n            - name: tls-webhook\n              port: 15017\n              targetPort: 15017\n        label:\n          app: istio-eastwestgateway\n          istio: eastwestgateway\n          topology.istio.io/network: ${mesh_network}"
  },
  {
    "path": "examples/istio-mc/scripts/cloud-init.sh",
    "content": "#!/bin/sh\n\nmodprobe br_netfilter \nmodprobe nf_nat\nmodprobe xt_REDIRECT\nmodprobe xt_owner\nmodprobe iptable_nat\nmodprobe iptable_mangle\nmodprobe iptable_filter\n\n/usr/libexec/oci-growfs -y\n\ntimedatectl set-timezone Australia/Sydney\n\n'curl --fail -H \"Authorization: Bearer Oracle\" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh'\n\nbash -x /var/run/oke-init.sh\n\ntouch /var/log/oke.done"
  },
  {
    "path": "examples/istio-mc/scripts/generate_kubeconfig.template.sh",
    "content": "#!/usr/bin/bash\n# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\noci ce cluster create-kubeconfig --cluster-id ${cluster_id} --file $HOME/.kube/config  --region ${region} --token-version 2.0.0 --kube-endpoint ${endpoint}"
  },
  {
    "path": "examples/istio-mc/scripts/istioctl.template.sh",
    "content": "#!/usr/bin/bash\n# Copyright (c) 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\necho \"Installing istioctl\"\ncurl -L curl -L https://istio.io/downloadIstio | ISTIO_VERSION=${version} TARGET_ARCH=x86_64 sh -"
  },
  {
    "path": "examples/istio-mc/scripts/kubeconfig_set_credentials.template.sh",
    "content": "#!/usr/bin/bash\n# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nkubectl config set-credentials \"user-${cluster_id_11}\" --exec-command=\"$HOME/bin/token_helper.sh\" \\\n  --exec-arg=\"ce\" \\\n  --exec-arg=\"cluster\" \\\n  --exec-arg=\"generate-token\" \\\n  --exec-arg=\"--cluster-id\" \\\n  --exec-arg=\"${cluster_id}\" \\\n  --exec-arg=\"--region\" \\\n  --exec-arg=\"${region}\""
  },
  {
    "path": "examples/istio-mc/scripts/set_alias.template.sh",
    "content": "#!/usr/bin/bash\n# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nkubectx ${cluster}=context-${cluster_id_11}\n"
  },
  {
    "path": "examples/istio-mc/scripts/token_helper.template.sh",
    "content": "#!/bin/bash\n# Copyright 2024 Oracle Corporation and/or affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nCLUSTER=$5\nREGION=$7\n\nTOKEN_FILE=$HOME/.kube/TOKEN-$CLUSTER\n\nif ! test -f \"$TOKEN_FILE\" || test $(( `date +%s` - `stat -L -c %Y $TOKEN_FILE` )) -gt 240; then\n  umask 022\n  oci ce cluster generate-token --cluster-id \"$CLUSTER\" --region \"$REGION\" > $TOKEN_FILE\nfi\n\ncat $TOKEN_FILE"
  },
  {
    "path": "examples/istio-mc/templates.tf",
    "content": "# Copyright (c) 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n\n  all_cluster_ids = merge(\n    { c1 = one(element([module.c1[*].cluster_id], 0)) },\n    { c2 = one(element([module.c2[*].cluster_id], 0)) }\n  )\n\n  kubeconfig_templates = {\n    for cluster_name, cluster_id in local.all_cluster_ids :\n    cluster_name => templatefile(\"${path.module}/scripts/generate_kubeconfig.template.sh\",\n      {\n        cluster_id = cluster_id\n        endpoint   = var.oke_control_plane == \"public\" ? \"PUBLIC_ENDPOINT\" : \"PRIVATE_ENDPOINT\"\n        region     = lookup(local.regions, lookup(lookup(var.clusters, cluster_name), \"region\"))\n      }\n    )\n  }\n\n  set_credentials_templates = {\n    for cluster_name, cluster_id in local.all_cluster_ids :\n    cluster_name => templatefile(\"${path.module}/scripts/kubeconfig_set_credentials.template.sh\",\n      {\n        cluster_id    = cluster_id\n        cluster_id_11 = substr(cluster_id, (length(cluster_id) - 11), length(cluster_id))\n        region        = lookup(local.regions, lookup(lookup(var.clusters, cluster_name), \"region\"))\n      }\n    )\n  }\n\n  set_alias_templates = {\n    for cluster_name, cluster_id in local.all_cluster_ids :\n    cluster_name => templatefile(\"${path.module}/scripts/set_alias.template.sh\",\n      {\n        cluster       = cluster_name\n        cluster_id_11 = substr(cluster_id, (length(cluster_id) - 11), length(cluster_id))\n      }\n    )\n  }\n\n  token_helper_template = templatefile(\"${path.module}/scripts/token_helper.template.sh\", {})\n\n  istioctl_template = templatefile(\"${path.module}/scripts/istioctl.template.sh\", {\n    version = var.istio_version\n  })\n}\n"
  },
  {
    "path": "examples/istio-mc/terraform.tfvars.example",
    "content": "    # provider\napi_fingerprint = \"\"\n\napi_private_key_path = \"~/.oci/oci_rsa.pem\"\n\nhome_region = \"ashburn\" # Use short form e.g. ashburn from location column https://docs.oracle.com/en-us/iaas/Content/General/Concepts/regions.htm\n\ntenancy_id = \"ocid1.tenancy.oc1..\"\n\nuser_id = \"ocid1.user.oc1..\"\n\ncompartment_id = \"ocid1.compartment.oc1..\"\n\n# ssh\nssh_private_key_path = \"~/.ssh/id_rsa\"\nssh_public_key_path  = \"~/.ssh/id_rsa.pub\"\n\n# clusters\n## For regions, # Use short form e.g. ashburn from location column https://docs.oracle.com/en-us/iaas/Content/General/Concepts/regions.htm\n## VCN, Pods and services clusters must not overlap with each other and with those of other clusters.\nclusters = {\n  c1 = { region = \"sydney\", vcn = \"10.1.0.0/16\", pods = \"10.201.0.0/16\", services = \"10.101.0.0/16\", enabled = true }\n  c2 = { region = \"melbourne\", vcn = \"10.2.0.0/16\", pods = \"10.202.0.0/16\", services = \"10.102.0.0/16\", enabled = true }\n}\n\nkubernetes_version = \"v1.32.1\"\n\ncluster_type = \"basic\"\n\noke_control_plane = \"private\"\n\nnodepools = {\n  np1 = {\n    shape            = \"VM.Standard.E4.Flex\",\n    ocpus            = 2,\n    memory           = 64,\n    size             = 2,\n    boot_volume_size = 150,\n  }\n}\n"
  },
  {
    "path": "examples/istio-mc/variables.tf",
    "content": "# Copyright (c) 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# OCI Provider parameters\nvariable \"api_fingerprint\" {\n  default     = \"\"\n  description = \"Fingerprint of the API private key to use with OCI API.\"\n  type        = string\n}\n\nvariable \"api_private_key_path\" {\n  default     = \"\"\n  description = \"The path to the OCI API private key.\"\n  type        = string\n}\n\nvariable \"home_region\" {\n  description = \"The tenancy's home region. Use the short form in lower case e.g. phoenix.\"\n  type        = string\n}\n\nvariable \"tenancy_id\" {\n  description = \"The tenancy id of the OCI Cloud Account in which to create the resources.\"\n  type        = string\n}\n\nvariable \"user_id\" {\n  description = \"The id of the user that Terraform will use to create the resources.\"\n  type        = string\n  default     = \"\"\n}\n\n# General OCI parameters\nvariable \"compartment_id\" {\n  description = \"The compartment id where to create all resources.\"\n  type        = string\n}\n\n# ssh keys\nvariable \"ssh_private_key_path\" {\n  default     = \"none\"\n  description = \"The path to ssh private key.\"\n  type        = string\n}\n\nvariable \"ssh_public_key_path\" {\n  default     = \"none\"\n  description = \"The path to ssh public key.\"\n  type        = string\n}\n\n# clusters\n\nvariable \"clusters\" {\n  description = \"A map of cidrs for vcns, pods and services for each region\"\n  type        = map(any)\n  default = {\n    c1 = { region = \"sydney\", vcn = \"10.1.0.0/16\", pods = \"10.201.0.0/16\", services = \"10.101.0.0/16\", enabled = true }\n    c2 = { region = \"melbourne\", vcn = \"10.2.0.0/16\", pods = \"10.202.0.0/16\", services = \"10.102.0.0/16\", enabled = true }\n  }\n}\n\nvariable \"kubernetes_version\" {\n  default     = \"v1.32.1\"\n  description = \"The version of Kubernetes to use.\"\n  type        = string\n}\n\nvariable \"cluster_type\" {\n  default     = \"basic\"\n  description = \"Whether to use basic or enhanced OKE clusters\"\n  type        = string\n\n  validation {\n    condition     = contains([\"basic\", \"enhanced\"], lower(var.cluster_type))\n    error_message = \"Accepted values are 'basic' or 'enhanced'.\"\n  }\n}\n\nvariable \"oke_control_plane\" {\n  default     = \"public\"\n  description = \"Whether to keep all OKE control planes public or private.\"\n  type        = string\n\n  validation {\n    condition     = contains([\"public\", \"private\"], lower(var.oke_control_plane))\n    error_message = \"Accepted values are 'public' or 'private'.\"\n  }\n}\n\nvariable \"preferred_cni\" {\n  default     = \"flannel\"\n  description = \"Whether to use flannel or NPN\"\n  type        = string\n\n  validation {\n    condition     = contains([\"flannel\", \"npn\"], lower(var.preferred_cni))\n    error_message = \"Accepted values are 'flannel' or 'npn'.\"\n  }\n}\n\n# node pools\nvariable \"timezone\" {\n  type        = string\n  description = \"Preferred timezone of computes\"\n  default     = \"Australia/Sydney\"\n}\n\nvariable \"nodepools\" {\n  type        = any\n  description = \"Node pools for all clusters\"\n  default = {\n    np1 = {\n      shape            = \"VM.Standard.E4.Flex\",\n      ocpus            = 2,\n      memory           = 32,\n      size             = 3,\n      boot_volume_size = 150,\n    }\n  }\n}\n\n# istio\nvariable \"istio_version\" {\n  default     = \"1.20.2\"\n  description = \"Istio version to install\"\n  type        = string\n}\n\nvariable \"istio_mesh_id\" {\n  description = \"mesh id to be used\"\n  type        = string\n  default     = \"yggdrasil\"\n}\n"
  },
  {
    "path": "examples/istio-mc/versions.tf",
    "content": "# Copyright (c) 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n#Terraform and provider version to use\nterraform {\n  required_providers {\n    oci = {\n      source = \"oracle/oci\"\n    }\n  }\n  required_version = \">= 1.0.0\"\n}\n"
  },
  {
    "path": "examples/network/README.md",
    "content": "# Network Examples\n\nExample configurations for VCN networking:\n\n| File | Description |\n|------|-------------|\n| `vars-network.auto.tfvars` | Full network configuration with subnets, NSGs, and gateways |\n| `vars-network-subnets-create.auto.tfvars` | Automatic subnet creation with defaults |\n| `vars-network-subnets-create-cidr.auto.tfvars` | Subnet creation with explicit CIDRs |\n| `vars-network-subnets-create-cidr-ipv4-and-ipv6.tfvars` | Dual-stack (IPv4/IPv6) subnet creation |\n| `vars-network-subnets-create-force.auto.tfvars` | Force subnet creation regardless of component settings |\n| `vars-network-subnets-existing.auto.tfvars` | Using existing subnets |\n| `vars-network-nsgs-create.auto.tfvars` | Creating network security groups |\n| `vars-network-nsgs-existing.auto.tfvars` | Using existing NSGs |\n| `vars-network-drg-create.auto.tfvars.example` | Creating a Dynamic Routing Gateway (example) |\n\n## Usage\n\nCopy the desired `.auto.tfvars` file(s) to your root module and adjust the values as needed.\n"
  },
  {
    "path": "examples/network/vars-network-drg-create.auto.tfvars.example",
    "content": "# Copyright (c) 2017, 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# to reuse an existing drg, set to false\ncreate_drg       = true\n\ndrg_display_name = \"drg\"\n\n# to reuse an existing drg, provide the drg ocid\ndrg_id           = null\n\n# \nremote_peering_connections = {\n  # unpeered rpc\n  rpc1 = {}\n\n  # peered rpc\n  rpc2 : {\n       \"rpc_acceptor_id\" : \"ocid1.remotepeeringconnection.oc1.aaaaaa\"\n       \"rpc_acceptor_region\" : \"us-ashburn-1\"\n  }\n}"
  },
  {
    "path": "examples/operator/README.md",
    "content": "# Operator Examples\n\nExample configurations for the operator host:\n\n| File | Description |\n|------|-------------|\n| `vars-operator.auto.tfvars` | Basic operator configuration |\n| `vars-operator-cloudinit.auto.tfvars` | Operator with custom cloud-init |\n\n## Usage\n\nCopy the desired `.auto.tfvars` file(s) to your root module and adjust the values as needed.\n"
  },
  {
    "path": "examples/profiles/README.md",
    "content": "# Deployment Profiles\n\nComposable deployment profiles that enable only the components you need:\n\n| Profile | Description |\n|---------|-------------|\n| `network-only` | VCN, subnets, NSGs, and gateways only |\n| `cluster-workers-only` | OKE cluster and worker pools (requires existing network) |\n| `workers-only` | Worker pools only (requires existing cluster) |\n| `network-cluster-workers` | Full stack: network, cluster, and workers |\n\n## Usage\n\nEach profile is a self-contained Terraform root module. Copy the profile directory and configure the variables.\n"
  },
  {
    "path": "examples/profiles/cluster-workers-only/main.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nprovider \"oci\" {\n  config_file_profile = var.config_file_profile\n  tenancy_ocid        = var.tenancy_id\n  region              = var.region\n}\n\nmodule \"cluster_workers_only\" {\n  source         = \"../../../\"\n  providers      = { oci.home = oci }\n  tenancy_id     = var.tenancy_id\n  compartment_id = var.compartment_id\n  ssh_public_key = var.ssh_public_key_path\n\n  create_vcn = false // *true/false; vcn_id required if false\n  vcn_id     = var.vcn_id\n  subnets    = var.subnets\n  nsgs       = var.nsgs\n\n  create_bastion    = false // *true/false\n  bastion_public_ip = var.bastion_public_ip\n\n  create_operator = true       // *true/false\n  create_cluster  = true       // *true/false\n  cluster_type    = \"enhanced\" // *basic/enhanced\n  cni_type        = \"flannel\"  // *flannel/npn\n\n  worker_pool_size = 1\n  worker_pools = {\n    oke-pool = {}\n  }\n}\n"
  },
  {
    "path": "examples/profiles/cluster-workers-only/variables.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nvariable \"tenancy_id\" { type = string }\nvariable \"compartment_id\" { type = string }\nvariable \"region\" { type = string }\n\nvariable \"config_file_profile\" {\n  default = \"DEFAULT\"\n  type    = string\n}\n\nvariable \"ssh_public_key_path\" {\n  default = null\n  type    = string\n}\n\nvariable \"subnets\" {\n  type = map(object({\n    create    = optional(string)\n    id        = optional(string)\n    newbits   = optional(string)\n    netnum    = optional(string)\n    cidr      = optional(string)\n    dns_label = optional(string)\n  }))\n}\n\nvariable \"nsgs\" {\n  type = map(object({\n    create = optional(string)\n    id     = optional(string)\n  }))\n}\n"
  },
  {
    "path": "examples/profiles/cluster-workers-only/versions.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nterraform {\n  required_version = \">= 1.3.0\"\n\n  required_providers {\n    oci = {\n      source  = \"oracle/oci\"\n      version = \">= 4.119.0\"\n    }\n  }\n}\n"
  },
  {
    "path": "examples/profiles/network-cluster-workers/main.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nprovider \"oci\" {\n  config_file_profile = var.config_file_profile\n  tenancy_ocid        = var.tenancy_id\n  region              = var.region\n}\n\nmodule \"network_cluster_workers\" {\n  source         = \"../../../\"\n  providers      = { oci.home = oci }\n  tenancy_id     = var.tenancy_id\n  compartment_id = var.compartment_id\n  ssh_public_key = var.ssh_public_key_path\n\n  worker_pool_size = 1\n  worker_pools = {\n    oke-pool = {}\n  }\n}\n"
  },
  {
    "path": "examples/profiles/network-cluster-workers/variables.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nvariable \"tenancy_id\" { type = string }\nvariable \"compartment_id\" { type = string }\nvariable \"region\" { type = string }\n\nvariable \"config_file_profile\" {\n  default = \"DEFAULT\"\n  type    = string\n}\n\nvariable \"ssh_public_key_path\" {\n  default = null\n  type    = string\n}\n"
  },
  {
    "path": "examples/profiles/network-cluster-workers/versions.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nterraform {\n  required_version = \">= 1.3.0\"\n\n  required_providers {\n    oci = {\n      source  = \"oracle/oci\"\n      version = \">= 4.119.0\"\n    }\n  }\n}\n"
  },
  {
    "path": "examples/profiles/network-only/main.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nprovider \"oci\" {\n  config_file_profile = var.config_file_profile\n  tenancy_ocid        = var.tenancy_id\n  region              = var.region\n}\n\nmodule \"network_only\" {\n  source         = \"../../../\"\n  providers      = { oci.home = oci }\n  tenancy_id     = var.tenancy_id\n  compartment_id = var.compartment_id\n\n  create_bastion  = false // *true/false\n  create_cluster  = false // *true/false\n  create_operator = false // *true/false\n\n  # Force creation of NSGs with associated components disabled\n  nsgs = {\n    bastion  = { create = \"always\" }\n    operator = { create = \"always\" }\n    cp       = { create = \"always\" }\n    int_lb   = { create = \"always\" }\n    pub_lb   = { create = \"always\" }\n    workers  = { create = \"always\" }\n    pods     = { create = \"always\" }\n  }\n\n  # Force creation of subnets with associated components disabled\n  subnets = {\n    bastion = {\n      create  = \"always\",\n      newbits = 13\n    }\n\n    operator = {\n      create  = \"always\",\n      newbits = 13\n    }\n\n    cp = {\n      create  = \"always\",\n      newbits = 13\n    }\n\n    int_lb = {\n      create  = \"always\",\n      newbits = 11\n    }\n\n    pub_lb = {\n      create  = \"always\",\n      newbits = 11\n    }\n\n    workers = {\n      create  = \"always\",\n      newbits = 4\n    }\n\n    pods = {\n      create  = \"always\",\n      newbits = 2\n    }\n  }\n}\n"
  },
  {
    "path": "examples/profiles/network-only/variables.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nvariable \"tenancy_id\" { type = string }\nvariable \"compartment_id\" { type = string }\nvariable \"region\" { type = string }\n\nvariable \"config_file_profile\" {\n  default = \"DEFAULT\"\n  type    = string\n}\n\nvariable \"ssh_public_key_path\" {\n  default = null\n  type    = string\n}\n"
  },
  {
    "path": "examples/profiles/network-only/versions.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nterraform {\n  required_version = \">= 1.3.0\"\n\n  required_providers {\n    oci = {\n      source  = \"oracle/oci\"\n      version = \">= 4.119.0\"\n    }\n  }\n}\n"
  },
  {
    "path": "examples/profiles/workers-only/main.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nprovider \"oci\" {\n  config_file_profile = var.config_file_profile\n  tenancy_ocid        = var.tenancy_id\n  region              = var.region\n}\n\nmodule \"workers_only\" {\n  source              = \"../../../\"\n  providers           = { oci.home = oci }\n  tenancy_id          = var.tenancy_id\n  compartment_id      = var.compartment_id\n  vcn_id              = var.vcn_id\n  bastion_public_ip   = var.bastion_public_ip\n  cluster_id          = var.cluster_id\n  operator_private_ip = var.operator_private_ip\n  ssh_public_key_path = var.ssh_public_key_path\n\n  create_vcn      = false\n  create_bastion  = false\n  create_cluster  = false\n  create_operator = false\n\n  subnets = {\n    workers = { id = var.worker_subnet_id }\n  }\n\n  nsgs           = {}\n  worker_nsg_ids = var.worker_nsg_ids\n\n  worker_pool_size = 1\n  worker_pools = {\n    oke-pool = {}\n  }\n}\n"
  },
  {
    "path": "examples/profiles/workers-only/variables.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nvariable \"tenancy_id\" { type = string }\nvariable \"compartment_id\" { type = string }\nvariable \"region\" { type = string }\nvariable \"vcn_id\" { type = string }\nvariable \"bastion_public_ip\" { type = string }\nvariable \"cluster_id\" { type = string }\nvariable \"worker_subnet_id\" { type = string }\n\nvariable \"config_file_profile\" {\n  default = \"DEFAULT\"\n  type    = string\n}\n\nvariable \"operator_private_ip\" {\n  default = null\n  type    = string\n}\n\nvariable \"worker_nsg_ids\" {\n  default = []\n  type    = list(string)\n}\n\nvariable \"ssh_public_key_path\" {\n  default = null\n  type    = string\n}\n"
  },
  {
    "path": "examples/profiles/workers-only/versions.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nterraform {\n  required_version = \">= 1.3.0\"\n\n  required_providers {\n    oci = {\n      source  = \"oracle/oci\"\n      version = \">= 4.119.0\"\n    }\n  }\n}\n"
  },
  {
    "path": "examples/provider-basic.tf",
    "content": "# Copyright 2017, 2023 Oracle Corporation and/or affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nprovider \"oci\" {\n  alias        = \"home\"\n  region       = \"us-ashburn-1\"\n  tenancy_ocid = \"ocid1.tenancy...\"\n}\n\nprovider \"oci\" {\n  region       = \"ap-osaka-1\"\n  tenancy_ocid = \"ocid1.tenancy...\"\n}\n"
  },
  {
    "path": "examples/rms/README.md",
    "content": "# Oracle Resource Manager Stack Examples\n\nPre-built configurations for deploying via [OCI Resource Manager (ORM)](https://docs.oracle.com/en-us/iaas/Content/ResourceManager/home.htm):\n\n| Stack | Description |\n|-------|-------------|\n| `oke-network-only` | Network infrastructure (VCN, subnets, NSGs, gateways, bastion, operator) |\n| `oke-cluster-only` | Full OKE cluster deployment |\n| `oke-workers-only` | Worker pools added to an existing cluster |\n\nEach stack includes a `schema.yaml` for the Resource Manager UI.\n\n## Usage\n\nUpload the stack directory as a Terraform configuration in the OCI Console under Resource Manager > Stacks.\n"
  },
  {
    "path": "examples/rms/oke-cluster-only/data.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nvariable \"ssh_public_key\" {\n  default = null\n  type    = string\n}\nvariable \"ssh_kms_vault_id\" {\n  default = null\n  type    = string\n}\nvariable \"ssh_kms_secret_id\" {\n  default = null\n  type    = string\n}\n\ndata \"oci_identity_region_subscriptions\" \"home\" {\n  tenancy_id = var.tenancy_ocid\n  filter {\n    name   = \"is_home_region\"\n    values = [true]\n  }\n}\n\ndata \"oci_secrets_secretbundle\" \"ssh_key\" {\n  secret_id = var.ssh_kms_secret_id\n}\n\nlocals {\n  ssh_public_key         = try(base64decode(var.ssh_public_key), var.ssh_public_key)\n  ssh_key_bundle         = sensitive(one(data.oci_secrets_secretbundle.ssh_key.secret_bundle_content))\n  ssh_key_bundle_content = sensitive(lookup(local.ssh_key_bundle, \"content\", null))\n}\n"
  },
  {
    "path": "examples/rms/oke-cluster-only/main.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\ndata \"oci_secrets_secretbundle\" \"ocir\" {\n  count     = var.ocir_kms_vault_id == null ? 0 : 1\n  secret_id = var.ocir_kms_secret_id\n}\n\nmodule \"oke\" {\n  source         = \"github.com/oracle-terraform-modules/terraform-oci-oke.git?ref=5.x&depth=1\"\n  providers      = { oci.home = oci.home }\n  tenancy_id     = var.tenancy_ocid\n  compartment_id = var.compartment_ocid\n\n  # General\n  timezone      = var.timezone\n  output_detail = var.output_detail\n\n  # Identity\n  create_iam_resources = true\n\n  # Network\n  create_vcn                  = false\n  vcn_id                      = var.vcn_id\n  vcn_create_internet_gateway = \"never\"\n  vcn_create_nat_gateway      = \"never\"\n  vcn_create_service_gateway  = \"never\"\n  assign_dns                  = var.assign_dns\n  ig_route_table_id           = var.ig_route_table_id\n  subnets = {\n    operator = { create = \"never\", id = var.operator_subnet_id }\n    cp       = { create = \"never\", id = var.control_plane_subnet_id }\n    int_lb   = { create = \"never\", id = var.int_lb_subnet_id }\n    pub_lb   = { create = \"never\", id = var.pub_lb_subnet_id }\n  }\n\n  nsgs = {\n    operator = { create = \"never\", id = var.operator_nsg_id }\n    cp       = { create = \"never\", id = var.control_plane_nsg_id }\n  }\n\n  # Network Security\n  control_plane_is_public = var.control_plane_is_public\n  load_balancers          = lower(var.load_balancers)\n  create_bastion          = false\n  bastion_public_ip       = var.bastion_public_ip\n\n  # Operator\n  create_operator                = var.create_operator\n  operator_availability_domain   = var.operator_availability_domain\n  operator_cloud_init            = var.operator_cloud_init\n  operator_image_id              = var.operator_image_id\n  operator_image_os              = var.operator_image_os\n  operator_image_os_version      = var.operator_image_os_version\n  operator_install_helm          = var.operator_install_helm\n  operator_install_k9s           = var.operator_install_k9s\n  operator_install_kubectx       = var.operator_install_kubectx\n  operator_private_ip            = var.operator_private_ip\n  operator_pv_transit_encryption = var.operator_pv_transit_encryption\n  operator_shape                 = var.operator_shape\n  operator_upgrade               = var.operator_upgrade\n  operator_user                  = var.operator_user\n  operator_volume_kms_key_id     = var.operator_volume_kms_key_id\n\n  # SSH\n  ssh_public_key  = local.ssh_public_key\n  ssh_private_key = sensitive(local.ssh_key_bundle_content)\n\n  # Cluster\n  cluster_kms_key_id      = var.cluster_kms_key_id\n  cluster_name            = var.cluster_name\n  cluster_type            = lower(var.cluster_type)\n  cni_type                = lower(var.cni_type)\n  create_cluster          = true\n  image_signing_keys      = var.image_signing_keys\n  kubernetes_version      = var.kubernetes_version\n  pods_cidr               = var.pods_cidr\n  preferred_load_balancer = lower(var.preferred_load_balancer)\n  services_cidr           = var.services_cidr\n  use_signed_images       = var.use_signed_images\n\n  # CNI: Cilium\n  cilium_install           = var.cilium_install\n  cilium_reapply           = var.cilium_reapply\n  cilium_namespace         = var.cilium_namespace\n  cilium_helm_version      = var.cilium_helm_version\n  cilium_helm_values       = var.cilium_helm_values\n  cilium_helm_values_files = var.cilium_helm_values_files\n\n  # Metrics server\n  metrics_server_install           = var.metrics_server_install\n  metrics_server_namespace         = var.metrics_server_namespace\n  metrics_server_helm_version      = var.metrics_server_helm_version\n  metrics_server_helm_values       = var.metrics_server_helm_values\n  metrics_server_helm_values_files = var.metrics_server_helm_values_files\n\n  # Cluster autoscaler\n  cluster_autoscaler_install           = var.cluster_autoscaler_install\n  cluster_autoscaler_namespace         = var.cluster_autoscaler_namespace\n  cluster_autoscaler_helm_version      = var.cluster_autoscaler_helm_version\n  cluster_autoscaler_helm_values       = var.cluster_autoscaler_helm_values\n  cluster_autoscaler_helm_values_files = var.cluster_autoscaler_helm_values_files\n\n  # Gatekeeper\n  gatekeeper_install           = var.gatekeeper_install\n  gatekeeper_namespace         = var.gatekeeper_namespace\n  gatekeeper_helm_version      = var.gatekeeper_helm_version\n  gatekeeper_helm_values       = var.gatekeeper_helm_values\n  gatekeeper_helm_values_files = var.gatekeeper_helm_values_files\n\n  # Prometheus\n  prometheus_install           = var.prometheus_install\n  prometheus_reapply           = var.prometheus_reapply\n  prometheus_namespace         = var.prometheus_namespace\n  prometheus_helm_version      = var.prometheus_helm_version\n  prometheus_helm_values       = var.prometheus_helm_values\n  prometheus_helm_values_files = var.prometheus_helm_values_files\n\n  # DCGM exporter\n  dcgm_exporter_install      = var.dcgm_exporter_install\n  dcgm_exporter_reapply      = var.dcgm_exporter_reapply\n  dcgm_exporter_namespace    = var.dcgm_exporter_namespace\n  dcgm_exporter_helm_version = var.dcgm_exporter_helm_version\n\n  # Multus\n  multus_install       = var.multus_install\n  multus_namespace     = var.multus_namespace\n  multus_daemonset_url = var.multus_daemonset_url\n  multus_version       = var.multus_version\n\n  # SR-IOV device plugin\n  sriov_device_plugin_install       = var.sriov_device_plugin_install\n  sriov_device_plugin_namespace     = var.sriov_device_plugin_namespace\n  sriov_device_plugin_daemonset_url = var.sriov_device_plugin_daemonset_url\n  sriov_device_plugin_version       = var.sriov_device_plugin_version\n\n  # Whereabouts\n  whereabouts_install       = var.whereabouts_install\n  whereabouts_namespace     = var.whereabouts_namespace\n  whereabouts_daemonset_url = var.whereabouts_daemonset_url\n  whereabouts_version       = var.whereabouts_version\n\n  # MPI operator\n  mpi_operator_install        = var.mpi_operator_install\n  mpi_operator_namespace      = var.mpi_operator_namespace\n  mpi_operator_deployment_url = var.mpi_operator_deployment_url\n  mpi_operator_version        = var.mpi_operator_version\n\n  # Tags\n  use_defined_tags = var.use_defined_tags\n  tag_namespace    = var.tag_namespace\n\n  freeform_tags = { # TODO Remaining tags in schema\n    cluster           = lookup(var.cluster_tags, \"freeformTags\", {})\n    persistent_volume = {}\n    service_lb        = {}\n    operator          = lookup(var.operator_tags, \"freeformTags\", {})\n  }\n\n  defined_tags = { # TODO Remaining tags in schema\n    cluster           = lookup(var.cluster_tags, \"definedTags\", {})\n    persistent_volume = {}\n    service_lb        = {}\n    operator          = lookup(var.operator_tags, \"definedTags\", {})\n  }\n}\n"
  },
  {
    "path": "examples/rms/oke-cluster-only/output.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# Terraform\noutput \"state_id\" { value = module.oke.state_id }\n\n# Identity\noutput \"dynamic_group_ids\" { value = module.oke.dynamic_group_ids }\noutput \"policy_statements\" { value = module.oke.policy_statements }\n\n# Cluster\noutput \"cluster_id\" { value = module.oke.cluster_id }\noutput \"cluster_endpoints\" { value = module.oke.cluster_endpoints }\noutput \"cluster_kubeconfig\" { value = module.oke.cluster_kubeconfig }\noutput \"cluster_ca_cert\" { value = module.oke.cluster_ca_cert }\n\n# Network\noutput \"vcn_id\" { value = module.oke.vcn_id }\noutput \"bastion_public_ip\" { value = module.oke.bastion_public_ip }\noutput \"bastion_ssh_command\" { value = module.oke.ssh_to_bastion }\noutput \"bastion_ssh_secret_id\" { value = var.ssh_kms_secret_id }\n\n# Operator\noutput \"operator_id\" { value = module.oke.operator_id }\noutput \"operator_private_ip\" { value = module.oke.operator_private_ip }\noutput \"operator_ssh_command\" { value = module.oke.ssh_to_operator }\noutput \"operator_ssh_secret_id\" { value = var.ssh_kms_secret_id }\noutput \"operator_subnet_id\" { value = module.oke.operator_subnet_id }\noutput \"operator_nsg_id\" { value = var.operator_nsg_id }\n\n# Cluster\noutput \"control_plane_subnet_id\" { value = module.oke.control_plane_subnet_id }\noutput \"control_plane_nsg_id\" { value = var.control_plane_nsg_id }\noutput \"int_lb_subnet_id\" { value = module.oke.int_lb_subnet_id }\noutput \"pub_lb_subnet_id\" { value = module.oke.pub_lb_subnet_id }\n"
  },
  {
    "path": "examples/rms/oke-cluster-only/schema.yaml",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\ntitle: \"OKE: Network & Cluster\"\ndescription: OKE cluster with VCN network resources\ninformationalText: \"Connect to operator host using the SSH command below for Kubernetes endpoint access.\"\nschemaVersion: 1.1.0\nversion: \"20230304\"\nlocale: \"en\"\n\nvariableGroups:\n  - title: \"Hidden\"\n    visible: false\n    variables:\n      - api_fingerprint\n      - current_user_ocid\n      - tenancy_ocid\n      - region\n      - output_detail\n      - timezone\n      - subnets\n      - await_node_readiness\n\n  - title: \"Identity\"\n    variables:\n      - compartment_ocid\n      - create_iam_resources\n      - create_iam_tag_namespace\n      - create_iam_defined_tags\n      - create_iam_autoscaler_policy\n      - create_iam_kms_policy\n      - create_iam_operator_policy\n      - create_iam_worker_policy\n      - use_defined_tags\n      - tag_namespace\n\n  - title: \"Network\"\n    variables:\n      - assign_dns\n      - vcn_id\n      - ig_route_table_id\n      - nat_gateway_id\n      - nat_route_table_id\n      - nat_gateway_public_ip_id\n      - service_gateway_id\n\n  - title: \"SSH\"\n    variables:\n      - bastion_public_ip\n      - ssh_public_key\n      - ssh_kms_vault_id\n      - ssh_kms_secret_id\n\n  - title: \"Operator\"\n    variables:\n      - operator_subnet_id\n      - operator_nsg_id\n      - ${create_operator}\n      - operator_upgrade\n      - operator_availability_domain\n      - operator_private_ip\n      - operator_image_os\n      - operator_image_os_version\n      - operator_image_id\n      - operator_user\n      - operator_shape_name\n      - operator_shape_ocpus\n      - operator_shape_memory\n      - operator_shape_boot\n      - operator_shape\n      - operator_use_encryption\n      - operator_volume_kms_vault_id\n      - operator_volume_kms_key_id\n      - operator_pv_transit_encryption\n      - operator_install_helm\n      - operator_install_k9s\n      - operator_install_kubectx\n      - operator_tags\n\n  - title: \"Cluster\"\n    variables:\n      - control_plane_is_public\n      - control_plane_subnet_id\n      - control_plane_nsg_id\n      - pods_cidr\n      - services_cidr\n      - int_lb_subnet_id\n      - pub_lb_subnet_id\n      - load_balancers\n      - preferred_load_balancer\n      - cluster_name\n      - cluster_type\n      - kubernetes_version\n      - cluster_dns\n      - cluster_ca_cert\n      - cluster_use_encryption\n      - cluster_kms_vault_id\n      - cluster_kms_key_id\n      - cni_type\n      - use_signed_images\n      - configure_ocir\n      - ocir_username\n      - ocir_email_address\n      - ocir_kms_vault_id\n      - ocir_secret_id\n      - ocir_secret_namespace\n      - ocir_secret_name\n      - cluster_tags\n\n  - title: \"Extensions\"\n    variables:\n      - cluster_autoscaler_install\n      - metrics_server_install\n      - prometheus_install\n      - dcgm_exporter_install\n      - gatekeeper_install\n      - multus_install\n      - cilium_install\n      - whereabouts_install\n      - sriov_device_plugin_install\n      - sriov_cni_plugin_install\n      - rdma_cni_plugin_install\n      - mpi_operator_install\n\n  - title: \"Cluster Autoscaler\"\n    visible: cluster_autoscaler_install\n    variables:\n      - ${cluster_autoscaler_namespace}\n      - ${cluster_autoscaler_helm_version}\n      - ${cluster_autoscaler_helm_values}\n      - ${cluster_autoscaler_helm_values_files}\n\n  - title: \"Metrics Server\"\n    visible:\n      and: metrics_server_install\n    variables:\n      - metrics_server_namespace\n      - metrics_server_helm_version\n      - metrics_server_helm_values\n      - metrics_server_helm_values_files\n\n  - title: \"Prometheus\"\n    visible: prometheus_install\n    variables:\n      - prometheus_namespace\n      - prometheus_reapply\n      - prometheus_helm_version\n      - prometheus_helm_values\n      - prometheus_helm_values_files\n\n  - title: \"DCGM exporter\"\n    visible: dcgm_exporter_install\n    variables:\n      - dcgm_exporter_namespace\n      - dcgm_exporter_reapply\n      - dcgm_exporter_helm_version\n      - dcgm_exporter_helm_values\n      - dcgm_exporter_helm_values_files\n\n  - title: \"Gatekeeper\"\n    visible: gatekeeper_install\n    variables:\n      - gatekeeper_namespace\n      - gatekeeper_helm_version\n      - gatekeeper_helm_values\n      - gatekeeper_helm_values_files\n\n  - title: \"Multus\"\n    visible: multus_install\n    variables:\n      - multus_namespace\n      - multus_daemonset_url\n      - multus_version\n\n  - title: \"Cilium\"\n    visible: cilium_install\n    variables:\n      - cilium_namespace\n      - cilium_reapply\n      - cilium_helm_version\n\n  - title: \"Whereabouts\"\n    visible: whereabouts_install\n    variables:\n      - whereabouts_namespace\n      - whereabouts_daemonset_url\n      - whereabouts_version\n\n  - title: \"SR-IOV Device Plugin\"\n    visible: sriov_device_plugin_install\n    variables:\n      - sriov_device_plugin_namespace\n      - sriov_device_plugin_daemonset_url\n      - sriov_device_plugin_version\n\n  - title: \"SR-IOV CNI Plugin\"\n    visible: sriov_cni_plugin_install\n    variables:\n      - sriov_cni_plugin_namespace\n      - sriov_cni_plugin_daemonset_url\n      - sriov_cni_plugin_version\n\n  - title: \"MPI Operator\"\n    visible: mpi_operator_install\n    variables:\n      - mpi_operator_namespace\n      - mpi_operator_deployment_url\n      - mpi_operator_version\n\nvariables:\n  # Identity\n  api_fingerprint:\n    required: false\n    visible: false\n  current_user_ocid:\n    title: User\n    type: ocid\n    required: true\n  tenancy_ocid:\n    title: Tenancy\n    type: oci:identity:compartment:id\n    required: true\n  compartment_ocid:\n    title: Compartment\n    description: The default compartment for created resources.\n    type: oci:identity:compartment:id\n    required: true\n  region:\n    required: true\n    title: Region\n    type: oci:identity:region:name\n  defined_tags:\n    visible: false\n  freeform_tags:\n    visible: false\n  create_iam_resources:\n    default: false\n    description: Whether to create any IAM dynamic groups, policies, and tags.\n    required: true\n    title: Create IAM resources\n    type: boolean\n  create_iam_tag_namespace:\n    default: false\n    required: true\n    title: Create tag namespace\n    type: boolean\n    visible: ${create_iam_resources}\n  create_iam_defined_tags:\n    default: false\n    required: true\n    title: Create defined tags\n    type: boolean\n    visible: ${create_iam_resources}\n  create_iam_autoscaler_policy:\n    title: Create IAM policy for Cluster Autoscaler\n    required: false\n    visible: ${create_iam_resources}\n    type: enum\n    enum: [Never, Auto, Always]\n    default: Auto\n  create_iam_kms_policy:\n    title: Create IAM policy for KMS\n    required: false\n    visible: ${create_iam_resources}\n    type: enum\n    enum: [Never, Auto, Always]\n    default: Auto\n  create_iam_operator_policy:\n    title: Create IAM policy for operater cluster management\n    required: false\n    visible: ${create_iam_resources}\n    type: enum\n    enum: [Never, Auto, Always]\n    default: Auto\n  create_iam_worker_policy:\n    title: Create IAM policy for self-managed worker nodes\n    required: false\n    visible: ${create_iam_resources}\n    type: enum\n    enum: [Never, Auto, Always]\n    default: Auto\n  use_defined_tags:\n    title: Use defined tags\n    default: false\n    type: boolean\n  tag_namespace:\n    title: Tag namespace\n    visible:\n      or:\n        - ${create_iam_tag_namespace}\n        - ${create_iam_defined_tags}\n        - ${use_defined_tags}\n  timezone:\n    title: Timezone\n    type: string\n    # type: oci:identity:region:name\n    # required: true\n  output_detail:\n    title: Output detail\n    type: boolean\n    default: false\n    required: true\n\n  # VCN\n  network_compartment_id:\n    required: false\n    visible: false\n  vcn_id:\n    title: Existing VCN\n    type: oci:core:vcn:id\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n  assign_dns:\n    title: Assign DNS records\n    type: boolean\n    required: true\n  ig_route_table_id:\n    title: Internet Gateway Route Table\n    type: ocid\n    required: false\n  service_gateway_id:\n    title: Service gateway\n    description: Existing service gateway in the VCN.\n    type: oci:core:servicegateway:id\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n  nat_gateway_id:\n    title: NAT gateway\n    description: Existing NAT gateway in the VCN.\n    type: oci:core:natgateway:id\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n\n  # NSGs\n  operator_nsg_id:\n    title: Additional Network Security Group\n    type: oci:core:nsg:id\n    # additionalProps:\n    #   allowMultiple: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n  control_plane_nsg_id:\n    title: Additional Network Security Group\n    type: oci:core:nsg:id\n    # additionalProps:\n    #   allowMultiple: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n  control_plane_is_public:\n    title: Public Kubernetes control plane\n    type: boolean\n    default: false\n    required: false\n\n  # Subnets\n  control_plane_subnet_id:\n    title: Control plane subnet\n    type: oci:core:subnet:id\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n      hidePublicSubnet: false\n      hidePrivateSubnet: false\n      hideRegionalSubnet: false\n      hideAdSubnet: true\n  int_lb_subnet_id:\n    title: Internal load balancer subnet\n    type: oci:core:subnet:id\n    required: false\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n      hidePublicSubnet: false\n      hidePrivateSubnet: false\n      hideRegionalSubnet: false\n      hideAdSubnet: true\n  pub_lb_subnet_id:\n    title: Public load balancer subnet\n    type: oci:core:subnet:id\n    required: false\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n      hidePublicSubnet: false\n      hidePrivateSubnet: false\n      hideRegionalSubnet: false\n      hideAdSubnet: true\n  operator_subnet_id:\n    title: Operator subnet\n    type: oci:core:subnet:id\n    required: false\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n      hidePublicSubnet: false\n      hidePrivateSubnet: false\n      hideRegionalSubnet: false\n      hideAdSubnet: false\n\n  # SSH\n  ssh_public_key:\n    title: SSH Public Key\n    type: oci:core:ssh:publickey\n    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})( [^,]*)?)*$\"\n    required: false\n  ssh_kms_vault_id:\n    title: SSH Vault\n    description: The OCI Vault used to encrypt the SSH key pair.\n    type: oci:kms:vault:id\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n  ssh_kms_secret_id:\n    title: SSH Vault secret\n    description: The OCI Vault secret containing the SSH private key.\n    type: oci:kms:secret:id\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vaultId: ${ssh_kms_vault_id}\n\n  # Bastion\n  bastion_public_ip:\n    title: Bastion IP\n    description: The address of an existing bastion host for SSH access to operator/cluster resources.\n    type: string\n    required: true\n\n  # Operator variables\n  create_operator:\n    title: Create operator instance\n    description: Provision an OCI Compute instance configured with IAM access to interact with the OKE Kubernetes endpoint, e.g. through a bastion host for private networks. Required for installation of extensions using the module.\n    type: boolean\n    default: true\n    required: false\n  operator_availability_domain:\n    title: Availability domain\n    type: oci:identity:availabilitydomain:name\n    required: false\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n    visible: ${create_operator}\n  operator_private_ip:\n    title: Operator IP\n    type: string\n    required: false\n    visible:\n      not:\n        - ${create_operator}\n  operator_user:\n    title: User\n    type: string\n    default: opc\n    required: true\n  operator_shape_name:\n    title: Shape\n    type: oci:core:instanceshape:name\n    default: \"VM.Standard.E4.Flex\"\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n    visible: ${create_bastion}\n  operator_shape_ocpus:\n    title: OCPUs (Cores)\n    type: number\n    default: 4\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n    visible: ${create_bastion}\n  operator_shape_memory:\n    title: Memory (GB)\n    type: number\n    default: 16\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n    visible: ${create_bastion}\n  operator_shape_boot:\n    title: Boot volume size (GB)\n    type: number\n    default: 50\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n    visible: ${create_bastion}\n  operator_shape:\n    visible: false\n  operator_image_os:\n    title: Image OS\n    type: enum\n    default: \"Oracle Linux\"\n    enum: [\"Oracle Linux\"]\n    required: true\n    visible:\n      and:\n        - ${create_operator}\n        - not:\n            - eq:\n                - ${operator_image_type}\n                - custom\n  operator_image_os_version:\n    title: Image OS version\n    type: enum\n    default: \"8\"\n    enum: [\"7.9\", \"8\"]\n    required: true\n    visible:\n      and:\n        - ${create_operator}\n        - not:\n            - eq:\n                - ${operator_image_type}\n                - custom\n  operator_image_type:\n    title: Image type\n    type: enum\n    default: platform\n    enum: [platform, custom]\n    required: true\n    visible: false\n  operator_image_id:\n    title: Image ID\n    type: oci:core:image:id\n    required: false\n    visible: ${create_operator}\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      operatingSystem: ${operator_image_os}\n      operatingSystemVersion: ${operator_image_os_version}\n      shape: ${operator_shape_name}\n  operator_pv_transit_encryption:\n    title: In-transit volume encryption\n    type: boolean\n    visible: ${create_operator}\n  operator_use_encryption:\n    title: Use encryption\n    type: boolean\n    default: false\n    required: true\n    visible: ${create_operator}\n  operator_volume_kms_vault_id:\n    title: KMS volume encryption vault\n    description: Vault containing operator volume encryption keys.\n    type: oci:kms:vault:id\n    required: false\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n    visible:\n      and:\n        - ${create_operator}\n        - operator_use_encryption\n  operator_volume_kms_key_id:\n    title: KMS volume encryption key\n    type: oci:kms:key:id\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vaultId: ${operator_volume_kms_vault_id}\n    visible:\n      and:\n        - ${create_operator}\n        - operator_use_encryption\n  operator_upgrade:\n    title: Upgrade OS\n    description: Upgrade the operating system on boot.\n    type: boolean\n    default: false\n    required: true\n    visible: ${create_operator}\n  operator_install_helm:\n    title: Install Helm\n    type: boolean\n    visible: ${create_operator}\n  operator_install_k9s:\n    title: Install K9s\n    type: boolean\n    default: true\n    visible: ${create_operator}\n  operator_install_kubectx:\n    title: Install Kubectx\n    type: boolean\n    visible: ${create_operator}\n  operator_tags:\n    type: oci:identity:tag:value\n    required: false\n    title: Tagging\n    description: Tag values for created resources.\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n    visible: ${create_operator}\n\n  # Cluster\n  cluster_use_encryption:\n    title: Use encryption\n    type: boolean\n    default: false\n    required: true\n  cluster_kms_vault_id:\n    title: Cluster etcd KMS encryption vault\n    type: oci:kms:vault:id\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n    visible: cluster_use_encryption\n  cluster_kms_key_id:\n    title: Cluster etcd KMS encryption key\n    type: oci:kms:key:id\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vaultId: ${cluster_kms_vault_id}\n    visible: cluster_use_encryption\n  cluster_name:\n    title: Cluster name\n    description: Display name for the created cluster. Defaults to 'oke' suffixed with the generated Terraform 'state_id' value.\n    type: string\n    required: false\n  cluster_type:\n    title: Cluster Type\n    type: enum\n    default: Basic\n    enum: [Basic, Enhanced]\n    allowMultiple: false\n    required: true\n  cni_type:\n    title: CNI Type\n    type: enum\n    default: Flannel\n    enum: [Flannel, NPN]\n    allowMultiple: false\n    required: true\n  kubernetes_version:\n    type: oci:kubernetes:versions:id\n    title: Kubernetes version\n    description: The Kubernetes version for the created OKE cluster and managed nodes.\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      clusterOptionId: \"all\"\n  pods_cidr:\n    title: Pod CIDR\n  services_cidr:\n    title: Service CIDR\n  preferred_load_balancer:\n    title: Preferred load balancer\n    type: enum\n    default: Internal\n    enum: [Internal, Public]\n    allowMultiple: false\n    required: true\n  load_balancers:\n    title: Load balancers\n    type: enum\n    enum: [Public, Internal, Both]\n    default: Internal\n    required: true\n  use_signed_images:\n    title: Use signed images\n    type: boolean\n    default: false\n    required: true\n\n  # OCIR\n  configure_ocir:\n    title: Configure container registry (OCIR)\n    type: boolean\n    default: false\n  ocir_username:\n    title: Username\n    visible: configure_ocir\n  ocir_email_address:\n    title: Email address\n    visible: configure_ocir\n  ocir_kms_vault_id:\n    title: Vault ID\n    type: oci:kms:vault:id\n    required: false\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n    visible: configure_ocir\n  ocir_kms_secret_id:\n    title: Vault secret ID\n    type: oci:kms:secret:id\n    required: false\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vaultId: ${ocir_kms_vault_id}\n    visible: configure_ocir\n  ocir_secret_namespace:\n    title: Secret namespace\n    visible: configure_ocir\n  ocir_secret_name:\n    title: Secret name\n    visible: configure_ocir\n\n  cluster_tags:\n    type: oci:identity:tag:value\n    required: false\n    title: Tagging\n    description: Tag values for created resources.\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n\n  # Metrics server\n  metrics_server_install:\n    title: Install Metrics Server\n    description: Deploy the Kubernetes Metrics Server with Oracle Cloud configuration. See <a href=https://github.com/kubernetes-sigs/metrics-server>kubernetes-sigs/metrics-server</a> for more information.\n    type: boolean\n    default: false\n    required: true\n  metrics_server_namespace:\n    title: Kubernetes namespace\n    type: string\n  metrics_server_helm_version:\n    title: Helm chart version\n    type: string\n  metrics_server_helm_values:\n    title: Helm chart values\n    visible: false\n  metrics_server_helm_values_files:\n    title: Helm chart values files\n    visible: false\n\n  # Cluster autoscaler\n  cluster_autoscaler_install:\n    title: Install Cluster Autoscaler\n    description: Deploy the Kubernetes Cluster Autoscaler with Oracle Cloud configuration. See <a href=https://github.com/kubernetes/autoscaler>kubernetes/autoscaler</a> for more information.\n    type: boolean\n    default: false\n    required: true\n  cluster_autoscaler_namespace:\n    title: Kubernetes namespace\n    type: string\n  cluster_autoscaler_helm_version:\n    title: Helm chart version\n    type: string\n  cluster_autoscaler_helm_values:\n    title: Helm chart values\n    visible: false\n  cluster_autoscaler_helm_values_files:\n    title: Helm chart values files\n    visible: false\n\n  # Gatekeeper\n  gatekeeper_install:\n    title: Install Gatekeeper\n    description: Deploy Gatekeeper with Oracle Cloud configuration. See <a href=https://github.com/open-policy-agent/gatekeeper>open-policy-agent/gatekeeper</a> for more information.\n    type: boolean\n    default: false\n    required: true\n  gatekeeper_namespace:\n    title: Kubernetes namespace\n    type: string\n  gatekeeper_helm_version:\n    title: Helm chart version\n    type: string\n  gatekeeper_helm_values:\n    title: Helm chart values\n    visible: false\n  gatekeeper_helm_values_files:\n    title: Helm chart values files\n    visible: false\n\n  # Prometheus\n  prometheus_install:\n    title: Install Prometheus\n    description: Deploy Prometheus with Oracle Cloud configuration. See <a href=https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack>prometheus-community/kube-prometheus-stack</a> for more information.\n    type: boolean\n    default: false\n    required: true\n  prometheus_reapply:\n    title: Re-apply\n    type: boolean\n    default: false\n    required: true\n  prometheus_namespace:\n    title: Kubernetes namespace\n    type: string\n  prometheus_helm_version:\n    title: Helm chart version\n    type: string\n  prometheus_helm_values:\n    title: Helm chart values\n    visible: false\n  prometheus_helm_values_files:\n    title: Helm chart values files\n    visible: false\n\n  # Multus\n  multus_install:\n    title: Install Multus\n    description: Deploy Multus for extended CNI configuration. See <a href=https://github.com/k8snetworkplumbingwg/multus-cni>k8snetworkplumbingwg/multus-cni</a> for more information. Preempts existing CNI configuration, with the configured cluster CNI plugin used by default.\n    type: boolean\n    default: false\n    required: true\n  multus_namespace:\n    title: Kubernetes namespace\n    type: string\n  multus_daemonset_url:\n    title: Daemonset URL\n    description: The URL path to the Multus manifest. Leave unset for tags of <a href=https://github.com/k8snetworkplumbingwg/multus-cni>k8snetworkplumbingwg/multus-cni</a> using the configured Multus version.\n    type: string\n  multus_version:\n    title: Version\n    type: string\n\n  # SR-IOV Device Plugin\n  sriov_device_plugin_install:\n    title: Install SR-IOV device plugin\n    description: Deploy SR-IOV device plugin to advertise Virtual Functions (VFs) to Kubernetes. See <a href=https://github.com/k8snetworkplumbingwg/sriov-network-device-plugin/tree/master/deployments>k8snetworkplumbingwg/sriov-network-device-plugin</a> for more information.\n    type: boolean\n    default: false\n    required: true\n  sriov_device_plugin_namespace:\n    title: Kubernetes namespace\n    type: string\n  sriov_device_plugin_daemonset_url:\n    title: Daemonset URL\n    description: The URL path to the manifest. Leave unset for tags of <a href=https://github.com/k8snetworkplumbingwg/sriov-network-device-plugin/tree/master/deployments>k8snetworkplumbingwg/sriov-network-device-plugin</a> using the configured version.\n    type: string\n  sriov_device_plugin_version:\n    title: Version\n    type: string\n\n  # SR-IOV CNI Plugin\n  sriov_cni_plugin_install:\n    title: Install SR-IOV CNI plugin\n    description: Deploy SR-IOV CNI plugin to configure Virtual Functions (VFs) for Pod networking with Kubernetes. See <a href=https://github.com/openshift/sriov-cni>openshift/sriov-cni</a> for more information.\n    type: boolean\n    default: false\n    required: true\n  sriov_cni_plugin_namespace:\n    title: Kubernetes namespace\n    type: string\n  sriov_cni_plugin_daemonset_url:\n    title: Daemonset URL\n    description: The URL path to the manifest. Leave unset for tags of <a href=https://github.com/openshift/sriov-cni>openshift/sriov-cni</a> using the configured version.\n    type: string\n  sriov_cni_plugin_version:\n    title: Version\n    type: string\n\n  # Whereabouts\n  whereabouts_install:\n    title: Install Whereabouts\n    description: Deploy Whereabouts for cluster-wide IP Address Management (IPAM). See <a href=https://github.com/k8snetworkplumbingwg/whereabouts>k8snetworkplumbingwg/whereabouts</a> for more information.\n    type: boolean\n    default: false\n    required: true\n  whereabouts_namespace:\n    title: Kubernetes namespace\n    type: string\n  whereabouts_daemonset_url:\n    title: Daemonset URL\n    description: The URL path to the manifest. Leave unset for tags of <a href=https://github.com/k8snetworkplumbingwg/whereabouts>k8snetworkplumbingwg/whereabouts</a> using the configured version.\n    type: string\n  whereabouts_version:\n    title: Version\n    type: string\n\n  # MPI Operator\n  mpi_operator_install:\n    title: Install MPI operator\n    description: Deploy MPI operator to run MPI jobs. See <a href=https://github.com/kubeflow/mpi-operator>kubeflow/mpi-operator</a> for more information.\n    type: boolean\n    default: false\n    required: true\n  mpi_operator_namespace:\n    title: Kubernetes namespace\n    type: string\n  mpi_operator_deployment_url:\n    title: Deployment URL\n    description: The URL path to the manifest. Leave unset for tags of <a href=https://github.com/kubeflow/mpi-operator>kubeflow/mpi-operator</a> using the configured version.\n    type: string\n  mpi_operator_version:\n    title: Version\n    type: string\n\noutputGroups:\n  - title: Terraform\n    outputs:\n      - state_id\n  - title: Identity\n    outputs:\n      - dynamic_group_ids\n      - policy_statements\n  - title: Network\n    outputs:\n      - vcn_id\n      - bastion_public_ip\n  - title: Operator\n    outputs:\n      - operator_id\n      - operator_subnet_id\n      - operator_nsg_id\n      - operator_private_ip\n      - operator_ssh_command\n      - operator_ssh_secret_id\n  - title: Cluster\n    outputs:\n      - cluster_id\n      - cluster_endpoints\n      - control_plane_subnet_id\n      - control_plane_nsg_id\n      - int_lb_subnet_id\n      - int_lb_nsg_id\n      - pub_lb_subnet_id\n      - pub_lb_nsg_id\n\noutputs:\n  # Terraform\n  state_id:\n    title: State ID\n    type: copyableString\n\n  # Identity\n  dynamic_group_ids:\n    title: Dynamic groups\n    type: list\n  policy_statements:\n    title: Policy statements\n    type: list\n\n  # Network\n  vcn_id:\n    title: VCN\n    type: ocid\n  bastion_public_ip:\n    title: Bastion IP\n    type: copyableString\n  bastion_ssh_command:\n    title: Bastion SSH command\n    type: copyableString\n  bastion_ssh_secret_id:\n    title: Bastion SSH Vault secret\n    type: ocid\n\n  # Operator\n  operator_id:\n    title: Operator instance\n    type: ocid\n  operator_subnet_id:\n    title: Operator subnet\n    type: ocid\n  operator_nsg_id:\n    title: Operator NSG\n    type: ocid\n  operator_private_ip:\n    title: Operator IP\n    type: copyableString\n  operator_ssh_command:\n    title: Operator SSH command\n    type: copyableString\n  operator_ssh_secret_id:\n    title: Operator SSH Vault secret\n    type: ocid\n\n  # Cluster\n  cluster_id:\n    title: OKE cluster\n    type: ocid\n  cluster_endpoints:\n    title: Cluster endpoints\n    type: map\n  control_plane_subnet_id:\n    title: Control plane subnet\n    type: ocid\n  control_plane_nsg_id:\n    title: Control plane NSG\n    type: ocid\n  int_lb_subnet_id:\n    title: Internal load balancer subnet\n    type: ocid\n  int_lb_nsg_id:\n    title: Internal load balancer NSG\n    type: ocid\n  pub_lb_subnet_id:\n    title: Public load balancer subnet\n    type: ocid\n  pub_lb_nsg_id:\n    title: Public load balancer NSG\n    type: ocid\n"
  },
  {
    "path": "examples/rms/oke-cluster-only/variables-cluster.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# General\n\nvariable \"output_detail\" { default = false }\nvariable \"timezone\" { default = \"Etc/UTC\" }\n\n# Cluster\n\nvariable \"cluster_type\" {\n  description = \"The cluster type. See <a href=https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengworkingwithenhancedclusters.htm>Working with Enhanced Clusters and Basic Clusters</a> for more information. NOTE: An Enhanced cluster is required for self-managed worker pools (mode != Node Pool).\"\n  type        = string\n}\nvariable \"cluster_name\" {\n  default = null\n  type    = string\n}\nvariable \"cni_type\" { type = string }\nvariable \"pods_cidr\" {\n  default = \"10.244.0.0/16\"\n  type    = string\n}\nvariable \"services_cidr\" {\n  default = \"10.96.0.0/16\"\n  type    = string\n}\nvariable \"kubernetes_version\" { default = \"v1.32.1\" }\n\nvariable \"cluster_kms_vault_id\" {\n  default = null\n  type    = string\n}\nvariable \"cluster_kms_key_id\" {\n  default = \"\"\n  type    = string\n}\n\nvariable \"use_signed_images\" {\n  default = false\n  type    = bool\n}\nvariable \"image_signing_keys\" {\n  default = []\n  type    = set(string)\n}\n\nvariable \"load_balancers\" {\n  default = \"Public\"\n  type    = string\n}\nvariable \"preferred_load_balancer\" {\n  default = \"Public\"\n  type    = string\n}\n\nvariable \"cluster_tags\" {\n  default = {}\n  type    = map(any)\n}\n\n# Oracle Container Image Registry (OCIR)\n\nvariable \"ocir_email_address\" {\n  default = null\n  type    = string\n}\nvariable \"ocir_secret_name\" { default = \"ocirsecret\" }\nvariable \"ocir_secret_namespace\" { default = \"default\" }\nvariable \"ocir_username\" {\n  default = null\n  type    = string\n}\nvariable \"ocir_kms_vault_id\" {\n  default = null\n  type    = string\n}\nvariable \"ocir_kms_secret_id\" {\n  default = null\n  type    = string\n}\n"
  },
  {
    "path": "examples/rms/oke-cluster-only/variables-extensions.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# CNI: Multus\n\nvariable \"multus_install\" { default = false }\nvariable \"multus_namespace\" { default = \"network\" }\nvariable \"multus_daemonset_url\" {\n  default = null\n  type    = string\n}\nvariable \"multus_version\" { default = \"master\" }\n\n# Metrics server\n\nvariable \"metrics_server_install\" { default = false }\nvariable \"metrics_server_namespace\" { default = \"metrics\" }\nvariable \"metrics_server_helm_version\" { default = \"3.8.3\" }\nvariable \"metrics_server_helm_values\" {\n  default = {}\n  type    = map(string)\n}\nvariable \"metrics_server_helm_values_files\" {\n  default = []\n  type    = list(string)\n}\n\n# Cluster autoscaler\n\nvariable \"cluster_autoscaler_install\" { default = false }\nvariable \"cluster_autoscaler_namespace\" { default = \"kube-system\" }\nvariable \"cluster_autoscaler_helm_version\" { default = \"9.24.0\" }\nvariable \"cluster_autoscaler_helm_values\" {\n  default = {}\n  type    = map(string)\n}\nvariable \"cluster_autoscaler_helm_values_files\" {\n  default = []\n  type    = list(string)\n}\n\n# Prometheus\n\nvariable \"prometheus_install\" { default = false }\nvariable \"prometheus_reapply\" { default = false }\nvariable \"prometheus_namespace\" { default = \"metrics\" }\nvariable \"prometheus_helm_version\" { default = \"45.2.0\" }\nvariable \"prometheus_helm_values\" {\n  default = {}\n  type    = map(string)\n}\nvariable \"prometheus_helm_values_files\" {\n  default = []\n  type    = list(string)\n}\n\n# DCGM exporter\n\nvariable \"dcgm_exporter_install\" { default = false }\nvariable \"dcgm_exporter_reapply\" { default = false }\nvariable \"dcgm_exporter_namespace\" { default = \"metrics\" }\nvariable \"dcgm_exporter_helm_version\" { default = \"3.1.5\" }\n\n# SR-IOV device plugin\n\nvariable \"sriov_device_plugin_install\" { default = false }\nvariable \"sriov_device_plugin_install_config\" { default = false }\nvariable \"sriov_device_plugin_namespace\" { default = \"network\" }\nvariable \"sriov_device_plugin_daemonset_url\" {\n  default = null\n  type    = string\n}\nvariable \"sriov_device_plugin_version\" { default = \"master\" }\n\n# SR-IOV CNI plugin\n\nvariable \"sriov_cni_plugin_install\" { default = false }\nvariable \"sriov_cni_plugin_namespace\" { default = \"network\" }\nvariable \"sriov_cni_plugin_daemonset_url\" {\n  default = null\n  type    = string\n}\nvariable \"sriov_cni_plugin_version\" { default = \"master\" }\n\n# RDMA CNI plugin\n\nvariable \"rdma_cni_plugin_install\" { default = false }\nvariable \"rdma_cni_plugin_namespace\" { default = \"network\" }\nvariable \"rdma_cni_plugin_daemonset_url\" {\n  default = null\n  type    = string\n}\nvariable \"rdma_cni_plugin_version\" { default = \"master\" }\n\n# MPI operator\n\nvariable \"mpi_operator_install\" { default = false }\nvariable \"mpi_operator_namespace\" { default = \"default\" }\nvariable \"mpi_operator_deployment_url\" {\n  default = null\n  type    = string\n}\nvariable \"mpi_operator_version\" { default = \"0.4.0\" }\n\n# Whereabouts\n\nvariable \"whereabouts_install\" { default = false }\nvariable \"whereabouts_namespace\" { default = \"network\" }\nvariable \"whereabouts_daemonset_url\" {\n  default = null\n  type    = string\n}\nvariable \"whereabouts_version\" { default = \"master\" }\n\n# Gatekeeper\n\nvariable \"gatekeeper_install\" { default = false }\nvariable \"gatekeeper_namespace\" { default = \"kube-system\" }\nvariable \"gatekeeper_helm_version\" { default = \"3.11.0\" }\nvariable \"gatekeeper_helm_values\" {\n  default = {}\n  type    = map(string)\n}\nvariable \"gatekeeper_helm_values_files\" {\n  default = []\n  type    = list(string)\n}\n"
  },
  {
    "path": "examples/rms/oke-cluster-only/variables-iam.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nvariable \"tenancy_ocid\" {\n  default = null\n  type    = string\n}\n\nvariable \"current_user_ocid\" {\n  default = null\n  type    = string\n}\n\nvariable \"compartment_ocid\" {\n  default = null\n  type    = string\n}\n\nvariable \"region\" {\n  default = null\n  type    = string\n}\n\nvariable \"create_iam_autoscaler_policy\" {\n  default = \"Auto\"\n  type    = string\n}\n\nvariable \"create_iam_kms_policy\" {\n  default = \"Auto\"\n  type    = string\n}\n\nvariable \"create_iam_operator_policy\" {\n  default = \"Auto\"\n  type    = string\n}\n\nvariable \"create_iam_worker_policy\" {\n  default = \"Auto\"\n  type    = string\n}\n\nvariable \"create_iam_resources\" { default = false }\nvariable \"create_iam_tag_namespace\" { default = false }\nvariable \"create_iam_defined_tags\" { default = false }\nvariable \"use_defined_tags\" {\n  default     = false\n  description = \"Add existing tags in the configured namespace to created resources when applicable.\"\n  type        = bool\n}\n\nvariable \"tag_namespace\" {\n  default     = \"oke\"\n  description = \"Tag namespace containing standard tags for resources created by the module: [state_id, role, pool, cluster_autoscaler].\"\n  type        = string\n}\n\nvariable \"freeform_tags\" {\n  default = {\n    cluster           = {}\n    persistent_volume = {}\n    service_lb        = {}\n    workers           = {}\n    bastion           = {}\n    operator          = {}\n    vcn               = {}\n  }\n  type = any\n}\n\nvariable \"defined_tags\" {\n  default = {\n    cluster           = {}\n    persistent_volume = {}\n    service_lb        = {}\n    workers           = {}\n    bastion           = {}\n    operator          = {}\n    vcn               = {}\n  }\n  type = any\n}\n"
  },
  {
    "path": "examples/rms/oke-cluster-only/variables-network.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nvariable \"vcn_id\" { type = string }\nvariable \"ig_route_table_id\" {\n  default = null\n  type    = string\n}\nvariable \"service_gateway_id\" {\n  default = null\n  type    = string\n}\nvariable \"nat_gateway_id\" {\n  default = null\n  type    = string\n}\nvariable \"assign_dns\" { default = true }\nvariable \"control_plane_is_public\" { default = false }\nvariable \"control_plane_nsg_id\" { default = \"\" }\nvariable \"operator_nsg_id\" { default = \"\" }\n\nvariable \"control_plane_subnet_id\" {\n  type = string\n}\nvariable \"int_lb_subnet_id\" {\n  type    = string\n  default = null\n}\nvariable \"operator_subnet_id\" {\n  type    = string\n  default = null\n}\nvariable \"pub_lb_subnet_id\" {\n  type    = string\n  default = null\n}\n\nvariable \"bastion_public_ip\" {\n  default = null\n  type    = string\n}\n"
  },
  {
    "path": "examples/rms/oke-cluster-only/variables-operator.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nvariable \"create_operator\" { default = true }\nvariable \"operator_install_helm\" { default = true }\nvariable \"operator_install_k9s\" { default = false }\nvariable \"operator_install_kubectx\" { default = true }\nvariable \"operator_pv_transit_encryption\" { default = false }\nvariable \"operator_upgrade\" { default = false }\nvariable \"operator_availability_domain\" {\n  default = null\n  type    = string\n}\nvariable \"operator_cloud_init\" {\n  default = []\n  type    = list(map(string))\n}\n\nvariable \"operator_user\" { default = \"opc\" }\nvariable \"operator_image_id\" {\n  default = null\n  type    = string\n}\nvariable \"operator_image_os\" { default = \"Oracle Linux\" }\nvariable \"operator_image_os_version\" { default = \"8\" }\nvariable \"operator_image_type\" {\n  default = \"Platform\"\n  type    = string\n  validation {\n    condition     = contains([\"custom\", \"platform\"], lower(var.operator_image_type))\n    error_message = \"Accepted values are custom or platform\"\n  }\n}\nvariable \"operator_shape\" {\n  default = {\n    shape            = \"VM.Standard.E4.Flex\",\n    ocpus            = 1,\n    memory           = 4,\n    boot_volume_size = 50\n  }\n  type = map(any)\n}\nvariable \"operator_volume_kms_vault_id\" {\n  default = null\n  type    = string\n}\nvariable \"operator_volume_kms_key_id\" {\n  default = null\n  type    = string\n}\nvariable \"operator_private_ip\" {\n  default = null\n  type    = string\n}\nvariable \"operator_tags\" {\n  default = {}\n  type    = map(any)\n}\n"
  },
  {
    "path": "examples/rms/oke-cluster-only/versions.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nterraform {\n  experiments      = [module_variable_optional_attrs]\n  required_version = \">= 1.2.0\"\n\n  required_providers {\n    oci = {\n      configuration_aliases = [oci.home]\n      source                = \"oracle/oci\"\n      version               = \">= 4.119.0\"\n    }\n  }\n}\n\n"
  },
  {
    "path": "examples/rms/oke-network-only/data.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nvariable \"ssh_public_key\" {\n  default = null\n  type    = string\n}\nvariable \"ssh_kms_vault_id\" {\n  default = null\n  type    = string\n}\nvariable \"ssh_kms_secret_id\" {\n  default = null\n  type    = string\n}\n\ndata \"oci_identity_region_subscriptions\" \"home\" {\n  tenancy_id = var.tenancy_ocid\n  filter {\n    name   = \"is_home_region\"\n    values = [true]\n  }\n}\n\ndata \"oci_secrets_secretbundle\" \"ssh_key\" {\n  secret_id = var.ssh_kms_secret_id\n}\n\nlocals {\n  ssh_public_key         = try(base64decode(var.ssh_public_key), var.ssh_public_key)\n  ssh_key_bundle         = sensitive(one(data.oci_secrets_secretbundle.ssh_key.secret_bundle_content))\n  ssh_key_bundle_content = sensitive(lookup(local.ssh_key_bundle, \"content\", null))\n}\n"
  },
  {
    "path": "examples/rms/oke-network-only/main.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nmodule \"oke\" {\n  source         = \"github.com/oracle-terraform-modules/terraform-oci-oke.git?ref=5.x&depth=1\"\n  providers      = { oci.home = oci.home }\n  tenancy_id     = var.tenancy_ocid\n  compartment_id = var.compartment_ocid\n\n  # Identity\n  create_iam_resources     = true\n  create_iam_tag_namespace = var.create_iam_tag_namespace\n  create_iam_defined_tags  = var.create_iam_tag_namespace || var.create_iam_defined_tags\n  use_defined_tags         = var.use_defined_tags\n  tag_namespace            = var.tag_namespace\n\n  # Network\n  create_vcn                  = var.create_vcn\n  vcn_id                      = var.vcn_id\n  vcn_cidrs                   = split(\",\", var.vcn_cidrs)\n  vcn_create_internet_gateway = var.vcn_create_internet_gateway ? \"always\" : \"never\"\n  vcn_create_nat_gateway      = var.vcn_create_nat_gateway ? \"always\" : \"never\"\n  vcn_create_service_gateway  = var.vcn_create_service_gateway ? \"always\" : \"never\"\n  vcn_name                    = var.vcn_name\n  vcn_dns_label               = var.vcn_dns_label\n  assign_dns                  = var.assign_dns\n  ig_route_table_id           = var.ig_route_table_id\n  local_peering_gateways      = var.local_peering_gateways\n  lockdown_default_seclist    = var.lockdown_default_seclist\n  create_drg                  = var.create_drg\n  drg_id                      = var.drg_id\n  drg_display_name            = var.drg_display_name\n\n  subnets = {\n    bastion = {\n      create  = var.bastion_subnet_create ? \"always\" : \"never\",\n      newbits = var.bastion_subnet_newbits,\n      id      = var.bastion_subnet_id\n    }\n\n    operator = {\n      create  = var.operator_subnet_create ? \"always\" : \"never\",\n      newbits = var.operator_subnet_newbits,\n      id      = var.operator_subnet_id\n    }\n\n    cp = {\n      create  = var.control_plane_subnet_create ? \"always\" : \"never\",\n      newbits = var.control_plane_subnet_newbits,\n      id      = var.control_plane_subnet_id\n    }\n\n    int_lb = {\n      create  = var.int_lb_subnet_create ? \"always\" : \"never\",\n      newbits = var.int_lb_subnet_newbits,\n      id      = var.int_lb_subnet_id\n    }\n\n    pub_lb = {\n      create  = var.pub_lb_subnet_create ? \"always\" : \"never\",\n      newbits = var.pub_lb_subnet_newbits,\n      id      = var.pub_lb_subnet_id\n    }\n\n    workers = {\n      create  = var.worker_subnet_create ? \"always\" : \"never\",\n      newbits = var.worker_subnet_newbits,\n      id      = var.worker_subnet_id\n    }\n\n    pods = {\n      create  = var.pod_subnet_create ? \"always\" : \"never\",\n      newbits = var.pod_subnet_newbits,\n      id      = var.pod_subnet_id\n    }\n  }\n\n  # Network Security\n  nsgs = {\n    bastion  = { create = var.create_nsgs ? \"always\" : \"never\" }\n    operator = { create = var.create_nsgs ? \"always\" : \"never\" }\n    cp       = { create = var.create_nsgs ? \"always\" : \"never\" }\n    int_lb   = { create = var.create_nsgs ? \"always\" : \"never\" }\n    pub_lb   = { create = var.create_nsgs ? \"always\" : \"never\" }\n    workers  = { create = var.create_nsgs ? \"always\" : \"never\" }\n    pods     = { create = var.create_nsgs ? \"always\" : \"never\" }\n  }\n\n  allow_node_port_access       = var.allow_node_port_access\n  allow_pod_internet_access    = var.allow_pod_internet_access\n  allow_rules_internal_lb      = var.allow_rules_internal_lb\n  allow_rules_public_lb        = var.allow_rules_public_lb\n  allow_worker_internet_access = var.allow_worker_internet_access\n  allow_worker_ssh_access      = var.allow_worker_ssh_access\n  enable_waf                   = var.enable_waf\n  bastion_allowed_cidrs        = compact(split(\",\", var.bastion_allowed_cidrs))\n  control_plane_allowed_cidrs  = compact(split(\",\", var.control_plane_allowed_cidrs))\n  control_plane_is_public      = var.control_plane_is_public\n  load_balancers               = lower(var.load_balancers)\n  worker_is_public             = var.worker_is_public\n\n  # Bastion\n  bastion_availability_domain = var.bastion_availability_domain\n  bastion_image_id            = var.bastion_image_id\n  bastion_image_os            = var.bastion_image_os\n  bastion_image_os_version    = var.bastion_image_os_version\n  bastion_image_type          = lower(var.bastion_image_type)\n  bastion_is_public           = var.bastion_is_public\n  bastion_shape               = var.bastion_shape\n  bastion_upgrade             = var.bastion_upgrade\n  bastion_user                = var.bastion_user\n  create_bastion              = var.create_bastion\n\n  # SSH\n  ssh_public_key  = local.ssh_public_key\n  ssh_private_key = sensitive(local.ssh_key_bundle_content)\n\n  # Cluster\n  create_cluster          = false\n  preferred_load_balancer = lower(var.preferred_load_balancer)\n  create_operator         = false\n\n  freeform_tags = { # TODO Remaining tags in schema\n    bastion = lookup(var.bastion_tags, \"freeformTags\", {})\n    vcn     = {}\n  }\n\n  defined_tags = { # TODO Remaining tags in schema\n    bastion = lookup(var.bastion_tags, \"definedTags\", {})\n    vcn     = {}\n  }\n}\n"
  },
  {
    "path": "examples/rms/oke-network-only/output.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# Terraform\noutput \"state_id\" { value = module.oke.state_id }\n\n# Network\noutput \"vcn_id\" { value = module.oke.vcn_id }\noutput \"drg_id\" { value = module.oke.drg_id }\noutput \"ig_route_table_id\" { value = module.oke.ig_route_table_id }\noutput \"nat_route_table_id\" { value = module.oke.nat_route_table_id }\n\n# Bastion\noutput \"bastion_id\" { value = module.oke.bastion_id }\noutput \"bastion_public_ip\" { value = module.oke.bastion_public_ip }\noutput \"bastion_subnet_id\" { value = module.oke.bastion_subnet_id }\noutput \"bastion_subnet_cidr\" { value = module.oke.bastion_subnet_cidr }\noutput \"bastion_nsg_id\" { value = module.oke.bastion_nsg_id }\noutput \"bastion_ssh_command\" { value = module.oke.ssh_to_bastion }\noutput \"bastion_ssh_secret_id\" { value = var.ssh_kms_secret_id }\n\n# Operator\noutput \"operator_subnet_id\" { value = module.oke.operator_subnet_id }\noutput \"operator_subnet_cidr\" { value = module.oke.operator_subnet_cidr }\noutput \"operator_nsg_id\" { value = module.oke.operator_nsg_id }\n\n# Cluster\noutput \"control_plane_subnet_id\" { value = module.oke.control_plane_subnet_id }\noutput \"control_plane_subnet_cidr\" { value = module.oke.control_plane_subnet_cidr }\noutput \"control_plane_nsg_id\" { value = module.oke.control_plane_nsg_id }\noutput \"int_lb_subnet_id\" { value = module.oke.int_lb_subnet_id }\noutput \"pub_lb_subnet_id\" { value = module.oke.pub_lb_subnet_id }\noutput \"int_lb_nsg_id\" { value = module.oke.int_lb_nsg_id }\noutput \"int_lb_subnet_cidr\" { value = module.oke.int_lb_subnet_cidr }\noutput \"pub_lb_nsg_id\" { value = module.oke.pub_lb_nsg_id }\noutput \"pub_lb_subnet_cidr\" { value = module.oke.pub_lb_subnet_cidr }\n\n# Workers\noutput \"worker_subnet_id\" { value = module.oke.worker_subnet_id }\noutput \"worker_subnet_cidr\" { value = module.oke.worker_subnet_cidr }\noutput \"worker_nsg_id\" { value = module.oke.worker_nsg_id }\noutput \"pod_subnet_id\" { value = module.oke.pod_subnet_id }\noutput \"pod_subnet_cidr\" { value = module.oke.pod_subnet_cidr }\noutput \"pod_nsg_id\" { value = module.oke.pod_nsg_id }\n"
  },
  {
    "path": "examples/rms/oke-network-only/schema.yaml",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\ntitle: \"OKE: Network Only\"\ndescription: Common Virtual Cloud Network resources for OKE cluster installations.\nschemaVersion: 1.1.0\nversion: \"20230304\"\nlocale: \"en\"\n\nvariableGroups:\n  - title: \"Hidden\"\n    visible: false\n    variables:\n      - api_fingerprint\n      - current_user_ocid\n      - tenancy_ocid\n      - region\n      - subnets\n      - bastion_public_ip\n\n  - title: \"Identity\"\n    variables:\n      - compartment_ocid\n      - create_iam_tag_namespace\n      - create_iam_defined_tags\n      - use_defined_tags\n      - tag_namespace\n\n  - title: \"VCN\"\n    variables:\n      - ${create_vcn}\n      - assign_dns\n      - vcn_id\n      - vcn_name\n      - vcn_cidrs\n      - vcn_dns_label\n      - ig_route_table_id\n      - vcn_create_internet_gateway\n      - vcn_create_nat_gateway\n      - vcn_create_service_gateway\n      - nat_gateway_id\n      - nat_route_table_id\n      - nat_gateway_public_ip_id\n      - service_gateway_id\n      - create_drg\n      - drg_id\n      - local_peering_gateways\n\n  - title: \"Security\"\n    variables:\n      - ${create_nsgs}\n      - lockdown_default_seclist\n      - enable_waf\n\n  - title: \"Bastion\"\n    variables:\n      - bastion_is_public\n      - bastion_subnet_create\n      - bastion_subnet_newbits\n      - bastion_subnet_id\n      - bastion_allowed_cidrs\n      - ${create_bastion}\n      - bastion_upgrade\n      - bastion_availability_domain\n      - bastion_image_os\n      - bastion_image_os_version\n      - bastion_image_id\n      - bastion_user\n      - bastion_shape_name\n      - bastion_shape_ocpus\n      - bastion_shape_memory\n      - bastion_shape_boot\n      - bastion_shape\n      - bastion_tags\n\n  - title: \"SSH\"\n    visible: ${create_bastion}\n    variables:\n      - ssh_public_key\n      - ssh_kms_vault_id\n      - ssh_kms_secret_id\n\n  - title: \"Operator\"\n    variables:\n      - operator_subnet_create\n      - operator_subnet_newbits\n      - operator_subnet_id\n\n  - title: \"Control Plane\"\n    variables:\n      - control_plane_is_public\n      - control_plane_allowed_cidrs\n      - control_plane_subnet_create\n      - control_plane_subnet_newbits\n      - control_plane_subnet_id\n\n  - title: \"Load Balancers\"\n    variables:\n      - load_balancers\n      - preferred_load_balancer\n      - allow_rules_internal_lb\n      - allow_rules_public_lb\n      - int_lb_subnet_create\n      - int_lb_subnet_newbits\n      - int_lb_subnet_id\n      - pub_lb_subnet_create\n      - pub_lb_subnet_newbits\n      - pub_lb_subnet_id\n\n  - title: \"Workers\"\n    variables:\n      - worker_is_public\n      - worker_subnet_create\n      - worker_subnet_newbits\n      - worker_subnet_id\n      - allow_worker_ssh_access\n      - allow_worker_internet_access\n      - allow_node_port_access\n      - pod_subnet_create\n      - pod_subnet_newbits\n      - pod_subnet_id\n      - allow_pod_internet_access\n\nvariables:\n  # Identity\n  api_fingerprint:\n    required: false\n    visible: false\n  current_user_ocid:\n    title: User\n    type: ocid\n    required: true\n  tenancy_ocid:\n    title: Tenancy\n    type: oci:identity:compartment:id\n    required: true\n  compartment_ocid:\n    title: Compartment\n    description: The default compartment for created resources.\n    type: oci:identity:compartment:id\n    required: true\n  region:\n    required: true\n    title: Region\n    type: oci:identity:region:name\n  defined_tags:\n    visible: false\n  freeform_tags:\n    visible: false\n  create_iam_tag_namespace:\n    default: false\n    required: true\n    title: Create tag namespace\n    type: boolean\n  create_iam_defined_tags:\n    default: false\n    required: true\n    title: Create defined tags\n    type: boolean\n  use_defined_tags:\n    title: Use defined tags\n    default: false\n    type: boolean\n  tag_namespace:\n    title: Tag namespace\n    visible:\n      or:\n        - ${create_iam_tag_namespace}\n        - ${create_iam_defined_tags}\n        - ${use_defined_tags}\n\n  # VCN\n  create_vcn:\n    title: Create VCN\n    type: boolean\n    default: true\n  vcn_id:\n    title: Existing VCN\n    type: oci:core:vcn:id\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n    visible: { not: [create_vcn] }\n  vcn_name:\n    title: Virtual Cloud Network (VCN) name\n    description: Display name for the created VCN. Defaults to 'oke' suffixed with the generated Terraform 'state_id' value.\n    type: string\n    visible: ${create_vcn}\n  assign_dns:\n    title: Assign DNS records\n    type: boolean\n    required: true\n    visible: ${create_vcn}\n  vcn_dns_label:\n    title: DNS label\n    description: DNS label for the created VCN. Defaults to the generated Terraform 'state_id' value.\n    visible:\n      and:\n        - ${create_vcn}\n        - ${assign_dns}\n  vcn_cidrs:\n    title: CIDR ranges\n    description: Comma-separated list of CIDR blocks for the created VCN.\n    type: string\n    required: true\n    visible: ${create_vcn}\n  lockdown_default_seclist:\n    title: Secure default security list\n    type: boolean\n    required: true\n    visible: ${create_vcn}\n  vcn_create_internet_gateway:\n    title: Create internet gateway\n    type: boolean\n    required: true\n    visible: ${create_vcn}\n  vcn_create_nat_gateway:\n    title: Create service gateway\n    type: boolean\n    required: true\n    visible: ${create_vcn}\n  vcn_create_service_gateway:\n    title: Create NAT gateway\n    type: boolean\n    required: true\n    visible: ${create_vcn}\n  local_peering_gateways:\n    title: Local peering gateways\n    visible: false\n  ig_route_table_id:\n    title: Internet Gateway Route Table\n    type: ocid\n    required: false\n    visible:\n      not:\n        - ${create_vcn}\n  service_gateway_id:\n    title: Service gateway\n    description: Existing service gateway in the VCN for access to Oracle Cloud services.\n    type: oci:core:servicegateway:id\n    required: true\n    visible:\n      not:\n        - ${create_vcn}\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n  nat_gateway_id:\n    title: NAT gateway\n    description: Existing NAT gateway in the VCN for private network egress.\n    type: oci:core:natgateway:id\n    required: true\n    visible:\n      not:\n        - ${create_vcn}\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n\n  # NSGs\n  create_nsgs:\n    title: Create NSGs\n    description: Create standard network security groups and traffic rules. Additional configuration may be required when disabled, e.g. providing existing NSGs, subnet security lists, etc.\n    type: boolean\n    default: true\n    required: true\n  bastion_allowed_cidrs:\n    title: Comma-separated list of CIDR blocks allowed SSH access to the bastion host.\n    type: string\n    required: false\n    visible: ${create_nsgs}\n  control_plane_allowed_cidrs:\n    title: Comma-separated list of CIDR blocks allowed access to the OKE control plane.\n    type: string\n    required: false\n    visible: ${create_nsgs}\n  control_plane_is_public:\n    title: Public Kubernetes control plane\n    type: boolean\n    default: false\n    required: true\n    visible: ${create_nsgs}\n  preferred_load_balancer:\n    title: Preferred load balancer\n    type: enum\n    default: Internal\n    enum: [Internal, Public]\n    allowMultiple: false\n    required: true\n  worker_is_public:\n    title: Public Kubernetes worker nodes\n    type: boolean\n    default: false\n    required: true\n    visible: ${create_nsgs}\n  allow_node_port_access:\n    title: Allow NodePort access\n    type: boolean\n    default: false\n    required: true\n    visible: ${create_nsgs}\n  allow_worker_ssh_access:\n    title: Allow worker SSH access\n    type: boolean\n    default: true\n    required: true\n    visible: ${create_nsgs}\n  allow_worker_internet_access:\n    title: Allow worker egress to internet\n    type: boolean\n    default: true\n    required: true\n    visible: ${create_nsgs}\n  allow_pod_internet_access:\n    title: Allow pod egress to internet\n    type: boolean\n    required: false\n    default: true\n    visible: ${create_nsgs}\n  allow_rules_internal_lb:\n    title: Additional internal load balancer rules\n    additionalProps:\n      allowMultiple: true\n    required: false\n    visible: ${create_nsgs}\n  allow_rules_public_lb:\n    title: Additional public load balancer rules\n    additionalProps:\n      allowMultiple: true\n    required: false\n    visible: ${create_nsgs}\n\n  create_drg:\n    title: Create DRG\n    description: Create a Dynamic Routing Gateway and attach it to the VCN.\n    type: boolean\n    default: false\n    required: false\n    visible: false\n  drg_id:\n    title: Dynamic Routing Gateway\n    description: Existing Dynamic Routing Gateway to attach to the VCN.\n    type: ocid\n    required: false\n    visible: { not: [create_drg] }\n  drg_display_name:\n    title: DRG display name\n    visible: ${create_drg}\n  enable_waf:\n    title: Enable WAF\n    type: boolean\n    default: false\n    required: false\n    visible: false\n  load_balancers:\n    title: Load balancers\n    type: enum\n    enum: [Public, Internal, Both]\n    default: Internal\n    required: true\n    visible: ${create_nsgs}\n\n  bastion_is_public:\n    title: Public network\n    description: Public network and address for bastion host.\n    type: boolean\n    default: true\n    required: true\n    visible:\n      or:\n        - ${bastion_subnet_create}\n        - ${create_bastion}\n  bastion_subnet_create:\n    title: Create bastion subnet\n    type: boolean\n    default: true\n    required: true\n  bastion_subnet_newbits:\n    title: Bastion subnet size\n    description: The number of network prefix bits added to the VCN CIDR block for the created subnet address range (i.e. a higher value is smaller). Refer to the Terraform <a href=https://developer.hashicorp.com/terraform/language/functions/cidrsubnets>cidrsubnets</a> function for more information.\n    type: number\n    visible: ${bastion_subnet_create}\n  bastion_subnet_id:\n    title: Bastion subnet\n    type: oci:core:subnet:id\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n      hidePublicSubnet: { not: [bastion_is_public] }\n      hidePrivateSubnet: ${bastion_is_public}\n      hideRegionalSubnet: false\n      hideAdSubnet: false\n    visible:\n      not:\n        - or:\n            - ${bastion_subnet_create}\n            - not:\n                - ${create_bastion}\n  create_bastion:\n    title: Create bastion instance\n    type: boolean\n    default: true\n    required: true\n  bastion_availability_domain:\n    title: Availability domain\n    type: oci:identity:availabilitydomain:name\n    required: false\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n    visible: ${create_bastion}\n  bastion_user:\n    title: User\n    type: string\n    default: opc\n    required: true\n    visible: ${create_bastion}\n  bastion_shape_name:\n    title: Shape\n    type: oci:core:instanceshape:name\n    default: \"VM.Standard.E4.Flex\"\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n    visible: ${create_bastion}\n  bastion_shape_ocpus:\n    title: OCPUs (Cores)\n    type: number\n    default: 4\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n    visible: ${create_bastion}\n  bastion_shape_memory:\n    title: Memory (GB)\n    type: number\n    default: 16\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n    visible: ${create_bastion}\n  bastion_shape_boot:\n    title: Boot volume size (GB)\n    type: number\n    default: 50\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n    visible: ${create_bastion}\n  bastion_shape:\n    visible: false\n  bastion_image_os:\n    title: Image OS\n    description: Image operating system.\n    type: enum\n    default: \"Oracle Autonomous Linux\"\n    enum: [\"Oracle Autonomous Linux\", \"Oracle Linux\"]\n    required: true\n    visible:\n      and:\n        - ${create_bastion}\n        - not:\n            - eq:\n                - ${bastion_image_type}\n                - custom\n  bastion_image_os_version:\n    title: Image OS version\n    description: Image operating system version.\n    type: enum\n    default: \"8.7\"\n    enum: [\"7.9\", \"8.7\"]\n    required: true\n    visible:\n      and:\n        - ${create_bastion}\n        - not:\n            - eq:\n                - ${bastion_image_type}\n                - custom\n  bastion_image_type:\n    title: Image type\n    type: enum\n    default: platform\n    enum: [platform, custom]\n    required: true\n    visible: false\n  bastion_image_id:\n    title: Image ID\n    type: oci:core:image:id\n    required: false\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      operatingSystem: ${bastion_image_os}\n      operatingSystemVersion: ${bastion_image_os_version}\n      shape: ${bastion_shape_name}\n    visible: ${create_bastion}\n  bastion_upgrade:\n    title: Upgrade OS\n    description: Upgrade the operating system on boot.\n    type: boolean\n    default: false\n    required: true\n    visible: ${create_bastion}\n  bastion_tags:\n    type: oci:identity:tag:value\n    required: false\n    title: Tagging\n    description: Tag values for created resources.\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n    visible: ${create_bastion}\n\n  # SSH\n  ssh_public_key:\n    title: SSH Public Key\n    type: oci:core:ssh:publickey\n    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})( [^,]*)?)*$\"\n    required: false\n  ssh_kms_vault_id:\n    title: SSH Vault\n    description: The OCI Vault used to encrypt the SSH key pair.\n    type: oci:kms:vault:id\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n    visible: ${create_bastion}\n  ssh_kms_secret_id:\n    title: SSH Vault secret\n    description: The OCI Vault secret containing the SSH private key.\n    type: oci:kms:secret:id\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vaultId: ${ssh_kms_vault_id}\n    visible: ${create_bastion}\n\n  operator_subnet_create:\n    title: Create operator subnet\n    type: boolean\n    required: true\n  operator_subnet_newbits:\n    title: Operator subnet size\n    description: The number of network prefix bits added to the VCN CIDR block for the created subnet address range (i.e. a higher value is smaller). Refer to the Terraform <a href=https://developer.hashicorp.com/terraform/language/functions/cidrsubnets>cidrsubnets</a> function for more information.\n    type: number\n    visible: ${operator_subnet_create}\n  operator_subnet_id:\n    title: Operator subnet\n    type: oci:core:subnet:id\n    required: false\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n      hidePublicSubnet: true\n      hidePrivateSubnet: false\n      hideRegionalSubnet: false\n      hideAdSubnet: false\n    visible:\n      not: ${operator_subnet_create}\n  control_plane_subnet_create:\n    title: Create control plane subnet\n    type: boolean\n    required: true\n  control_plane_subnet_newbits:\n    title: Control plane subnet size\n    description: The number of network prefix bits added to the VCN CIDR block for the created subnet address range (i.e. a higher value is smaller). Refer to the Terraform <a href=https://developer.hashicorp.com/terraform/language/functions/cidrsubnets>cidrsubnets</a> function for more information.\n    type: number\n    visible: ${control_plane_subnet_create}\n  control_plane_subnet_id:\n    title: Control plane subnet\n    type: oci:core:subnet:id\n    required: false\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n      hidePublicSubnet: { not: [control_plane_is_public] }\n      hidePrivateSubnet: ${control_plane_is_public}\n      hideRegionalSubnet: false\n      hideAdSubnet: true\n    visible:\n      not: ${control_plane_subnet_create}\n  int_lb_subnet_create:\n    title: Create internal load balancer subnet\n    type: boolean\n    required: true\n  int_lb_subnet_newbits:\n    title: Internal load balancer subnet size\n    description: The number of network prefix bits added to the VCN CIDR block for the created subnet address range (i.e. a higher value is smaller). Refer to the Terraform <a href=https://developer.hashicorp.com/terraform/language/functions/cidrsubnets>cidrsubnets</a> function for more information.\n    type: number\n    visible: ${int_lb_subnet_create}\n  int_lb_subnet_id:\n    title: Internal load balancer subnet\n    type: oci:core:subnet:id\n    required: false\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n      hidePublicSubnet: true\n      hidePrivateSubnet: false\n      hideRegionalSubnet: false\n      hideAdSubnet: true\n    visible:\n      not: ${int_lb_subnet_create}\n  pub_lb_subnet_create:\n    title: Create public load balancer subnet\n    type: boolean\n    required: true\n  pub_lb_subnet_newbits:\n    title: Public load balancer subnet size\n    description: The number of network prefix bits added to the VCN CIDR block for the created subnet address range (i.e. a higher value is smaller). Refer to the Terraform <a href=https://developer.hashicorp.com/terraform/language/functions/cidrsubnets>cidrsubnets</a> function for more information.\n    type: number\n    visible: ${pub_lb_subnet_create}\n  pub_lb_subnet_id:\n    title: Public load balancer subnet\n    type: oci:core:subnet:id\n    required: false\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n      hidePublicSubnet: false\n      hidePrivateSubnet: true\n      hideRegionalSubnet: false\n      hideAdSubnet: true\n    visible:\n      not: ${pub_lb_subnet_create}\n  worker_subnet_create:\n    title: Create worker subnet\n    type: boolean\n    required: true\n  worker_subnet_newbits:\n    title: Worker subnet size\n    description: The number of network prefix bits added to the VCN CIDR block for the created subnet address range (i.e. a higher value is smaller). Refer to the Terraform <a href=https://developer.hashicorp.com/terraform/language/functions/cidrsubnets>cidrsubnets</a> function for more information.\n    type: number\n    visible: ${worker_subnet_create}\n  worker_subnet_id:\n    title: Worker subnet\n    type: oci:core:subnet:id\n    required: false\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n      hidePublicSubnet: { not: [worker_is_public] }\n      hidePrivateSubnet: ${worker_is_public}\n      hideRegionalSubnet: false\n      hideAdSubnet: false\n    visible:\n      not: ${worker_subnet_create}\n  pod_subnet_create:\n    title: Create pod subnet\n    type: boolean\n    required: true\n  pod_subnet_newbits:\n    title: Pod subnet size\n    description: The number of network prefix bits added to the VCN CIDR block for the created subnet address range (i.e. a higher value is smaller). Refer to the Terraform <a href=https://developer.hashicorp.com/terraform/language/functions/cidrsubnets>cidrsubnets</a> function for more information.\n    type: number\n    visible: ${pod_subnet_create}\n  pod_subnet_id:\n    title: Pod subnet\n    type: oci:core:subnet:id\n    required: false\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n      hidePublicSubnet: true\n      hidePrivateSubnet: false\n      hideRegionalSubnet: false\n      hideAdSubnet: true\n    visible:\n      not: ${pod_subnet_create}\n\noutputGroups:\n  - title: Terraform\n    outputs:\n      - state_id\n  - title: Network\n    outputs:\n      - vcn_id\n      - ig_route_table_id\n      - nat_route_table_id\n      - drg_id\n  - title: Bastion\n    outputs:\n      - bastion_id\n      - bastion_subnet_id\n      - bastion_subnet_cidr\n      - bastion_public_ip\n      - bastion_ssh_command\n      - bastion_ssh_secret_id\n  - title: Operator\n    outputs:\n      - operator_subnet_id\n      - operator_subnet_cidr\n  - title: Cluster\n    outputs:\n      - control_plane_subnet_id\n      - control_plane_subnet_cidr\n      - int_lb_subnet_id\n      - int_lb_subnet_cidr\n      - pub_lb_subnet_id\n      - pub_lb_subnet_cidr\n  - title: Workers\n    outputs:\n      - worker_subnet_id\n      - worker_subnet_cidr\n      - pod_subnet_id\n      - pod_subnet_cidr\n\noutputs:\n  # Terraform\n  state_id:\n    title: State ID\n    type: copyableString\n\n  # Network\n  vcn_id:\n    title: VCN\n    type: ocid\n  drg_id:\n    title: Dynamic routing gateway\n    type: ocid\n  ig_route_table_id:\n    title: Internet gateway route table\n    type: ocid\n  nat_route_table_id:\n    title: NAT gateway route table\n    type: ocid\n  subnet_cidrs:\n    visible: false\n  subnet_ids:\n    visible: false\n  network_security_rules:\n    visible: false\n\n  # Bastion\n  bastion_id:\n    title: Bastion instance\n    type: ocid\n  bastion_subnet_id:\n    title: Bastion subnet\n    type: ocid\n  bastion_subnet_cidr:\n    title: Bastion CIDR\n    type: string\n  bastion_public_ip:\n    title: Bastion IP\n    type: copyableString\n  bastion_ssh_command:\n    title: Bastion SSH command\n    type: copyableString\n  bastion_ssh_secret_id:\n    title: Bastion SSH Vault secret\n    type: ocid\n\n  # Operator\n  operator_subnet_id:\n    title: Operator subnet\n    type: ocid\n  operator_subnet_cidr:\n    title: Operator CIDR\n    type: string\n\n  # Cluster\n  control_plane_subnet_id:\n    title: Control plane subnet\n    type: ocid\n  control_plane_subnet_cidr:\n    title: Control plane CIDR\n    type: string\n  int_lb_subnet_id:\n    title: Internal load balancer subnet\n    type: ocid\n  int_lb_subnet_cidr:\n    title: Internal load balancer CIDR\n    type: string\n  pub_lb_subnet_id:\n    title: Public load balancer subnet\n    type: ocid\n  pub_lb_subnet_cidr:\n    title: Public load balancer CIDR\n    type: string\n\n  # Workers\n  worker_subnet_id:\n    title: Worker subnet\n    type: ocid\n  worker_subnet_cidr:\n    title: Worker CIDR\n    type: string\n  pod_subnet_id:\n    title: Pod subnet\n    type: ocid\n  pod_subnet_cidr:\n    title: Pod CIDR\n    type: string\n"
  },
  {
    "path": "examples/rms/oke-network-only/variables-bastion.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nvariable \"create_bastion\" { default = true }\nvariable \"bastion_is_public\" { default = true }\nvariable \"bastion_upgrade\" { default = false }\n\nvariable \"bastion_allowed_cidrs\" {\n  default = \"0.0.0.0/0\"\n  type    = string\n}\n\nvariable \"bastion_availability_domain\" {\n  default = null\n  type    = string\n}\n\nvariable \"bastion_user\" {\n  default = \"opc\"\n  type    = string\n}\n\nvariable \"bastion_image_id\" {\n  default = null\n  type    = string\n}\n\nvariable \"bastion_image_type\" {\n  default = \"platform\"\n  type    = string\n  validation {\n    condition     = contains([\"custom\", \"platform\"], lower(var.bastion_image_type))\n    error_message = \"Accepted values are custom or platform\"\n  }\n}\n\nvariable \"bastion_image_os\" {\n  default = \"Oracle Autonomous Linux\"\n  type    = string\n}\n\nvariable \"bastion_image_os_version\" {\n  default = \"8.7\"\n  type    = string\n}\n\nvariable \"bastion_shape\" {\n  default = {\n    shape            = \"VM.Standard.E4.Flex\",\n    ocpus            = 1,\n    memory           = 4,\n    boot_volume_size = 50\n  }\n  type = map(any)\n}\n\nvariable \"bastion_tags\" {\n  default = {}\n  type    = map(any)\n}\n"
  },
  {
    "path": "examples/rms/oke-network-only/variables-iam.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nvariable \"tenancy_ocid\" {\n  default = null\n  type    = string\n}\n\nvariable \"current_user_ocid\" {\n  default = null\n  type    = string\n}\n\nvariable \"compartment_ocid\" {\n  default = null\n  type    = string\n}\n\nvariable \"region\" {\n  default = null\n  type    = string\n}\n\nvariable \"api_fingerprint\" {\n  default = null\n  type    = string\n}\n\nvariable \"create_iam_tag_namespace\" { default = false }\nvariable \"create_iam_defined_tags\" { default = false }\nvariable \"use_defined_tags\" {\n  default     = false\n  description = \"Add existing tags in the configured namespace to created resources when applicable.\"\n  type        = bool\n}\n\nvariable \"tag_namespace\" {\n  default     = \"oke\"\n  description = \"Tag namespace containing standard tags for resources created by the module: [state_id, role, pool, cluster_autoscaler].\"\n  type        = string\n}\n\nvariable \"freeform_tags\" {\n  default = {\n    cluster           = {}\n    persistent_volume = {}\n    service_lb        = {}\n    workers           = {}\n    bastion           = {}\n    operator          = {}\n    vcn               = {}\n  }\n  type = any\n}\n\nvariable \"defined_tags\" {\n  default = {\n    cluster           = {}\n    persistent_volume = {}\n    service_lb        = {}\n    workers           = {}\n    bastion           = {}\n    operator          = {}\n    vcn               = {}\n  }\n  type = any\n}\n"
  },
  {
    "path": "examples/rms/oke-network-only/variables-network.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nvariable \"create_vcn\" { default = true }\nvariable \"assign_dns\" { default = true }\nvariable \"control_plane_is_public\" { default = false }\nvariable \"enable_waf\" { default = false }\nvariable \"worker_is_public\" { default = false }\n\nvariable \"vcn_name\" {\n  default = null\n  type    = string\n}\n\nvariable \"vcn_id\" {\n  default = null\n  type    = string\n}\n\nvariable \"vcn_create_nat_gateway\" {\n  default = true\n  type    = bool\n}\n\nvariable \"vcn_create_internet_gateway\" {\n  default = true\n  type    = bool\n}\n\nvariable \"vcn_create_service_gateway\" {\n  default = true\n  type    = bool\n}\n\nvariable \"ig_route_table_id\" {\n  default = null\n  type    = string\n}\n\nvariable \"create_drg\" { default = false }\n\nvariable \"drg_display_name\" {\n  default = null\n  type    = string\n}\n\nvariable \"drg_id\" {\n  default = null\n  type    = string\n}\n\nvariable \"internet_gateway_route_rules\" {\n  default = null\n  type    = list(map(string))\n}\n\nvariable \"local_peering_gateways\" {\n  default = null\n  type    = map(any)\n}\n\nvariable \"lockdown_default_seclist\" { default = true }\n\nvariable \"nat_gateway_route_rules\" {\n  default = null\n  type    = list(map(string))\n}\n\nvariable \"vcn_cidrs\" {\n  default = \"10.0.0.0/16\"\n  type    = string\n}\n\nvariable \"vcn_dns_label\" {\n  default = null\n  type    = string\n}\n\nvariable \"load_balancers\" {\n  default = \"Internal\"\n  type    = string\n}\n\nvariable \"preferred_load_balancer\" {\n  default = \"Internal\"\n  type    = string\n}\n\nvariable \"create_nsgs\" { default = true }\nvariable \"allow_node_port_access\" { default = false }\nvariable \"allow_pod_internet_access\" { default = true }\nvariable \"allow_worker_internet_access\" { default = true }\nvariable \"allow_worker_ssh_access\" { default = false }\n\nvariable \"allow_rules_internal_lb\" {\n  default = {}\n  type    = any\n}\n\nvariable \"allow_rules_public_lb\" {\n  default = {}\n  type    = any\n}\n\nvariable \"control_plane_allowed_cidrs\" {\n  default = \"\"\n  type    = string\n}\n"
  },
  {
    "path": "examples/rms/oke-network-only/variables-subnets.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nvariable \"bastion_subnet_create\" { default = true }\nvariable \"control_plane_subnet_create\" { default = true }\nvariable \"int_lb_subnet_create\" { default = true }\nvariable \"operator_subnet_create\" { default = true }\nvariable \"pod_subnet_create\" { default = true }\nvariable \"pub_lb_subnet_create\" { default = true }\nvariable \"worker_subnet_create\" { default = true }\n\nvariable \"bastion_subnet_newbits\" { default = 13 }\nvariable \"control_plane_subnet_newbits\" { default = 13 }\nvariable \"int_lb_subnet_newbits\" { default = 11 }\nvariable \"operator_subnet_newbits\" { default = 13 }\nvariable \"pod_subnet_newbits\" { default = 2 }\nvariable \"pub_lb_subnet_newbits\" { default = 11 }\nvariable \"worker_subnet_newbits\" { default = 2 }\n\nvariable \"bastion_subnet_id\" {\n  type    = string\n  default = null\n}\nvariable \"control_plane_subnet_id\" {\n  type    = string\n  default = null\n}\nvariable \"int_lb_subnet_id\" {\n  type    = string\n  default = null\n}\nvariable \"operator_subnet_id\" {\n  type    = string\n  default = null\n}\nvariable \"pod_subnet_id\" {\n  type    = string\n  default = null\n}\nvariable \"pub_lb_subnet_id\" {\n  type    = string\n  default = null\n}\nvariable \"worker_subnet_id\" {\n  type    = string\n  default = null\n}\n"
  },
  {
    "path": "examples/rms/oke-network-only/versions.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nterraform {\n  experiments      = [module_variable_optional_attrs]\n  required_version = \">= 1.2.0\"\n\n  required_providers {\n    oci = {\n      configuration_aliases = [oci.home]\n      source                = \"oracle/oci\"\n      version               = \">= 4.119.0\"\n    }\n  }\n}\n\n"
  },
  {
    "path": "examples/rms/oke-workers-only/data.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nvariable \"ssh_public_key\" {\n  default = null\n  type    = string\n}\nvariable \"ssh_kms_vault_id\" {\n  default = null\n  type    = string\n}\nvariable \"ssh_kms_secret_id\" {\n  default = null\n  type    = string\n}\n\ndata \"oci_identity_region_subscriptions\" \"home\" {\n  tenancy_id = var.tenancy_ocid\n  filter {\n    name   = \"is_home_region\"\n    values = [true]\n  }\n}\n\ndata \"oci_secrets_secretbundle\" \"ssh_key\" {\n  secret_id = var.ssh_kms_secret_id\n}\n\nlocals {\n  ssh_public_key         = try(base64decode(var.ssh_public_key), var.ssh_public_key)\n  ssh_key_bundle         = sensitive(one(data.oci_secrets_secretbundle.ssh_key.secret_bundle_content))\n  ssh_key_bundle_content = sensitive(lookup(local.ssh_key_bundle, \"content\", null))\n}\n"
  },
  {
    "path": "examples/rms/oke-workers-only/main.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  worker_image_id   = coalesce(var.worker_image_custom_id, var.worker_image_platform_id, \"none\")\n  worker_image_type = contains([\"platform\", \"custom\"], lower(var.worker_image_type)) ? \"custom\" : \"oke\"\n\n  worker_cloud_init = var.worker_cloud_init_configure ? [{\n    content_type = \"text/x-shellscript\",\n    content      = var.worker_pool_mode == \"Node Pool\" ? var.worker_cloud_init_oke : var.worker_cloud_init_byon\n  }] : []\n}\n\nmodule \"oke\" {\n  source    = \"github.com/oracle-terraform-modules/terraform-oci-oke.git?ref=5.x&depth=1\"\n  providers = { oci.home = oci.home }\n\n  # Identity\n  tenancy_id     = var.tenancy_ocid\n  compartment_id = var.compartment_ocid\n\n  create_iam_resources         = true\n  create_iam_autoscaler_policy = var.create_iam_autoscaler_policy ? \"always\" : \"never\"\n  create_iam_worker_policy     = var.create_iam_worker_policy ? \"always\" : \"never\"\n  create_bastion               = false\n  create_operator              = false\n  create_cluster               = false\n\n  # Network\n  create_vcn     = false\n  vcn_id         = var.vcn_id\n  assign_dns     = var.assign_dns\n  worker_nsg_ids = compact([var.worker_nsg_id])\n  pod_nsg_ids    = compact([var.pod_nsg_id])\n\n  subnets = {\n    workers = { create = \"never\", id = var.worker_subnet_id }\n    pods    = { create = \"never\", id = var.pod_subnet_id }\n  }\n\n  nsgs = {\n    workers = { create = \"never\", id = var.worker_nsg_id }\n    pods    = { create = \"never\", id = var.pod_nsg_id }\n  }\n\n  # Cluster\n  cluster_id              = var.cluster_id\n  cni_type                = lower(var.cni_type)\n  control_plane_is_public = false # workers only need private\n\n  # Workers\n  ssh_public_key   = local.ssh_public_key\n  worker_pool_size = var.worker_pool_size\n  worker_pool_mode = lookup({\n    \"Node Pool\"       = \"node-pool\"\n    \"Instances\"       = \"instances\"\n    \"Instance Pool\"   = \"instance-pool\",\n    \"Cluster Network\" = \"cluster-network\",\n  }, var.worker_pool_mode, \"node-pool\")\n\n  worker_image_type       = lower(local.worker_image_type)\n  worker_image_id         = local.worker_image_id\n  worker_image_os         = var.worker_image_os\n  worker_image_os_version = var.worker_image_os_version\n  worker_cloud_init       = local.worker_cloud_init\n\n  worker_shape = {\n    shape            = var.worker_shape\n    ocpus            = var.worker_ocpus\n    memory           = var.worker_memory\n    boot_volume_size = var.worker_boot_volume_size\n  }\n\n  worker_pools = {\n    format(\"%v\", var.worker_pool_name) = {\n      description = lookup({\n        \"Node Pool\"       = \"OKE-managed Node Pool\"\n        \"Instances\"       = \"Self-managed Instances\"\n        \"Instance Pool\"   = \"Self-managed Instance Pool\"\n        \"Cluster Network\" = \"Self-managed Cluster Network\"\n      }, var.worker_pool_mode, \"\")\n    }\n  }\n\n  freeform_tags = {\n    workers = lookup(var.worker_tags, \"freeformTags\", {})\n  }\n\n  defined_tags = {\n    workers = lookup(var.worker_tags, \"definedTags\", {})\n  }\n}\n"
  },
  {
    "path": "examples/rms/oke-workers-only/output.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# Terraform\noutput \"state_id\" { value = module.oke.state_id }\n\n# Network\noutput \"worker_subnet_id\" { value = var.worker_subnet_id }\noutput \"worker_nsg_id\" { value = var.worker_nsg_id }\n\n# Identity\noutput \"dynamic_group_ids\" { value = module.oke.dynamic_group_ids }\noutput \"policy_statements\" { value = module.oke.policy_statements }\noutput \"create_iam_autoscaler_policy\" { value = var.create_iam_autoscaler_policy }\noutput \"create_iam_worker_policy\" { value = var.create_iam_worker_policy }\n\n# Cluster\noutput \"cluster_id\" { value = var.cluster_id }\noutput \"apiserver_private_host\" { value = module.oke.apiserver_private_host }\n\n# Workers\noutput \"worker_pool_name\" { value = var.worker_pool_name }\noutput \"worker_pool_mode\" { value = var.worker_pool_mode }\noutput \"worker_shape\" { value = var.worker_shape }\noutput \"worker_pool_size\" { value = var.worker_pool_size }\noutput \"worker_image_id\" { value = local.worker_image_id }\noutput \"autoscale\" { value = var.autoscale }\n\noutput \"worker_pool_ids\" {\n  value = concat(\n    values(coalesce(module.oke.worker_pool_ids, {})),\n    values(coalesce(module.oke.worker_instance_ids, {})),\n  )\n}\n"
  },
  {
    "path": "examples/rms/oke-workers-only/schema.yaml",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\ntitle: \"OKE: Worker Pool\"\ndescription: Kubernetes worker nodes for an OKE cluster\nschemaVersion: 1.1.0\nversion: \"20230304\"\nlocale: \"en\"\n\nvariableGroups:\n  - title: \"Hidden\"\n    visible: false\n    variables:\n      - api_fingerprint\n      - config_file_profile\n      - current_user_ocid\n      - user_id\n      - tenancy_id\n      - tenancy_ocid\n      - region\n      - kubernetes_version\n      - apiserver_private_host\n      - cluster_ca_cert\n\n  - title: \"Identity\"\n    variables:\n      - compartment_ocid\n      - create_iam_autoscaler_policy\n      - create_iam_worker_policy\n      - use_defined_tags\n      - tag_namespace\n\n  - title: \"Cluster\"\n    variables:\n      - cluster_id\n      - cni_type\n      - kubeproxy_mode\n      - worker_node_labels\n\n  - title: \"Network\"\n    variables:\n      - vcn_id\n      - assign_dns\n      - vcn_dns_label\n      - worker_subnet_id\n      - worker_nsg_id\n      - pod_subnet_id\n      - pod_nsg_id\n\n  - title: \"SSH\"\n    variables:\n      - ssh_public_key\n      - ssh_kms_vault_id\n      - ssh_kms_secret_id\n\n  - title: \"Image\"\n    variables:\n      - worker_image_type\n      - worker_image_os\n      - worker_image_os_version\n      - worker_image_platform_id\n      - worker_image_custom_id\n\n  - title: \"Instances\"\n    variables:\n      - worker_pool_name\n      - worker_pool_mode\n      - worker_shape\n      - worker_pool_size\n      - worker_ocpus\n      - worker_memory\n      - worker_boot_volume_size\n      - worker_block_volume_type\n      - worker_use_encryption\n      - worker_volume_kms_vault_id\n      - worker_volume_kms_key_id\n      - worker_pv_transit_encryption\n      - worker_cloud_init_configure\n      - worker_cloud_init\n      - worker_cloud_init_byon\n      - worker_cloud_init_oke\n      - autoscale\n      - drain\n      - worker_tags\n\nvariables:\n  # Identity\n  current_user_ocid:\n    title: User\n    type: ocid\n    required: true\n  tenancy_ocid:\n    title: Tenancy\n    type: oci:identity:compartment:id\n    required: true\n  compartment_ocid:\n    title: Compartment\n    description: The default compartment for created resources.\n    type: oci:identity:compartment:id\n    required: true\n  region:\n    required: true\n    title: Region\n    type: oci:identity:region:name\n  create_iam_autoscaler_policy:\n    title: Authorize instance(s) to manage pools with Cluster Autoscaler\n    description: |\n      Create the required Identity policy with a dynamic group to authorize pool management by worker nodes for Cluster Autoscaler. See <a href=https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengusingclusterautoscaler.htm>Using the Kubernetes Cluster Autoscaler</a> for more information.\n    type: boolean\n    default: false\n    required: true\n    visible: { not: [autoscale] }\n  create_iam_worker_policy:\n    title: Authorize instance(s) to join the target cluster\n    description: |\n      Create the required Identity policy with a dynamic group to authorize self-managed worker node membership for an OKE cluster, e.g. `Allow dynamic-group ... to {CLUSTER_JOIN} in compartment id ... where { target.cluster.id = '...' }`. See <a href=https://docs.oracle.com/en-us/iaas/Content/Identity/policyreference/contengpolicyreference.htm#Details_for_Container_Engine_for_Kubernetes>OKE Self-managed nodes</a> for more information.\n    type: boolean\n    default: false\n    required: true\n    visible:\n      not:\n        - eq:\n            - worker_pool_mode\n            - Node Pool\n  use_defined_tags:\n    title: Use defined tags\n    default: false\n    type: boolean\n  tag_namespace:\n    title: Tag namespace\n    visible: ${use_defined_tags}\n\n  # VCN\n  vcn_id:\n    title: Virtual Cloud Network\n    type: oci:core:vcn:id\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n  assign_dns:\n    title: Assign DNS records\n    type: boolean\n    default: false\n    required: true\n  worker_subnet_id:\n    title: Worker subnet\n    description: VCN subnet for the primary network interface of created worker node(s).\n    type: oci:core:subnet:id\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n      hidePublicSubnet: false\n      hidePrivateSubnet: false\n      hideRegionalSubnet: false\n      hideAdSubnet: false\n  worker_nsg_id:\n    title: Worker Network Security Group\n    description: Network Security Groups for the created worker node(s), used to configure network access to instances. See <a href=https://docs.oracle.com/en-us/iaas/Content/ContEng/Concepts/contengnetworkconfig.htm#securitylistconfig>Security Rule Configuration in ... Network Security Groups</a> for more information.\n    type: oci:core:nsg:id\n    # additionalProps:\n    #   allowMultiple: true\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n  pod_subnet_id:\n    title: Pod subnet\n    description: VCN subnet for the primary network interface of created worker node(s).\n    type: oci:core:subnet:id\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n      hidePublicSubnet: false\n      hidePrivateSubnet: false\n      hideRegionalSubnet: false\n      hideAdSubnet: false\n  pod_nsg_id:\n    title: Pod Network Security Group\n    description: Network Security Groups for the created worker node(s), used to configure network access to instances. See <a href=https://docs.oracle.com/en-us/iaas/Content/ContEng/Concepts/contengnetworkconfig.htm#securitylistconfig>Security Rule Configuration in ... Network Security Groups</a> for more information.\n    type: oci:core:nsg:id\n    # additionalProps:\n    #   allowMultiple: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vcnId: ${vcn_id}\n\n  # SSH\n  ssh_public_key:\n    title: SSH Public Key\n    type: oci:core:ssh:publickey\n    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})( [^,]*)?)*$\"\n    required: false\n  ssh_kms_vault_id:\n    title: SSH Vault\n    description: The OCI Vault used to encrypt the SSH key pair.\n    type: oci:kms:vault:id\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n  ssh_kms_secret_id:\n    title: SSH Vault secret\n    description: The OCI Vault secret containing the SSH private key.\n    type: oci:kms:secret:id\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vaultId: ${ssh_kms_vault_id}\n\n  # Cluster\n  cluster_id:\n    title: Cluster\n    type: oci:container:cluster:id\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n  cni_type:\n    title: CNI Type\n    description: The CNI type ('Flannel' or 'NPN') of the target OKE cluster.\n    type: enum\n    default: Flannel\n    enum: [Flannel, NPN]\n    allowMultiple: false\n    required: true\n    visible:\n      eq: [worker_pool_mode, Node Pool]\n  apiserver_private_host:\n    title: Cluster private endpoint\n    description: |\n      Private OKE endpoint IP address only - no protocol/port. Retrieve from an existing kubeconfig with: `kubectl config view --raw -o json | jq -rcM '.clusters[0].cluster.server' | cut -d: -f2 | tr -d '/'`\n    type: string\n    required: false\n  cluster_ca_cert:\n    title: Cluster CA certificate\n    description: |\n      Base64+PEM-encoded cluster CA certificate for a trusted connection to the OKE managed control plane. Retrieve from an existing kubeconfig with: `kubectl config view --raw -o json | jq -rcM '.clusters[0].cluster[\"certificate-authority-data\"]'\n    type: text\n    multiline: true\n\n  # Worker\n  worker_pool_name:\n    title: Pool name\n    description: Display name for created worker node resources.\n    type: string\n    default: \"oke-worker\"\n    required: true\n  worker_pool_mode:\n    title: Resource type\n    description: Type of Oracle Cloud Compute resources for the created worker nodes.\n    type: enum\n    default: Instance Pool\n    enum: [Node Pool, Instances, Instance Pool, Cluster Network]\n    required: true\n  worker_pool_size:\n    title: Number of worker nodes\n    type: number\n    default: 1\n    required: true\n  worker_shape:\n    title: Shape\n    # type: oci:core:instanceshapewithflex:name\n    type: oci:core:instanceshape:name\n    default: \"VM.Standard.E4.Flex\"\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n  worker_ocpus:\n    title: OCPUs\n    type: number\n    default: 2\n    required: false\n  worker_memory:\n    title: Memory (GB)\n    type: number\n    default: 16\n    required: false\n  worker_boot_volume_size:\n    title: Boot volume size (GB)\n    type: number\n    required: false\n  worker_image_type:\n    title: Image type\n    description: Whether to use a Platform, OKE, or Custom image for worker nodes.\n    type: enum\n    default: OKE\n    enum: [OKE, Platform, Custom]\n    required: true\n  worker_image_os:\n    title: Operating system\n    type: enum\n    default: \"Oracle Linux\"\n    enum: [\"Oracle Linux\"]\n    required: true\n    visible:\n      not:\n        - eq:\n            - worker_image_type\n            - Custom\n  worker_image_os_version:\n    title: Operating system version\n    type: enum\n    default: \"8\"\n    enum: [\"7.9\", \"8\"]\n    required: true\n    visible:\n      not:\n        - eq:\n            - worker_image_type\n            - Custom\n  worker_image_id:\n    visible: false\n  worker_image_custom_id:\n    title: Image ID\n    type: ocid\n    required: true\n    visible:\n      eq:\n        - worker_image_type\n        - Custom\n  worker_image_platform_id:\n    title: Image\n    type: oci:core:image:id\n    required: true\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      operatingSystem: ${worker_image_os}\n      operatingSystemVersion: ${worker_image_os_version}\n      shape: ${worker_shape_name}\n    visible:\n      eq:\n        - worker_image_type\n        - Platform\n  worker_cloud_init:\n    visible: false\n  worker_cloud_init_configure:\n    type: boolean\n    title: Custom cloud-init\n  worker_cloud_init_byon:\n    title: Cloud-init script\n    type: text\n    multiline: true\n    required: true\n    description: |\n      Custom cloud-init script for worker node startup configuration. Must include the default OKE initialization call to join the cluster and begin operation.\n    visible:\n      and:\n        - worker_cloud_init_configure\n        - not:\n            - eq:\n                - worker_pool_mode\n                - Node Pool\n  worker_cloud_init_oke:\n    title: Cloud-init script\n    type: text\n    multiline: true\n    required: true\n    description: |\n      Custom cloud-init script for self-managed worker node startup configuration. Must uncomment and define the two required parameters and include the default OKE initialization call to join the cluster and begin operation.\n    visible:\n      and:\n        - worker_cloud_init_configure\n        - eq:\n            - worker_pool_mode\n            - Node Pool\n  worker_block_volume_type:\n    title: Block volume type\n    type: enum\n    enum: [Paravirtualized, iSCSI]\n    default: Paravirtualized\n    required: true\n  worker_node_labels:\n    title: Node labels\n    type: map\n    required: false\n  worker_use_encryption:\n    title: KMS volume encryption\n    type: boolean\n    default: false\n    required: true\n  worker_volume_kms_vault_id:\n    title: KMS volume encryption vault\n    description: Vault containing operator volume encryption keys.\n    type: oci:kms:vault:id\n    required: false\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n    visible: worker_use_encryption\n  worker_volume_kms_key_id:\n    title: KMS volume encryption key\n    type: oci:kms:key:id\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n      vaultId: ${worker_volume_kms_vault_id}\n    required: false\n    visible: worker_use_encryption\n  worker_pv_transit_encryption:\n    title: In-transit volume encryption\n    type: boolean\n    default: false\n    visible:\n      eq:\n        - worker_block_volume_type\n        - Paravirtualized\n  kubeproxy_mode:\n    title: Kubeproxy mode\n    type: enum\n    enum: [IPTables, IPVS]\n    default: IPTables\n    required: true\n  worker_tags:\n    title: Tagging\n    type: oci:identity:tag:value\n    required: false\n    description: Tag values for created resources.\n    dependsOn:\n      compartmentId: ${compartment_ocid}\n  autoscale:\n    title: Manage with Cluster Autoscaler\n    description: |\n      Include pool in Dynamic Group for policies required by the Cluster Autoscaler. See <a href=https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengusingclusterautoscaler.htm>Using the Kubernetes Cluster Autoscaler</a> for more information.\n    type: boolean\n    default: false\n    required: true\n    visible:\n      and:\n        - eq: [worker_pool_mode, Node Pool]\n        - not: [create_iam_autoscaler_policy]\n\n  drain:\n    title: Cordon & Drain\n    description: |\n      Move non-Daemonset workloads off of the pool. See also: <a href=https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/>Safely Drain a Node</a>, <a href=https://kubernetes.io/docs/tasks/run-application/configure-pdb/#protecting-an-application-with-a-poddisruptionbudget>Protecting an Application with a PodDisruptionBudget</a>.\n    type: boolean\n    default: false\n    required: true\n\noutputGroups:\n  - title: Identity\n    outputs:\n      - state_id\n      - create_iam_autoscaler_policy\n      - create_iam_worker_policy\n      - dynamic_group_ids\n      - policy_statements\n  - title: Network\n    outputs:\n      - worker_subnet_id\n      - worker_nsg_id\n  - title: Cluster\n    outputs:\n      - cluster_id\n      - apiserver_private_host\n  - title: Workers\n    outputs:\n      - worker_pool_name\n      - worker_pool_ids\n      - worker_pool_mode\n      - worker_pool_size\n      - worker_shape\n      - worker_image_id\n      - autoscale\n\noutputs:\n  state_id:\n    title: Terraform state ID\n    type: copyableString\n  worker_pool_mode:\n    title: Resource type\n    type: string\n  worker_pool_name:\n    title: Pool name\n    type: string\n  worker_pool_size:\n    title: Size\n    type: number\n  cluster_id:\n    title: Cluster\n    type: ocid\n  apiserver_private_host:\n    title: Cluster private endpoint IP\n    type: copyableString\n  dynamic_group_ids:\n    title: Dynamic groups\n    type: list\n  policy_statements:\n    title: Policy statements\n    type: list\n  worker_subnet_id:\n    title: Subnet\n    type: ocid\n  worker_nsg_id:\n    title: Network Security Group\n    type: ocid\n  worker_pool_ids:\n    title: Pool\n    type: list\n  worker_image_id:\n    title: Image\n    type: ocid\n  worker_shape:\n    title: Shape\n    type: string\n  create_iam_autoscaler_policy:\n    title: Create Cluster Autoscaler policy\n    type: boolean\n  create_iam_worker_policy:\n    title: Create self-managed worker policy\n    type: string\n  autoscale:\n    title: Manage with Cluster Autoscaler\n    type: string\n"
  },
  {
    "path": "examples/rms/oke-workers-only/variables.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# Identity\n\n# Automatically populated by Resource Manager\nvariable \"tenancy_ocid\" { type = string }\nvariable \"current_user_ocid\" { type = string }\nvariable \"compartment_ocid\" { type = string }\nvariable \"region\" { type = string }\nvariable \"use_defined_tags\" {\n  default     = false\n  description = \"Add existing tags in the configured namespace to created resources when applicable.\"\n  type        = bool\n}\n\nvariable \"tag_namespace\" {\n  default     = \"oke\"\n  description = \"Tag namespace containing standard tags for resources created by the module: [state_id, role, pool, cluster_autoscaler].\"\n  type        = string\n}\n\nvariable \"create_iam_autoscaler_policy\" { default = false }\nvariable \"create_iam_worker_policy\" { default = false }\nvariable \"autoscale\" { default = false }\n\n# Cluster\n\nvariable \"cluster_id\" {\n  default = null\n  type    = string\n}\nvariable \"cni_type\" { default = \"Flannel\" }\nvariable \"kubernetes_version\" {\n  default = \"v1.32.1\"\n  type    = string\n}\n\n# Worker pools\nvariable \"worker_pool_mode\" {\n  default = \"Instances\"\n  type    = string\n  validation {\n    condition     = contains([\"Node Pool\", \"Instances\", \"Instance Pool\", \"Cluster Network\"], var.worker_pool_mode)\n    error_message = \"Accepted values are Node Pool, Instances, Instance Pool, or Cluster Network\"\n  }\n}\nvariable \"worker_pool_size\" {\n  default = 1\n  type    = number\n}\n\n# Workers: network\n\nvariable \"vcn_id\" {\n  default = null\n  type    = string\n}\nvariable \"assign_dns\" { default = true }\nvariable \"pod_nsg_id\" { default = \"\" }\nvariable \"pod_subnet_id\" { default = \"\" }\nvariable \"worker_nsg_id\" { default = \"\" }\nvariable \"worker_subnet_id\" { type = string }\nvariable \"kubeproxy_mode\" { type = string }\n\n# Workers: instance\n\nvariable \"worker_block_volume_type\" { type = string }\nvariable \"worker_node_labels\" {\n  default = {}\n  type    = map(string)\n}\nvariable \"worker_image_type\" { type = string }\nvariable \"worker_image_id\" {\n  default = null\n  type    = string\n}\nvariable \"worker_image_os\" {\n  default = \"Oracle Linux\"\n  type    = string\n}\nvariable \"worker_image_os_version\" {\n  default = \"8\"\n  type    = string\n}\n\nvariable \"worker_pool_name\" { type = string }\n\nvariable \"worker_shape\" { default = \"VM.Standard.E4.Flex\" }\nvariable \"worker_ocpus\" { default = 2 }\nvariable \"worker_memory\" { default = 16 }\nvariable \"worker_boot_volume_size\" { default = 50 }\nvariable \"worker_pv_transit_encryption\" { default = false }\n\nvariable \"worker_cloud_init_configure\" { type = bool }\nvariable \"worker_cloud_init_oke\" {\n  default = <<-EOT\n  #!/usr/bin/env bash\n  curl --fail -H \"Authorization: Bearer Oracle\" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh\n  bash /etc/oke/oke-install.sh\n  EOT\n  type    = string\n}\nvariable \"worker_cloud_init_byon\" {\n  default = <<-EOT\n  #!/usr/bin/env bash\n  #apiserver_host=\"10.0.0.1\"\n  #ca_base64=\"LS0tLS1...LS0tCg==\" # kubectl config view --raw -o json | jq -rcM '.clusters[0].cluster[\"certificate-authority-data\"]'\n  bash /etc/oke/oke-install.sh --apiserver-endpoint \"$\\{apiserver_host}\" --kubelet-ca-cert \"$\\{ca_base64}\"\n  EOT\n  type    = string\n}\n\nvariable \"worker_volume_kms_key_id\" {\n  default = null\n  type    = string\n}\nvariable \"worker_volume_kms_vault_id\" {\n  default = null\n  type    = string\n}\n\nvariable \"worker_image_platform_id\" {\n  default = null\n  type    = string\n}\nvariable \"worker_image_custom_id\" {\n  default = null\n  type    = string\n}\n\nvariable \"worker_tags\" {\n  default = {}\n  type    = map(any)\n}\n"
  },
  {
    "path": "examples/rms/oke-workers-only/versions.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nterraform {\n  experiments      = [module_variable_optional_attrs]\n  required_version = \">= 1.2.0\"\n\n  required_providers {\n    oci = {\n      configuration_aliases = [oci.home]\n      source                = \"oracle/oci\"\n      version               = \">= 4.119.0\"\n    }\n  }\n}\n\n"
  },
  {
    "path": "examples/utilities/README.md",
    "content": "# Utility Examples\n\nExample configurations for utility features:\n\n| File | Description |\n|------|-------------|\n| `vars-utilities-drain.auto.tfvars` | Worker pool draining configuration |\n| `vars-utilities-ocir.auto.tfvars` | Oracle Container Image Registry (OCIR) secret |\n| `vars-utilities-serviceaccount.auto.tfvars` | Kubernetes service account creation |\n\n## Usage\n\nCopy the desired `.auto.tfvars` file(s) to your root module and adjust the values as needed.\n"
  },
  {
    "path": "examples/workers/README.md",
    "content": "# Worker Examples\n\nExample configurations for various worker pool modes and features:\n\n| File | Description |\n|------|-------------|\n| `vars-workers.auto.tfvars` | Basic worker pool defaults |\n| `vars-workers-basic.auto.tfvars` | Simple node pool |\n| `vars-workers-nodepool.auto.tfvars` | OKE-managed node pool |\n| `vars-workers-virtualnodepool.auto.tfvars` | OKE-managed virtual node pool |\n| `vars-workers-instance.auto.tfvars` | Self-managed compute instance |\n| `vars-workers-instancepool.auto.tfvars` | Self-managed instance pool |\n| `vars-workers-clusternetwork.auto.tfvars` | Cluster network (HPC/GPU with RDMA) |\n| `vars-workers-computecluster.auto.tfvars` | Shared compute cluster |\n| `vars-workers-autoscaling.auto.tfvars` | Autoscaled node pool |\n| `vars-workers-advanced.auto.tfvars` | Advanced configuration options |\n| `vars-workers-agent.auto.tfvars` | Management agent configuration |\n| `vars-workers-cloudinit-global.auto.tfvars` | Global cloud-init for all pools |\n| `vars-workers-cloudinit-pool.auto.tfvars` | Pool-specific cloud-init |\n| `vars-workers-drain.auto.tfvars` | Worker pool draining |\n| `vars-workers-network-nsgs.auto.tfvars` | Custom NSG configuration |\n| `vars-workers-network-subnets.auto.tfvars` | Custom subnet configuration |\n| `vars-workers-network-vnics.auto.tfvars` | Secondary VNIC configuration |\n| `vars-workers-node-cycling.auto.tfvars` | Node cycling for updates |\n\n## Usage\n\nCopy the desired `.auto.tfvars` file(s) to your root module and adjust the values as needed.\n"
  },
  {
    "path": "migration.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# Subnets\n\nmoved {\n  from = module.network.oci_core_subnet.cp\n  to   = module.network.oci_core_subnet.oke[\"cp\"]\n}\nmoved {\n  from = module.bastion[0].oci_core_subnet.bastion\n  to   = module.network.oci_core_subnet.oke[\"bastion\"]\n}\nmoved {\n  from = module.operator[0].oci_core_subnet.operator\n  to   = module.network.oci_core_subnet.oke[\"operator\"]\n}\nmoved {\n  from = module.network.oci_core_subnet.int_lb[0]\n  to   = module.network.oci_core_subnet.oke[\"int_lb\"]\n}\nmoved {\n  from = module.network.oci_core_subnet.pub_lb[0]\n  to   = module.network.oci_core_subnet.oke[\"pub_lb\"]\n}\nmoved {\n  from = module.network.oci_core_subnet.workers\n  to   = module.network.oci_core_subnet.oke[\"workers\"]\n}\nmoved {\n  from = module.network.oci_core_subnet.pods\n  to   = module.network.oci_core_subnet.oke[\"pods\"]\n}\nmoved {\n  from = module.network.oci_core_subnet.fss\n  to   = module.network.oci_core_subnet.oke[\"fss\"]\n}\n\n# Cluster\n\nmoved {\n  from = module.oke.oci_containerengine_cluster.k8s_cluster\n  to   = module.cluster[0].oci_containerengine_cluster.k8s_cluster\n}\n\n# Workers\n\nmoved {\n  from = module.oke.oci_containerengine_node_pool.nodepools\n  to   = module.workers[0].oci_containerengine_node_pool.workers\n}\n\nmoved {\n  from = module.workers[0].oci_containerengine_node_pool.workers\n  to   = module.workers[0].oci_containerengine_node_pool.tfscaled_workers\n}\n\nmoved {\n  from = module.workers[0].oci_core_instance_pool.workers\n  to   = module.workers[0].oci_core_instance_pool.tfscaled_workers\n}"
  },
  {
    "path": "module-bastion.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n// Used to retrieve available bastion images when enabled\ndata \"oci_core_images\" \"bastion\" {\n  count                    = var.create_bastion ? 1 : 0\n  compartment_id           = local.compartment_id\n  operating_system         = var.bastion_image_os\n  operating_system_version = var.bastion_image_os_version\n  shape                    = lookup(var.bastion_shape, \"shape\", \"VM.Standard.E4.Flex\")\n  state                    = \"AVAILABLE\"\n  sort_by                  = \"TIMECREATED\"\n  sort_order               = \"DESC\"\n\n  filter {\n    name   = \"launch_mode\"\n    values = [\"NATIVE\"]\n  }\n}\n\nlocals {\n  bastion_public_ip = (var.create_bastion && length(module.bastion) > 0\n    ? lookup(element(module.bastion, 0), \"public_ip\", var.bastion_public_ip)\n    : var.bastion_public_ip\n  )\n\n  bastion_images    = try(data.oci_core_images.bastion[0].images, tolist([])) # Data source result or empty\n  bastion_image_ids = local.bastion_images[*].id                              # Image OCIDs from data source\n  bastion_image_id = (var.bastion_image_type == \"custom\"\n    ? var.bastion_image_id : element(coalescelist(local.bastion_image_ids, [\"none\"]), 0)\n  )\n\n  # Bastion SSH ProxyCommand argument used in e.g. ssh_to_operator command output if created/provided\n  bastion_ssh_user_ip = join(\"@\", compact([var.bastion_user, local.bastion_public_ip]))\n  bastion_ssh_args    = compact([local.ssh_key_arg, local.bastion_ssh_user_ip])\n  bastion_ssh_command = join(\" \", concat([\"ssh\"], local.bastion_ssh_args))\n  bastion_proxy_command = try((local.bastion_public_ip == null ? []\n    : [\"-o\", format(\"ProxyCommand='ssh -W %%h:%%p %v'\", join(\" \", local.bastion_ssh_args))]\n  ), [])\n}\n\nmodule \"bastion\" {\n  count          = var.create_bastion ? 1 : 0\n  source         = \"./modules/bastion\"\n  state_id       = local.state_id\n  compartment_id = local.compartment_id\n\n  # Bastion\n  await_cloudinit                = var.bastion_await_cloudinit\n  assign_dns                     = var.assign_dns\n  availability_domain            = coalesce(var.bastion_availability_domain, lookup(local.ad_numbers_to_names, local.ad_numbers[0]))\n  bastion_image_os_version       = var.bastion_image_os_version\n  image_id                       = local.bastion_image_id\n  nsg_ids                        = try(compact(flatten([var.bastion_nsg_ids, [try(module.network.bastion_nsg_id, null)]])), [])\n  is_public                      = var.bastion_is_public\n  shape                          = var.bastion_shape\n  legacy_imds_endpoints_disabled = var.bastion_legacy_imds_endpoints_disabled\n  ssh_private_key                = sensitive(local.ssh_private_key) # to await cloud-init completion\n  ssh_public_key                 = local.ssh_public_key\n  subnet_id                      = try(module.network.bastion_subnet_id, \"\") # safe destroy; validated in submodule\n  timezone                       = var.timezone\n  upgrade                        = var.bastion_upgrade\n  user                           = var.bastion_user\n  volume_kms_key_id              = var.bastion_volume_kms_key_id\n\n  # Standard tags as defined if enabled for use, or freeform\n  # User-provided tags are merged last and take precedence\n  use_defined_tags = var.use_defined_tags\n  tag_namespace    = var.tag_namespace\n  defined_tags = merge(var.use_defined_tags ? {\n    \"${var.tag_namespace}.state_id\" = local.state_id,\n    \"${var.tag_namespace}.role\"     = \"bastion\",\n  } : {}, local.bastion_defined_tags)\n  freeform_tags = merge(var.use_defined_tags ? {} : {\n    \"state_id\" = local.state_id,\n    \"role\"     = \"bastion\",\n  }, local.bastion_freeform_tags)\n}\n\noutput \"bastion_id\" {\n  description = \"ID of bastion instance\"\n  value       = one(module.bastion[*].id)\n}\n\noutput \"bastion_public_ip\" {\n  description = \"Public IP address of bastion host\"\n  value       = local.bastion_public_ip\n}\n\noutput \"ssh_to_bastion\" {\n  description = \"SSH command for bastion host\"\n  value       = local.bastion_ssh_command\n}"
  },
  {
    "path": "module-cluster-addons.tf",
    "content": "# Copyright (c) 2017, 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nmodule \"cluster-addons\" {\n  count  = local.cluster_enabled && lower(var.cluster_type) == \"enhanced\" ? 1 : 0\n  source = \"./modules/cluster-addons\"\n\n  operator_enabled = local.operator_enabled\n\n  cluster_addons           = var.cluster_addons\n  cluster_addons_to_remove = var.cluster_addons_to_remove\n\n  cluster_id         = coalesce(var.cluster_id, one(module.cluster[*].cluster_id))\n  kubernetes_version = var.kubernetes_version\n\n  # Bastion/operator connection\n  ssh_private_key = sensitive(local.ssh_private_key)\n  bastion_host    = local.bastion_public_ip\n  bastion_user    = var.bastion_user\n  operator_host   = local.operator_private_ip\n  operator_user   = var.operator_user\n}\n\n\n# output \"supported_addons\" {\n#   description = \"Supported cluster addons\"\n#   value       = var.output_detail ? try(one(module.cluster-addons[*].supported_addons), null) : null\n# }"
  },
  {
    "path": "module-cluster.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# Used to retrieve cluster CA certificate or configure local kube context\n\ndata \"oci_containerengine_clusters\" \"existing_cluster\" {\n  count          = var.cluster_id != null ? 1 : 0\n  compartment_id = local.compartment_id\n\n  state = [\"ACTIVE\", \"UPDATING\"]\n  filter {\n    name   = \"id\"\n    values = [var.cluster_id]\n  }\n}\n\ndata \"oci_containerengine_cluster_kube_config\" \"public\" {\n  count = local.cluster_enabled && local.public_endpoint_available ? 1 : 0\n\n  cluster_id = local.cluster_id\n  endpoint   = \"PUBLIC_ENDPOINT\"\n}\n\ndata \"oci_containerengine_cluster_kube_config\" \"private\" {\n  count = local.cluster_enabled && local.private_endpoint_available ? 1 : 0\n\n  cluster_id = local.cluster_id\n  endpoint   = \"PRIVATE_ENDPOINT\"\n}\n\nlocals {\n  cluster_enabled = var.create_cluster || coalesce(var.cluster_id, \"none\") != \"none\"\n  cluster_id      = var.create_cluster ? one(module.cluster[*].cluster_id) : var.cluster_id\n  cluster_name    = var.cluster_name\n\n  cluster-context = try(format(\"context-%s\", substr(local.cluster_id, -11, -1)), \"\")\n\n  existing_cluster_endpoints = coalesce(one(flatten(data.oci_containerengine_clusters.existing_cluster[*].clusters[*].endpoints)), tomap({}))\n  public_endpoint_available  = var.cluster_id != null ? length(lookup(local.existing_cluster_endpoints, \"public_endpoint\", \"\")) > 0 : var.control_plane_is_public && var.assign_public_ip_to_control_plane\n  private_endpoint_available = var.cluster_id != null ? length(lookup(local.existing_cluster_endpoints, \"private_endpoint\", \"\")) > 0 : true\n  kubeconfig_public          = var.control_plane_is_public ? try(yamldecode(replace(lookup(one(data.oci_containerengine_cluster_kube_config.public), \"content\", \"\"), local.cluster-context, var.cluster_name)), tomap({})) : null\n  kubeconfig_private         = try(yamldecode(replace(lookup(one(data.oci_containerengine_cluster_kube_config.private), \"content\", \"\"), local.cluster-context, var.cluster_name)), tomap({}))\n\n  kubeconfig_clusters = try(lookup(local.kubeconfig_private, \"clusters\", []), [])\n  apiserver_private_host = (var.create_cluster\n    ? try(split(\":\", one(module.cluster[*].endpoints.private_endpoint))[0], \"\")\n  : split(\":\", replace(try(lookup(lookup(local.kubeconfig_clusters[0], \"cluster\", {}), \"server\", \"\"), \"none\"), \"https://\", \"\"))[0])\n\n  kubeconfig_ca_cert = try(lookup(lookup(local.kubeconfig_clusters[0], \"cluster\", {}), \"certificate-authority-data\", \"\"), \"none\")\n  cluster_ca_cert    = coalesce(var.cluster_ca_cert, local.kubeconfig_ca_cert)\n}\n\nmodule \"cluster\" {\n  count          = var.create_cluster ? 1 : 0\n  source         = \"./modules/cluster\"\n  compartment_id = local.compartment_id\n  state_id       = local.state_id\n\n  # Network\n  vcn_id                            = local.vcn_id\n  cni_type                          = var.cni_type\n  control_plane_is_public           = var.control_plane_is_public\n  ip_families                       = length(var.oke_ip_families) > 0 ? var.oke_ip_families :  var.enable_ipv6 ? [\"IPv4\", \"IPv6\"] : [\"IPv4\"] \n  assign_public_ip_to_control_plane = var.assign_public_ip_to_control_plane\n  control_plane_nsg_ids             = compact(flatten([var.control_plane_nsg_ids, try(module.network.control_plane_nsg_id, null)]))\n  control_plane_subnet_id           = try(module.network.control_plane_subnet_id, \"\") # safe destroy; validated in submodule\n  pods_cidr                         = var.pods_cidr\n  services_cidr                     = var.services_cidr\n  service_lb_subnet_id = (var.preferred_load_balancer == \"public\"\n    ? try(module.network.pub_lb_subnet_id, \"\") # safe destroy; validated in submodule\n    : try(module.network.int_lb_subnet_id, \"\")\n  )\n  backend_nsg_ids                   = compact(flatten([\n    var.backend_nsg_ids,\n    try(module.network.worker_nsg_id, null),\n    var.cni_type == \"npn\" ? try(module.network.pod_nsg_id, null) : null\n  ]))\n\n  # Cluster\n  cluster_kms_key_id = var.cluster_kms_key_id\n  cluster_name       = local.cluster_name\n  cluster_type = lookup({\n    \"basic\"    = \"BASIC_CLUSTER\",\n    \"enhanced\" = \"ENHANCED_CLUSTER\"\n  }, lower(var.cluster_type), \"BASIC_CLUSTER\")\n  kubernetes_version = var.kubernetes_version\n\n  # KMS\n  use_signed_images  = var.use_signed_images\n  image_signing_keys = var.image_signing_keys\n\n  # Tags\n  use_defined_tags = var.use_defined_tags\n  tag_namespace    = var.tag_namespace\n\n  # Standard tags as defined if enabled for use, or freeform\n  # User-provided tags are merged last and take precedence\n  cluster_defined_tags = merge(\n    var.use_defined_tags ? {\n      \"${var.tag_namespace}.state_id\" = local.state_id,\n      \"${var.tag_namespace}.role\"     = \"cluster\",\n    } : {},\n    local.cluster_defined_tags,\n  )\n  cluster_freeform_tags = merge(\n    var.use_defined_tags ? {} : {\n      \"state_id\" = local.state_id,\n      \"role\"     = \"cluster\",\n    },\n    local.cluster_freeform_tags,\n  )\n  persistent_volume_defined_tags = merge(\n    var.use_defined_tags ? {\n      \"${var.tag_namespace}.state_id\" = local.state_id,\n      \"${var.tag_namespace}.role\"     = \"persistent_volume\",\n    } : {},\n    local.persistent_volume_defined_tags,\n  )\n  persistent_volume_freeform_tags = merge(\n    var.use_defined_tags ? {} : {\n      \"state_id\" = local.state_id,\n      \"role\"     = \"persistent_volume\",\n    },\n    local.persistent_volume_freeform_tags,\n  )\n  service_lb_defined_tags = merge(\n    var.use_defined_tags ? {\n      \"${var.tag_namespace}.state_id\" = local.state_id,\n      \"${var.tag_namespace}.role\"     = \"service_lb\"\n    } : {},\n    local.service_lb_defined_tags,\n  )\n  service_lb_freeform_tags = merge(\n    var.use_defined_tags ? {} : {\n      \"state_id\" = local.state_id,\n      \"role\"     = \"service_lb\"\n    },\n    local.service_lb_freeform_tags,\n  )\n\n  oidc_discovery_enabled           = var.oidc_discovery_enabled\n  oidc_token_auth_enabled          = var.oidc_token_auth_enabled\n  oidc_token_authentication_config = var.oidc_token_authentication_config\n\n  depends_on = [\n    module.iam_cluster_prerequisites,\n  ]\n}\n\noutput \"cluster_id\" {\n  description = \"ID of the OKE cluster\"\n  value       = one(module.cluster[*].cluster_id)\n}\n\noutput \"cluster_endpoints\" {\n  description = \"Endpoints for the OKE cluster\"\n  value       = var.create_cluster ? one(module.cluster[*].endpoints) : local.existing_cluster_endpoints\n}\n\noutput \"cluster_oidc_discovery_endpoint\" {\n  description = \"OIDC discovery endpoint for the OKE cluster\"\n  value       = var.create_cluster && var.oidc_discovery_enabled ? one(module.cluster[*].oidc_discovery_endpoint) : null\n}\n\noutput \"cluster_kubeconfig\" {\n  description = \"OKE kubeconfig\"\n  value = var.output_detail ? (\n    local.public_endpoint_available ? local.kubeconfig_public : local.kubeconfig_private\n  ) : null\n}\n\noutput \"cluster_ca_cert\" {\n  description = \"OKE cluster CA certificate\"\n  value       = var.output_detail && length(local.cluster_ca_cert) > 0 ? local.cluster_ca_cert : null\n}\n\noutput \"apiserver_private_host\" {\n  description = \"Private OKE cluster endpoint address\"\n  value       = local.apiserver_private_host\n}\n"
  },
  {
    "path": "module-extensions.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  cluster_private_endpoint = (var.create_cluster ?\n    coalesce(split(\":\", lookup(one(module.cluster[*].endpoints), \"private_endpoint\", \"\"))...) :\n    (length(local.existing_cluster_endpoints) > 0 ?\n      coalesce(split(\":\", lookup(local.existing_cluster_endpoints, \"private_endpoint\", \"\"))...) :\n      null\n    )\n  )\n}\n\nmodule \"extensions\" {\n  source     = \"./modules/extensions\"\n  depends_on = [module.network]\n  count      = alltrue([var.create_cluster, local.operator_enabled]) ? 1 : 0\n  region     = var.region\n  state_id   = local.state_id\n\n  # Cluster\n  kubernetes_version       = var.kubernetes_version\n  expected_node_count      = local.worker_count_expected\n  worker_pools             = one(module.workers[*].worker_pools)\n  cluster_private_endpoint = local.cluster_private_endpoint\n\n  # Bastion/operator connection\n  ssh_private_key = sensitive(local.ssh_private_key)\n  bastion_host    = local.bastion_public_ip\n  bastion_user    = var.bastion_user\n  operator_host   = local.operator_private_ip\n  operator_user   = var.operator_user\n\n  # CNI\n  vcn_cidrs = local.vcn_cidrs\n  cni_type  = var.cni_type\n  pods_cidr = var.pods_cidr\n\n  # CNI: Cilium\n  cilium_install           = var.cilium_install\n  cilium_reapply           = var.cilium_reapply\n  cilium_namespace         = var.cilium_namespace\n  cilium_helm_version      = var.cilium_helm_version\n  cilium_helm_values       = var.cilium_helm_values\n  cilium_helm_values_files = var.cilium_helm_values_files\n\n\n  # CNI: Multus\n  multus_install       = var.multus_install\n  multus_namespace     = var.multus_namespace\n  multus_daemonset_url = var.multus_daemonset_url\n  multus_version       = var.multus_version\n\n  # Metrics server\n  metrics_server_install           = var.metrics_server_install\n  metrics_server_namespace         = var.metrics_server_namespace\n  metrics_server_helm_version      = var.metrics_server_helm_version\n  metrics_server_helm_values       = var.metrics_server_helm_values\n  metrics_server_helm_values_files = var.metrics_server_helm_values_files\n\n  # Cluster autoscaler\n  cluster_autoscaler_install           = var.cluster_autoscaler_install\n  cluster_autoscaler_namespace         = var.cluster_autoscaler_namespace\n  cluster_autoscaler_helm_version      = var.cluster_autoscaler_helm_version\n  cluster_autoscaler_helm_values       = var.cluster_autoscaler_helm_values\n  cluster_autoscaler_helm_values_files = var.cluster_autoscaler_helm_values_files\n  expected_autoscale_worker_pools      = coalesce(one(module.workers[*].worker_pool_autoscale_expected), 0)\n\n  # Gatekeeper\n  gatekeeper_install           = var.gatekeeper_install\n  gatekeeper_namespace         = var.gatekeeper_namespace\n  gatekeeper_helm_version      = var.gatekeeper_helm_version\n  gatekeeper_helm_values       = var.gatekeeper_helm_values\n  gatekeeper_helm_values_files = var.gatekeeper_helm_values_files\n\n  # Prometheus\n  prometheus_install           = var.prometheus_install\n  prometheus_reapply           = var.prometheus_reapply\n  prometheus_namespace         = var.prometheus_namespace\n  prometheus_helm_version      = var.prometheus_helm_version\n  prometheus_helm_values       = var.prometheus_helm_values\n  prometheus_helm_values_files = var.prometheus_helm_values_files\n\n  # DCGM exporter\n  dcgm_exporter_install           = var.dcgm_exporter_install\n  dcgm_exporter_reapply           = var.dcgm_exporter_reapply\n  dcgm_exporter_namespace         = var.dcgm_exporter_namespace\n  dcgm_exporter_helm_version      = var.dcgm_exporter_helm_version\n  dcgm_exporter_helm_values       = var.dcgm_exporter_helm_values\n  dcgm_exporter_helm_values_files = var.dcgm_exporter_helm_values_files\n\n  # SR-IOV device plugin\n  sriov_device_plugin_install       = var.sriov_device_plugin_install\n  sriov_device_plugin_namespace     = var.sriov_device_plugin_namespace\n  sriov_device_plugin_daemonset_url = var.sriov_device_plugin_daemonset_url\n  sriov_device_plugin_version       = var.sriov_device_plugin_version\n\n  # SR-IOV CNI plugin\n  sriov_cni_plugin_install       = var.sriov_cni_plugin_install\n  sriov_cni_plugin_namespace     = var.sriov_cni_plugin_namespace\n  sriov_cni_plugin_daemonset_url = var.sriov_cni_plugin_daemonset_url\n  sriov_cni_plugin_version       = var.sriov_cni_plugin_version\n\n  # SR-IOV CNI plugin\n  rdma_cni_plugin_install       = var.rdma_cni_plugin_install\n  rdma_cni_plugin_namespace     = var.rdma_cni_plugin_namespace\n  rdma_cni_plugin_daemonset_url = var.rdma_cni_plugin_daemonset_url\n  rdma_cni_plugin_version       = var.rdma_cni_plugin_version\n\n  # Whereabouts IPAM plugin\n  whereabouts_install       = var.whereabouts_install\n  whereabouts_namespace     = var.whereabouts_namespace\n  whereabouts_daemonset_url = var.whereabouts_daemonset_url\n  whereabouts_version       = var.whereabouts_version\n\n  # MPI operator\n  mpi_operator_install        = var.mpi_operator_install\n  mpi_operator_namespace      = var.mpi_operator_namespace\n  mpi_operator_deployment_url = var.mpi_operator_deployment_url\n  mpi_operator_version        = var.mpi_operator_version\n\n  # Service Account\n  create_service_account = var.create_service_account\n  service_accounts       = var.service_accounts\n\n  # Argocd\n  argocd_install           = var.argocd_install\n  argocd_namespace         = var.argocd_namespace\n  argocd_helm_version      = var.argocd_helm_version\n  argocd_helm_values       = var.argocd_helm_values\n  argocd_helm_values_files = var.argocd_helm_values_files\n}\n"
  },
  {
    "path": "module-iam.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\ndata \"oci_identity_availability_domains\" \"all\" {\n  compartment_id = local.tenancy_id != \"unknown\" ? local.tenancy_id : local.compartment_id\n}\n\nlocals {\n  // Tenancy-specific availability domains in region\n  // Common reference for data source re-used throughout module\n  ads = data.oci_identity_availability_domains.all.availability_domains\n\n  // Map of parsed availability domain numbers to tenancy-specific names\n  // Used by resources with AD placement for generic selection\n  ad_numbers_to_names = local.ads != null ? {\n    for ad in local.ads : parseint(substr(ad.name, -1, -1), 10) => ad.name\n  } : { -1 : \"\" } # Fallback handles failure when unavailable but not required\n\n  // List of availability domain numbers in region\n  // Used to intersect desired AD lists against presence in region\n  ad_numbers = local.ads != null ? sort(keys(local.ad_numbers_to_names)) : []\n\n  create_iam_worker_policy = anytrue([\n    var.create_iam_worker_policy == \"always\",\n    var.create_iam_worker_policy == \"auto\" && var.create_cluster && anytrue([for k, v in var.worker_pools :\n      tobool(lookup(v, \"create\", true)) &&\n      lookup(v, \"mode\", var.worker_pool_mode) != \"node-pool\"\n    ])\n  ])\n\n  create_iam_autoscaler_policy = anytrue([\n    var.create_iam_autoscaler_policy == \"always\",\n    var.create_iam_autoscaler_policy == \"auto\" && var.create_cluster && anytrue([for k, v in var.worker_pools :\n      tobool(lookup(v, \"create\", true)) &&\n      tobool(lookup(v, \"allow_autoscaler\", false))\n    ])\n  ])\n\n  create_iam_operator_policy = anytrue([\n    var.create_iam_operator_policy == \"always\",\n    var.create_iam_operator_policy == \"auto\" && local.operator_enabled\n  ])\n\n  create_iam_kms_policy = anytrue([\n    var.create_iam_kms_policy == \"always\",\n    var.create_iam_kms_policy == \"auto\" && anytrue([\n      # coalesce(var.worker_volume_kms_key_id, \"none\") != \"none\", ## Validated in group-workers.tf in the IAM module.\n      coalesce(var.cluster_kms_key_id, \"none\") != \"none\",\n    ])\n  ])\n  default_policy_name       = format(\"oke-cluster-%v\", local.state_id)\n  prerequisites_policy_name = format(\"oke-cluster-prerequisites-%v\", local.state_id)\n}\n\n# Default IAM sub-module implementation for OKE cluster\nmodule \"iam_cluster_prerequisites\" {\n  source                       = \"./modules/iam\"\n  compartment_id               = local.compartment_id\n  state_id                     = local.state_id\n  tenancy_id                   = local.tenancy_id\n  cluster_id                   = var.cluster_id\n  create_iam_resources         = var.create_iam_resources\n  create_iam_autoscaler_policy = false\n  create_iam_kms_policy        = local.create_iam_kms_policy\n  create_iam_operator_policy   = false\n  create_iam_worker_policy     = false\n  create_iam_cluster_policy    = false\n  policy_name                  = local.prerequisites_policy_name\n\n  create_iam_tag_namespace = var.create_iam_tag_namespace\n  create_iam_defined_tags  = var.create_iam_defined_tags\n  defined_tags             = local.iam_defined_tags\n  freeform_tags            = local.iam_freeform_tags\n  tag_namespace            = var.tag_namespace\n  use_defined_tags         = var.use_defined_tags\n\n  cluster_kms_key_id         = var.cluster_kms_key_id\n  operator_volume_kms_key_id = var.operator_volume_kms_key_id\n  worker_volume_kms_key_id   = var.worker_volume_kms_key_id\n\n  autoscaler_compartments = []\n  worker_compartments     = []\n\n  enable_ipv6            = false\n  network_compartment_id = var.network_compartment_id\n\n  providers = {\n    oci.home = oci.home\n  }\n}\n\n# Default IAM sub-module implementation for OKE cluster\nmodule \"iam\" {\n  source                       = \"./modules/iam\"\n  compartment_id               = local.compartment_id\n  state_id                     = local.state_id\n  tenancy_id                   = local.tenancy_id\n  cluster_id                   = local.cluster_id\n  create_iam_resources         = var.create_iam_resources\n  create_iam_autoscaler_policy = local.create_iam_autoscaler_policy\n  create_iam_kms_policy        = false\n  create_iam_operator_policy   = local.create_iam_operator_policy\n  create_iam_worker_policy     = local.create_iam_worker_policy\n  create_iam_cluster_policy    = true\n  policy_name                  = local.default_policy_name\n\n  create_iam_tag_namespace = var.create_iam_tag_namespace\n  create_iam_defined_tags  = var.create_iam_defined_tags\n  defined_tags             = local.iam_defined_tags\n  freeform_tags            = local.iam_freeform_tags\n  tag_namespace            = var.tag_namespace\n  use_defined_tags         = var.use_defined_tags\n\n  cluster_kms_key_id         = var.cluster_kms_key_id\n  operator_volume_kms_key_id = var.operator_volume_kms_key_id\n  worker_volume_kms_key_id   = var.worker_volume_kms_key_id\n\n  autoscaler_compartments = local.autoscaler_compartments\n  worker_compartments     = local.worker_compartments\n\n  enable_ipv6            = var.enable_ipv6\n  network_compartment_id = var.network_compartment_id\n\n  providers = {\n    oci.home = oci.home\n  }\n}\n\noutput \"availability_domains\" {\n  description = \"Availability domains for tenancy & region\"\n  value       = local.ad_numbers_to_names\n}\n\noutput \"dynamic_group_ids\" {\n  description = \"Cluster IAM dynamic group IDs\"\n  value = concat(\n    coalesce(module.iam_cluster_prerequisites.dynamic_group_ids, []),\n    coalesce(module.iam.dynamic_group_ids, [])\n  )\n}\n\noutput \"policy_statements\" {\n  description = \"Cluster IAM policy statements\"\n  value = concat(\n    coalesce(module.iam_cluster_prerequisites.policy_statements, []),\n    coalesce(module.iam.policy_statements, [])\n  )\n}\n"
  },
  {
    "path": "module-network.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\ndata \"oci_core_vcn\" \"oke\" {\n  count  = var.create_vcn ? 0 : 1\n  vcn_id = coalesce(var.vcn_id, \"none\")\n}\n\nlocals {\n  # Created VCN if enabled, else var.vcn_id\n  vcn_id = var.create_vcn ? try(one(module.vcn[*].vcn_id), var.vcn_id) : var.vcn_id\n\n  # Configured VCN CIDRs if creating, else from provided vcn_id\n  vcn_lookup             = coalesce(one(data.oci_core_vcn.oke[*].cidr_blocks), [])\n  vcn_lookup_cidr_blocks = flatten(local.vcn_lookup)\n  vcn_cidrs              = var.create_vcn ? var.vcn_cidrs : local.vcn_lookup_cidr_blocks\n  vcn_ipv6_cidrs         = var.create_vcn ? concat(module.vcn[0].vcn_all_attributes[\"ipv6cidr_blocks\"], module.vcn[0].vcn_all_attributes[\"byoipv6cidr_blocks\"], module.vcn[0].vcn_all_attributes[\"ipv6private_cidr_blocks\"]) : concat(data.oci_core_vcn.oke[0].ipv6cidr_blocks, data.oci_core_vcn.oke[0].byoipv6cidr_blocks, data.oci_core_vcn.oke[0].ipv6private_cidr_blocks)\n  # Created route table if enabled, else var.ig_route_table_id\n  ig_route_table_id = var.create_vcn ? try(one(module.vcn[*].ig_route_id), var.ig_route_table_id) : var.ig_route_table_id\n\n  # Created route table if enabled, else var.nat_route_table_id\n  nat_route_table_id = var.create_vcn ? try(one(module.vcn[*].nat_route_id), var.ig_route_table_id) : var.nat_route_table_id\n\n  create_internet_gateway = alltrue([\n    var.vcn_create_internet_gateway != \"never\",    # always disable\n    anytrue([                                      # enable for configurations that generally utilize it\n      var.vcn_create_internet_gateway == \"always\", # always enable\n      var.create_bastion && var.bastion_is_public, # enable for public bastion\n      var.control_plane_is_public,                 # enable for cluster w/ public endpoint\n      var.load_balancers != \"internal\",            # enable for cluster w/ public load balancers\n    ])\n  ])\n\n  create_nat_gateway = alltrue([\n    var.vcn_create_nat_gateway != \"never\",                # always disable\n    anytrue([                                             # enable for configurations that generally utilize it\n      var.vcn_create_nat_gateway == \"always\",             # always enable\n      !var.worker_is_public,                              # enable for private workers\n      var.create_operator,                                # enable for operator\n      !var.control_plane_is_public,                       # enable for cluster w/ private endpoint\n      contains([\"internal\", \"both\"], var.load_balancers), # enable for cluster w/ private load balancers\n    ])\n  ])\n\n  internet_gateway_id = var.create_vcn ? try(one(module.vcn[*].internet_gateway_id), var.internet_gateway_id) : var.internet_gateway_id\n  nat_gateway_id      = var.create_vcn ? try(one(module.vcn[*].nat_gateway_id), var.nat_gateway_id) : var.nat_gateway_id\n}\n\nmodule \"vcn\" {\n  count          = var.create_vcn ? 1 : 0\n  source         = \"oracle-terraform-modules/vcn/oci\"\n  version        = \"3.6.0\"\n  compartment_id = coalesce(var.network_compartment_id, local.compartment_id)\n\n  # Standard tags as defined if enabled for use, or freeform\n  # User-provided tags are merged last and take precedence\n  defined_tags = merge(var.use_defined_tags ? {\n    \"${var.tag_namespace}.state_id\" = local.state_id,\n    \"${var.tag_namespace}.role\"     = \"network\",\n    } : {},\n    local.network_defined_tags,\n  )\n  freeform_tags = merge(var.use_defined_tags ? {} : {\n    \"state_id\" = local.state_id,\n    \"role\"     = \"network\",\n    },\n    local.network_freeform_tags,\n  )\n\n  attached_drg_id = var.drg_id != null ? var.drg_id : (tobool(var.create_drg) ? module.drg[0].drg_id : null)\n\n  create_internet_gateway = local.create_internet_gateway\n\n  create_nat_gateway = local.create_nat_gateway\n\n  create_service_gateway       = var.vcn_create_service_gateway != \"never\"\n  internet_gateway_route_rules = var.internet_gateway_route_rules\n  local_peering_gateways       = var.local_peering_gateways\n  lockdown_default_seclist     = var.lockdown_default_seclist\n  nat_gateway_public_ip_id     = var.nat_gateway_public_ip_id\n  nat_gateway_route_rules      = var.nat_gateway_route_rules\n\n  enable_ipv6   = var.enable_ipv6\n  vcn_cidrs     = local.vcn_cidrs\n  vcn_dns_label = var.assign_dns ? coalesce(var.vcn_dns_label, local.state_id) : null\n  vcn_name      = coalesce(var.vcn_name, \"oke-${local.state_id}\")\n}\n\nmodule \"drg\" {\n  count              = tobool(var.create_drg) || var.drg_id != null ? 1 : 0\n  source             = \"oracle-terraform-modules/drg/oci\"\n  version            = \"1.0.6\"\n  compartment_id     = coalesce(var.network_compartment_id, local.compartment_id)\n  drg_compartment_id = var.drg_compartment_id\n\n  drg_id           = one([var.drg_id]) # existing DRG ID or null\n  drg_display_name = coalesce(var.drg_display_name, \"oke-${local.state_id}\")\n  drg_vcn_attachments = tobool(var.create_drg) || var.drg_id != null ? { for k, v in module.vcn : k => {\n    # gets the vcn_id values dynamically from the vcn module \n    vcn_id : v.vcn_id\n    vcn_transit_routing_rt_id : null\n    drg_route_table_id : null\n    }\n  } : var.drg_attachments\n\n  # rpc parameters\n  remote_peering_connections = { for k, v in var.remote_peering_connections : k => {\n    \"rpc_acceptor_id\"     = try(v.rpc_acceptor_id, null),\n    \"rpc_acceptor_region\" = try(v.rpc_acceptor_region, null)\n    }\n  }\n}\n\nmodule \"network\" {\n  source           = \"./modules/network\"\n  state_id         = local.state_id\n  compartment_id   = coalesce(var.network_compartment_id, local.compartment_id)\n  defined_tags     = local.network_defined_tags\n  freeform_tags    = local.network_freeform_tags\n  tag_namespace    = var.tag_namespace\n  use_defined_tags = var.use_defined_tags\n\n  allow_node_port_access       = var.allow_node_port_access\n  allow_pod_internet_access    = var.allow_pod_internet_access\n  allow_rules_cp               = var.allow_rules_cp\n  allow_rules_internal_lb      = var.allow_rules_internal_lb\n  allow_rules_pods             = var.allow_rules_pods\n  allow_rules_public_lb        = var.allow_rules_public_lb\n  allow_rules_workers          = var.allow_rules_workers\n  allow_worker_internet_access = var.allow_worker_internet_access\n  allow_worker_ssh_access      = var.allow_worker_ssh_access\n  allow_bastion_cluster_access = var.allow_bastion_cluster_access\n  assign_dns                   = var.assign_dns\n  bastion_allowed_cidrs        = var.bastion_allowed_cidrs\n  bastion_is_public            = var.bastion_is_public\n  cni_type                     = var.cni_type\n  control_plane_allowed_cidrs  = var.control_plane_allowed_cidrs\n  control_plane_is_public      = var.control_plane_is_public\n  create_cluster               = var.create_cluster\n  create_bastion               = var.create_bastion\n  create_internet_gateway      = local.create_internet_gateway\n  create_nat_gateway           = local.create_nat_gateway\n  enable_ipv6                  = var.enable_ipv6\n  nsgs                         = var.nsgs\n  create_operator              = local.operator_enabled\n  drg_attachments              = var.drg_attachments\n  enable_waf                   = var.enable_waf\n  ig_route_table_id            = local.ig_route_table_id\n  igw_ngw_mixed_route_id       = var.igw_ngw_mixed_route_id\n  internet_gateway_id          = local.internet_gateway_id\n  load_balancers               = var.load_balancers\n  nat_gateway_id               = local.nat_gateway_id\n  nat_route_table_id           = local.nat_route_table_id\n  subnets                      = var.subnets\n  use_stateless_rules          = var.use_stateless_rules\n  vcn_cidrs                    = local.vcn_cidrs\n  vcn_ipv6_cidrs               = local.vcn_ipv6_cidrs\n  vcn_id                       = local.vcn_id\n  worker_is_public             = var.worker_is_public\n}\n\n# VCN\noutput \"vcn_id\" {\n  description = \"VCN ID\"\n  value       = try(local.vcn_id, null)\n}\noutput \"ig_route_table_id\" {\n  description = \"Internet gateway route table ID\"\n  value       = try(local.ig_route_table_id, null)\n}\noutput \"nat_route_table_id\" {\n  description = \"NAT gateway route table ID\"\n  value       = try(local.nat_route_table_id, null)\n}\n\n# Subnets\noutput \"bastion_subnet_id\" {\n  value = try(module.network.bastion_subnet_id, null)\n}\noutput \"bastion_subnet_cidr\" {\n  value = try(module.network.bastion_subnet_cidr, null)\n}\noutput \"operator_subnet_id\" {\n  value = try(module.network.operator_subnet_id, null)\n}\noutput \"operator_subnet_cidr\" {\n  value = try(module.network.operator_subnet_cidr, null)\n}\noutput \"control_plane_subnet_id\" {\n  value = try(module.network.control_plane_subnet_id, null)\n}\noutput \"control_plane_subnet_cidr\" {\n  value = try(module.network.control_plane_subnet_cidr, null)\n}\noutput \"worker_subnet_id\" {\n  value = try(module.network.worker_subnet_id, null)\n}\noutput \"worker_subnet_cidr\" {\n  value = try(module.network.worker_subnet_cidr, null)\n}\noutput \"pod_subnet_id\" {\n  value = try(module.network.pod_subnet_id, null)\n}\noutput \"pod_subnet_cidr\" {\n  value = try(module.network.pod_subnet_cidr, null)\n}\noutput \"int_lb_subnet_id\" {\n  value = try(module.network.int_lb_subnet_id, null)\n}\noutput \"int_lb_subnet_cidr\" {\n  value = try(module.network.int_lb_subnet_cidr, null)\n}\noutput \"pub_lb_subnet_id\" {\n  value = try(module.network.pub_lb_subnet_id, null)\n}\noutput \"pub_lb_subnet_cidr\" {\n  value = try(module.network.pub_lb_subnet_cidr, null)\n}\noutput \"fss_subnet_id\" {\n  value = try(module.network.fss_subnet_id, null)\n}\noutput \"fss_subnet_cidr\" {\n  value = try(module.network.fss_subnet_cidr, null)\n}\n\n# NSGs\noutput \"bastion_nsg_id\" {\n  description = \"Network Security Group for bastion host(s).\"\n  value       = try(module.network.bastion_nsg_id, null)\n}\noutput \"operator_nsg_id\" {\n  description = \"Network Security Group for operator host(s).\"\n  value       = try(module.network.operator_nsg_id, null)\n}\noutput \"control_plane_nsg_id\" {\n  description = \"Network Security Group for Kubernetes control plane(s).\"\n  value       = try(module.network.control_plane_nsg_id, null)\n}\noutput \"int_lb_nsg_id\" {\n  description = \"Network Security Group for internal load balancers.\"\n  value       = try(module.network.int_lb_nsg_id, null)\n}\noutput \"pub_lb_nsg_id\" {\n  description = \"Network Security Group for public load balancers.\"\n  value       = try(module.network.pub_lb_nsg_id, null)\n}\noutput \"worker_nsg_id\" {\n  description = \"Network Security Group for worker nodes.\"\n  value       = try(module.network.worker_nsg_id, null)\n}\noutput \"pod_nsg_id\" {\n  description = \"Network Security Group for pods.\"\n  value       = try(module.network.pod_nsg_id, null)\n}\noutput \"fss_nsg_id\" {\n  description = \"Network Security Group for File Storage Service resources.\"\n  value       = try(module.network.fss_nsg_id, null)\n}\n\noutput \"network_security_rules\" {\n  value = var.output_detail ? try(module.network.network_security_rules, null) : null\n}\n\n# DRG\noutput \"drg_id\" {\n  description = \"Dynamic routing gateway ID\"\n  value       = try(one(module.drg[*].drg_id), null)\n}\n\n# LPG\noutput \"lpg_all_attributes\" {\n  description = \"all attributes of created lpg\"\n  value       = try(one(module.vcn[*].lpg_all_attributes), null)\n}"
  },
  {
    "path": "module-operator.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n// Used to retrieve available operator images when enabled\ndata \"oci_core_images\" \"operator\" {\n  count                    = var.create_operator ? 1 : 0\n  compartment_id           = local.compartment_id\n  operating_system         = var.operator_image_os\n  operating_system_version = var.operator_image_os_version\n  shape                    = lookup(var.operator_shape, \"shape\", \"VM.Standard.E4.Flex\")\n  state                    = \"AVAILABLE\"\n  sort_by                  = \"TIMECREATED\"\n  sort_order               = \"DESC\"\n\n  filter {\n    name   = \"launch_mode\"\n    values = [\"NATIVE\"]\n  }\n}\n\nlocals {\n  // The private IP of the operator instance, whether created in this TF state or existing provided by ID\n  operator_private_ip = (local.cluster_enabled && var.create_operator && length(module.operator) > 0\n    ? lookup(element(module.operator, 0), \"private_ip\", var.operator_private_ip)\n    : var.operator_private_ip\n  )\n\n  // Whether the operator is enabled, i.e. created in this TF state or existing provided by ID\n  operator_enabled = anytrue([\n    (local.cluster_enabled || coalesce(var.cluster_id, \"none\") != \"none\"),\n    (var.create_operator || coalesce(var.operator_private_ip, \"none\") != \"none\"),\n  ])\n\n  // The resolved image ID for the created operator instance\n  operator_images    = try(data.oci_core_images.operator[0].images, tolist([])) # Data source result or empty\n  operator_image_ids = local.operator_images[*].id                              # Image OCIDs from data source\n  operator_image_id = (var.operator_image_type == \"custom\"\n    ? var.operator_image_id : element(coalescelist(local.operator_image_ids, [\"none\"]), 0)\n  )\n\n  # Operator SSH command args for.ssh_to_operator output if created/provided\n  operator_ssh_user_ip = join(\"@\", compact([var.operator_user, local.operator_private_ip]))\n  operator_ssh_args    = compact([local.ssh_key_arg, local.operator_ssh_user_ip])\n}\n\nmodule \"operator\" {\n  count          = var.create_operator ? 1 : 0\n  source         = \"./modules/operator\"\n  state_id       = local.state_id\n  compartment_id = local.compartment_id\n\n  # Bastion (to await cloud-init completion)\n  bastion_host = local.bastion_public_ip\n  bastion_user = var.bastion_user\n\n  # Operator\n  await_cloudinit                = var.operator_await_cloudinit\n  assign_dns                     = var.assign_dns\n  availability_domain            = coalesce(var.operator_availability_domain, lookup(local.ad_numbers_to_names, local.ad_numbers[0]))\n  cloud_init                     = var.operator_cloud_init\n  image_id                       = local.operator_image_id\n  install_cilium                 = var.cilium_install\n  install_helm                   = var.operator_install_helm\n  install_helm_from_repo         = var.operator_install_helm_from_repo\n  install_oci_cli_from_repo      = var.operator_install_oci_cli_from_repo\n  install_istioctl               = var.operator_install_istioctl\n  install_k8sgpt                 = var.operator_install_k8sgpt\n  install_k9s                    = var.operator_install_k9s\n  install_kubectx                = var.operator_install_kubectx\n  install_kubectl_from_repo      = var.operator_install_kubectl_from_repo\n  install_stern                  = var.operator_install_stern\n  kubeconfig                     = yamlencode(local.kubeconfig_private)\n  kubernetes_version             = var.kubernetes_version\n  nsg_ids                        = compact(flatten([var.operator_nsg_ids, try(module.network.operator_nsg_id, null)]))\n  operator_image_os_version      = var.operator_image_os_version\n  pv_transit_encryption          = var.operator_pv_transit_encryption\n  shape                          = var.operator_shape\n  legacy_imds_endpoints_disabled = var.operator_legacy_imds_endpoints_disabled\n  ssh_private_key                = sensitive(local.ssh_private_key) # to await cloud-init completion\n  ssh_public_key                 = local.ssh_public_key\n  subnet_id                      = try(module.network.operator_subnet_id, \"\") # safe destroy; validated in submodule\n  timezone                       = var.timezone\n  upgrade                        = var.operator_upgrade\n  user                           = var.operator_user\n  volume_kms_key_id              = var.operator_volume_kms_key_id\n\n\n  # Standard tags as defined if enabled for use, or freeform\n  # User-provided tags are merged last and take precedence\n  defined_tags = merge(var.use_defined_tags ? {\n    \"${var.tag_namespace}.state_id\" = local.state_id,\n    \"${var.tag_namespace}.role\"     = \"operator\",\n  } : {}, local.operator_defined_tags)\n  freeform_tags = merge(var.use_defined_tags ? {} : {\n    \"state_id\" = local.state_id,\n    \"role\"     = \"operator\",\n  }, local.operator_freeform_tags)\n  use_defined_tags = var.use_defined_tags\n  tag_namespace    = var.tag_namespace\n\n  depends_on = [\n    module.iam,\n  ]\n}\n\noutput \"operator_id\" {\n  description = \"ID of operator instance\"\n  value       = one(module.operator[*].id)\n}\n\noutput \"operator_private_ip\" {\n  description = \"Private IP address of operator host\"\n  value       = local.operator_private_ip\n}\n\noutput \"ssh_to_operator\" {\n  description = \"SSH command for operator host\"\n  value = local.operator_enabled ? join(\" \", concat([\"ssh\"],\n    local.bastion_proxy_command, local.operator_ssh_args)\n  ) : null\n}"
  },
  {
    "path": "module-utilities.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nmodule \"utilities\" {\n  count  = local.cluster_enabled && local.operator_enabled ? 1 : 0\n  source = \"./modules/utilities\"\n  region = var.region\n\n  # Cluster\n  await_node_readiness = var.await_node_readiness\n  expected_node_count  = local.worker_count_expected\n  worker_pools         = one(module.workers[*].worker_pools)\n\n  # Bastion/operator connection\n  ssh_private_key = sensitive(local.ssh_private_key)\n  bastion_host    = local.bastion_public_ip\n  bastion_user    = var.bastion_user\n  operator_host   = local.operator_private_ip\n  operator_user   = var.operator_user\n\n  # OCIR\n  ocir_email_address    = var.ocir_email_address\n  ocir_secret_id        = var.ocir_secret_id\n  ocir_secret_name      = var.ocir_secret_name\n  ocir_secret_namespace = var.ocir_secret_namespace\n  ocir_username         = var.ocir_username\n\n  # Worker pool draining\n  expected_drain_count           = local.worker_drain_expected\n  worker_drain_delete_local_data = var.worker_drain_delete_local_data\n  worker_drain_ignore_daemonsets = var.worker_drain_ignore_daemonsets\n  worker_drain_timeout_seconds   = var.worker_drain_timeout_seconds\n}\n"
  },
  {
    "path": "module-workers.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  worker_count_expected = coalesce(one(module.workers[*].worker_count_expected), 0)\n  worker_drain_expected = coalesce(one(module.workers[*].worker_drain_expected), 0)\n\n  # Distinct list of compartments for enabled worker pools\n  worker_compartments = distinct(compact([\n    for k, v in var.worker_pools : lookup(v, \"compartment_id\", local.compartment_id)\n    if tobool(lookup(v, \"create\", true))\n  ]))\n\n  # Worker pools with cluster autoscaler management enabled\n  autoscaler_compartments = distinct(compact([\n    for k, v in var.worker_pools : lookup(v, \"compartment_id\", local.compartment_id)\n    if tobool(lookup(v, \"create\", true)) && tobool(lookup(v, \"allow_autoscaler\", false))\n  ]))\n}\n\n# Default workers sub-module implementation for OKE cluster\nmodule \"workers\" {\n  count  = local.cluster_enabled ? 1 : 0\n  source = \"./modules/workers\"\n\n  # Common\n  compartment_id      = local.worker_compartment_id\n  tenancy_id          = local.tenancy_id\n  state_id            = local.state_id\n  ad_numbers          = local.ad_numbers\n  ad_numbers_to_names = local.ad_numbers_to_names\n\n  # Cluster\n  apiserver_private_host            = local.apiserver_private_host\n  cluster_ca_cert                   = local.cluster_ca_cert\n  cluster_dns                       = var.cluster_dns\n  cluster_id                        = coalesce(var.cluster_id, one(module.cluster[*].cluster_id))\n  cluster_type                      = var.cluster_type\n  kubernetes_version                = var.kubernetes_version\n  allow_short_container_image_names = var.allow_short_container_image_names\n\n  # Compute clusters\n  compute_clusters = var.worker_compute_clusters\n\n  # GPU memory cluster scale config defaults\n  gmc_scale_is_upsize_enabled   = var.worker_gmc_scale_is_upsize_enabled\n  gmc_scale_is_downsize_enabled = var.worker_gmc_scale_is_downsize_enabled\n  gmc_scale_target_size         = var.worker_gmc_scale_target_size\n\n  # Worker pools\n  worker_pool_mode = var.worker_pool_mode\n  worker_pool_size = var.worker_pool_size\n  worker_pools     = var.worker_pools\n\n  # Workers\n  assign_dns                     = var.assign_dns\n  assign_public_ip               = var.worker_is_public\n  block_volume_type              = var.worker_block_volume_type\n  capacity_reservation_id        = var.worker_capacity_reservation_id\n  cloud_init                     = var.worker_cloud_init\n  disable_default_cloud_init     = var.worker_disable_default_cloud_init\n  cni_type                       = var.cni_type\n  image_id                       = var.worker_image_id\n  image_ids                      = local.image_ids\n  image_os                       = var.worker_image_os\n  image_os_version               = var.worker_image_os_version\n  image_type                     = var.worker_image_type\n  indexed_images                 = local.indexed_images\n  kubeproxy_mode                 = var.kubeproxy_mode\n  legacy_imds_endpoints_disabled = var.worker_legacy_imds_endpoints_disabled\n  max_pods_per_node              = var.max_pods_per_node\n  node_labels                    = alltrue([var.cluster_type == \"basic\", var.cilium_install == true]) ? merge(var.worker_node_labels, { \"oci.oraclecloud.com/custom-k8s-networking\" = true }) : var.worker_node_labels\n  node_metadata                  = var.worker_node_metadata\n  agent_config                   = var.agent_config\n  platform_config                = var.platform_config\n  pod_nsg_ids                    = concat(var.pod_nsg_ids, var.cni_type == \"npn\" ? [try(module.network.pod_nsg_id, null)] : [])\n  pod_subnet_id                  = try(module.network.pod_subnet_id, \"\") # safe destroy; validated in submodule\n  pv_transit_encryption          = var.worker_pv_transit_encryption\n  shape                          = var.worker_shape\n  ssh_public_key                 = local.ssh_public_key\n  timezone                       = var.timezone\n  volume_kms_key_id              = var.worker_volume_kms_key_id\n  worker_nsg_ids                 = concat(var.worker_nsg_ids, [try(module.network.worker_nsg_id, null)])\n  worker_subnet_id               = try(module.network.worker_subnet_id, \"\") # safe destroy; validated in submodule\n  preemptible_config             = var.worker_preemptible_config\n  enable_ipv6                    = var.enable_ipv6\n\n  # Tagging\n  tag_namespace    = var.tag_namespace\n  defined_tags     = local.workers_defined_tags\n  freeform_tags    = local.workers_freeform_tags\n  use_defined_tags = var.use_defined_tags\n\n  depends_on = [\n    module.iam,\n  ]\n}\n\noutput \"worker_pools\" {\n  description = \"Created worker pools (mode != 'instance')\"\n  value       = var.output_detail && local.worker_count_expected > 0 ? try(one(module.workers[*].worker_pools), null) : null\n}\n\noutput \"worker_instances\" {\n  description = \"Created worker pools (mode == 'instance')\"\n  value       = var.output_detail && local.worker_count_expected > 0 ? try(one(module.workers[*].worker_instances), null) : null\n}\n\noutput \"worker_pool_ids\" {\n  description = \"Enabled worker pool IDs\"\n  value       = local.worker_count_expected > 0 ? try(one(module.workers[*].worker_pool_ids), null) : null\n}\n\noutput \"worker_pool_ips\" {\n  description = \"Created worker instance private IPs by pool for available modes ('node-pool', 'instance').\"\n  value       = local.worker_count_expected > 0 ? try(one(module.workers[*].worker_pool_ips), null) : null\n}\n\noutput \"worker_gpu_memory_clusters\" {\n  description = \"Created GPU Memory Clusters keyed by '<pool_name>###<gpu_memory_fabric_id>'.\"\n  value       = var.output_detail && local.worker_count_expected > 0 ? try(one(module.workers[*].worker_gpu_memory_clusters), null) : null\n}\n\noutput \"worker_gpu_memory_cluster_ids\" {\n  description = \"OCIDs of created GPU Memory Clusters keyed by '<pool_name>###<gpu_memory_fabric_id>'.\"\n  value       = local.worker_count_expected > 0 ? try(one(module.workers[*].worker_gpu_memory_cluster_ids), null) : null\n}\n"
  },
  {
    "path": "modules/bastion/README.md",
    "content": "# Bastion\n\nThis sub-module creates a bastion host in a public subnet for SSH access into the VCN.\n\n## Usage\n\nRefer to the [Bastion section](../../docs/terraformoptions.md#bastion) of the module documentation.\n"
  },
  {
    "path": "modules/bastion/cloudinit.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/cloudinit_config.html\ndata \"cloudinit_config\" \"bastion\" {\n  gzip          = true\n  base64_encode = true\n\n  part {\n    content_type = \"text/cloud-config\"\n    # https://cloudinit.readthedocs.io/en/latest/reference/examples.html#run-commands-on-first-boot\n    content = <<-EOT\n    runcmd:\n    - ${format(\"dnf config-manager --disable ol%v_addons --disable ol%v_appstream\", var.bastion_image_os_version, var.bastion_image_os_version)}\n    EOT\n  }\n\n  part {\n    content_type = \"text/cloud-config\"\n    # https://cloudinit.readthedocs.io/en/latest/reference/modules.html#package-update-upgrade-install\n    content  = jsonencode({ package_upgrade = var.upgrade })\n    filename = \"10-packages.yml\"\n  }\n\n  part {\n    content_type = \"text/cloud-config\"\n    # https://cloudinit.readthedocs.io/en/latest/reference/modules.html#timezone\n    content  = jsonencode({ timezone = var.timezone })\n    filename = \"10-timezone.yml\"\n  }\n\n  part {\n    content_type = \"text/cloud-config\"\n    # https://cloudinit.readthedocs.io/en/latest/reference/modules.html#package-update-upgrade-install\n    content  = jsonencode({ users = [\"default\", var.user] })\n    filename = \"10-user.yml\"\n  }\n}\n\nresource \"null_resource\" \"await_cloudinit\" {\n  count = var.await_cloudinit ? 1 : 0\n  connection {\n    host        = oci_core_instance.bastion.public_ip\n    user        = var.user\n    private_key = var.ssh_private_key\n    timeout     = \"40m\"\n    type        = \"ssh\"\n  }\n\n  lifecycle {\n    replace_triggered_by = [oci_core_instance.bastion]\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\"cloud-init status --wait &> /dev/null\"]\n  }\n}"
  },
  {
    "path": "modules/bastion/compute.tf",
    "content": "# Copyright (c) 2019, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  boot_volume_size = tonumber(lookup(var.shape, \"boot_volume_size\", 50))\n  memory           = tonumber(lookup(var.shape, \"memory\", 4))\n  ocpus            = max(1, tonumber(lookup(var.shape, \"ocpus\", 1)))\n  shape            = lookup(var.shape, \"shape\", \"VM.Standard.E4.Flex\")\n\n  baseline_ocpu_utilization_map = {\n    \"12.5\" = \"BASELINE_1_8\"\n    \"50\"   = \"BASELINE_1_2\"\n    \"100\"  = \"BASELINE_1_1\"\n  }\n  baseline_ocpu_utilization = lookup(local.baseline_ocpu_utilization_map, lookup(var.shape, \"baseline_ocpu_utilization\", \"100\"))\n}\n\noutput \"id\" {\n  value = oci_core_instance.bastion.id\n}\n\noutput \"public_ip\" {\n  value = oci_core_instance.bastion.public_ip\n}\n\nresource \"oci_core_instance\" \"bastion\" {\n  availability_domain = var.availability_domain\n  compartment_id      = var.compartment_id\n  display_name        = \"bastion-${var.state_id}\"\n  defined_tags        = var.defined_tags\n  freeform_tags       = var.freeform_tags\n  shape               = lookup(var.shape, \"shape\")\n\n  agent_config {\n    are_all_plugins_disabled = false\n    is_management_disabled   = false\n    is_monitoring_disabled   = false\n\n    plugins_config {\n      desired_state = \"DISABLED\"\n      name          = \"Bastion\"\n    }\n  }\n\n  create_vnic_details {\n    assign_public_ip = var.is_public\n    display_name     = \"bastion-${var.state_id}\"\n    hostname_label   = var.assign_dns ? \"b-${var.state_id}\" : null\n    nsg_ids          = var.nsg_ids\n    subnet_id        = var.subnet_id\n  }\n\n  instance_options {\n    are_legacy_imds_endpoints_disabled = var.legacy_imds_endpoints_disabled\n  }\n\n  metadata = {\n    ssh_authorized_keys = var.ssh_public_key\n    user_data           = data.cloudinit_config.bastion.rendered\n  }\n\n  dynamic \"shape_config\" {\n    for_each = length(regexall(\"Flex\", local.shape)) > 0 ? [1] : []\n    content {\n      baseline_ocpu_utilization = local.baseline_ocpu_utilization\n      ocpus                     = local.ocpus\n      memory_in_gbs             = (local.memory / local.ocpus) > 64 ? (local.ocpus * 4) : local.memory\n    }\n  }\n\n  source_details {\n    boot_volume_size_in_gbs = local.boot_volume_size\n    source_id               = var.image_id\n    source_type             = \"image\"\n    kms_key_id              = var.volume_kms_key_id\n  }\n\n  lifecycle {\n    ignore_changes = [\n      availability_domain,\n      defined_tags, freeform_tags, display_name,\n      create_vnic_details, metadata, source_details,\n    ]\n\n    precondition {\n      condition     = coalesce(var.image_id, \"none\") != \"none\"\n      error_message = \"Missing image_id for bastion. Check provided value for image_id if image_type is 'custom', or image_os/image_os_version if image_type is 'platform'.\"\n    }\n  }\n\n  timeouts {\n    create = \"60m\"\n  }\n}\n"
  },
  {
    "path": "modules/bastion/variables.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\r\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\r\n\r\n# Common\r\nvariable \"compartment_id\" { type = string }\r\nvariable \"state_id\" { type = string }\r\n\r\n# Bastion\r\nvariable \"await_cloudinit\" { type = string }\r\nvariable \"assign_dns\" { type = bool }\r\nvariable \"availability_domain\" { type = string }\r\nvariable \"bastion_image_os_version\" { type = string }\r\nvariable \"image_id\" { type = string }\r\nvariable \"is_public\" { type = bool }\r\nvariable \"nsg_ids\" { type = list(string) }\r\nvariable \"shape\" { type = map(any) }\r\nvariable \"legacy_imds_endpoints_disabled\" {\r\n  type    = bool\r\n  default = true\r\n}\r\nvariable \"ssh_private_key\" {\r\n  type      = string\r\n  sensitive = true\r\n}\r\nvariable \"ssh_public_key\" { type = string }\r\nvariable \"subnet_id\" { type = string }\r\nvariable \"timezone\" { type = string }\r\nvariable \"upgrade\" { type = bool }\r\nvariable \"user\" { type = string }\r\nvariable \"volume_kms_key_id\" { type = string }\r\n\r\n# Tags\r\nvariable \"defined_tags\" { type = map(string) }\r\nvariable \"freeform_tags\" { type = map(string) }\r\nvariable \"tag_namespace\" { type = string }\r\nvariable \"use_defined_tags\" { type = bool }"
  },
  {
    "path": "modules/bastion/versions.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nterraform {\n  required_version = \">= 1.2.0\"\n\n  required_providers {\n    cloudinit = {\n      source  = \"hashicorp/cloudinit\"\n      version = \">= 2.2.0\"\n    }\n\n    null = {\n      source  = \"hashicorp/null\"\n      version = \">= 3.2.1\"\n    }\n\n    oci = {\n      source  = \"oracle/oci\"\n      version = \">= 7.30.0\"\n    }\n  }\n}\n"
  },
  {
    "path": "modules/cluster/README.md",
    "content": "# Cluster\n\nThis sub-module creates an OKE cluster with configurable CNI, Kubernetes version, and OIDC authentication.\n\n## Usage\n\nRefer to the [Cluster section](../../docs/terraformoptions.md#cluster) of the module documentation.\n"
  },
  {
    "path": "modules/cluster/cluster.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nresource \"oci_containerengine_cluster\" \"k8s_cluster\" {\n  compartment_id     = var.compartment_id\n  kms_key_id         = coalesce(var.cluster_kms_key_id, \"none\") != \"none\" ? var.cluster_kms_key_id : null\n  kubernetes_version = var.kubernetes_version\n  name               = var.cluster_name\n  type               = var.cluster_type\n  defined_tags       = var.cluster_defined_tags\n  freeform_tags      = var.cluster_freeform_tags\n  vcn_id             = var.vcn_id\n\n  cluster_pod_network_options {\n    cni_type = var.cni_type == \"flannel\" ? \"FLANNEL_OVERLAY\" : \"OCI_VCN_IP_NATIVE\"\n  }\n\n  endpoint_config {\n    is_public_ip_enabled = var.control_plane_is_public && var.assign_public_ip_to_control_plane\n    nsg_ids              = var.control_plane_nsg_ids\n    subnet_id            = var.control_plane_subnet_id\n  }\n\n  dynamic \"image_policy_config\" {\n    for_each = var.use_signed_images ? [1] : []\n\n    content {\n      is_policy_enabled = true\n\n      dynamic \"key_details\" {\n        iterator = signing_keys_iterator\n        for_each = var.image_signing_keys\n\n        content {\n          kms_key_id = signing_keys_iterator.value\n        }\n      }\n    }\n  }\n\n  options {\n\n    dynamic \"open_id_connect_token_authentication_config\" {\n      for_each = var.oidc_token_auth_enabled ? [1] : []\n\n      content {\n        is_open_id_connect_auth_enabled = var.oidc_token_auth_enabled\n\n\n        issuer_url         = lookup(var.oidc_token_authentication_config, \"issuer_url\", null)\n        ca_certificate     = lookup(var.oidc_token_authentication_config, \"ca_certificate\", null)\n        client_id          = lookup(var.oidc_token_authentication_config, \"client_id\", null)\n        signing_algorithms = lookup(var.oidc_token_authentication_config, \"signing_algorithms\", null)\n\n        groups_claim  = lookup(var.oidc_token_authentication_config, \"groups_claim\", null)\n        groups_prefix = lookup(var.oidc_token_authentication_config, \"groups_prefix\", null)\n\n        username_claim  = lookup(var.oidc_token_authentication_config, \"username_claim\", null)\n        username_prefix = lookup(var.oidc_token_authentication_config, \"username_prefix\", null)\n\n        dynamic \"required_claims\" {\n          for_each = lookup(var.oidc_token_authentication_config, \"required_claims\", [])\n          content {\n            key   = lookup(required_claims.value, \"key\")\n            value = lookup(required_claims.value, \"value\")\n          }\n        }\n        configuration_file = lookup(var.oidc_token_authentication_config, \"configuration_file\", null)\n      }\n    }\n\n    dynamic \"open_id_connect_discovery\" {\n      for_each = var.oidc_discovery_enabled ? [1] : []\n      content {\n        is_open_id_connect_discovery_enabled = var.oidc_discovery_enabled\n      }\n    }\n\n\n\n    kubernetes_network_config {\n      pods_cidr     = var.pods_cidr\n      services_cidr = var.services_cidr\n    }\n\n    persistent_volume_config {\n      defined_tags  = var.persistent_volume_defined_tags\n      freeform_tags = var.persistent_volume_freeform_tags\n    }\n\n    service_lb_config {\n      backend_nsg_ids = var.backend_nsg_ids\n      defined_tags    = var.service_lb_defined_tags\n      freeform_tags   = var.service_lb_freeform_tags\n    }\n\n    service_lb_subnet_ids = compact([var.service_lb_subnet_id])\n    ip_families           = var.ip_families\n  }\n\n  timeouts {\n    update = \"120m\"\n  }\n\n  lifecycle {\n    ignore_changes = [\n      defined_tags,\n      options[0].kubernetes_network_config\n    ]\n\n    precondition {\n      condition     = !var.use_signed_images || length(var.image_signing_keys) > 0\n      error_message = \"Must provide at least 1 image signing key when use_signed_images is enabled.\"\n    }\n\n    precondition {\n      condition     = var.service_lb_subnet_id != null\n      error_message = <<-EOT\n      Must have a service load balancer subnet ID for the preferred load balancer type.\n        control_plane_is_public: ${coalesce(var.control_plane_is_public, \"none\")}\n        service_lb_subnet_id: ${coalesce(var.service_lb_subnet_id, \"none\")}\n      EOT\n    }\n  }\n}\n"
  },
  {
    "path": "modules/cluster/outputs.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\noutput \"cluster_id\" {\n  value = oci_containerengine_cluster.k8s_cluster.id\n}\n\noutput \"endpoints\" {\n  value = one(oci_containerengine_cluster.k8s_cluster.endpoints)\n}\n\noutput \"oidc_discovery_endpoint\" {\n  value = oci_containerengine_cluster.k8s_cluster.open_id_connect_discovery_endpoint\n}"
  },
  {
    "path": "modules/cluster/variables.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# Common\nvariable \"compartment_id\" { type = string }\nvariable \"state_id\" { type = string }\n\n# Cluster\nvariable \"cluster_kms_key_id\" { type = string }\nvariable \"cluster_name\" { type = string }\nvariable \"cluster_type\" { type = string }\nvariable \"cni_type\" { type = string }\nvariable \"ip_families\" { type = list(string) }\nvariable \"control_plane_is_public\" { type = bool }\nvariable \"control_plane_nsg_ids\" { type = set(string) }\nvariable \"assign_public_ip_to_control_plane\" { type = bool }\nvariable \"control_plane_subnet_id\" { type = string }\nvariable \"image_signing_keys\" { type = set(string) }\nvariable \"kubernetes_version\" { type = string }\nvariable \"pods_cidr\" { type = string }\nvariable \"service_lb_subnet_id\" { type = string }\nvariable \"services_cidr\" { type = string }\nvariable \"tag_namespace\" { type = string }\nvariable \"use_defined_tags\" { type = string }\nvariable \"use_signed_images\" { type = bool }\nvariable \"vcn_id\" { type = string }\nvariable \"backend_nsg_ids\" { type = set(string) }\n\n# Tagging\nvariable \"cluster_defined_tags\" { type = map(string) }\nvariable \"cluster_freeform_tags\" { type = map(string) }\nvariable \"persistent_volume_defined_tags\" { type = map(string) }\nvariable \"persistent_volume_freeform_tags\" { type = map(string) }\nvariable \"service_lb_defined_tags\" { type = map(string) }\nvariable \"service_lb_freeform_tags\" { type = map(string) }\n\n# OIDC\nvariable \"oidc_discovery_enabled\" { type = bool }\nvariable \"oidc_token_auth_enabled\" { type = bool }\nvariable \"oidc_token_authentication_config\" { type = any }"
  },
  {
    "path": "modules/cluster/versions.tf",
    "content": "# Copyright (c) 2017, 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nterraform {\n  required_version = \">= 1.2.0\"\n\n  required_providers {\n    oci = {\n      source  = \"oracle/oci\"\n      version = \">= 7.30.0\"\n    }\n  }\n}\n"
  },
  {
    "path": "modules/cluster-addons/README.md",
    "content": "# Cluster Add-ons\n\nThis sub-module manages OKE cluster add-ons and their configurations.\n\n## Usage\n\nRefer to the [Cluster Add-ons section](../../docs/terraformoptions.md#cluster-add-ons) of the module documentation.\n"
  },
  {
    "path": "modules/cluster-addons/addons.tf",
    "content": "# Copyright (c) 2017, 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\ndata \"oci_containerengine_addon_options\" \"k8s_addon_options\" {\n  kubernetes_version = var.kubernetes_version\n}\n\nlocals {\n  supported_addons = [for entry in data.oci_containerengine_addon_options.k8s_addon_options.addon_options : entry.name]\n  primary_addons   = [\"CertManager\"]\n  addons_defaults = {\n    remove_addon_resources_on_delete = true\n    configurations                   = []\n    version                          = null\n  }\n  addons_with_defaults = { for addon_name, addon_value in var.cluster_addons :\n    addon_name => merge(local.addons_defaults, addon_value)\n  }\n}\n\nresource \"oci_containerengine_addon\" \"primary_addon\" {\n  for_each = { for k, v in local.addons_with_defaults : k => v if contains(local.primary_addons, k) }\n\n  addon_name = each.key\n  cluster_id = var.cluster_id\n\n  remove_addon_resources_on_delete = lookup(each.value, \"remove_addon_resources_on_delete\", true)\n\n  dynamic \"configurations\" {\n    for_each = lookup(each.value, \"configurations\", [])\n    iterator = config\n\n    content {\n      key   = tostring(lookup(config.value, \"key\"))\n      value = tostring(lookup(config.value, \"value\"))\n    }\n  }\n  override_existing = lookup(each.value, \"override_existing\", false)\n  version           = lookup(each.value, \"version\", null)\n\n  timeouts {\n    create = \"30m\"\n  }\n\n  lifecycle {\n\n    precondition {\n      condition     = contains(local.supported_addons, each.key)\n      error_message = <<-EOT\n      The addon ${each.key} is not supported.\n      The list of supported addons is: ${join(\", \", local.supported_addons)}.\n      EOT\n    }\n  }\n}\n\nresource \"oci_containerengine_addon\" \"secondary_addon\" {\n  for_each   = { for k, v in local.addons_with_defaults : k => v if !contains(local.primary_addons, k) }\n  depends_on = [oci_containerengine_addon.primary_addon]\n  addon_name = each.key\n  cluster_id = var.cluster_id\n\n  remove_addon_resources_on_delete = lookup(each.value, \"remove_addon_resources_on_delete\", true)\n\n  dynamic \"configurations\" {\n    for_each = lookup(each.value, \"configurations\", [])\n    iterator = config\n\n    content {\n      key   = tostring(lookup(config.value, \"key\"))\n      value = tostring(lookup(config.value, \"value\"))\n    }\n  }\n  override_existing = lookup(each.value, \"override_existing\", false)\n  version           = lookup(each.value, \"version\", null)\n\n  timeouts {\n    create = \"30m\"\n  }\n  \n  lifecycle {\n\n    precondition {\n      condition     = contains(local.supported_addons, each.key)\n      error_message = <<-EOT\n      The addon ${each.key} is not supported.\n      The list of supported addons is: ${join(\", \", local.supported_addons)}.\n      EOT\n    }\n  }\n}"
  },
  {
    "path": "modules/cluster-addons/delete_addons.tf",
    "content": "# Copyright (c) 2017, 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  remove_addon_command = \"oci ce cluster disable-addon --addon-name %s --cluster-id %s --is-remove-existing-add-on %t --force\"\n  remove_addons_defaults = {\n    custom_commands      = []\n    remove_k8s_resources = true\n  }\n  remove_addons_with_defaults = { for addon_name, addon_value in var.cluster_addons_to_remove :\n    addon_name => merge(local.remove_addons_defaults, addon_value)\n  }\n}\n\nresource \"null_resource\" \"remove_addons\" {\n  for_each   = var.operator_enabled ? local.remove_addons_with_defaults : {}\n  depends_on = [oci_containerengine_addon.primary_addon, oci_containerengine_addon.secondary_addon]\n\n  connection {\n    bastion_host        = var.bastion_host\n    bastion_user        = var.bastion_user\n    bastion_private_key = var.ssh_private_key\n    host                = var.operator_host\n    user                = var.operator_user\n    private_key         = var.ssh_private_key\n    timeout             = \"40m\"\n    type                = \"ssh\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = concat(\n      [\n        \"echo 'Removing ${each.key} addon'\",\n        format(local.remove_addon_command, each.key, var.cluster_id, lookup(each.value, \"remove_k8s_resources\"))\n      ],\n      lookup(each.value, \"custom_commands\")\n    )\n  }\n\n  lifecycle {\n    precondition {\n      condition     = contains(local.supported_addons, each.key)\n      error_message = <<-EOT\n      The addon ${each.key} is not supported.\n      The list of supported addons is: ${join(\", \", local.supported_addons)}.\n      EOT\n    }\n  }\n}"
  },
  {
    "path": "modules/cluster-addons/outputs.tf",
    "content": "# Copyright (c) 2017, 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\noutput \"supported_addons\" {\n  value = data.oci_containerengine_addon_options.k8s_addon_options.addon_options\n}\n"
  },
  {
    "path": "modules/cluster-addons/variables.tf",
    "content": "# Copyright (c) 2017, 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# General variables\nvariable \"cluster_id\" { type = string }\nvariable \"cluster_addons\" { type = any }\nvariable \"cluster_addons_to_remove\" { type = any }\nvariable \"kubernetes_version\" { type = string }\n\n# Variables required to access the operator host\nvariable \"bastion_host\" { type = string }\nvariable \"bastion_user\" { type = string }\nvariable \"operator_enabled\" { type = bool }\nvariable \"operator_host\" { type = string }\nvariable \"operator_user\" { type = string }\nvariable \"ssh_private_key\" { type = string }\n\n"
  },
  {
    "path": "modules/cluster-addons/versions.tf",
    "content": "# Copyright (c) 2017, 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nterraform {\n  required_version = \">= 1.2.0\"\n\n  required_providers {\n    oci = {\n      source  = \"oracle/oci\"\n      version = \">= 7.30.0\"\n    }\n  }\n}\n"
  },
  {
    "path": "modules/extensions/README.md",
    "content": "# Extensions\n\nThis sub-module deploys Kubernetes extensions via Helm charts or YAML manifests, including Cilium, Multus, Prometheus, Gatekeeper, ArgoCD, and more.\n\n## Usage\n\nRefer to the [Extensions section](../../docs/terraformoptions.md#extensions) of the module documentation.\n"
  },
  {
    "path": "modules/extensions/argocd.tf",
    "content": "# Copyright (c) 2021, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  argocd_enabled       = var.argocd_install && var.expected_node_count > 0\n  argocd_manifest      = sensitive(one(data.helm_template.argocd[*].manifest))\n  argocd_manifest_path = join(\"/\", [local.yaml_manifest_path, \"argocd.yaml\"])\n}\n\ndata \"helm_template\" \"argocd\" {\n  count        = local.argocd_enabled ? 1 : 0\n  chart        = \"argo-cd\"\n  repository   = \"https://argoproj.github.io/argo-helm\"\n  version      = var.argocd_helm_version\n  kube_version = var.kubernetes_version\n\n  name             = \"argocd\"\n  namespace        = var.argocd_namespace\n  create_namespace = true\n  include_crds     = true\n  skip_tests       = true\n  values = length(var.argocd_helm_values_files) > 0 ? [\n    for path in var.argocd_helm_values_files : file(path)\n  ] : null\n\n  set = concat(\n    [ for k, v in var.argocd_helm_values:\n      {\n        name  = k,\n        value = v\n      }\n    ]\n  )\n\n  lifecycle {\n    precondition {\n      condition = alltrue([for path in var.argocd_helm_values_files : fileexists(path)])\n      error_message = format(\"Missing Helm values files in configuration: %s\",\n        jsonencode([for path in var.argocd_helm_values_files : path if !fileexists(path)])\n      )\n    }\n  }\n}\n\nresource \"null_resource\" \"argocd\" {\n  count = local.argocd_enabled ? 1 : 0\n\n  triggers = {\n    manifest_md5 = try(md5(local.argocd_manifest), null)\n  }\n\n  connection {\n    bastion_host        = var.bastion_host\n    bastion_user        = var.bastion_user\n    bastion_private_key = var.ssh_private_key\n    host                = var.operator_host\n    user                = var.operator_user\n    private_key         = var.ssh_private_key\n    timeout             = \"40m\"\n    type                = \"ssh\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\"mkdir -p ${local.yaml_manifest_path}\"]\n  }\n\n  provisioner \"file\" {\n    content     = local.argocd_manifest\n    destination = local.argocd_manifest_path\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [for c in compact([\n      (contains([\"kube-system\", \"default\"], var.argocd_namespace) ? null\n      : format(local.kubectl_create_missing_ns, var.argocd_namespace)),\n      format(local.kubectl_apply_server_file, local.argocd_manifest_path),\n      ]) : format(local.output_log, c, \"argocd\")\n    ]\n  }\n}\n"
  },
  {
    "path": "modules/extensions/autoscaler.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# https://github.com/kubernetes/autoscaler/tree/master/charts/cluster-autoscaler\n# https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengautoscalingclusters.htm\n\nlocals {\n  # Active worker pools that should be managed by the cluster autoscaler\n  worker_pools_autoscaling = { for k, v in var.worker_pools : k => v if tobool(lookup(v, \"autoscale\", false)) }\n\n  # Whether to enable cluster autoscaler deployment based on configuration, active nodes, and autoscaling pools\n  cluster_autoscaler_enabled = alltrue([\n    var.cluster_autoscaler_install,\n    var.expected_node_count > 0,\n    var.expected_autoscale_worker_pools > 0,\n  ])\n\n  # Templated Helm manifest values\n  cluster_autoscaler_manifest      = sensitive(one(data.helm_template.cluster_autoscaler[*].manifest))\n  cluster_autoscaler_manifest_path = join(\"/\", [local.yaml_manifest_path, \"cluster_autoscaler.yaml\"])\n  cluster_autoscaler_defaults = {\n    \"cloudProvider\"                              = \"oci-oke\",\n    \"extraArgs.logtostderr\"                      = \"true\",\n    \"extraArgs.v\"                                = \"4\",\n    \"extraArgs.stderrthreshold\"                  = \"info\",\n    \"extraArgs.max-node-provision-time\"          = \"25m\",\n    \"extraArgs.scale-down-unneeded-time\"         = \"2m\",\n    \"extraArgs.unremovable-node-recheck-timeout\" = \"5m\",\n    \"extraArgs.balance-similar-node-groups\"      = \"true\",\n    \"extraArgs.balancing-ignore-label\"           = \"displayName\",\n    \"extraArgs.balancing-ignore-label\"           = \"hostname\",\n    \"extraArgs.balancing-ignore-label\"           = \"internal_addr\",\n    \"extraArgs.balancing-ignore-label\"           = \"oci.oraclecloud.com/fault-domain\",\n    \"extraEnv.OCI_REGION\"                        = var.region,\n    \"extraEnv.OCI_USE_INSTANCE_PRINCIPAL\"        = \"true\",\n    \"extraEnv.OKE_USE_INSTANCE_PRINCIPAL\"        = \"true\",\n    \"extraEnv.OCI_SDK_APPEND_USER_AGENT\"         = \"oci-oke-cluster-autoscaler\",\n    \"image.repository\"                           = \"iad.ocir.io/oracle/oci-cluster-autoscaler\",\n    \"image.tag\"                                  = \"1.26.2-7\",\n  }\n}\n\ndata \"helm_template\" \"cluster_autoscaler\" {\n  count        = local.cluster_autoscaler_enabled ? 1 : 0\n  chart        = \"cluster-autoscaler\"\n  repository   = \"https://kubernetes.github.io/autoscaler\"\n  version      = var.cluster_autoscaler_helm_version\n  kube_version = var.kubernetes_version\n\n  name             = \"cluster-autoscaler\"\n  namespace        = var.cluster_autoscaler_namespace\n  create_namespace = true\n  include_crds     = true\n  skip_tests       = true\n\n  values = length(var.cluster_autoscaler_helm_values_files) > 0 ? [\n    for path in var.cluster_autoscaler_helm_values_files : file(path)\n  ] : null\n\n  set = concat(\n    [\n      {\n        name  = \"nodeSelector.oke\\\\.oraclecloud\\\\.com/cluster_autoscaler\"\n        value = \"allowed\"\n      }\n    ],\n    [ for k, v in merge(local.cluster_autoscaler_defaults, var.cluster_autoscaler_helm_values) : \n      { \n        name  = k, \n        value = v \n      } \n    ],\n    [ for k, v in local.worker_pools_autoscaling : \n      { \n        name  = \"autoscalingGroups[${index(keys(local.worker_pools_autoscaling), k)}].name\", \n        value = lookup(v, \"id\")\n      } \n    ],\n    [ for k, v in local.worker_pools_autoscaling : \n      { \n        name  = \"autoscalingGroups[${index(keys(local.worker_pools_autoscaling), k)}].minSize\", \n        value = lookup(v, \"min_size\", lookup(v, \"size\"))\n      }\n    ],\n    [ for k, v in local.worker_pools_autoscaling : \n      { \n        name  = \"autoscalingGroups[${index(keys(local.worker_pools_autoscaling), k)}].maxSize\", \n        value = lookup(v, \"max_size\", lookup(v, \"size\"))\n      }\n    ],\n  )\n\n  lifecycle {\n    precondition {\n      condition = alltrue([for path in var.cluster_autoscaler_helm_values_files : fileexists(path)])\n      error_message = format(\"Missing Helm values files in configuration: %s\",\n        jsonencode([for path in var.cluster_autoscaler_helm_values_files : path if !fileexists(path)])\n      )\n    }\n  }\n}\n\nresource \"null_resource\" \"cluster_autoscaler\" {\n  count = local.cluster_autoscaler_enabled ? 1 : 0\n\n  triggers = {\n    manifest_md5 = try(md5(local.cluster_autoscaler_manifest), null)\n  }\n\n  connection {\n    bastion_host        = var.bastion_host\n    bastion_user        = var.bastion_user\n    bastion_private_key = var.ssh_private_key\n    host                = var.operator_host\n    user                = var.operator_user\n    private_key         = var.ssh_private_key\n    timeout             = \"40m\"\n    type                = \"ssh\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\"mkdir -p ${local.yaml_manifest_path}\"]\n  }\n\n  provisioner \"file\" {\n    content     = local.cluster_autoscaler_manifest\n    destination = local.cluster_autoscaler_manifest_path\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\n      \"kubectl apply -f ${local.cluster_autoscaler_manifest_path}\"\n      ]\n  }\n}\n"
  },
  {
    "path": "modules/extensions/cilium.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  cilium_helm_crds_file            = join(\"/\", [local.yaml_manifest_path, \"cilium.crds.yaml\"])\n  cilium_helm_manifest_file        = join(\"/\", [local.yaml_manifest_path, \"cilium.manifest.yaml\"])\n  cilium_helm_values_file          = join(\"/\", [local.yaml_manifest_path, \"cilium.values.yaml\"])\n  cilium_helm_values_override_file = join(\"/\", [local.yaml_manifest_path, \"cilium.values-override.yaml\"])\n  cilium_net_attach_def_file       = join(\"/\", [local.yaml_manifest_path, \"cilium.net_attach_def.yaml\"])\n  cilium_veth_config_map_file      = join(\"/\", [local.yaml_manifest_path, \"cilium.cni_config_map.yaml\"])\n\n  cilium_helm_crds            = one(data.helm_template.cilium[*].crds)\n  cilium_helm_values_override = one(data.helm_template.cilium[*].values)\n\n  cilium_helm_repository = \"https://helm.cilium.io\"\n\n  cilium_vxlan_cni = {\n    install   = true\n    exclusive = true # !var.multus_install\n  }\n\n  cilium_helm_values = {\n    annotateK8sNode = true\n    cluster = {\n      name = \"oke-${var.state_id}\"\n      id   = 1\n    }\n    clustermesh = {\n      useAPIServer = false\n      apiserver = {\n        kvstoremesh = {\n          enabled = false\n        }\n      }\n    }\n    cni                             = local.cilium_vxlan_cni\n    installNoConntrackIptablesRules = false\n    ipam                            = { mode = \"kubernetes\" }\n    kubeProxyReplacement            = false\n    k8sServiceHost                  = var.cluster_private_endpoint\n    k8sServicePort                  = \"6443\"\n    pmtuDiscovery                   = { enabled = true }\n    rollOutCiliumPods               = true\n    tunnelProtocol                  = local.cilium_tunnel\n\n    hubble = {\n      metrics = {\n        dashboards = { enabled = var.prometheus_install }\n        # serviceMonitor = { enabled = var.prometheus_enabled }\n      }\n      relay = { enabled = true }\n      ui    = { enabled = true }\n    }\n\n    k8s = {\n      requireIPv4PodCIDR = true # wait for Kubernetes to provide the PodCIDR (ipam kubernetes)\n    }\n\n    # Prometheus metrics\n\n    operator = {\n      prometheus = {\n        enabled = var.prometheus_install\n        # serviceMonitor = { enabled = var.prometheus_enabled }\n      }\n    }\n  }\n\n  # TODO Support Flannel w/ generic-veth & tunnel disabled\n  cilium_tunnel = \"vxlan\" # var.cni_type == \"flannel\" ? \"disabled\" : \"vxlan\"\n\n  cilium_flannel_cni = {\n    install      = true\n    chainingMode = \"generic-veth\"\n    configMap    = \"cni-configuration\"\n    customConf   = var.cni_type == \"flannel\"\n    exclusive    = !var.multus_install\n  }\n\n  cilium_net_attach_def_conf = {\n    cniVersion = \"0.3.1\"\n    name       = \"cilium\"\n    plugins = [\n      {\n        cniVersion = \"0.3.1\"\n        name       = \"cilium\"\n        type       = \"cilium-cni\"\n      },\n      {\n        name = \"cilium-sbr\"\n        type = \"sbr\"\n      }\n    ],\n  }\n\n  cilium_net_attach_def = {\n    apiVersion = \"k8s.cni.cncf.io/v1\"\n    kind       = \"NetworkAttachmentDefinition\"\n    metadata   = { name = \"cilium\" }\n    spec       = { config = jsonencode(local.cilium_net_attach_def_conf) }\n  }\n\n  cilium_veth_conf = {\n    cniVersion = \"0.3.1\"\n    name       = \"cbr0\"\n    \"plugins\" = [\n      {\n        type = \"flannel\"\n        delegate = {\n          hairpinMode      = true\n          isDefaultGateway = true\n        }\n      },\n      {\n        type         = \"portmap\"\n        capabilities = { portMappings = true }\n      },\n      { type = \"cilium-cni\" },\n    ]\n  }\n\n  cilium_veth_config_map = {\n    apiVersion = \"v1\"\n    kind       = \"ConfigMap\"\n    metadata = {\n      name      = \"cni-configuration\"\n      namespace = var.cilium_namespace\n    }\n    data = { \"cni-config\" = jsonencode(local.cilium_veth_conf) }\n  }\n\n  cilium_net_attach_def_yaml       = yamlencode(local.cilium_net_attach_def)\n  cilium_veth_config_map_yaml      = yamlencode(local.cilium_veth_config_map)\n  cilium_helm_values_yaml          = yamlencode(merge(local.cilium_helm_values, var.cilium_helm_values))\n  cilium_helm_values_override_yaml = local.cilium_helm_values_override != null ? join(\"\\n\", local.cilium_helm_values_override) : \"\"\n}\n\ndata \"helm_template\" \"cilium\" {\n  count        = var.cilium_install ? 1 : 0\n  chart        = \"cilium\"\n  repository   = local.cilium_helm_repository\n  version      = var.cilium_helm_version\n  kube_version = var.kubernetes_version\n\n  name             = \"cilium\"\n  namespace        = var.cilium_namespace\n  create_namespace = true\n  include_crds     = true\n  skip_tests       = true\n  values = concat(\n    [local.cilium_helm_values_yaml],\n    [for path in var.cilium_helm_values_files : file(path)],\n  )\n\n  lifecycle {\n    precondition {\n      condition = alltrue([for path in var.cilium_helm_values_files : fileexists(path)])\n      error_message = format(\"Missing Helm values files in configuration: %s\",\n        jsonencode([for path in var.cilium_helm_values_files : path if !fileexists(path)])\n      )\n    }\n  }\n}\n\nresource \"null_resource\" \"cilium\" {\n  count      = var.cilium_install ? 1 : 0\n  depends_on = [null_resource.prometheus]\n\n  triggers = {\n    helm_version = var.cilium_helm_version\n    crds_md5     = try(md5(join(\"\\n\", local.cilium_helm_crds)), null)\n    manifest_md5 = try(md5(local.cilium_helm_values_override_yaml), null)\n    reapply      = var.cilium_reapply ? uuid() : null\n  }\n\n  connection {\n    bastion_host        = var.bastion_host\n    bastion_user        = var.bastion_user\n    bastion_private_key = var.ssh_private_key\n    host                = var.operator_host\n    user                = var.operator_user\n    private_key         = var.ssh_private_key\n    timeout             = \"40m\"\n    type                = \"ssh\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\"mkdir -p ${local.yaml_manifest_path}\"]\n  }\n\n  provisioner \"file\" {\n    content     = join(\"\\n\", local.cilium_helm_crds)\n    destination = local.cilium_helm_crds_file\n  }\n\n  provisioner \"file\" {\n    content     = local.cilium_helm_values_override_yaml\n    destination = local.cilium_helm_values_override_file\n  }\n\n  # provisioner \"file\" {\n  #   content     = local.cilium_net_attach_def_yaml\n  #   destination = local.cilium_net_attach_def_file\n  # }\n\n  # provisioner \"file\" {\n  #   content     = local.cilium_veth_config_map_yaml\n  #   destination = local.cilium_veth_config_map_file\n  # }\n\n  provisioner \"remote-exec\" {\n    inline = [for c in compact([\n      # Create namespace if non-standard and missing\n      (contains([\"kube-system\", \"default\"], var.cilium_namespace) ? null\n      : format(local.kubectl_create_missing_ns, var.cilium_namespace)),\n\n      # Install CRDs first\n      format(local.kubectl_apply_server_ns_file, var.cilium_namespace, local.cilium_helm_crds_file),\n\n      # Install full manifest\n      format(local.helm_upgrade_install, \"cilium\", \"cilium\", local.cilium_helm_repository, var.cilium_helm_version, var.cilium_namespace, local.cilium_helm_values_override_file),\n\n      # Install Network Attachment Definition when Multus is enabled\n      # var.multus_install ? format(local.kubectl_apply_file, local.cilium_net_attach_def_file) : null,\n\n      # Install CNI ConfigMap for Flannel\n      # var.cni_type == \"flannel\" ? format(local.kubectl_apply_file, local.cilium_veth_config_map_file) : null,\n      ]) : format(local.output_log, c, \"cilium\")\n    ]\n  }\n\n  lifecycle {\n    precondition {\n      condition     = var.cni_type == \"flannel\"\n      error_message = \"Incompatible cni_type for installation - must be 'flannel'.\"\n    }\n  }\n}"
  },
  {
    "path": "modules/extensions/dcgm_exporter.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  dcgm_exporter_helm_crds_file     = join(\"/\", [local.yaml_manifest_path, \"dcgm_exporter.crds.yaml\"])\n  dcgm_exporter_helm_manifest_file = join(\"/\", [local.yaml_manifest_path, \"dcgm_exporter.manifest.yaml\"])\n  dcgm_exporter_helm_crds          = sensitive(one(data.helm_template.dcgm_exporter[*].crds))\n  dcgm_exporter_helm_manifest      = sensitive(one(data.helm_template.dcgm_exporter[*].manifest))\n\n  dcgm_exporter_scrape_config = [\n    {\n      job_name        = \"gpu-metrics\"\n      scrape_interval = \"10s\"\n      metrics_path    = \"/metrics\"\n      scheme          = \"http\"\n      kubernetes_sd_configs = [\n        {\n          role       = \"endpoints\"\n          namespaces = { names = [\"metrics\"] }\n          selectors  = [{ label = \"app.kubernetes.io/component=dcgm-exporter\" }]\n        }\n      ]\n      relabel_configs = [\n        {\n          source_labels = [\"__meta_kubernetes_pod_node_name\"]\n          action        = \"replace\"\n          target_label  = \"kubernetes_node\"\n        }\n      ]\n    }\n  ]\n}\n\ndata \"helm_template\" \"dcgm_exporter\" {\n  count        = var.dcgm_exporter_install ? 1 : 0\n  chart        = \"dcgm-exporter\"\n  repository   = \"https://nvidia.github.io/dcgm-exporter/helm-charts\"\n  version      = var.dcgm_exporter_helm_version\n  kube_version = var.kubernetes_version\n\n  name             = \"dcgm-exporter\"\n  namespace        = var.dcgm_exporter_namespace\n  create_namespace = true\n  include_crds     = true\n  skip_tests       = true\n  values = length(var.dcgm_exporter_helm_values_files) > 0 ? [\n    for path in var.dcgm_exporter_helm_values_files : file(path)\n  ] : null\n\n  set = concat(\n    [ for k, v in var.dcgm_exporter_helm_values:\n      {\n        name  = k,\n        value = v\n      }\n    ]\n  )\n\n  lifecycle {\n    precondition {\n      condition = alltrue([for path in var.dcgm_exporter_helm_values_files : fileexists(path)])\n      error_message = format(\"Missing Helm values files in configuration: %s\",\n        jsonencode([for path in var.dcgm_exporter_helm_values_files : path if !fileexists(path)])\n      )\n    }\n  }\n}\n\nresource \"null_resource\" \"dcgm_exporter\" {\n  count = var.dcgm_exporter_install ? 1 : 0\n\n  triggers = {\n    helm_version = var.dcgm_exporter_helm_version\n    crds_md5     = try(md5(join(\"\\n\", local.dcgm_exporter_helm_crds)), null)\n    manifest_md5 = try(md5(local.dcgm_exporter_helm_manifest), null)\n    reapply      = var.dcgm_exporter_reapply ? uuid() : null\n  }\n\n  connection {\n    bastion_host        = var.bastion_host\n    bastion_user        = var.bastion_user\n    bastion_private_key = var.ssh_private_key\n    host                = var.operator_host\n    user                = var.operator_user\n    private_key         = var.ssh_private_key\n    timeout             = \"40m\"\n    type                = \"ssh\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\"mkdir -p ${local.yaml_manifest_path}\"]\n  }\n\n  provisioner \"file\" {\n    content     = join(\"\\n\", local.dcgm_exporter_helm_crds)\n    destination = local.dcgm_exporter_helm_crds_file\n  }\n\n  provisioner \"file\" {\n    content     = local.dcgm_exporter_helm_manifest\n    destination = local.dcgm_exporter_helm_manifest_file\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [for c in compact([\n      (contains([\"kube-system\", \"default\"], var.dcgm_exporter_namespace) ? null\n      : format(local.kubectl_create_missing_ns, var.dcgm_exporter_namespace)),\n      format(local.kubectl_apply_server_file, local.dcgm_exporter_helm_crds_file),\n      format(local.kubectl_apply_server_file, local.dcgm_exporter_helm_manifest_file),\n      ]) : format(local.output_log, c, \"dcgm_exporter\")\n    ]\n  }\n}\n"
  },
  {
    "path": "modules/extensions/gatekeeper.tf",
    "content": "# Copyright (c) 2021, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  gatekeeper_enabled       = var.gatekeeper_install && var.expected_node_count > 0\n  gatekeeper_manifest      = sensitive(one(data.helm_template.gatekeeper[*].manifest))\n  gatekeeper_manifest_path = join(\"/\", [local.yaml_manifest_path, \"gatekeeper.yaml\"])\n}\n\ndata \"helm_template\" \"gatekeeper\" {\n  count        = local.gatekeeper_enabled ? 1 : 0\n  chart        = \"gatekeeper\"\n  repository   = \"https://open-policy-agent.github.io/gatekeeper/charts\"\n  version      = var.gatekeeper_helm_version\n  kube_version = var.kubernetes_version\n\n  name             = \"gatekeeper\"\n  namespace        = var.gatekeeper_namespace\n  create_namespace = true\n  include_crds     = true\n  skip_tests       = true\n  values = length(var.gatekeeper_helm_values_files) > 0 ? [\n    for path in var.gatekeeper_helm_values_files : file(path)\n  ] : null\n\n  set = concat(\n    [ for k, v in var.gatekeeper_helm_values:\n      {\n        name  = k,\n        value = v\n      }\n    ]\n  )\n\n  lifecycle {\n    precondition {\n      condition = alltrue([for path in var.gatekeeper_helm_values_files : fileexists(path)])\n      error_message = format(\"Missing Helm values files in configuration: %s\",\n        jsonencode([for path in var.gatekeeper_helm_values_files : path if !fileexists(path)])\n      )\n    }\n  }\n}\n\nresource \"null_resource\" \"gatekeeper\" {\n  count = local.gatekeeper_enabled ? 1 : 0\n\n  triggers = {\n    manifest_md5 = try(md5(local.gatekeeper_manifest), null)\n  }\n\n  connection {\n    bastion_host        = var.bastion_host\n    bastion_user        = var.bastion_user\n    bastion_private_key = var.ssh_private_key\n    host                = var.operator_host\n    user                = var.operator_user\n    private_key         = var.ssh_private_key\n    timeout             = \"40m\"\n    type                = \"ssh\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\"mkdir -p ${local.yaml_manifest_path}\"]\n  }\n\n  provisioner \"file\" {\n    content     = local.gatekeeper_manifest\n    destination = local.gatekeeper_manifest_path\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\"kubectl apply --force-conflicts=true --server-side -f ${local.gatekeeper_manifest_path}\"]\n  }\n}\n"
  },
  {
    "path": "modules/extensions/locals.tf",
    "content": "# Copyright (c)  2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  yaml_manifest_path           = \"/home/${var.operator_user}/yaml\"\n  kubectl                      = \"set -o pipefail; kubectl\"\n  helm                         = \"set -o pipefail; helm\"\n  kubectl_apply_ns_file        = \"${local.kubectl} apply -n %s -f %s\"\n  kubectl_apply_file           = \"${local.kubectl} apply -f %s\"\n  kubectl_apply_server_file    = \"${local.kubectl} apply --force-conflicts=true --server-side -f %s\"\n  kubectl_apply_server_ns_file = \"${local.kubectl} apply -n %s --force-conflicts=true --server-side -f %s\"\n  kubectl_create_missing_ns    = \"${local.kubectl} create ns %s --dry-run=client -o yaml | kubectl apply -f -\"\n  selector_linux               = { \"kubernetes.io/os\" = \"linux\" }\n  output_log                   = \"bash -c \\\"%s | tee >(systemd-cat -t %s -p info)\\\"\"\n  helm_upgrade_install         = \"${local.helm} upgrade --install %s %s --repo %s --version %s --namespace %s --create-namespace --skip-crds -f %s\"\n}\n"
  },
  {
    "path": "modules/extensions/metricserver.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  metrics_server_enabled       = var.metrics_server_install && var.expected_node_count > 0\n  metrics_server_manifest      = sensitive(one(data.helm_template.metrics_server[*].manifest))\n  metrics_server_manifest_path = join(\"/\", [local.yaml_manifest_path, \"metrics_server.manifest.yaml\"])\n}\n\ndata \"helm_template\" \"metrics_server\" {\n  count        = local.metrics_server_enabled ? 1 : 0\n  chart        = \"metrics-server\"\n  repository   = \"https://kubernetes-sigs.github.io/metrics-server\"\n  version      = var.metrics_server_helm_version\n  kube_version = var.kubernetes_version\n\n  name             = \"metrics-server\"\n  namespace        = var.metrics_server_namespace\n  create_namespace = true\n  include_crds     = true\n  skip_tests       = true\n  values = length(var.metrics_server_helm_values_files) > 0 ? [\n    for path in var.metrics_server_helm_values_files : file(path)\n  ] : null\n\n  set = concat(\n    [ for k, v in var.metrics_server_helm_values:\n      {\n        name  = k,\n        value = v\n      }\n    ]\n  )\n\n  lifecycle {\n    precondition {\n      condition = alltrue([for path in var.metrics_server_helm_values_files : fileexists(path)])\n      error_message = format(\"Missing Helm values files in configuration: %s\",\n        jsonencode([for path in var.metrics_server_helm_values_files : path if !fileexists(path)])\n      )\n    }\n  }\n}\n\nresource \"null_resource\" \"metrics_server\" {\n  count = local.metrics_server_enabled ? 1 : 0\n\n  triggers = {\n    manifest_md5 = try(md5(local.metrics_server_manifest), null)\n  }\n\n  connection {\n    bastion_host        = var.bastion_host\n    bastion_user        = var.bastion_user\n    bastion_private_key = var.ssh_private_key\n    host                = var.operator_host\n    user                = var.operator_user\n    private_key         = var.ssh_private_key\n    timeout             = \"40m\"\n    type                = \"ssh\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\"mkdir -p ${local.yaml_manifest_path}\"]\n  }\n\n  provisioner \"file\" {\n    content     = local.metrics_server_manifest\n    destination = local.metrics_server_manifest_path\n  }\n\n  provisioner \"remote-exec\" {\n    inline = compact([\n      (contains([\"kube-system\", \"default\"], var.metrics_server_namespace) ? null\n      : format(local.kubectl_create_missing_ns, var.metrics_server_namespace)),\n      format(local.kubectl_apply_server_file, local.metrics_server_manifest_path),\n    ])\n  }\n}\n"
  },
  {
    "path": "modules/extensions/mpi_operator.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  mpi_operator_url = \"https://raw.githubusercontent.com/kubeflow/mpi-operator/v${var.mpi_operator_version}/deploy/v2beta1\"\n  mpi_operator_deployment_url = coalesce(\n    var.mpi_operator_deployment_url,\n    \"${local.mpi_operator_url}/mpi-operator.yaml\"\n  )\n  mpi_operator_manifest_path        = join(\"/\", [local.yaml_manifest_path, \"mpi-operator.manifest.yaml\"])\n  mpi_operator_manifest_status_code = one(data.http.mpi_operator[*].status_code)\n  mpi_operator_manifest_content     = sensitive(one(data.http.mpi_operator[*].response_body))\n}\n\ndata \"http\" \"mpi_operator\" {\n  count = var.mpi_operator_install ? 1 : 0\n  url   = local.mpi_operator_deployment_url\n}\n\nresource \"null_resource\" \"mpi_operator\" {\n  count = var.mpi_operator_install ? 1 : 0\n\n  triggers = {\n    mpi_operator_deployment_url = local.mpi_operator_deployment_url\n    mpi_operator_deployment_md5 = md5(local.mpi_operator_manifest_content)\n  }\n\n  connection {\n    bastion_host        = var.bastion_host\n    bastion_user        = var.bastion_user\n    bastion_private_key = var.ssh_private_key\n    host                = var.operator_host\n    user                = var.operator_user\n    private_key         = var.ssh_private_key\n    timeout             = \"40m\"\n    type                = \"ssh\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\"mkdir -p ${local.yaml_manifest_path}\"]\n  }\n\n  provisioner \"file\" {\n    content     = local.mpi_operator_manifest_content\n    destination = local.mpi_operator_manifest_path\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\n      format(local.kubectl_apply_file, local.mpi_operator_manifest_path),\n    ]\n  }\n\n  lifecycle {\n    precondition {\n      condition     = local.mpi_operator_manifest_status_code == 200\n      error_message = <<-EOT\n      Error retrieving MPI Operator manifest\n      URL: ${local.mpi_operator_deployment_url}\n      Status code: ${local.mpi_operator_manifest_status_code}\n      Response: ${local.mpi_operator_manifest_content}\n      EOT\n    }\n  }\n}\n"
  },
  {
    "path": "modules/extensions/multus.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  multus_url = \"https://raw.githubusercontent.com/k8snetworkplumbingwg/multus-cni\"\n  multus_daemonset_url = coalesce(\n    var.multus_daemonset_url,\n    \"${local.multus_url}/v${var.multus_version}/deployments/multus-daemonset.yml\"\n  )\n  multus_manifest_path        = join(\"/\", [local.yaml_manifest_path, \"multus.manifest.yaml\"])\n  multus_manifest_status_code = one(data.http.multus[*].status_code)\n  multus_manifest_content     = sensitive(one(data.http.multus[*].response_body))\n}\n\ndata \"http\" \"multus\" {\n  count = var.multus_install ? 1 : 0\n  url   = local.multus_daemonset_url\n}\n\nresource \"null_resource\" \"multus\" {\n  count = var.multus_install ? 1 : 0\n\n  triggers = {\n    multus_daemonset_url = local.multus_daemonset_url\n    multus_daemonset_md5 = md5(local.multus_manifest_content)\n  }\n\n  connection {\n    bastion_host        = var.bastion_host\n    bastion_user        = var.bastion_user\n    bastion_private_key = var.ssh_private_key\n    host                = var.operator_host\n    user                = var.operator_user\n    private_key         = var.ssh_private_key\n    timeout             = \"40m\"\n    type                = \"ssh\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\"mkdir -p ${local.yaml_manifest_path}\"]\n  }\n\n  provisioner \"file\" {\n    content     = local.multus_manifest_content\n    destination = local.multus_manifest_path\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\n      format(local.kubectl_apply_file, local.multus_manifest_path),\n    ]\n  }\n\n  lifecycle {\n    precondition {\n      condition     = local.multus_manifest_status_code == 200\n      error_message = <<-EOT\n      Error retrieving Multus Daemonset manifest\n      Status code: ${local.multus_manifest_status_code}\n      Response: ${local.multus_manifest_content}\n      EOT\n    }\n  }\n}\n"
  },
  {
    "path": "modules/extensions/prometheus.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  prometheus_helm_crds_file     = join(\"/\", [local.yaml_manifest_path, \"prometheus.crds.yaml\"])\n  prometheus_helm_manifest_file = join(\"/\", [local.yaml_manifest_path, \"prometheus.manifest.yaml\"])\n  prometheus_helm_values_file   = join(\"/\", [local.yaml_manifest_path, \"prometheus.values.yaml\"])\n  prometheus_helm_crds          = sensitive(one(data.helm_template.prometheus[*].crds))\n  prometheus_helm_manifest      = sensitive(one(data.helm_template.prometheus[*].manifest))\n\n  prometheus_helm_values = {\n    additionalScrapeConfigs = local.dcgm_exporter_scrape_config\n  }\n\n  prometheus_helm_values_yaml = jsonencode(local.prometheus_helm_values)\n}\n\ndata \"helm_template\" \"prometheus\" {\n  count        = var.prometheus_install ? 1 : 0\n  chart        = \"kube-prometheus-stack\"\n  repository   = \"https://prometheus-community.github.io/helm-charts\"\n  version      = var.prometheus_helm_version\n  kube_version = var.kubernetes_version\n\n  name             = \"prometheus\"\n  namespace        = var.prometheus_namespace\n  create_namespace = true\n  include_crds     = true\n  skip_tests       = true\n  values = concat(\n    [local.prometheus_helm_values_yaml],\n    [for path in var.prometheus_helm_values_files : file(path)],\n  )\n  \n  set = concat(\n    [\n      {\n        name  = \"podSecurityPolicy.enabled\"\n        value = \"false\"\n      },\n    ],\n    [ for k, v in var.prometheus_helm_values:\n      {\n        name  = k,\n        value = v\n      }\n    ]\n  )\n\n  lifecycle {\n    precondition {\n      condition = alltrue([for path in var.prometheus_helm_values_files : fileexists(path)])\n      error_message = format(\"Missing Helm values files in configuration: %s\",\n        jsonencode([for path in var.prometheus_helm_values_files : path if !fileexists(path)])\n      )\n    }\n  }\n}\n\nresource \"null_resource\" \"prometheus\" {\n  count = var.prometheus_install ? 1 : 0\n\n  triggers = {\n    helm_version = var.prometheus_helm_version\n    crds_md5     = try(md5(join(\"\\n\", local.prometheus_helm_crds)), null)\n    manifest_md5 = try(md5(local.prometheus_helm_manifest), null)\n    reapply      = var.prometheus_reapply ? uuid() : null\n  }\n\n  connection {\n    bastion_host        = var.bastion_host\n    bastion_user        = var.bastion_user\n    bastion_private_key = var.ssh_private_key\n    host                = var.operator_host\n    user                = var.operator_user\n    private_key         = var.ssh_private_key\n    timeout             = \"40m\"\n    type                = \"ssh\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\"mkdir -p ${local.yaml_manifest_path}\"]\n  }\n\n  provisioner \"file\" {\n    content     = join(\"\\n\", local.prometheus_helm_crds)\n    destination = local.prometheus_helm_crds_file\n  }\n\n  provisioner \"file\" {\n    content     = local.prometheus_helm_manifest\n    destination = local.prometheus_helm_manifest_file\n  }\n\n  provisioner \"file\" {\n    content     = local.prometheus_helm_values_yaml\n    destination = local.prometheus_helm_values_file\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [for c in compact([\n      (contains([\"kube-system\", \"default\"], var.prometheus_namespace) ? null\n      : format(local.kubectl_create_missing_ns, var.prometheus_namespace)),\n      format(local.kubectl_apply_server_file, local.prometheus_helm_crds_file),\n      format(local.kubectl_apply_server_file, local.prometheus_helm_manifest_file),\n      ]) : format(local.output_log, c, \"prometheus\")\n    ]\n  }\n}\n"
  },
  {
    "path": "modules/extensions/rdma_cni_plugin.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  rdma_cni_plugin_url = \"https://raw.githubusercontent.com/k8snetworkplumbingwg/rdma-cni\"\n  rdma_cni_plugin_daemonset_url = coalesce(\n    var.rdma_cni_plugin_daemonset_url,\n    \"${local.rdma_cni_plugin_url}/${var.rdma_cni_plugin_version}/deployment/rdma-cni-daemonset.yaml\"\n  )\n  rdma_cni_plugin_manifest_path        = join(\"/\", [local.yaml_manifest_path, \"rdma-cni-daemonset.yaml\"])\n  rdma_cni_plugin_manifest_status_code = one(data.http.rdma_cni_plugin[*].status_code)\n  rdma_cni_plugin_manifest_content     = one(data.http.rdma_cni_plugin[*].response_body)\n}\n\ndata \"http\" \"rdma_cni_plugin\" {\n  count = var.rdma_cni_plugin_install ? 1 : 0\n  url   = local.rdma_cni_plugin_daemonset_url\n}\n\nresource \"null_resource\" \"rdma_cni_plugin\" {\n  count = var.rdma_cni_plugin_install ? 1 : 0\n\n  triggers = {\n    rdma_cni_plugin_daemonset_url = local.rdma_cni_plugin_daemonset_url\n    rdma_cni_plugin_daemonset_md5 = md5(local.rdma_cni_plugin_manifest_content)\n  }\n\n  connection {\n    bastion_host        = var.bastion_host\n    bastion_user        = var.bastion_user\n    bastion_private_key = var.ssh_private_key\n    host                = var.operator_host\n    user                = var.operator_user\n    private_key         = var.ssh_private_key\n    timeout             = \"40m\"\n    type                = \"ssh\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\"mkdir -p ${local.yaml_manifest_path}\"]\n  }\n\n  provisioner \"file\" {\n    content     = local.rdma_cni_plugin_manifest_content\n    destination = local.rdma_cni_plugin_manifest_path\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\n      format(local.kubectl_apply_file, local.rdma_cni_plugin_manifest_path),\n    ]\n  }\n\n  lifecycle {\n    precondition {\n      condition     = local.rdma_cni_plugin_manifest_status_code == 200\n      error_message = <<-EOT\n      Error retrieving RDMA CNI Daemonset manifest\n      URL: ${local.rdma_cni_plugin_daemonset_url}\n      Status code: ${local.rdma_cni_plugin_manifest_status_code}\n      Response: ${local.rdma_cni_plugin_manifest_content}\n      EOT\n    }\n  }\n}\n"
  },
  {
    "path": "modules/extensions/service_account.tf",
    "content": "# Copyright (c) 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  sa_with_cluster_role_bindings = {\n    for k, v in var.service_accounts : k => v\n    if lookup(v, \"sa_cluster_role_binding\", null) != null\n  }\n  sa_with_role_bindings = {\n    for k, v in var.service_accounts : k => v\n    if lookup(v, \"sa_role_binding\", null) != null\n  }\n}\n\nresource \"null_resource\" \"service_account_crb\" {\n  for_each = var.create_service_account ? local.sa_with_cluster_role_bindings : {}\n\n  triggers = {\n    service_account_name                 = each.value.sa_name\n    service_account_namespace            = each.value.sa_namespace\n    service_account_cluster_role         = each.value.sa_cluster_role\n    service_account_cluster_role_binding = each.value.sa_cluster_role_binding\n\n    # Parameters ignored as triggers in the life_cycle block. Required to establish connections.\n    bastion_host    = var.bastion_host\n    bastion_user    = var.bastion_user\n    ssh_private_key = var.ssh_private_key\n    operator_host   = var.operator_host\n    operator_user   = var.operator_user\n  }\n\n  connection {\n    bastion_host        = self.triggers.bastion_host\n    bastion_user        = self.triggers.bastion_user\n    bastion_private_key = self.triggers.ssh_private_key\n    host                = self.triggers.operator_host\n    user                = self.triggers.operator_user\n    private_key         = self.triggers.ssh_private_key\n    timeout             = \"10m\"\n    type                = \"ssh\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\n      \"kubectl get ns ${self.triggers.service_account_namespace} || kubectl create ns ${self.triggers.service_account_namespace}\",\n      \"kubectl create sa -n ${self.triggers.service_account_namespace} ${self.triggers.service_account_name}\",\n      \"kubectl create clusterrolebinding ${self.triggers.service_account_cluster_role_binding} --clusterrole=${self.triggers.service_account_cluster_role} --serviceaccount=${self.triggers.service_account_namespace}:${self.triggers.service_account_name}\"\n    ]\n  }\n\n  provisioner \"remote-exec\" {\n    when       = destroy\n    on_failure = continue\n    inline = [\n      \"kubectl delete clusterrolebinding ${self.triggers.service_account_cluster_role_binding}\",\n      \"kubectl delete sa -n ${self.triggers.service_account_namespace} ${self.triggers.service_account_name}\"\n    ]\n  }\n\n  lifecycle {\n    ignore_changes = [\n      triggers[\"bastion_host\"],\n      triggers[\"bastion_user\"],\n      triggers[\"ssh_private_key\"],\n      triggers[\"operator_host\"],\n      triggers[\"operator_user\"]\n    ]\n  }\n}\n\nresource \"null_resource\" \"service_account_rb\" {\n  for_each = var.create_service_account ? local.sa_with_role_bindings : {}\n\n  triggers = {\n    service_account_name         = each.value.sa_name\n    service_account_namespace    = each.value.sa_namespace\n    service_account_cluster_role = each.value.sa_cluster_role\n    service_account_role         = lookup(each.value, \"sa_role\", \"\")\n    service_account_role_binding = each.value.sa_role_binding\n\n    # Parameters ignored as triggers in the life_cycle block. Required to establish connections.\n    bastion_host    = var.bastion_host\n    bastion_user    = var.bastion_user\n    ssh_private_key = var.ssh_private_key\n    operator_host   = var.operator_host\n    operator_user   = var.operator_user\n  }\n\n  connection {\n    bastion_host        = self.triggers.bastion_host\n    bastion_user        = self.triggers.bastion_user\n    bastion_private_key = self.triggers.ssh_private_key\n    host                = self.triggers.operator_host\n    user                = self.triggers.operator_user\n    private_key         = self.triggers.ssh_private_key\n    timeout             = \"10m\"\n    type                = \"ssh\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\n      \"kubectl get ns ${self.triggers.service_account_namespace} || kubectl create ns ${self.triggers.service_account_namespace}\",\n      \"kubectl create sa -n ${self.triggers.service_account_namespace} ${self.triggers.service_account_name}\",\n      self.triggers.service_account_role != \"\" ?\n      \"kubectl create rolebinding -n ${self.triggers.service_account_namespace} ${self.triggers.service_account_role_binding} --role=${self.triggers.service_account_role} --serviceaccount=${self.triggers.service_account_namespace}:${self.triggers.service_account_name}\" :\n      \"kubectl create rolebinding -n ${self.triggers.service_account_namespace} ${self.triggers.service_account_role_binding} --clusterrole=${self.triggers.service_account_cluster_role} --serviceaccount=${self.triggers.service_account_namespace}:${self.triggers.service_account_name}\"\n    ]\n  }\n\n  provisioner \"remote-exec\" {\n    when       = destroy\n    on_failure = continue\n    inline = [\n      \"kubectl delete rolebinding -n ${self.triggers.service_account_namespace} ${self.triggers.service_account_role_binding}\",\n      \"kubectl delete sa -n ${self.triggers.service_account_namespace} ${self.triggers.service_account_name}\"\n    ]\n  }\n\n  lifecycle {\n    ignore_changes = [\n      triggers[\"bastion_host\"],\n      triggers[\"bastion_user\"],\n      triggers[\"ssh_private_key\"],\n      triggers[\"operator_host\"],\n      triggers[\"operator_user\"]\n    ]\n  }\n}"
  },
  {
    "path": "modules/extensions/sriov_cni_plugin.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  sriov_cni_plugin_url = \"https://raw.githubusercontent.com/openshift/sriov-cni\"\n  sriov_cni_plugin_daemonset_url = coalesce(\n    var.sriov_cni_plugin_daemonset_url,\n    \"${local.sriov_cni_plugin_url}/${var.sriov_cni_plugin_version}/images/k8s-v1.16/sriov-cni-daemonset.yaml\"\n  )\n  sriov_cni_plugin_manifest_path        = join(\"/\", [local.yaml_manifest_path, \"sriov_cni_plugin-manifest.yaml\"])\n  sriov_cni_plugin_manifest_status_code = one(data.http.sriov_cni_plugin[*].status_code)\n  sriov_cni_plugin_manifest_content     = sensitive(one(data.http.sriov_cni_plugin[*].response_body))\n}\n\ndata \"http\" \"sriov_cni_plugin\" {\n  count = var.sriov_cni_plugin_install ? 1 : 0\n  url   = local.sriov_cni_plugin_daemonset_url\n}\n\nresource \"null_resource\" \"sriov_cni_plugin\" {\n  count = var.sriov_cni_plugin_install ? 1 : 0\n\n  triggers = {\n    sriov_cni_plugin_daemonset_url = local.sriov_cni_plugin_daemonset_url\n    sriov_cni_plugin_daemonset_md5 = md5(local.sriov_cni_plugin_manifest_content)\n  }\n\n  connection {\n    bastion_host        = var.bastion_host\n    bastion_user        = var.bastion_user\n    bastion_private_key = var.ssh_private_key\n    host                = var.operator_host\n    user                = var.operator_user\n    private_key         = var.ssh_private_key\n    timeout             = \"40m\"\n    type                = \"ssh\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\"mkdir -p ${local.yaml_manifest_path}\"]\n  }\n\n  provisioner \"file\" {\n    content     = local.sriov_cni_plugin_manifest_content\n    destination = local.sriov_cni_plugin_manifest_path\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\n      format(local.kubectl_apply_file, local.sriov_cni_plugin_manifest_path),\n    ]\n  }\n\n  lifecycle {\n    precondition {\n      condition     = local.sriov_cni_plugin_manifest_status_code == 200\n      error_message = <<-EOT\n      Error retrieving SR-IOV CNI Daemonset manifest\n      URL: ${local.sriov_cni_plugin_daemonset_url}\n      Status code: ${local.sriov_cni_plugin_manifest_status_code}\n      Response: ${local.sriov_cni_plugin_manifest_content}\n      EOT\n    }\n  }\n}\n"
  },
  {
    "path": "modules/extensions/sriov_device_plugin.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  sriov_device_plugin_url = \"https://raw.githubusercontent.com/k8snetworkplumbingwg/sriov-network-device-plugin\"\n  sriov_device_plugin_daemonset_url = coalesce(\n    var.sriov_device_plugin_daemonset_url,\n    \"${local.sriov_device_plugin_url}/${var.sriov_device_plugin_version}/deployments/sriovdp-daemonset.yaml\"\n  )\n  sriov_device_plugin_manifest_path        = join(\"/\", [local.yaml_manifest_path, \"sriov_device_plugin-manifest.yaml\"])\n  sriov_device_plugin_manifest_status_code = one(data.http.sriov_device_plugin[*].status_code)\n  sriov_device_plugin_manifest_content     = sensitive(one(data.http.sriov_device_plugin[*].response_body))\n}\n\ndata \"http\" \"sriov_device_plugin\" {\n  count = var.sriov_device_plugin_install ? 1 : 0\n  url   = local.sriov_device_plugin_daemonset_url\n}\n\nresource \"null_resource\" \"sriov_device_plugin\" {\n  count = var.sriov_device_plugin_install ? 1 : 0\n\n  triggers = {\n    sriov_device_plugin_daemonset_url = local.sriov_device_plugin_daemonset_url\n    sriov_device_plugin_daemonset_md5 = md5(local.sriov_device_plugin_manifest_content)\n  }\n\n  connection {\n    bastion_host        = var.bastion_host\n    bastion_user        = var.bastion_user\n    bastion_private_key = var.ssh_private_key\n    host                = var.operator_host\n    user                = var.operator_user\n    private_key         = var.ssh_private_key\n    timeout             = \"40m\"\n    type                = \"ssh\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\"mkdir -p ${local.yaml_manifest_path}\"]\n  }\n\n  provisioner \"file\" {\n    content     = local.sriov_device_plugin_manifest_content\n    destination = local.sriov_device_plugin_manifest_path\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\n      format(local.kubectl_apply_file, local.sriov_device_plugin_manifest_path),\n    ]\n  }\n\n  lifecycle {\n    precondition {\n      condition     = local.sriov_device_plugin_manifest_status_code == 200\n      error_message = <<-EOT\n      Error retrieving SR-IOV Daemonset manifest\n      URL: ${local.sriov_device_plugin_daemonset_url}\n      Status code: ${local.sriov_device_plugin_manifest_status_code}\n      Response: ${local.sriov_device_plugin_manifest_content}\n      EOT\n    }\n  }\n}\n"
  },
  {
    "path": "modules/extensions/variables.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# Common\nvariable \"region\" { type = string }\nvariable \"state_id\" { type = string }\nvariable \"worker_pools\" { type = any }\nvariable \"kubernetes_version\" { type = string }\nvariable \"expected_node_count\" { type = number }\nvariable \"cluster_private_endpoint\" { type = string }\n\n# Connection\nvariable \"bastion_host\" { type = string }\nvariable \"bastion_user\" { type = string }\nvariable \"operator_host\" { type = string }\nvariable \"operator_user\" { type = string }\nvariable \"ssh_private_key\" { type = string }\n\n# CNI\nvariable \"vcn_cidrs\" { type = list(string) }\nvariable \"cni_type\" { type = string }\nvariable \"pods_cidr\" { type = string }\n\n# CNI: Cilium\nvariable \"cilium_install\" { type = bool }\nvariable \"cilium_reapply\" { type = bool }\nvariable \"cilium_namespace\" { type = string }\nvariable \"cilium_helm_version\" { type = string }\nvariable \"cilium_helm_values\" { type = any }\nvariable \"cilium_helm_values_files\" { type = list(string) }\n\n# CNI: Multus\nvariable \"multus_install\" { type = bool }\nvariable \"multus_namespace\" { type = string }\nvariable \"multus_daemonset_url\" { type = string }\nvariable \"multus_version\" { type = string }\n\n# SR-IOV Device Plugin\nvariable \"sriov_device_plugin_install\" { type = bool }\nvariable \"sriov_device_plugin_namespace\" { type = string }\nvariable \"sriov_device_plugin_daemonset_url\" { type = string }\nvariable \"sriov_device_plugin_version\" { type = string }\n\n# SR-IOV CNI Plugin\nvariable \"sriov_cni_plugin_install\" { type = bool }\nvariable \"sriov_cni_plugin_namespace\" { type = string }\nvariable \"sriov_cni_plugin_daemonset_url\" { type = string }\nvariable \"sriov_cni_plugin_version\" { type = string }\n\n# RDMA CNI Plugin\nvariable \"rdma_cni_plugin_install\" { type = bool }\nvariable \"rdma_cni_plugin_namespace\" { type = string }\nvariable \"rdma_cni_plugin_daemonset_url\" { type = string }\nvariable \"rdma_cni_plugin_version\" { type = string }\n\n# Whereabouts\nvariable \"whereabouts_install\" { type = bool }\nvariable \"whereabouts_namespace\" { type = string }\nvariable \"whereabouts_daemonset_url\" { type = string }\nvariable \"whereabouts_version\" { type = string }\n\n# Metrics server\nvariable \"metrics_server_install\" { type = bool }\nvariable \"metrics_server_namespace\" { type = string }\nvariable \"metrics_server_helm_version\" { type = string }\nvariable \"metrics_server_helm_values\" { type = map(string) }\nvariable \"metrics_server_helm_values_files\" { type = list(string) }\n\n# Cluster autoscaler\nvariable \"cluster_autoscaler_install\" { type = bool }\nvariable \"cluster_autoscaler_namespace\" { type = string }\nvariable \"cluster_autoscaler_helm_version\" { type = string }\nvariable \"cluster_autoscaler_helm_values\" { type = map(string) }\nvariable \"cluster_autoscaler_helm_values_files\" { type = list(string) }\nvariable \"expected_autoscale_worker_pools\" { type = number }\n\n# Prometheus\nvariable \"prometheus_install\" { type = bool }\nvariable \"prometheus_reapply\" { type = bool }\nvariable \"prometheus_namespace\" { type = string }\nvariable \"prometheus_helm_version\" { type = string }\nvariable \"prometheus_helm_values\" { type = map(string) }\nvariable \"prometheus_helm_values_files\" { type = list(string) }\n\n# DCGM exporter\nvariable \"dcgm_exporter_install\" { type = bool }\nvariable \"dcgm_exporter_reapply\" { type = bool }\nvariable \"dcgm_exporter_namespace\" { type = string }\nvariable \"dcgm_exporter_helm_version\" { type = string }\nvariable \"dcgm_exporter_helm_values\" { type = map(string) }\nvariable \"dcgm_exporter_helm_values_files\" { type = list(string) }\n\n# MPI Operator\nvariable \"mpi_operator_install\" { type = bool }\nvariable \"mpi_operator_namespace\" { type = string }\nvariable \"mpi_operator_deployment_url\" { type = string }\nvariable \"mpi_operator_version\" { type = string }\n\n# Gatekeeper\nvariable \"gatekeeper_install\" { type = bool }\nvariable \"gatekeeper_namespace\" { type = string }\nvariable \"gatekeeper_helm_version\" { type = string }\nvariable \"gatekeeper_helm_values\" { type = map(string) }\nvariable \"gatekeeper_helm_values_files\" { type = list(string) }\n\n# Service Account\nvariable \"create_service_account\" { type = bool }\nvariable \"service_accounts\" { type = map(any) }\n\n# Argocd\nvariable \"argocd_install\" { type = bool }\nvariable \"argocd_namespace\" { type = string }\nvariable \"argocd_helm_version\" { type = string }\nvariable \"argocd_helm_values\" { type = map(string) }\nvariable \"argocd_helm_values_files\" { type = list(string) }"
  },
  {
    "path": "modules/extensions/versions.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nterraform {\n  required_version = \">= 1.2.0\"\n\n  required_providers {\n    helm = {\n      source  = \"hashicorp/helm\"\n      version = \">= 3.0.1\"\n    }\n\n    http = {\n      source  = \"hashicorp/http\"\n      version = \">= 3.2.1\"\n    }\n\n    null = {\n      source  = \"hashicorp/null\"\n      version = \">= 3.2.1\"\n    }\n  }\n}\n"
  },
  {
    "path": "modules/extensions/whereabouts.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  whereabouts_url                     = \"https://raw.githubusercontent.com/k8snetworkplumbingwg/whereabouts/${var.whereabouts_version}/doc/crds\"\n  whereabouts_ippools_url             = \"${local.whereabouts_url}/whereabouts.cni.cncf.io_ippools.yaml\"\n  whereabouts_overlap_res_url         = \"${local.whereabouts_url}/whereabouts.cni.cncf.io_overlappingrangeipreservations.yaml\"\n  whereabouts_daemonset_url           = coalesce(var.whereabouts_daemonset_url, \"${local.whereabouts_url}/daemonset-install.yaml\")\n  whereabouts_ippools_path            = join(\"/\", [local.yaml_manifest_path, \"whereabouts.ippools.crd.yaml\"])\n  whereabouts_ippools_status_code     = one(data.http.whereabouts_ippools[*].status_code)\n  whereabouts_ippools_content         = sensitive(one(data.http.whereabouts_ippools[*].response_body))\n  whereabouts_overlap_res_path        = join(\"/\", [local.yaml_manifest_path, \"whereabouts.overlap_res.crd.yaml\"])\n  whereabouts_overlap_res_status_code = one(data.http.whereabouts_overlap_res[*].status_code)\n  whereabouts_overlap_res_content     = sensitive(one(data.http.whereabouts_overlap_res[*].response_body))\n  whereabouts_manifest_path           = join(\"/\", [local.yaml_manifest_path, \"whereabouts.manifest.yaml\"])\n  whereabouts_manifest_status_code    = one(data.http.whereabouts_daemonset[*].status_code)\n  whereabouts_manifest_content        = sensitive(one(data.http.whereabouts_daemonset[*].response_body))\n}\n\ndata \"http\" \"whereabouts_ippools\" {\n  count = var.whereabouts_install ? 1 : 0\n  url   = local.whereabouts_ippools_url\n}\n\ndata \"http\" \"whereabouts_overlap_res\" {\n  count = var.whereabouts_install ? 1 : 0\n  url   = local.whereabouts_overlap_res_url\n}\n\ndata \"http\" \"whereabouts_daemonset\" {\n  count = var.whereabouts_install ? 1 : 0\n  url   = local.whereabouts_daemonset_url\n}\n\nresource \"null_resource\" \"whereabouts\" {\n  count = var.whereabouts_install ? 1 : 0\n\n  triggers = {\n    whereabouts_ippools_url     = local.whereabouts_ippools_url\n    whereabouts_overlap_res_url = local.whereabouts_overlap_res_url\n    whereabouts_daemonset_url   = local.whereabouts_daemonset_url\n    whereabouts_ippools_md5     = md5(local.whereabouts_ippools_content)\n    whereabouts_overlap_res_md5 = md5(local.whereabouts_overlap_res_content)\n    whereabouts_daemonset_md5   = md5(local.whereabouts_manifest_content)\n  }\n\n  connection {\n    bastion_host        = var.bastion_host\n    bastion_user        = var.bastion_user\n    bastion_private_key = var.ssh_private_key\n    host                = var.operator_host\n    user                = var.operator_user\n    private_key         = var.ssh_private_key\n    timeout             = \"40m\"\n    type                = \"ssh\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\"mkdir -p ${local.yaml_manifest_path}\"]\n  }\n\n  provisioner \"file\" {\n    content     = local.whereabouts_ippools_content\n    destination = local.whereabouts_ippools_path\n  }\n\n  provisioner \"file\" {\n    content     = local.whereabouts_overlap_res_content\n    destination = local.whereabouts_overlap_res_path\n  }\n\n  provisioner \"file\" {\n    content     = local.whereabouts_manifest_content\n    destination = local.whereabouts_manifest_path\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\n      format(\"${local.kubectl} apply -f %s -f %s -f %s\",\n        local.whereabouts_ippools_path,\n        local.whereabouts_overlap_res_path,\n        local.whereabouts_manifest_path\n      )\n    ]\n  }\n\n  lifecycle {\n    precondition {\n      condition     = local.whereabouts_ippools_status_code == 200\n      error_message = <<-EOT\n      Error retrieving Whereabouts CRD\n      URL: ${local.whereabouts_ippools_url}\n      Status code: ${local.whereabouts_ippools_status_code}\n      Response: ${local.whereabouts_ippools_content}\n      EOT\n    }\n    precondition {\n      condition     = local.whereabouts_overlap_res_status_code == 200\n      error_message = <<-EOT\n      Error retrieving Whereabouts CRD\n      URL: ${local.whereabouts_overlap_res_url}\n      Status code: ${local.whereabouts_overlap_res_status_code}\n      Response: ${local.whereabouts_overlap_res_content}\n      EOT\n    }\n    precondition {\n      condition     = local.whereabouts_manifest_status_code == 200\n      error_message = <<-EOT\n      Error retrieving Whereabouts manifest\n      URL: ${local.whereabouts_daemonset_url}\n      Status code: ${local.whereabouts_manifest_status_code}\n      Response: ${local.whereabouts_manifest_content}\n      EOT\n    }\n  }\n}\n"
  },
  {
    "path": "modules/iam/README.md",
    "content": "# IAM\n\nThis sub-module creates IAM dynamic groups, policies, and optional tag namespaces for OKE resources.\n\n## Usage\n\nRefer to the [Identity & Access Management section](../../docs/terraformoptions.md#identity--access-management) of the module documentation.\n"
  },
  {
    "path": "modules/iam/await.tf",
    "content": "resource \"time_sleep\" \"await_iam_resources\" {\n  count = anytrue([\n    local.has_policy_statements,\n    local.create_iam_tag_namespace,\n  ]) ? 1 : 0\n  create_duration  = \"30s\"\n  destroy_duration = \"0s\"\n}\n"
  },
  {
    "path": "modules/iam/group-autoscaling.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  autoscaler_group_name          = format(\"oke-autoscaler-%v\", var.state_id)\n  autoscaler_compartments        = coalescelist(var.autoscaler_compartments, [var.compartment_id])\n  autoscaler_compartment_matches = formatlist(\"instance.compartment.id = '%v'\", local.autoscaler_compartments)\n  autoscaler_compartment_rule    = format(\"ANY {%v}\", join(\", \", local.autoscaler_compartment_matches))\n\n  autoscaler_group_rules = var.use_defined_tags ? format(\"ALL {%v}\", join(\", \", [\n    format(\"tag.%v.role.value='worker'\", var.tag_namespace),\n    format(\"tag.%v.cluster_autoscaler.value='allowed'\", var.tag_namespace),\n    local.autoscaler_compartment_rule,\n    # \"tag.${var.tag_namespace}.state_id.value='${var.state_id}'\", # TODO optional use w/ config\n  ])) : local.autoscaler_compartment_rule\n\n  autoscaler_templates = [\n    \"Allow dynamic-group %v to manage cluster-node-pools in compartment id %v\",\n    \"Allow dynamic-group %v to manage compute-management-family in compartment id %v\",\n    \"Allow dynamic-group %v to manage instance-family in compartment id %v\",\n    \"Allow dynamic-group %v to manage volume-family in compartment id %v\",\n    \"Allow dynamic-group %v to use subnets in compartment id %v\",\n    \"Allow dynamic-group %v to read virtual-network-family in compartment id %v\",\n    \"Allow dynamic-group %v to use vnics in compartment id %v\",\n    \"Allow dynamic-group %v to inspect compartments in compartment id %v\",\n  ]\n\n  autoscaler_policy_statements = var.create_iam_autoscaler_policy ? tolist([\n    for statement in local.autoscaler_templates : formatlist(statement,\n      local.autoscaler_group_name, local.worker_compartments,\n    )\n  ]) : []\n}\n\nresource \"oci_identity_dynamic_group\" \"autoscaling\" {\n  provider       = oci.home\n  count          = var.create_iam_resources && var.create_iam_autoscaler_policy ? 1 : 0\n  compartment_id = var.tenancy_id # dynamic groups exist in root compartment (tenancy)\n  description    = format(\"Dynamic group of cluster autoscaler-capable worker nodes for OKE Terraform state %v\", var.state_id)\n  matching_rule  = local.autoscaler_group_rules\n  name           = local.autoscaler_group_name\n  defined_tags   = local.defined_tags\n  freeform_tags  = local.freeform_tags\n  lifecycle {\n    ignore_changes = [defined_tags, freeform_tags]\n  }\n}\n"
  },
  {
    "path": "modules/iam/group-cluster.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  cluster_group_name = format(\"oke-cluster-%v\", var.state_id)\n  cluster_rule = format(\"ALL {%v}\", join(\", \", compact([\n    \"resource.type = 'cluster'\",\n    format(\"resource.compartment.id = '%v'\", var.compartment_id),\n    var.use_defined_tags ? format(\"tag.%v.state_id.value='%v'\",\n    var.tag_namespace, var.state_id) : null,\n  ])))\n\n  # Cluster secrets encryption using OCI Key Management System (KMS)\n  cluster_policy_statements = coalesce(var.cluster_kms_key_id, \"none\") != \"none\" ? tolist([format(\n    \"Allow dynamic-group %v to use keys in compartment id %v where target.key.id = '%v'\",\n    local.cluster_group_name, var.compartment_id, var.cluster_kms_key_id,\n  ), format(\"Allow dynamic-group %v to read instance-images in compartment id %v\",\n    local.cluster_group_name, var.compartment_id)\n  ]) : []\n}\n\nresource \"oci_identity_dynamic_group\" \"cluster\" {\n  provider       = oci.home\n  count          = var.create_iam_resources && var.create_iam_kms_policy ? 1 : 0\n  compartment_id = var.tenancy_id # dynamic groups exist in root compartment (tenancy)\n  description    = format(\"Dynamic group with cluster for OKE Terraform state %v\", var.state_id)\n  matching_rule  = local.cluster_rule\n  name           = local.cluster_group_name\n  defined_tags   = local.defined_tags\n  freeform_tags  = local.freeform_tags\n  lifecycle {\n    ignore_changes = [defined_tags, freeform_tags]\n  }\n}\n"
  },
  {
    "path": "modules/iam/group-operator.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  operator_group_name = format(\"oke-operator-%v\", var.state_id)\n  operator_group_rules = var.use_defined_tags ? format(\"ALL {%v}\", join(\", \", [\n    format(\"tag.%v.role.value='operator'\", var.tag_namespace),\n    format(\"tag.%v.state_id.value='%v'\", var.tag_namespace, var.state_id),\n  ])) : \"ALL {instance.compartment.id = '${var.compartment_id}'}\"\n\n  cluster_manage_statement = format(\n    \"Allow dynamic-group %v to MANAGE clusters in compartment id %v\",\n    local.operator_group_name, var.compartment_id,\n  )\n\n  # TODO support keys defined at worker group level\n  operator_kms_volume_templates = [\n    \"Allow service blockstorage to USE keys in compartment id %v where target.key.id = '%v'\",\n    \"Allow dynamic-group ${local.operator_group_name} to USE key-delegates in compartment id %v where target.key.id = '%v'\"\n  ]\n\n  # Block volume encryption using OCI Key Management System (KMS)\n  operator_kms_volume_statements = coalesce(var.operator_volume_kms_key_id, \"none\") != \"none\" ? tolist([\n    for statement in local.operator_kms_volume_templates :\n    format(statement, var.compartment_id, var.operator_volume_kms_key_id)\n  ]) : []\n\n  operator_policy_statements = var.create_iam_operator_policy ? concat(\n    [local.cluster_manage_statement],\n    local.operator_kms_volume_statements,\n  ) : []\n}\n\nresource \"oci_identity_dynamic_group\" \"operator\" {\n  provider       = oci.home\n  count          = var.create_iam_resources && var.create_iam_operator_policy ? 1 : 0\n  compartment_id = var.tenancy_id # dynamic groups exist in root compartment (tenancy)\n  description    = format(\"Dynamic group of operator instance(s) for OKE Terraform state %v\", var.state_id)\n  matching_rule  = local.operator_group_rules\n  name           = local.operator_group_name\n  defined_tags   = local.defined_tags\n  freeform_tags  = local.freeform_tags\n  lifecycle {\n    ignore_changes = [defined_tags, freeform_tags]\n  }\n}\n"
  },
  {
    "path": "modules/iam/group-workers.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  worker_group_name          = format(\"oke-workers-%v\", var.state_id)\n  worker_compartments        = coalescelist(var.worker_compartments, [var.compartment_id])\n  worker_compartment_matches = formatlist(\"instance.compartment.id = '%v'\", local.worker_compartments)\n  worker_compartment_rule    = format(\"ANY {%v}\", join(\", \", local.worker_compartment_matches))\n\n  worker_group_rules = var.use_defined_tags ? format(\"ALL {%v}\", join(\", \", [\n    format(\"tag.%v.role.value='worker'\", var.tag_namespace),\n    format(\"tag.%v.state_id.value='%v'\", var.tag_namespace, var.state_id),\n  ])) : local.worker_compartment_rule\n\n  cluster_join_where_clause = format(\"ALL {%v}\", join(\", \", compact([\n    var.create_iam_worker_policy && var.cluster_id != null\n    ? format(\"target.cluster.id = %v\", var.cluster_id) : null\n  ])))\n\n  cluster_join_statements = formatlist(\n    \"Allow dynamic-group %v to {CLUSTER_JOIN} in compartment id %v where %v\",\n    local.worker_group_name, local.worker_compartments, local.cluster_join_where_clause\n  )\n\n  # TODO support keys defined at worker group level\n  worker_kms_volume_templates = tolist([\n    \"Allow service oke to USE key-delegates in compartment id %v where target.key.id = '%v'\",\n    \"Allow service blockstorage to USE keys in compartment id %v where target.key.id = '%v'\",\n    \"Allow dynamic-group ${local.worker_group_name} to USE key-delegates in compartment id %v where target.key.id = '%v'\"\n  ])\n\n  # Block volume encryption using OCI Key Management System (KMS)\n  worker_kms_volume_statements = coalesce(var.worker_volume_kms_key_id, \"none\") != \"none\" ? flatten(tolist([\n    for statement in local.worker_kms_volume_templates :\n    formatlist(statement, local.worker_compartments, var.worker_volume_kms_key_id)\n  ])) : []\n\n  worker_policy_statements = var.create_iam_worker_policy ? tolist(concat(\n    local.cluster_join_statements,\n    local.worker_kms_volume_statements,\n  )) : []\n}\n\nresource \"oci_identity_dynamic_group\" \"workers\" {\n  provider       = oci.home\n  count          = var.create_iam_resources && var.create_iam_worker_policy ? 1 : 0\n  compartment_id = var.tenancy_id # dynamic groups exist in root compartment (tenancy)\n  description    = format(\"Dynamic group of self-managed worker nodes for OKE Terraform state %v\", var.state_id)\n  matching_rule  = local.worker_group_rules\n  name           = local.worker_group_name\n  defined_tags   = local.defined_tags\n  freeform_tags  = local.freeform_tags\n  lifecycle {\n    ignore_changes = [defined_tags, freeform_tags]\n  }\n}\n"
  },
  {
    "path": "modules/iam/outputs.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\noutput \"dynamic_group_ids\" {\n  description = \"Cluster IAM dynamic group IDs\"\n  value = local.has_policy_statements ? compact([\n    one(oci_identity_dynamic_group.cluster[*].id),\n    one(oci_identity_dynamic_group.workers[*].id),\n    one(oci_identity_dynamic_group.autoscaling[*].id),\n    one(oci_identity_dynamic_group.operator[*].id),\n  ]) : null\n}\n\noutput \"policy_statements\" {\n  description = \"Cluster IAM policy statements\"\n  value       = local.has_policy_statements ? local.policy_statements : null\n}\n"
  },
  {
    "path": "modules/iam/policy.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  policy_statements = distinct(compact(flatten([\n    local.cluster_policy_statements,\n    local.worker_policy_statements,\n    local.operator_policy_statements,\n    local.autoscaler_policy_statements,\n  ])))\n\n  has_policy_statements = var.create_iam_resources && anytrue([\n    var.create_iam_autoscaler_policy,\n    var.create_iam_kms_policy,\n    var.create_iam_operator_policy,\n    var.create_iam_worker_policy,\n  ])\n}\n\nresource \"oci_identity_policy\" \"cluster\" {\n  provider       = oci.home\n  count          = local.has_policy_statements ? 1 : 0\n  compartment_id = var.compartment_id\n  description    = format(\"Policies for OKE Terraform state %v\", var.state_id)\n  name           = var.policy_name\n  statements     = local.policy_statements\n  defined_tags   = local.defined_tags\n  freeform_tags  = local.freeform_tags\n  lifecycle {\n    ignore_changes = [defined_tags, freeform_tags]\n  }\n}\n\nresource \"oci_identity_policy\" \"networking_policies\" {\n  provider       = oci.home\n  count          = alltrue([var.create_iam_resources, var.create_iam_cluster_policy]) ? 1 : 0\n  compartment_id = var.network_compartment_id != null ? var.network_compartment_id : var.compartment_id\n  description    = format(\"Policies for OKE Terraform state %v\", var.state_id)\n  name           = format(\"%v-network\", var.policy_name)\n  statements     = compact([\n    var.enable_ipv6 ? format(\"Allow any-user to use ipv6s in compartment id %v where all { request.principal.type = 'cluster' }\", coalesce(var.network_compartment_id, var.compartment_id)) : null,\n    format(\"Allow any-user to manage network-security-groups in compartment id %v where request.principal.type = 'cluster'\", coalesce(var.network_compartment_id, var.compartment_id)),\n  ])\n  defined_tags   = local.defined_tags\n  freeform_tags  = local.freeform_tags\n  lifecycle {\n    ignore_changes = [defined_tags, freeform_tags]\n  }\n}"
  },
  {
    "path": "modules/iam/tagging.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\ndata \"oci_identity_tag_namespaces\" \"oke\" {\n  count          = var.create_iam_resources ? 1 : 0\n  provider       = oci.home\n  compartment_id = var.compartment_id\n  filter {\n    name   = \"name\"\n    values = [var.tag_namespace]\n  }\n\n  state = \"ACTIVE\" // TODO Support reactivation of retired namespace w/ update\n}\n\nlocals {\n  # Filtered value from data source (only 1 by name, or null)\n  # Identified tag namespace ID when not created and used\n  tag_namespace_id_found = one(\n    one(data.oci_identity_tag_namespaces.oke[*].tag_namespaces)[*].id\n  )\n\n  create_iam_tag_namespace = alltrue([\n    var.create_iam_resources,\n    var.create_iam_tag_namespace,\n    local.tag_namespace_id_found == null,\n  ])\n\n  # Map of standard tags & descriptions to be created if enabled\n  tags = var.create_iam_resources && var.create_iam_defined_tags ? {\n    \"role\"               = \"Functional role of a resource\"\n    \"state_id\"           = \"Terraform state ID associated with a resource\"\n    \"cluster_autoscaler\" = \"Granted permissions for Kubernetes cluster autoscaler\"\n    \"pool\"               = \"Named group of resources with shared configuration\"\n  } : {}\n\n  # Standard tags as freeform if defined tags are disabled\n  freeform_tags = merge(var.freeform_tags, !var.use_defined_tags ? {\n    \"state_id\" = var.state_id,\n    \"role\"     = \"iam\",\n    } : {},\n  )\n\n  # Standard tags as defined if enabled for use\n  defined_tags = merge(var.defined_tags, var.use_defined_tags ? {\n    \"${var.tag_namespace}.state_id\" = var.state_id,\n    \"${var.tag_namespace}.role\"     = \"iam\",\n    } : {},\n  )\n}\n\nresource \"oci_identity_tag_namespace\" \"oke\" {\n  provider       = oci.home\n  count          = local.create_iam_tag_namespace ? 1 : 0\n  compartment_id = var.compartment_id\n  description    = \"Tag namespace for OKE resources\"\n  name           = var.tag_namespace\n  # defined_tags   = local.defined_tags\n  freeform_tags = local.freeform_tags\n  lifecycle {\n    ignore_changes = [defined_tags, freeform_tags]\n  }\n}\n\nresource \"oci_identity_tag\" \"oke\" {\n  provider    = oci.home\n  for_each    = local.create_iam_tag_namespace ? local.tags : {} #{ for k, v in oci_identity_tag_namespace.oke : k => local.tags } # local.create_iam_tag_namespace ? local.tags : {}\n  description = each.value\n  name        = each.key\n  # defined_tags     = local.defined_tags\n  freeform_tags    = local.freeform_tags\n  tag_namespace_id = one(oci_identity_tag_namespace.oke[*].id)\n\n  lifecycle {\n    ignore_changes = [defined_tags, freeform_tags]\n  }\n}\n"
  },
  {
    "path": "modules/iam/variables.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# Common\nvariable \"cluster_id\" { type = string }\nvariable \"compartment_id\" { type = string }\nvariable \"network_compartment_id\" { type = string }\nvariable \"state_id\" { type = string }\nvariable \"tenancy_id\" { type = string }\nvariable \"worker_compartments\" { type = list(string) }\nvariable \"enable_ipv6\" { type = bool }\n# Tags\nvariable \"create_iam_defined_tags\" { type = bool }\nvariable \"create_iam_tag_namespace\" { type = bool }\nvariable \"defined_tags\" { type = map(string) }\nvariable \"freeform_tags\" { type = map(string) }\nvariable \"tag_namespace\" { type = string }\nvariable \"use_defined_tags\" { type = bool }\n\n# Policy\nvariable \"autoscaler_compartments\" { type = list(string) }\nvariable \"create_iam_resources\" { type = bool }\nvariable \"create_iam_cluster_policy\" { type = bool }\nvariable \"create_iam_autoscaler_policy\" { type = bool }\nvariable \"create_iam_kms_policy\" { type = bool }\nvariable \"create_iam_operator_policy\" { type = bool }\nvariable \"create_iam_worker_policy\" { type = bool }\nvariable \"policy_name\" { type = string }\n\n# KMS\nvariable \"cluster_kms_key_id\" { type = string }\nvariable \"operator_volume_kms_key_id\" { type = string }\nvariable \"worker_volume_kms_key_id\" { type = string }\n"
  },
  {
    "path": "modules/iam/versions.tf",
    "content": "// Copyright (c) 2024 Oracle and/or its affiliates\n\n# Copyright (c) 2017, 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nterraform {\n  required_version = \">= 1.2.0\"\n\n  required_providers {\n    oci = {\n      configuration_aliases = [oci.home]\n      source                = \"oracle/oci\"\n      version               = \">= 7.30.0\"\n    }\n  }\n}"
  },
  {
    "path": "modules/network/README.md",
    "content": "# Network\n\nThis sub-module creates the VCN, subnets, network security groups, gateways, routing, DRG, and LPG configurations.\n\n## Usage\n\nRefer to the [Network section](../../docs/terraformoptions.md#network) of the module documentation.\n"
  },
  {
    "path": "modules/network/datasources.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\ndata \"oci_core_services\" \"all_oci_services\" {\n  filter {\n    name   = \"name\"\n    values = [\"All .* Services In Oracle Services Network\"]\n    regex  = true\n  }\n}\n\ndata \"oci_waas_edge_subnets\" \"waf_cidr_blocks\" {\n  count = var.enable_waf ? 1 : 0\n}\n"
  },
  {
    "path": "modules/network/drgs.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  drg_attachments = (var.drg_attachments == null ? {}\n    : { for k, v in var.drg_attachments : k => v if tobool(lookup(v, \"create\", true)) }\n  )\n}\n\n// Create a DRG if any attachments are defined\nresource \"oci_core_drg\" \"oke\" {\n  count          = length(local.drg_attachments) > 0 ? 1 : 0\n  compartment_id = var.compartment_id\n  display_name   = \"oke-${var.state_id}\"\n  defined_tags   = var.defined_tags\n  freeform_tags  = var.freeform_tags\n  lifecycle {\n    ignore_changes = [freeform_tags, defined_tags]\n  }\n}\n\n// Attach the current VCN to the DRG\nresource \"oci_core_drg_attachment\" \"oke\" {\n  count         = length(local.drg_attachments) > 0 && length(oci_core_drg.oke[*]) > 0 ? 1 : 0\n  drg_id        = one(oci_core_drg.oke[*].id)\n  display_name  = \"drg-oke-${var.state_id}\"\n  defined_tags  = var.defined_tags\n  freeform_tags = var.freeform_tags\n\n  network_details {\n    id   = var.vcn_id\n    type = \"VCN\"\n  }\n\n  lifecycle {\n    ignore_changes = [freeform_tags, defined_tags]\n  }\n}\n\n// Attach configured VCNs to the DRG\nresource \"oci_core_drg_attachment\" \"extra\" {\n  for_each      = local.drg_attachments\n  drg_id        = one(oci_core_drg.oke[*].id)\n  display_name  = format(\"%v-%v\", each.key, var.state_id)\n  defined_tags  = var.defined_tags\n  freeform_tags = var.freeform_tags\n\n  network_details {\n    id   = lookup(each.value, \"vcn_id\")\n    type = \"VCN\"\n  }\n\n  lifecycle {\n    precondition {\n      condition     = alltrue([for k, v in local.drg_attachments : contains(keys(v), \"vcn_id\")])\n      error_message = \"DRG attachments must specify a 'vcn_id'.\"\n    }\n    ignore_changes = [freeform_tags, defined_tags]\n  }\n}\n"
  },
  {
    "path": "modules/network/locals.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  # Port numbers\n  all_ports               = -1\n  apiserver_port          = 6443\n  fss_nfs_portmapper_port = 111\n  fss_nfs_port_min        = 2048\n  fss_nfs_port_max        = 2050\n  health_check_port       = 10256\n  kubelet_api_port        = 10250\n  oke_port                = 12250\n  node_port_min           = 30000\n  node_port_max           = 32767\n  ssh_port                = 22\n\n  # Protocols\n  # See https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml\n  all_protocols   = \"all\"\n  icmp_protocol   = 1\n  icmpv6_protocol = 58\n  tcp_protocol    = 6\n  udp_protocol    = 17\n\n\n  anywhere          = \"0.0.0.0/0\"\n  anywhere_ipv6     = \"::/0\"\n  rule_type_nsg     = \"NETWORK_SECURITY_GROUP\"\n  rule_type_cidr    = \"CIDR_BLOCK\"\n  rule_type_service = \"SERVICE_CIDR_BLOCK\"\n\n  # Oracle Services Network (OSN)\n  osn = one(data.oci_core_services.all_oci_services.services[*].cidr_block)\n}\n"
  },
  {
    "path": "modules/network/nsg-bastion.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  bastion_nsg_config = try(var.nsgs.bastion, { create = \"never\" })\n  bastion_nsg_create = coalesce(lookup(local.bastion_nsg_config, \"create\", null), \"auto\")\n  bastion_nsg_enabled = anytrue([\n    local.bastion_nsg_create == \"always\",\n    alltrue([\n      local.bastion_nsg_create == \"auto\",\n      coalesce(lookup(local.bastion_nsg_config, \"id\", null), \"none\") == \"none\",\n      var.create_bastion,\n    ]),\n  ])\n  # Return provided NSG when configured with an existing ID or created resource ID\n  bastion_nsg_id = one(compact([try(var.nsgs.bastion.id, null), one(oci_core_network_security_group.bastion[*].id)]))\n  bastion_rules = local.bastion_nsg_enabled ? ( var.use_stateless_rules ? local.bastion_stateless_rules: local.bastion_stateful_rules ) : {}\n\n  bastion_stateful_rules = merge(\n    { for cidr in var.bastion_allowed_cidrs :\n      \"Allow SSH ingress to bastion from ${cidr}\" => {\n        protocol = local.tcp_protocol, port = local.ssh_port, source = cidr, source_type = local.rule_type_cidr,\n      }\n    },\n    {\n      \"Allow TCP egress from bastion to OCI services\" : {\n        protocol = local.tcp_protocol, port = local.all_ports, destination = local.osn, destination_type = local.rule_type_service,\n      },\n    },\n    local.operator_nsg_enabled ? {\n      \"Allow SSH egress from bastion to operator\" = {\n        protocol = local.tcp_protocol, port = local.ssh_port, destination = local.operator_nsg_id, destination_type = local.rule_type_nsg,\n      },\n    } : {},\n    var.allow_worker_ssh_access && local.worker_nsg_enabled ? {\n      \"Allow SSH egress from bastion to workers\" = {\n        protocol = local.tcp_protocol, port = local.ssh_port, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n    } : {},\n    (var.allow_bastion_cluster_access && local.control_plane_nsg_enabled) ? {\n      \"Allow TCP egress from bastion to cluster endpoint\" = {\n        protocol = local.tcp_protocol, port = local.apiserver_port, destination = local.control_plane_nsg_id, destination_type = local.rule_type_nsg,\n      },\n    } : {},\n  )\n\n  bastion_stateless_rules = merge(\n    { for cidr in var.bastion_allowed_cidrs :\n      \"Allow SSH ingress to bastion from ${cidr}\" => {\n        protocol = local.tcp_protocol, port = local.ssh_port, source = cidr, source_type = local.rule_type_cidr,\n      }\n    },\n    {\n      \"Allow TCP egress from bastion to OCI services\" : {\n        protocol = local.tcp_protocol, port = local.all_ports, destination = local.osn, destination_type = local.rule_type_service,\n      },\n    },\n    local.operator_nsg_enabled ? {\n      \"Allow SSH egress from bastion to operator\" = {\n        protocol = local.tcp_protocol, port = local.ssh_port, destination = local.operator_nsg_id, destination_type = local.rule_type_nsg,\n      },\n    } : {},\n    var.allow_worker_ssh_access && local.worker_nsg_enabled ? {\n      \"Allow SSH egress from bastion to workers\" = {\n        protocol = local.tcp_protocol, port = local.ssh_port, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n    } : {},\n    (var.allow_bastion_cluster_access && local.control_plane_nsg_enabled) ? {\n      \"Allow TCP egress from bastion to cluster endpoint\" = {\n        protocol = local.tcp_protocol, port = local.apiserver_port, destination = local.control_plane_nsg_id, destination_type = local.rule_type_nsg,\n      },\n    } : {},\n  )\n}\n\nresource \"oci_core_network_security_group\" \"bastion\" {\n  count          = local.bastion_nsg_enabled ? 1 : 0\n  compartment_id = var.compartment_id\n  display_name   = \"bastion-${var.state_id}\"\n  vcn_id         = var.vcn_id\n  defined_tags   = var.defined_tags\n  freeform_tags  = var.freeform_tags\n  lifecycle {\n    ignore_changes = [defined_tags, freeform_tags, display_name, vcn_id]\n  }\n}\n\noutput \"bastion_nsg_id\" {\n  value = local.bastion_nsg_id\n}\n"
  },
  {
    "path": "modules/network/nsg-controlplane.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  control_plane_nsg_config = try(var.nsgs.cp, { create = \"never\" })\n  control_plane_nsg_create = coalesce(lookup(local.control_plane_nsg_config, \"create\", null), \"auto\")\n  control_plane_nsg_enabled = anytrue([\n    local.control_plane_nsg_create == \"always\",\n    alltrue([\n      local.control_plane_nsg_create == \"auto\",\n      coalesce(lookup(local.control_plane_nsg_config, \"id\", null), \"none\") == \"none\",\n      var.create_cluster,\n    ]),\n  ])\n  # Return provided NSG when configured with an existing ID or created resource ID\n  control_plane_nsg_id = one(compact([try(var.nsgs.cp.id, null), one(oci_core_network_security_group.cp[*].id)]))\n  control_plane_rules = local.control_plane_nsg_enabled ? ( var.use_stateless_rules ? local.control_plane_stateless_rules: local.control_plane_stateful_rules ) : {}\n  \n  control_plane_stateful_rules= merge(\n    {\n      \"Allow TCP egress from OKE control plane to OCI services\" : {\n        protocol = local.tcp_protocol, port = local.all_ports, destination = local.osn, destination_type = local.rule_type_service,\n      },\n      \"Allow TCP egress from OKE control plane to Kubelet on worker nodes\" : {\n        protocol = local.tcp_protocol, port = local.kubelet_api_port, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n\n      \"Allow TCP ingress to OKE control plane from worker nodes\" : {\n        protocol = local.tcp_protocol, port = local.oke_port, source = local.worker_nsg_id, source_type = local.rule_type_nsg,\n      },\n      \"Allow TCP egress from OKE control plane to worker nodes\" : {\n        protocol = local.tcp_protocol, port = local.oke_port, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n\n      \"Allow TCP egress for Kubernetes control plane inter-communication\" : {\n        protocol = local.tcp_protocol, port = local.apiserver_port, destination = local.control_plane_nsg_id, destination_type = local.rule_type_nsg,\n      },\n      \"Allow TCP ingress for Kubernetes control plane inter-communication\" : {\n        protocol = local.tcp_protocol, port = local.apiserver_port, source = local.control_plane_nsg_id, source_type = local.rule_type_nsg,\n      },\n      \"Allow TCP ingress to kube-apiserver from worker nodes\" : {\n        protocol = local.tcp_protocol, port = local.apiserver_port, source = local.worker_nsg_id, source_type = local.rule_type_nsg,\n      },\n\n      \"Allow ICMP egress for path discovery to worker nodes\" : {\n        protocol = local.icmp_protocol, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n      \"Allow ICMP ingress for path discovery from worker nodes\" : {\n        protocol = local.icmp_protocol, source = local.worker_nsg_id, source_type = local.rule_type_nsg,\n      },\n    },\n    var.enable_ipv6 ? {\n      \"Allow ICMPv6 egress for path discovery to worker nodes\" : {\n        protocol = local.icmpv6_protocol, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n      \"Allow ICMPv6 ingress for path discovery from worker nodes\" : {\n        protocol = local.icmpv6_protocol, source = local.worker_nsg_id, source_type = local.rule_type_nsg,\n      },\n    } : {},\n    local.operator_nsg_enabled ? {\n      \"Allow TCP ingress to kube-apiserver from operator instance\" : {\n        protocol = local.tcp_protocol, port = local.apiserver_port, source = local.operator_nsg_id, source_type = local.rule_type_nsg,\n      },\n    } : {},\n    local.pod_nsg_enabled ? {\n      \"Allow TCP ingress to kube-apiserver from pods\" : {\n        protocol = local.tcp_protocol, port = local.apiserver_port, source = local.pod_nsg_id, source_type = local.rule_type_nsg,\n      },\n      \"Allow TCP ingress to OKE control plane from pods\" : {\n        protocol = local.tcp_protocol, port = local.oke_port, source = local.pod_nsg_id, source_type = local.rule_type_nsg,\n      },\n      \"Allow TCP egress from OKE control plane to pods\" : {\n        protocol = local.tcp_protocol, port = local.all_ports, destination = local.pod_nsg_id, destination_type = local.rule_type_nsg,\n      }\n    } : {},\n    (var.allow_bastion_cluster_access && local.bastion_nsg_enabled) ? {\n      \"Allow TCP ingress to kube-apiserver from bastion host\" = {\n        protocol = local.tcp_protocol, port = local.apiserver_port, source = local.bastion_nsg_id, source_type = local.rule_type_nsg,\n      },\n    } : {},\n\n    { for allowed_cidr in var.control_plane_allowed_cidrs :\n      \"Allow TCP ingress to kube-apiserver from ${allowed_cidr}\" => {\n        protocol = local.tcp_protocol, port = local.apiserver_port, source = allowed_cidr, source_type = local.rule_type_cidr\n      }\n    },\n    var.allow_rules_cp\n  )\n\n  control_plane_stateless_rules= merge(\n    {\n      \"Allow TCP egress from OKE control plane to OCI services\" : {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.osn, destination_type = local.rule_type_service, stateless = true\n      },\n      \"Allow TCP ingress to OKE control plane from OCI services\" : {\n        protocol = local.all_protocols, port = local.all_ports, source = local.osn, source_type = local.rule_type_service, stateless = true\n      },\n\n      \"Allow ingress to OKE control plane from worker nodes\" : {\n        protocol = local.all_protocols, port = local.all_ports, source = local.worker_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow egress from OKE control plane to worker nodes\" : {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n\n      \"Allow TCP ingress for Kubernetes control plane inter-communication\" : {\n        protocol = local.tcp_protocol, destination_port_min = local.apiserver_port, destination_port_max = local.apiserver_port, source = local.control_plane_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow TCP egress for Kubernetes control plane inter-communication\" : {\n        protocol = local.tcp_protocol, source_port_min = local.apiserver_port, source_port_max = local.apiserver_port, destination = local.control_plane_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n    },\n    var.enable_ipv6 ? {\n      \"Allow ICMPv6 egress for path discovery to worker nodes\" : {\n        protocol = local.icmpv6_protocol, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n      \"Allow ICMPv6 ingress for path discovery from worker nodes\" : {\n        protocol = local.icmpv6_protocol, source = local.worker_nsg_id, source_type = local.rule_type_nsg,\n      },\n    } : {},\n    local.operator_nsg_enabled ? {\n      \"Allow TCP ingress to kube-apiserver from operator instance\" : {\n        protocol = local.tcp_protocol, destination_port_min = local.apiserver_port, destination_port_max = local.apiserver_port, source = local.operator_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow TCP egress from kube-apiserver to operator instance\" : {\n        protocol = local.tcp_protocol, source_port_min = local.apiserver_port, source_port_max = local.apiserver_port, destination = local.operator_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n    } : {},\n    local.pod_nsg_enabled ? {\n      \"Allow TCP ingress to OKE control plane from pods\" : {\n        protocol = local.all_protocols, port = local.all_ports, source = local.pod_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      }\n      \"Allow TCP egress from OKE control plane to pods\" : {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.pod_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      }\n    } : {},\n    (var.allow_bastion_cluster_access && local.bastion_nsg_enabled) ? {\n      \"Allow TCP ingress to kube-apiserver from bastion host\" = {\n        protocol = local.tcp_protocol, destination_port_min = local.apiserver_port, destination_port_max = local.apiserver_port, source = local.bastion_nsg_id, source_type = local.rule_type_nsg\n      },\n    } : {},\n\n    { for allowed_cidr in var.control_plane_allowed_cidrs :\n      \"Allow TCP ingress to kube-apiserver from ${allowed_cidr}\" => {\n        protocol = local.tcp_protocol, destination_port_min = local.apiserver_port, destination_port_max = local.apiserver_port, source = allowed_cidr, source_type = local.rule_type_cidr\n      }\n    },\n    var.allow_rules_cp\n  )\n}\n\nresource \"oci_core_network_security_group\" \"cp\" {\n  count          = local.control_plane_nsg_enabled ? 1 : 0\n  compartment_id = var.compartment_id\n  display_name   = \"cp-${var.state_id}\"\n  vcn_id         = var.vcn_id\n  defined_tags   = var.defined_tags\n  freeform_tags  = var.freeform_tags\n  lifecycle {\n    ignore_changes = [defined_tags, freeform_tags, display_name, vcn_id]\n  }\n}\n\noutput \"control_plane_nsg_id\" {\n  value = local.control_plane_nsg_id\n}\n"
  },
  {
    "path": "modules/network/nsg-fss.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  fss_nsg_config = try(var.nsgs.fss, { create = \"never\" })\n  fss_nsg_create = coalesce(lookup(local.fss_nsg_config, \"create\", null), \"auto\")\n  fss_nsg_enabled = anytrue([\n    local.fss_nsg_create == \"always\",\n    alltrue([\n      local.fss_nsg_create == \"auto\",\n      coalesce(lookup(local.fss_nsg_config, \"id\", null), \"none\") == \"none\",\n      var.create_cluster,\n    ]),\n  ])\n  # Return provided NSG when configured with an existing ID or created resource ID\n  fss_nsg_id = one(compact([try(var.nsgs.fss.id, null), one(oci_core_network_security_group.fss[*].id)]))\n  fss_rules = local.fss_nsg_enabled ? ( var.use_stateless_rules ? local.fss_stateless_rules: local.fss_stateful_rules ) : {}\n  \n  fss_stateful_rules = {\n    # See https://docs.oracle.com/en-us/iaas/Content/File/Tasks/securitylistsfilestorage.htm\n    # Ingress\n    \"Allow UDP ingress for NFS portmapper from workers\" : {\n      protocol = local.udp_protocol, port = local.fss_nfs_portmapper_port, source = local.worker_nsg_id, source_type = local.rule_type_nsg,\n    },\n    \"Allow TCP ingress for NFS portmapper from workers\" : {\n      protocol = local.tcp_protocol, port = local.fss_nfs_portmapper_port, source = local.worker_nsg_id, source_type = local.rule_type_nsg,\n    },\n    \"Allow UDP ingress for NFS from workers\" : {\n      protocol = local.udp_protocol, port = local.fss_nfs_port_min, source = local.worker_nsg_id, source_type = local.rule_type_nsg,\n    },\n    \"Allow TCP ingress for NFS from workers\" : {\n      protocol = local.tcp_protocol, port_min = local.fss_nfs_port_min, port_max = local.fss_nfs_port_max, source = local.worker_nsg_id, source_type = local.rule_type_nsg,\n    },\n\n    # Egress\n    \"Allow UDP egress for NFS portmapper to the workers\" : {\n      protocol = local.udp_protocol, source_port_min = local.fss_nfs_portmapper_port, source_port_max = local.fss_nfs_portmapper_port, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n    },\n    \"Allow TCP egress for NFS portmapper to the workers\" : {\n      protocol = local.tcp_protocol, source_port_min = local.fss_nfs_portmapper_port, source_port_max = local.fss_nfs_portmapper_port, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n    },\n    \"Allow TCP egress for NFS to the workers\" : {\n      protocol = local.tcp_protocol, source_port_min = local.fss_nfs_port_min, source_port_max = local.fss_nfs_port_max, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n    },\n  }\n\n  fss_stateless_rules = {\n    # See https://docs.oracle.com/en-us/iaas/Content/File/Tasks/securitylistsfilestorage.htm\n    # Ingress\n    \"Allow UDP ingress for NFS portmapper from workers\" : {\n      protocol = local.udp_protocol, destination_port_min = local.fss_nfs_portmapper_port, destination_port_max = local.fss_nfs_portmapper_port, source = local.worker_nsg_id, source_type = local.rule_type_nsg, stateless = true\n    },\n    \"Allow UDP egress for NFS portmapper to workers\" : {\n      protocol = local.udp_protocol, source_port_min = local.fss_nfs_portmapper_port, source_port_max = local.fss_nfs_portmapper_port, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n    },\n\n    \"Allow TCP ingress for NFS portmapper from workers\" : {\n      protocol = local.tcp_protocol, destination_port_min = local.fss_nfs_portmapper_port, destination_port_max = local.fss_nfs_portmapper_port, source = local.worker_nsg_id, source_type = local.rule_type_nsg, stateless = true\n    },\n    \"Allow TCP egress for NFS portmapper to workers\" : {\n      protocol = local.tcp_protocol, source_port_min = local.fss_nfs_portmapper_port, source_port_max = local.fss_nfs_portmapper_port, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n    },\n\n    \"Allow UDP ingress for NFS from workers\" : {\n      protocol = local.udp_protocol, destination_port_min = local.fss_nfs_port_min, destination_port_max = local.fss_nfs_port_min, source = local.worker_nsg_id, source_type = local.rule_type_nsg, stateless = true\n    },\n    \"Allow UDP egress for NFS to workers\" : {\n      protocol = local.udp_protocol, source_port_min = local.fss_nfs_port_min, source_port_max = local.fss_nfs_port_min, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n    },\n\n    \"Allow TCP ingress for NFS from workers\" : {\n      protocol = local.tcp_protocol, destination_port_min = local.fss_nfs_port_min, destination_port_max = local.fss_nfs_port_max, source = local.worker_nsg_id, source_type = local.rule_type_nsg, stateless = true\n    },\n    \"Allow TCP egress for NFS to workers\" : {\n      protocol = local.tcp_protocol, source_port_min = local.fss_nfs_port_min, source_port_max = local.fss_nfs_port_max, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n    },\n  }\n}\n\nresource \"oci_core_network_security_group\" \"fss\" {\n  count          = local.fss_nsg_enabled ? 1 : 0\n  compartment_id = var.compartment_id\n  display_name   = \"fss-${var.state_id}\"\n  vcn_id         = var.vcn_id\n  defined_tags   = var.defined_tags\n  freeform_tags  = var.freeform_tags\n  lifecycle {\n    ignore_changes = [defined_tags, freeform_tags, display_name, vcn_id]\n  }\n}\n\noutput \"fss_nsg_id\" {\n  value = local.fss_nsg_id\n}\n"
  },
  {
    "path": "modules/network/nsg-loadbalancers-int.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  int_lb_nsg_config = try(var.nsgs.int_lb, { create = \"never\" })\n  int_lb_nsg_create = coalesce(lookup(local.int_lb_nsg_config, \"create\", null), \"auto\")\n  int_lb_nsg_enabled = anytrue([\n    local.int_lb_nsg_create == \"always\",\n    alltrue([\n      local.int_lb_nsg_create == \"auto\",\n      coalesce(lookup(local.int_lb_nsg_config, \"id\", null), \"none\") == \"none\",\n      var.create_cluster, var.load_balancers == \"internal\" || var.load_balancers == \"both\",\n    ]),\n  ])\n  # Return provided NSG when configured with an existing ID or created resource ID\n  int_lb_nsg_id = one(compact([try(var.nsgs.int_lb.id, null), one(oci_core_network_security_group.int_lb[*].id)]))\n  int_lb_rules = local.int_lb_nsg_enabled ? ( var.use_stateless_rules ? local.int_lb_stateless_rules: local.int_lb_stateful_rules ) : {}\n  int_lb_stateful_rules = merge(\n    {\n      \"Allow TCP egress from internal load balancers to workers for Node Ports\" : {\n        protocol = local.tcp_protocol, port_min = local.node_port_min, port_max = local.node_port_max, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n      \"Allow UDP egress from internal load balancers to workers for Node Ports\" : {\n        protocol = local.udp_protocol, port_min = local.node_port_min, port_max = local.node_port_max, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n      \"Allow ICMP egress from internal load balancers to worker nodes for path discovery\" : {\n        protocol = local.icmp_protocol, port = local.all_ports, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n      \"Allow TCP egress from internal load balancers to workers for health checks\" : {\n        protocol = local.tcp_protocol, port = local.health_check_port, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n    },\n    \n    local.pod_nsg_enabled ? {\n      \"Allow all egress from internal load balancers to pods\" : {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.pod_nsg_id, destination_type = local.rule_type_nsg,\n      },\n    } : {},\n    \n    var.enable_ipv6 ? {\n      \"Allow ICMPv6 egress from internal load balancers to worker nodes for path discovery\" : {\n        protocol = local.icmpv6_protocol, port = local.all_ports, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n    } : {},\n    var.enable_waf ? local.waf_rules : {},\n    var.allow_rules_internal_lb,\n  )\n\n  int_lb_stateless_rules = merge(\n    {\n      \"Allow TCP egress from internal load balancers to workers for Node Ports\" : {\n        protocol = local.tcp_protocol, destination_port_min = local.node_port_min, destination_port_max = local.node_port_max, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow TCP ingress to internal load balancers from workers for Node Ports\" : {\n        protocol = local.tcp_protocol, source_port_min = local.node_port_min, source_port_max = local.node_port_max, source = local.worker_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n      \n      \"Allow UDP egress from internal load balancers to workers for Node Ports\" : {\n        protocol = local.udp_protocol, destination_port_min = local.node_port_min, destination_port_max = local.node_port_max, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow UDP ingress to internal load balancers from workers for Node Ports\" : {\n        protocol = local.udp_protocol, source_port_min = local.node_port_min, source_port_max = local.node_port_max, source = local.worker_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n\n      \"Allow TCP egress from internal load balancers to pods for health checks\" : {\n        protocol = local.tcp_protocol, destination_port_min = local.health_check_port, destination_port_max = local.health_check_port, destination = local.pod_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow TCP egress to internal load balancers from pods for health checks\" : {\n        protocol = local.tcp_protocol, source_port_min = local.health_check_port, source_port_max = local.health_check_port, source = local.pod_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n\n      \"Allow ICMP egress from internal load balancers to worker nodes for path discovery\" : {\n        protocol = local.icmp_protocol, port = local.all_ports, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n    },\n\n    local.pod_nsg_enabled ? {\n      \"Allow all egress from internal load balancers to pods\" : {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.pod_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow all ingress from pods to internal load balancers\" : {\n        protocol = local.all_protocols, port = local.all_ports, source = local.pod_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n    } : {},\n\n    var.enable_ipv6 ? {\n      \"Allow ICMPv6 egress from internal load balancers to worker nodes for path discovery\" : {\n        protocol = local.icmpv6_protocol, port = local.all_ports, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n    } : {},\n    var.enable_waf ? local.waf_rules : {},\n    var.allow_rules_internal_lb,\n  )\n}\n\nresource \"oci_core_network_security_group\" \"int_lb\" {\n  count          = local.int_lb_nsg_enabled ? 1 : 0\n  compartment_id = var.compartment_id\n  display_name   = \"int_lb-${var.state_id}\"\n  vcn_id         = var.vcn_id\n  defined_tags   = var.defined_tags\n  freeform_tags  = var.freeform_tags\n  lifecycle {\n    ignore_changes = [defined_tags, freeform_tags, display_name, vcn_id]\n  }\n}\n\noutput \"int_lb_nsg_id\" {\n  value = local.int_lb_nsg_id\n}\n"
  },
  {
    "path": "modules/network/nsg-loadbalancers-pub.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  pub_lb_nsg_config = try(var.nsgs.pub_lb, { create = \"never\" })\n  pub_lb_nsg_create = coalesce(lookup(local.pub_lb_nsg_config, \"create\", null), \"auto\")\n  pub_lb_nsg_enabled = anytrue([\n    local.pub_lb_nsg_create == \"always\",\n    alltrue([\n      local.pub_lb_nsg_create == \"auto\",\n      coalesce(lookup(local.pub_lb_nsg_config, \"id\", null), \"none\") == \"none\",\n      var.create_cluster, var.load_balancers == \"public\" || var.load_balancers == \"both\",\n    ]),\n  ])\n  # Return provided NSG when configured with an existing ID or created resource ID\n  pub_lb_nsg_id = one(compact([try(var.nsgs.pub_lb.id, null), one(oci_core_network_security_group.pub_lb[*].id)]))\n  pub_lb_rules = local.pub_lb_nsg_enabled ? ( var.use_stateless_rules ? local.pub_lb_stateless_rules: local.pub_lb_stateful_rules ) : {}\n  \n  pub_lb_stateful_rules = merge(\n    {\n      \"Allow TCP egress from public load balancers to workers nodes for NodePort traffic\" : {\n        protocol = local.tcp_protocol, port_min = local.node_port_min, port_max = local.node_port_max, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n      \"Allow UDP egress from public load balancers to workers nodes for NodePort traffic\" : {\n        protocol = local.udp_protocol, port_min = local.node_port_min, port_max = local.node_port_max, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n      \"Allow TCP egress from public load balancers to worker nodes for health checks\" : {\n        protocol = local.tcp_protocol, port = local.health_check_port, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n      \"Allow ICMP egress from public load balancers to worker nodes for path discovery\" : {\n        protocol = local.icmp_protocol, port = local.all_ports, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n    },\n\n    local.pod_nsg_enabled ? {\n      \"Allow all egress from public load balancers to pods\" : {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.pod_nsg_id, destination_type = local.rule_type_nsg,\n      },\n    } : {},\n\n    var.enable_ipv6 ? {\n      \"Allow ICMPv6 egress from public load balancers to worker nodes for path discovery\" : {\n        protocol = local.icmpv6_protocol, port = local.all_ports, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n    } : {},\n    var.enable_waf ? local.waf_rules : {},\n    var.allow_rules_public_lb,\n  )\n\n  pub_lb_stateless_rules = merge(\n    {\n      \"Allow TCP egress from public load balancers to workers nodes for NodePort traffic\" : {\n        protocol = local.tcp_protocol, destination_port_min = local.node_port_min, destination_port_max = local.node_port_max, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow TCP ingress to public load balancers from workers nodes for NodePort traffic\" : {\n        protocol = local.tcp_protocol, source_port_min = local.node_port_min, source_port_max = local.node_port_max, source = local.worker_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n\n      \"Allow UDP egress from public load balancers to workers nodes for NodePort traffic\" : {\n        protocol = local.udp_protocol, destination_port_min = local.node_port_min, destination_port_max = local.node_port_max, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow UDP ingress to public load balancers from workers nodes for NodePort traffic\" : {\n        protocol = local.udp_protocol, source_port_min = local.node_port_min, source_port_max = local.node_port_max, source = local.worker_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n\n      \"Allow TCP egress from public load balancers to worker nodes for health checks\" : {\n        protocol = local.tcp_protocol, destination_port_min = local.health_check_port, destination_port_max = local.health_check_port, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow TCP ingress to public load balancers from worker nodes for health checks\" : {\n        protocol = local.tcp_protocol, source_port_min = local.health_check_port, source_port_max = local.health_check_port, source = local.worker_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n\n      \"Allow ICMP egress from public load balancers to worker nodes for path discovery\" : {\n        protocol = local.icmp_protocol, port = local.all_ports, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n    },\n\n    local.pod_nsg_enabled ? {\n      \"Allow all egress from public load balancers to pods\" : {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.pod_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow all ingress from pods to public load balancers\" : {\n        protocol = local.all_protocols, port = local.all_ports, source = local.pod_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n    } : {},\n\n    var.enable_ipv6 ? {\n      \"Allow ICMPv6 egress from public load balancers to worker nodes for path discovery\" : {\n        protocol = local.icmpv6_protocol, port = local.all_ports, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n    } : {},\n    var.enable_waf ? local.waf_rules : {},\n    var.allow_rules_public_lb,\n  )\n}\n\nresource \"oci_core_network_security_group\" \"pub_lb\" {\n  count          = local.pub_lb_nsg_enabled ? 1 : 0\n  compartment_id = var.compartment_id\n  display_name   = \"pub_lb-${var.state_id}\"\n  vcn_id         = var.vcn_id\n  defined_tags   = var.defined_tags\n  freeform_tags  = var.freeform_tags\n  lifecycle {\n    ignore_changes = [defined_tags, freeform_tags, display_name, vcn_id]\n  }\n}\n\noutput \"pub_lb_nsg_id\" {\n  value = local.pub_lb_nsg_id\n}\n"
  },
  {
    "path": "modules/network/nsg-operator.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  operator_nsg_config = try(var.nsgs.operator, { create = \"never\" })\n  operator_nsg_create = coalesce(lookup(local.operator_nsg_config, \"create\", null), \"auto\")\n  operator_nsg_enabled = anytrue([\n    local.operator_nsg_create == \"always\",\n    alltrue([\n      local.operator_nsg_create == \"auto\",\n      coalesce(lookup(local.operator_nsg_config, \"id\", null), \"none\") == \"none\",\n      var.create_cluster, var.create_operator,\n    ]),\n  ])\n  # Return provided NSG when configured with an existing ID or created resource ID\n  operator_nsg_id = one(compact([try(var.nsgs.operator.id, null), one(oci_core_network_security_group.operator[*].id)]))\n  operator_rules = local.operator_nsg_enabled ? ( var.use_stateless_rules ? local.operator_stateless_rules: local.operator_stateful_rules ) : {}\n  \n  operator_stateful_rules = merge(\n    {\n      \"Allow TCP egress from operator to OCI services\" : {\n        protocol = local.tcp_protocol, port = local.all_ports, destination = local.osn, destination_type = local.rule_type_service,\n      },\n      \"Allow TCP egress from operator to Kubernetes API server\" : {\n        protocol = local.tcp_protocol, port = local.apiserver_port, destination = local.control_plane_nsg_id, destination_type = local.rule_type_nsg,\n      },\n      \"Allow ALL egress from operator to internet\" : {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.anywhere, destination_type = local.rule_type_cidr,\n      },\n    },\n\n    local.bastion_nsg_enabled ? merge(\n      var.enable_ipv6 ? {\n        \"Allow ICMPv6 ingress to operator from bastion for path discovery\" : {\n          protocol = local.icmpv6_protocol, source = local.bastion_nsg_id, source_type = local.rule_type_nsg,\n        }\n      } : {},\n      {\n        \"Allow ICMP ingress to operator from bastion for path discovery\" : {\n          protocol = local.icmp_protocol, source = local.bastion_nsg_id, source_type = local.rule_type_nsg,\n        }\n        \"Allow SSH ingress to operator from bastion\" : {\n          protocol = local.tcp_protocol, port = local.ssh_port, source = local.bastion_nsg_id, source_type = local.rule_type_nsg,\n        }\n    }) : {},\n  )\n\n  operator_stateless_rules = merge(\n    {\n      \"Allow TCP egress from operator to OCI services\" : {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.osn, destination_type = local.rule_type_service\n      },\n\n      \"Allow TCP egress from operator to Kubernetes API server\" : {\n        protocol = local.tcp_protocol, destination_port_min = local.apiserver_port, destination_port_max = local.apiserver_port, destination = local.control_plane_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow TCP ingress to operator from Kubernetes API server\" : {\n        protocol = local.tcp_protocol, source_port_min = local.apiserver_port, source_port_max = local.apiserver_port, source = local.control_plane_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n\n      \"Allow ALL egress from operator to all\" : {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.anywhere, destination_type = local.rule_type_cidr\n      }\n    },\n\n    local.bastion_nsg_enabled ? merge(\n      var.enable_ipv6 ? {\n        \"Allow ICMPv6 ingress to operator from bastion for path discovery\" : {\n          protocol = local.icmpv6_protocol, source = local.bastion_nsg_id, source_type = local.rule_type_nsg,\n        }\n      } : {},\n      {\n        \"Allow ICMP ingress to operator from bastion for path discovery\" : {\n          protocol = local.icmp_protocol, source = local.bastion_nsg_id, source_type = local.rule_type_nsg,\n        }\n        \"Allow ingress to operator SSH from bastion\" : {\n          protocol = local.tcp_protocol, destination_port_min = local.ssh_port, destination_port_max = local.ssh_port, source = local.bastion_nsg_id, source_type = local.rule_type_nsg\n        },\n    }) : {},\n  )\n}\n\nresource \"oci_core_network_security_group\" \"operator\" {\n  count          = local.operator_nsg_enabled ? 1 : 0\n  compartment_id = var.compartment_id\n  display_name   = \"operator-${var.state_id}\"\n  vcn_id         = var.vcn_id\n  defined_tags   = var.defined_tags\n  freeform_tags  = var.freeform_tags\n  lifecycle {\n    ignore_changes = [defined_tags, freeform_tags, display_name, vcn_id]\n  }\n}\n\noutput \"operator_nsg_id\" {\n  value = local.operator_nsg_id\n}\n"
  },
  {
    "path": "modules/network/nsg-pods.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  pod_nsg_config = try(var.nsgs.pods, { create = \"never\" })\n  pod_nsg_create = coalesce(lookup(local.pod_nsg_config, \"create\", null), \"auto\")\n  pod_nsg_enabled = anytrue([\n    local.pod_nsg_create == \"always\",\n    alltrue([\n      local.pod_nsg_create == \"auto\",\n      coalesce(lookup(local.pod_nsg_config, \"id\", null), \"none\") == \"none\",\n      var.create_cluster, var.cni_type == \"npn\",\n    ]),\n  ])\n  # Return provided NSG when configured with an existing ID or created resource ID\n  pod_nsg_id = one(compact([try(var.nsgs.pods.id, null), one(oci_core_network_security_group.pods[*].id)]))\n  pods_rules = local.pod_nsg_enabled ? ( var.use_stateless_rules ? local.pod_stateless_rules: local.pod_stateful_rules ) : {}\n  \n  pod_stateful_rules = merge(\n    {\n      \"Allow TCP egress from pods to OCI Services\" : {\n        protocol = local.tcp_protocol, port = local.all_ports, destination = local.osn, destination_type = local.rule_type_service,\n      },\n\n      \"Allow ALL egress from pods to other pods\" = {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.pod_nsg_id, destination_type = local.rule_type_nsg,\n      }\n      \"Allow ALL ingress to pods from other pods\" = {\n        protocol = local.all_protocols, port = local.all_ports, source = local.pod_nsg_id, source_type = local.rule_type_nsg,\n      }\n\n      \"Allow TCP egress from pods to Kubernetes API server\" = {\n        protocol = local.tcp_protocol, port = local.apiserver_port, destination = local.control_plane_nsg_id, destination_type = local.rule_type_nsg,\n      }\n      \"Allow ALL ingress to pods from Kubernetes control plane for webhooks served by pods\" = {\n        protocol = local.all_protocols, port = local.all_ports, source = local.control_plane_nsg_id, source_type = local.rule_type_nsg,\n      }\n\n      \"Allow ALL egress from pods for cross-node pod communication when using NodePorts or hostNetwork: true\" = {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      }\n      \"Allow ALL ingress to pods for cross-node pod communication when using NodePorts or hostNetwork: true\" = {\n        protocol = local.all_protocols, port = local.all_ports, source = local.worker_nsg_id, source_type = local.rule_type_nsg,\n      }\n\n      \"Allow ICMP egress from pods for path discovery\" = {\n        protocol = local.icmp_protocol, port = local.all_ports, destination = local.anywhere, destination_type = local.rule_type_cidr,\n      }\n      \"Allow ICMP ingress to pods for path discovery\" = {\n        protocol = local.icmp_protocol, port = local.all_ports, source = local.anywhere, source_type = local.rule_type_cidr,\n      },\n    },\n\n    local.int_lb_nsg_enabled ? {\n      \"Allow ALL egress from pods to internal_lb\" = {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.int_lb_nsg_id, destination_type = local.rule_type_nsg,\n      }\n      \"Allow ALL ingress from internal_lb to pods\" = {\n        protocol = local.all_protocols, port = local.all_ports, source = local.int_lb_nsg_id, source_type = local.rule_type_nsg,\n      }\n    } : {},\n\n    local.pub_lb_nsg_enabled ? {\n      \"Allow ALL egress from pods to pub_lb\" = {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.pub_lb_nsg_id, destination_type = local.rule_type_nsg,\n      }\n      \"Allow ALL ingress from pub_lb to pods\" = {\n        protocol = local.all_protocols, port = local.all_ports, source = local.pub_lb_nsg_id, source_type = local.rule_type_nsg,\n      }\n    }: {},\n\n    var.enable_ipv6 ? {\n      \"Allow ICMPv6 ingress to pods for path discovery\" : {\n        protocol = local.icmpv6_protocol, port = local.all_ports, source = local.anywhere_ipv6, source_type = local.rule_type_cidr,\n      },\n      \"Allow ICMPv6 egress from pods for path discovery\" : {\n        protocol = local.icmpv6_protocol, port = local.all_ports, destination = local.anywhere_ipv6, destination_type = local.rule_type_cidr,\n      },\n    } : {},\n\n    var.allow_pod_internet_access ?\n    merge(\n      var.enable_ipv6 ? {\n        \"Allow ALL IPv6 egress from pods to internet\" = {\n          protocol = local.all_protocols, port = local.all_ports, destination = local.anywhere_ipv6, destination_type = local.rule_type_cidr,\n        }\n      } : {},\n      {\n        \"Allow ALL egress from pods to internet\" = {\n          protocol = local.all_protocols, port = local.all_ports, destination = local.anywhere, destination_type = local.rule_type_cidr,\n        }\n    }) : {},\n    var.allow_rules_pods\n  )\n\n\n  pod_stateless_rules = merge(\n    {\n      \"Allow TCP egress from pods to OCI Services\" : {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.osn, destination_type = local.rule_type_service, stateless = true\n      },\n      \"Allow TCP egress to pods from OCI Services\" : {\n        protocol = local.all_protocols, port = local.all_ports, source = local.osn, source_type = local.rule_type_service, stateless = true\n      },\n\n      \"Allow ALL egress from pods to other pods\" = {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.pod_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      }\n      \"Allow ALL ingress to pods from other pods\" = {\n        protocol = local.all_protocols, port = local.all_ports, source = local.pod_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      }\n\n      \"Allow TCP egress from pods to Kubernetes control_plane\" = {\n        protocol = local.tcp_protocol, port = local.all_ports, destination = local.control_plane_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      }\n      \"Allow TCP ingress to pods from Kubernetes control_plane\" = {\n        protocol = local.tcp_protocol, port = local.all_ports, source = local.control_plane_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      }\n\n      \"Allow ALL egress from pods for cross-node pod communication when using NodePorts or hostNetwork: true\" = {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      }\n      \"Allow ALL ingress to pods for cross-node pod communication when using NodePorts or hostNetwork: true\" = {\n        protocol = local.all_protocols, port = local.all_ports, source = local.worker_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      }\n\n      \"Allow ICMP egress from pods for path discovery\" = {\n        protocol = local.icmp_protocol, port = local.all_ports, destination = local.anywhere, destination_type = local.rule_type_cidr,\n      }\n      \"Allow ICMP ingress to pods for path discovery\" = {\n        protocol = local.icmp_protocol, port = local.all_ports, source = local.anywhere, source_type = local.rule_type_cidr,\n      }\n    },\n\n    local.int_lb_nsg_enabled ? {\n      \"Allow ALL egress from pods to internal_lb\" = {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.int_lb_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      }\n      \"Allow ALL egress from pods to internal_lb\" = {\n        protocol = local.all_protocols, port = local.all_ports, source = local.int_lb_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      }\n    } : {},\n\n    local.pub_lb_nsg_enabled ? {\n      \"Allow ALL egress from pods to pub_lb\" = {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.pub_lb_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      }\n      \"Allow ALL egress from pods to pub_lb\" = {\n        protocol = local.all_protocols, port = local.all_ports, source = local.pub_lb_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      }\n    }: {},\n    \n    var.enable_ipv6 ? {\n      \"Allow ICMPv6 ingress to pods for path discovery\" : {\n        protocol = local.icmpv6_protocol, port = local.all_ports, source = local.anywhere_ipv6, source_type = local.rule_type_cidr,\n      },\n      \"Allow ICMPv6 egress from pods for path discovery\" : {\n        protocol = local.icmpv6_protocol, port = local.all_ports, destination = local.anywhere_ipv6, destination_type = local.rule_type_cidr,\n      },\n    } : {},\n\n    var.allow_pod_internet_access ?\n      merge(\n        var.enable_ipv6 ? {\n          \"Allow ALL IPv6 egress from pods to internet (not using stateless rules because of security concern with IPv6 GUA and routing over IGW)\" = {\n            protocol = local.all_protocols, port = local.all_ports, destination = local.anywhere_ipv6, destination_type = local.rule_type_cidr,\n          }\n        } : {},\n        {\n          \"Allow ALL egress from pods to anywhere\" = {\n            protocol = local.all_protocols, port = local.all_ports, destination = local.anywhere, destination_type = local.rule_type_cidr, stateless = true\n          }\n          \"Allow ALL ingress to pods from anywhere\" = {\n            protocol = local.all_protocols, port = local.all_ports, source = local.anywhere, source_type = local.rule_type_cidr, stateless = true\n          }\n      }) : {},\n    var.allow_rules_pods\n  )\n}\n\nresource \"oci_core_network_security_group\" \"pods\" {\n  count          = local.pod_nsg_enabled ? 1 : 0\n  compartment_id = var.compartment_id\n  display_name   = \"pods-${var.state_id}\"\n  vcn_id         = var.vcn_id\n  defined_tags   = var.defined_tags\n  freeform_tags  = var.freeform_tags\n  lifecycle {\n    ignore_changes = [defined_tags, freeform_tags, display_name, vcn_id]\n  }\n}\n\noutput \"pod_nsg_id\" {\n  value = local.pod_nsg_id\n}\n"
  },
  {
    "path": "modules/network/nsg-workers.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  worker_nsg_config = try(var.nsgs.workers, { create = \"never\" })\n  worker_nsg_create = coalesce(lookup(local.worker_nsg_config, \"create\", null), \"auto\")\n  worker_nsg_enabled = anytrue([\n    local.worker_nsg_create == \"always\",\n    alltrue([\n      local.worker_nsg_create == \"auto\",\n      coalesce(lookup(local.worker_nsg_config, \"id\", null), \"none\") == \"none\",\n      var.create_cluster,\n    ]),\n  ])\n  # Return provided NSG when configured with an existing ID or created resource ID\n  worker_nsg_id = one(compact([try(var.nsgs.workers.id, null), one(oci_core_network_security_group.workers[*].id)]))\n  workers_rules = local.worker_nsg_enabled ? ( var.use_stateless_rules ? local.workers_stateless_rules: local.workers_stateful_rules ) : {}\n  \n  workers_stateful_rules = merge(\n    {\n      \"Allow TCP egress from workers to OCI Services\" : {\n        protocol = local.tcp_protocol, port = local.all_ports, destination = local.osn, destination_type = local.rule_type_service,\n      },\n\n      \"Allow ALL egress from workers to other workers\" : {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg,\n      },\n      \"Allow ALL ingress to workers from other workers\" : {\n        protocol = local.all_protocols, port = local.all_ports, source = local.worker_nsg_id, source_type = local.rule_type_nsg,\n      },\n\n      \"Allow TCP egress from workers to Kubernetes API server\" : {\n        protocol = local.tcp_protocol, port = local.apiserver_port, destination = local.control_plane_nsg_id, destination_type = local.rule_type_nsg,\n      },\n      \"Allow TCP egress from workers to OKE control plane\" : {\n        protocol = local.tcp_protocol, port = local.oke_port, destination = local.control_plane_nsg_id, destination_type = local.rule_type_nsg,\n      },\n      \"Allow TCP egress to OKE control plane from workers for health check\" : {\n        protocol = local.tcp_protocol, port = local.kubelet_api_port, destination = local.control_plane_nsg_id, destination_type = local.rule_type_nsg,\n      },\n      \"Allow ALL ingress to workers from Kubernetes control plane for webhooks served by workers\" : {\n        protocol = local.all_protocols, port = local.all_ports, source = local.control_plane_nsg_id, source_type = local.rule_type_nsg,\n      },\n      \"Allow ICMP egress from workers for path discovery\" : {\n        protocol = local.icmp_protocol, port = local.all_ports, destination = local.anywhere, destination_type = local.rule_type_cidr,\n      },\n      \"Allow ICMP ingress to workers for path discovery\" : {\n        protocol = local.icmp_protocol, port = local.all_ports, source = local.anywhere, source_type = local.rule_type_cidr,\n      },\n    },\n\n    var.enable_ipv6 ? {\n      \"Allow ICMPv6 ingress to workers for path discovery\" : {\n        protocol = local.icmpv6_protocol, port = local.all_ports, source = local.anywhere_ipv6, source_type = local.rule_type_cidr,\n      },\n      \"Allow ICMPv6 egress from workers for path discovery\" : {\n        protocol = local.icmpv6_protocol, port = local.all_ports, destination = local.anywhere_ipv6, destination_type = local.rule_type_cidr,\n      },\n    } : {},\n\n    local.pod_nsg_enabled ? {\n      \"Allow ALL egress from workers to pods\" : {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.pod_nsg_id, destination_type = local.rule_type_nsg,\n      },\n      \"Allow ALL ingress to workers from pods\" : {\n        protocol = local.all_protocols, port = local.all_ports, source = local.pod_nsg_id, source_type = local.rule_type_nsg,\n      },\n    } : {},\n\n    var.allow_worker_internet_access ?\n    merge(\n      var.enable_ipv6 ? {\n        \"Allow ALL IPv6 egress from workers to internet\" = {\n          protocol = local.all_protocols, port = local.all_ports, destination = local.anywhere_ipv6, destination_type = local.rule_type_cidr,\n        }\n      } : {},\n      {\n        \"Allow ALL egress from workers to internet\" : {\n          protocol = local.all_protocols, port = local.all_ports, destination = local.anywhere, destination_type = local.rule_type_cidr,\n        },\n    }) : {},\n\n    local.int_lb_nsg_enabled ? {\n      \"Allow TCP ingress to workers from internal load balancers\" : {\n        protocol = local.tcp_protocol, port_min = local.node_port_min, port_max = local.node_port_max, source = local.int_lb_nsg_id, source_type = local.rule_type_nsg,\n      },\n      \"Allow UDP ingress to workers from internal load balancers\" : {\n        protocol = local.udp_protocol, port_min = local.node_port_min, port_max = local.node_port_max, source = local.int_lb_nsg_id, source_type = local.rule_type_nsg,\n      },\n      \"Allow TCP ingress to workers for health check from internal load balancers\" : {\n        protocol = local.tcp_protocol, port = local.health_check_port, source = local.int_lb_nsg_id, source_type = local.rule_type_nsg,\n      },\n    } : {},\n\n    local.pub_lb_nsg_enabled ? {\n      \"Allow TCP ingress to workers from public load balancers\" : {\n        protocol = local.tcp_protocol, port_min = local.node_port_min, port_max = local.node_port_max, source = local.pub_lb_nsg_id, source_type = local.rule_type_nsg,\n      },\n      \"Allow UDP ingress to workers from public load balancers\" : {\n        protocol = local.udp_protocol, port_min = local.node_port_min, port_max = local.node_port_max, source = local.pub_lb_nsg_id, source_type = local.rule_type_nsg,\n      },\n      \"Allow TCP ingress to workers for health check from public load balancers\" : {\n        protocol = local.tcp_protocol, port = local.health_check_port, source = local.pub_lb_nsg_id, source_type = local.rule_type_nsg,\n      },\n    } : {},\n\n    local.bastion_nsg_enabled && var.allow_worker_ssh_access ? {\n      \"Allow SSH ingress to workers from bastion\" : {\n        protocol = local.tcp_protocol, port = local.ssh_port, source = local.bastion_nsg_id, source_type = local.rule_type_nsg,\n      }\n    } : {},\n\n    local.fss_nsg_enabled ? {\n      # See https://docs.oracle.com/en-us/iaas/Content/File/Tasks/securitylistsfilestorage.htm\n      # Ingress\n      \"Allow TCP ingress to workers for NFS portmapper from FSS mounts\" : {\n        protocol = local.tcp_protocol, port = local.fss_nfs_portmapper_port, source = local.fss_nsg_id, source_type = local.rule_type_nsg,\n      },\n      \"Allow UDP ingress to workers for NFS portmapper from FSS mounts\" : {\n        protocol = local.udp_protocol, port = local.fss_nfs_portmapper_port, source = local.fss_nsg_id, source_type = local.rule_type_nsg,\n      },\n      \"Allow TCP ingress to workers for NFS from FSS mounts\" : {\n        protocol = local.tcp_protocol, port_min = local.fss_nfs_port_min, port_max = local.fss_nfs_port_max, source = local.fss_nsg_id, source_type = local.rule_type_nsg,\n      },\n\n      # Egress\n      \"Allow TCP egress from workers for NFS portmapper to FSS mounts\" : {\n        protocol = local.tcp_protocol, port = local.fss_nfs_portmapper_port, destination = local.fss_nsg_id, destination_type = local.rule_type_nsg,\n      },\n      \"Allow UDP egress from workers for NFS portmapper to FSS mounts\" : {\n        protocol = local.udp_protocol, port = local.fss_nfs_portmapper_port, destination = local.fss_nsg_id, destination_type = local.rule_type_nsg,\n      },\n      \"Allow TCP egress from workers for NFS to FSS mounts\" : {\n        protocol = local.tcp_protocol, port_min = local.fss_nfs_port_min, port_max = local.fss_nfs_port_max, destination = local.fss_nsg_id, destination_type = local.rule_type_nsg,\n      },\n      \"Allow UDP egress from workers for NFS to FSS mounts\" : {\n        protocol = local.udp_protocol, port = local.fss_nfs_port_min, destination = local.fss_nsg_id, destination_type = local.rule_type_nsg,\n      },\n    } : {},\n    var.allow_rules_workers\n  )\n\n  workers_stateless_rules = merge(\n    {\n      \"Allow TCP egress from workers to OCI Services\" : {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.osn, destination_type = local.rule_type_service, stateless = true\n      },\n      \"Allow TCP ingress to workers from OCI Services\" : {\n        protocol = local.all_protocols, port = local.all_ports, source = local.osn, source_type = local.rule_type_service, stateless = true\n      },\n\n      \"Allow ALL egress from workers to other workers\" : {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.worker_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow ALL ingress to workers from other workers\" : {\n        protocol = local.all_protocols, port = local.all_ports, source = local.worker_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n\n      \"Allow ALL egress from workers to Kubernetes control plane\" : {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.control_plane_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow ALL ingress to workers from Kubernetes control plane\" : {\n        protocol = local.all_protocols, port = local.all_ports, source = local.control_plane_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n\n      \"Allow ICMP egress from workers for path discovery\" : {\n        protocol = local.icmp_protocol, port = local.all_ports, destination = local.anywhere, destination_type = local.rule_type_cidr,\n      },\n      \"Allow ICMP ingress to workers for path discovery\" : {\n        protocol = local.icmp_protocol, port = local.all_ports, source = local.anywhere, source_type = local.rule_type_cidr,\n      },\n    },\n\n    var.enable_ipv6 ? {\n      \"Allow ICMPv6 ingress to workers for path discovery\" : {\n        protocol = local.icmpv6_protocol, port = local.all_ports, source = local.anywhere_ipv6, source_type = local.rule_type_cidr,\n      },\n      \"Allow ICMPv6 egress from workers for path discovery\" : {\n        protocol = local.icmpv6_protocol, port = local.all_ports, destination = local.anywhere_ipv6, destination_type = local.rule_type_cidr,\n      },\n    } : {},\n\n    local.pod_nsg_enabled ? {\n      \"Allow ALL egress from workers to pods\" : {\n        protocol = local.all_protocols, port = local.all_ports, destination = local.pod_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow ALL ingress to workers from pods\" : {\n        protocol = local.all_protocols, port = local.all_ports, source = local.pod_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n    } : {},\n\n    var.allow_worker_internet_access ?\n    merge(\n      var.enable_ipv6 ? {\n        \"Allow ALL IPv6 egress from workers to internet (not using stateless rules because of security concern with IPv6 GUA and routing over IGW)\" = {\n          protocol = local.all_protocols, port = local.all_ports, destination = local.anywhere_ipv6, destination_type = local.rule_type_cidr,\n        }\n      } : {},\n      {\n        \"Allow ALL egress from workers to internet (not using stateless rules because of security concern with Public IPs and routing over IGW)\" : {\n          protocol = local.all_protocols, port = local.all_ports, destination = local.anywhere, destination_type = local.rule_type_cidr,\n        },\n    }) : {},\n\n    local.int_lb_nsg_enabled ? {\n      \"Allow TCP ingress to workers from internal load balancers\" : {\n        protocol = local.tcp_protocol, destination_port_min = local.node_port_min, destination_port_max = local.node_port_max, source = local.int_lb_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow TCP egress from workers to internal load balancers\" : {\n        protocol = local.tcp_protocol, source_port_min = local.node_port_min, source_port_max = local.node_port_max, destination = local.int_lb_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n\n      \"Allow UDP ingress to workers from internal load balancers\" : {\n        protocol = local.udp_protocol, destination_port_min = local.node_port_min, destination_port_max = local.node_port_max, source = local.int_lb_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow UDP egress from workers to internal load balancers\" : {\n        protocol = local.udp_protocol, source_port_min = local.node_port_min, source_port_max = local.node_port_max, destination = local.int_lb_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n\n      \"Allow TCP ingress to workers for health check from internal load balancers\" : {\n        protocol = local.tcp_protocol, destination_port_min = local.health_check_port, destination_port_max = local.health_check_port, source = local.int_lb_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow TCP egress from workers for health check to internal load balancers\" : {\n        protocol = local.tcp_protocol, source_port_min = local.health_check_port, source_port_max = local.health_check_port, destination = local.int_lb_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n    } : {},\n\n    local.pub_lb_nsg_enabled ? {\n      \"Allow TCP ingress to workers from public load balancers\" : {\n        protocol = local.tcp_protocol, destination_port_min = local.node_port_min, destination_port_max = local.node_port_max, source = local.pub_lb_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow TCP egress from workers to public load balancers\" : {\n        protocol = local.tcp_protocol, source_port_min = local.node_port_min, source_port_max = local.node_port_max, destination = local.pub_lb_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n\n      \"Allow UDP ingress to workers from public load balancers\" : {\n        protocol = local.udp_protocol, destination_port_min = local.node_port_min, destination_port_max = local.node_port_max, source = local.pub_lb_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow UDP egress from workers to public load balancers\" : {\n        protocol = local.udp_protocol, source_port_min = local.node_port_min, source_port_max = local.node_port_max, destination = local.pub_lb_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n\n      \"Allow TCP ingress to workers for health check from public load balancers\" : {\n        protocol = local.tcp_protocol, destination_port_min = local.health_check_port, destination_port_max = local.health_check_port, source = local.pub_lb_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow TCP egress from workers for health check to public load balancers\" : {\n        protocol = local.tcp_protocol, source_port_min = local.health_check_port, source_port_max = local.health_check_port, destination = local.pub_lb_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n    } : {},\n\n    local.bastion_nsg_enabled && var.allow_worker_ssh_access ? {\n      \"Allow ingress to workers SSH from bastion\" : {\n        protocol = local.tcp_protocol, destination_port_min = local.ssh_port, destination_port_max = local.ssh_port, source = local.bastion_nsg_id, source_type = local.rule_type_nsg\n      },\n    } : {},\n\n    local.fss_nsg_enabled ? {\n      # See https://docs.oracle.com/en-us/iaas/Content/File/Tasks/securitylistsfilestorage.htm\n      # Ingress\n      \"Allow UDP ingress to workers for NFS portmapper from FSS mounts\" : {\n        protocol = local.udp_protocol, source_port_min = local.fss_nfs_portmapper_port, source_port_max = local.fss_nfs_portmapper_port, source = local.fss_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow UDP egress from workers for NFS portmapper to FSS mounts\" : {\n        protocol = local.udp_protocol, destination_port_min = local.fss_nfs_portmapper_port, destination_port_max = local.fss_nfs_portmapper_port, destination = local.fss_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n\n      \"Allow TCP ingress to workers for NFS portmapper from FSS mounts\" : {\n        protocol = local.tcp_protocol, source_port_min = local.fss_nfs_portmapper_port, source_port_max = local.fss_nfs_portmapper_port, source = local.fss_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow TCP egress from workers for NFS portmapper to FSS mounts\" : {\n        protocol = local.tcp_protocol, destination_port_min = local.fss_nfs_portmapper_port, destination_port_max = local.fss_nfs_portmapper_port, destination = local.fss_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n\n\n      \"Allow TCP ingress to workers for NFS from FSS mounts\" : {\n        protocol = local.tcp_protocol, source_port_min = local.fss_nfs_port_min, source_port_max = local.fss_nfs_port_max, source = local.fss_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },      \n      \"Allow TCP egress from workers for NFS to FSS mounts\" : {\n        protocol = local.tcp_protocol, destination_port_min = local.fss_nfs_port_min, destination_port_max = local.fss_nfs_port_max, destination = local.fss_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      },\n\n      \"Allow UDP ingress to workers for NFS from FSS mounts\" : {\n        protocol = local.udp_protocol, source_port_min = local.fss_nfs_port_min, source_port_max = local.fss_nfs_port_min, source = local.fss_nsg_id, source_type = local.rule_type_nsg, stateless = true\n      },\n      \"Allow UDP egress from workers for NFS to FSS mounts\" : {\n        protocol = local.udp_protocol, destination_port_min = local.fss_nfs_port_min, destination_port_max = local.fss_nfs_port_min, destination = local.fss_nsg_id, destination_type = local.rule_type_nsg, stateless = true\n      }\n    } : {},\n    var.allow_rules_workers\n  )\n}\n\nresource \"oci_core_network_security_group\" \"workers\" {\n  count          = local.worker_nsg_enabled ? 1 : 0\n  compartment_id = var.compartment_id\n  display_name   = \"workers-${var.state_id}\"\n  vcn_id         = var.vcn_id\n  defined_tags   = var.defined_tags\n  freeform_tags  = var.freeform_tags\n  lifecycle {\n    ignore_changes = [defined_tags, freeform_tags, display_name, vcn_id]\n  }\n}\n\noutput \"worker_nsg_id\" {\n  value = local.worker_nsg_id\n}\n"
  },
  {
    "path": "modules/network/rules.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  waf_rules = var.enable_waf ? { # Used in load balancer NSGs if enabled\n    for waf_subnet in data.oci_waas_edge_subnets.waf_cidr_blocks[0].edge_subnets : \"Allow SSL ingress from WAF ${waf_subnet.cidr}\" => {\n      protocol = local.tcp_protocol, port = 443, source = waf_subnet.cidr, source_type = local.rule_type_cidr,\n    }\n  } : {}\n\n  # Dynamic map of all NSG rules for enabled NSGs\n  all_rules = { for x, y in merge(\n    { for k, v in local.bastion_rules : k => merge(v, { \"nsg_id\" = local.bastion_nsg_id }) },\n    { for k, v in local.control_plane_rules : k => merge(v, { \"nsg_id\" = local.control_plane_nsg_id }) },\n    { for k, v in local.int_lb_rules : k => merge(v, { \"nsg_id\" = local.int_lb_nsg_id }) },\n    { for k, v in local.pub_lb_rules : k => merge(v, { \"nsg_id\" = local.pub_lb_nsg_id }) },\n    { for k, v in local.workers_rules : k => merge(v, { \"nsg_id\" = local.worker_nsg_id }) },\n    { for k, v in local.pods_rules : k => merge(v, { \"nsg_id\" = local.pod_nsg_id }) },\n    { for k, v in local.operator_rules : k => merge(v, { \"nsg_id\" = local.operator_nsg_id }) },\n    { for k, v in local.fss_rules : k => merge(v, { \"nsg_id\" = local.fss_nsg_id }) },\n    ) : x => merge(y, {\n      description               = x\n      stateless                 = lookup(y, \"stateless\", false)\n      network_security_group_id = lookup(y, \"nsg_id\")\n      direction                 = contains(keys(y), \"source\") ? \"INGRESS\" : \"EGRESS\"\n      protocol                  = lookup(y, \"protocol\")\n      source = (\n        alltrue([\n          upper(lookup(y, \"source_type\", \"\")) == local.rule_type_nsg,\n        length(regexall(\"ocid\\\\d+\\\\.networksecuritygroup\", lower(lookup(y, \"source\", \"\")))) == 0]) ?\n        lookup(local.all_nsg_ids, lower(lookup(y, \"source\", \"\")), null) :\n        lookup(y, \"source\", null)\n      )\n      source_type = lookup(y, \"source_type\", null)\n      destination = (\n        alltrue([\n          upper(lookup(y, \"destination_type\", \"\")) == local.rule_type_nsg,\n        length(regexall(\"ocid\\\\d+\\\\.networksecuritygroup\", lower(lookup(y, \"destination\", \"\")))) == 0]) ?\n        lookup(local.all_nsg_ids, lower(lookup(y, \"destination\", \"\")), null) :\n        lookup(y, \"destination\", null)\n      )\n      destination_type = lookup(y, \"destination_type\", null)\n  }) }\n\n  # Dynamic map of all NSG IDs for enabled NSGs\n  all_nsg_ids = { for x, y in merge(\n    local.bastion_nsg_enabled ? { \"bastion\" = local.bastion_nsg_id } : {},\n    local.control_plane_nsg_enabled ? { \"cp\" = local.control_plane_nsg_id } : {},\n    local.int_lb_nsg_enabled ? { \"int_lb\" = local.int_lb_nsg_id } : {},\n    local.pub_lb_nsg_enabled ? { \"pub_lb\" = local.pub_lb_nsg_id } : {},\n    local.worker_nsg_enabled ? { \"workers\" = local.worker_nsg_id } : {},\n    local.pod_nsg_enabled ? { \"pods\" = local.pod_nsg_id } : {},\n    local.operator_nsg_enabled ? { \"operator\" = local.operator_nsg_id } : {},\n    local.fss_nsg_enabled ? { \"fss\" = local.fss_nsg_id } : {},\n  ) : x => y }\n}\n\nresource \"oci_core_network_security_group_security_rule\" \"oke\" {\n  for_each                  = local.all_rules\n  stateless                 = each.value.stateless\n  description               = each.value.description\n  destination               = each.value.destination\n  destination_type          = each.value.destination_type\n  direction                 = each.value.direction\n  network_security_group_id = each.value.network_security_group_id\n  protocol                  = each.value.protocol\n  source                    = each.value.source\n  source_type               = each.value.source_type\n\n  dynamic \"tcp_options\" {\n    for_each = (tostring(each.value.protocol) == tostring(local.tcp_protocol) &&\n      tonumber(lookup(each.value, \"port\", 0)) != local.all_ports ? [each.value] : []\n    )\n    content {\n      dynamic \"destination_port_range\" {\n        for_each = (\n          (contains(keys(tcp_options.value), \"destination_port_min\") &&\n          contains(keys(tcp_options.value), \"destination_port_max\")) ||\n          (contains(keys(tcp_options.value), \"source_port_min\") &&\n          contains(keys(tcp_options.value), \"source_port_max\"))\n        ) ? [] : [tcp_options.value]\n        content {\n          min = tonumber(lookup(destination_port_range.value, \"port_min\", lookup(destination_port_range.value, \"port\", 0)))\n          max = tonumber(lookup(destination_port_range.value, \"port_max\", lookup(destination_port_range.value, \"port\", 0)))\n        }\n      }\n      dynamic \"destination_port_range\" {\n        for_each = (contains(keys(tcp_options.value), \"destination_port_min\") &&\n        contains(keys(tcp_options.value), \"destination_port_max\")) ? [tcp_options.value] : []\n        content {\n          min = tonumber(lookup(destination_port_range.value, \"destination_port_min\", 0))\n          max = tonumber(lookup(destination_port_range.value, \"destination_port_max\", 0))\n        }\n      }\n      dynamic \"source_port_range\" {\n        for_each = (contains(keys(tcp_options.value), \"source_port_min\") &&\n        contains(keys(tcp_options.value), \"source_port_max\")) ? [tcp_options.value] : []\n        content {\n          min = tonumber(lookup(source_port_range.value, \"source_port_min\", 0))\n          max = tonumber(lookup(source_port_range.value, \"source_port_max\", 0))\n        }\n      }\n    }\n  }\n\n  dynamic \"udp_options\" {\n    for_each = (tostring(each.value.protocol) == tostring(local.udp_protocol) &&\n      tonumber(lookup(each.value, \"port\", 0)) != local.all_ports ? [each.value] : []\n    )\n    content {\n      dynamic \"destination_port_range\" {\n        for_each = (\n          (contains(keys(udp_options.value), \"destination_port_min\") &&\n          contains(keys(udp_options.value), \"destination_port_max\")) ||\n          (contains(keys(udp_options.value), \"source_port_min\") &&\n          contains(keys(udp_options.value), \"source_port_max\"))\n        ) ? [] : [udp_options.value]\n        content {\n          min = tonumber(lookup(destination_port_range.value, \"port_min\", lookup(destination_port_range.value, \"port\", 0)))\n          max = tonumber(lookup(destination_port_range.value, \"port_max\", lookup(destination_port_range.value, \"port\", 0)))\n        }\n      }\n      dynamic \"destination_port_range\" {\n        for_each = (contains(keys(udp_options.value), \"destination_port_min\") &&\n        contains(keys(udp_options.value), \"destination_port_max\")) ? [udp_options.value] : []\n        content {\n          min = tonumber(lookup(destination_port_range.value, \"destination_port_min\", 0))\n          max = tonumber(lookup(destination_port_range.value, \"destination_port_max\", 0))\n        }\n      }\n      dynamic \"source_port_range\" {\n        for_each = (contains(keys(udp_options.value), \"source_port_min\") &&\n        contains(keys(udp_options.value), \"source_port_max\")) ? [udp_options.value] : []\n        content {\n          min = tonumber(lookup(source_port_range.value, \"source_port_min\", 0))\n          max = tonumber(lookup(source_port_range.value, \"source_port_max\", 0))\n        }\n      }\n    }\n  }\n\n  dynamic \"icmp_options\" {\n    for_each = tostring(each.value.protocol) == tostring(local.icmp_protocol) ? [1] : []\n    content {\n      type = 3\n      code = 4\n    }\n  }\n\n  dynamic \"icmp_options\" {\n    for_each = tostring(each.value.protocol) == tostring(local.icmpv6_protocol) ? [1] : []\n    content {\n      type = 2\n      code = 0\n    }\n  }\n\n  lifecycle {\n    precondition {\n      condition = contains([tostring(local.icmp_protocol), tostring(local.icmpv6_protocol)], tostring(each.value.protocol)) || contains(keys(each.value), \"port\") || (\n        contains(keys(each.value), \"port_min\") && contains(keys(each.value), \"port_max\")) || (\n        contains(keys(each.value), \"source_port_min\") && contains(keys(each.value), \"source_port_max\") || (\n          contains(keys(each.value), \"destination_port_min\") && contains(keys(each.value), \"destination_port_max\")\n        )\n      )\n      error_message = \"TCP/UDP rule must contain a port or port range: '${each.key}'\"\n    }\n\n    precondition {\n      condition = (\n        contains([tostring(local.icmp_protocol), tostring(local.icmpv6_protocol)], tostring(each.value.protocol))\n        || can(tonumber(each.value.port))\n        || (can(tonumber(each.value.port_min)) && can(tonumber(each.value.port_max)))\n        || (can(tonumber(each.value.source_port_min)) && can(tonumber(each.value.source_port_max)))\n        || (can(tonumber(each.value.destination_port_min)) && can(tonumber(each.value.destination_port_max)))\n      )\n\n      error_message = \"TCP/UDP ports must be numeric: '${each.key}'\"\n    }\n\n    precondition {\n      condition     = each.value.direction == \"EGRESS\" || coalesce(each.value.source, \"none\") != \"none\"\n      error_message = \"Ingress rule must have a source: '${each.key}'\"\n    }\n\n    precondition {\n      condition     = each.value.direction == \"INGRESS\" || coalesce(each.value.destination, \"none\") != \"none\"\n      error_message = \"Egress rule must have a destination: '${each.key}'\"\n    }\n\n    # Extra precaution against unexpected allow-all ingress rules created by the module\n    # Generated rules will produce errors unless any of the follow conditions are true\n    precondition {\n      condition = var.use_stateless_rules || anytrue([\n        tostring(each.value.protocol) == tostring(local.icmp_protocol), # Traffic is ICMP\n        each.value.direction == \"EGRESS\",                               # Traffic is outbound\n        each.value.source != local.anywhere,                            # Rule does not allow all traffic\n\n        # SSH ingress to bastion from anywhere has been configured explicitly\n        alltrue([\n          tonumber(lookup(each.value, \"port\", 0)) == local.ssh_port,\n          contains(var.bastion_allowed_cidrs, local.anywhere),\n        ]),\n\n        # TCP ingress to Kubernetes endpoint from anywhere has been configured explicitly\n        alltrue([\n          tonumber(lookup(each.value, \"port\", 0)) == local.apiserver_port,\n          contains(var.control_plane_allowed_cidrs, local.anywhere),\n        ]),\n\n        # TCP ingress to internal load balancer from anywhere has been configured explicitly\n        contains(keys(var.allow_rules_internal_lb), each.key),\n\n        # TCP ingress to public load balancer from anywhere has been configured explicitly\n        contains(keys(var.allow_rules_public_lb), each.key),\n\n      ])\n      error_message = \"Unexpected open ingress rule: ${each.key}\"\n    }\n  }\n}\n\noutput \"network_security_rules\" {\n  value = local.all_rules\n}\n\noutput \"nsg_ids\" {\n  value = length(local.all_nsg_ids) > 0 ? local.all_nsg_ids : null\n}\n"
  },
  {
    "path": "modules/network/subnets.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  # VCN subnet configuration\n  # See https://docs.oracle.com/en-us/iaas/Content/ContEng/Concepts/contengnetworkconfig.htm#vcnconfig\n  # May be undefined when VCN is neither created nor required, e.g. when creating only workers for\n  # an existing cluster. Fallback value is unused.\n  vcn_cidr = length(var.vcn_cidrs) > 0 ? element(var.vcn_cidrs, 0) : \"0.0.0.0/16\"\n\n  # Filter configured subnets eligible for resource creation\n  subnet_cidrs_new = {\n    for k, v in var.subnets : k => merge(v, {\n      \"type\" = (lookup(v, \"netnum\", null) == null && lookup(v, \"newbits\", null) != null ? \"newbits\"\n        : (lookup(v, \"netnum\", null) != null && lookup(v, \"newbits\", null) != null ? \"netnum\"\n          : (lookup(v, \"cidr\", null) != null ? \"cidr\"\n            : (lookup(v, \"id\", null) != null ? \"id\"\n      : \"invalid\"))))\n    }) if lookup(v, \"create\", \"auto\") != \"never\"\n  }\n\n  # Handle subnets configured with provided CIDRs\n  subnet_cidrs_cidr_input = {\n    for k, v in local.subnet_cidrs_new : k => lookup(v, \"cidr\") if v.type == \"cidr\"\n  }\n\n  # Handle subnets configured with only newbits for sizing\n  subnet_cidrs_newbits_input = {\n    for k, v in local.subnet_cidrs_new : k => lookup(v, \"newbits\") if v.type == \"newbits\"\n  }\n\n  # Generate CIDR ranges for subnets to be created\n  subnet_cidrs_newbits_ranges = cidrsubnets(local.vcn_cidr, values(local.subnet_cidrs_newbits_input)...)\n  subnet_cidrs_newbits_resolved = length(local.vcn_cidr) > 0 ? {\n    for k, v in local.subnet_cidrs_newbits_input : k => element(local.subnet_cidrs_newbits_ranges, index(keys(local.subnet_cidrs_newbits_input), k))\n  } : {}\n\n  # Handle subnets configured with netnum + newbits for sizing\n  subnet_cidrs_netnum_newbits_ranges = {\n    for k, v in local.subnet_cidrs_new : k => cidrsubnet(local.vcn_cidr, lookup(v, \"newbits\"), lookup(v, \"netnum\"))\n    if v.type == \"netnum\"\n  }\n\n  // Combine provided and calculated subnet CIDRs\n  subnet_cidrs_all = merge(\n    local.subnet_cidrs_cidr_input,\n    local.subnet_cidrs_newbits_resolved,\n    local.subnet_cidrs_netnum_newbits_ranges,\n  )\n\n  # IPv6 Default CIDRs\n  default_ipv6_cidrs = {\n    bastion  = { ipv6_cidr = \"8, 0\" }\n    operator = { ipv6_cidr = \"8, 1\" }\n    cp       = { ipv6_cidr = \"8, 2\" }\n    int_lb   = { ipv6_cidr = \"8, 3\" }\n    pub_lb   = { ipv6_cidr = \"8, 4\" }\n    workers  = { ipv6_cidr = \"8, 5\" }\n    pods     = { ipv6_cidr = \"8, 6\" }\n    fss      = { ipv6_cidr = \"8, 7\" }\n  }\n\n  # Add default ipv6 cidrs to var.subnets if missing\n  subnets_with_ipv6_cidr_defaults = { for k, v in var.subnets :\n    k => merge(v, lookup(v, \"ipv6_cidr\", null) == null ? lookup(local.default_ipv6_cidrs, k, { \"ipv6_cidr\" : \"::/0\" }) : {})\n  }\n\n  # Generate IPv6 CIDRs\n  subnets_ipv6_cidr = var.enable_ipv6 == true ? {\n    for k, v in local.subnets_with_ipv6_cidr_defaults : k => merge(v, {\n      \"ipv6_cidr\" = length(regexall(\"^\\\\d+,[ ]?\\\\d+$\", lookup(v, \"ipv6_cidr\"))) > 0 ? cidrsubnet(var.vcn_ipv6_cidrs[0], tonumber(split(\",\", lookup(v, \"ipv6_cidr\"))[0]), tonumber(trim(split(\",\", lookup(v, \"ipv6_cidr\"))[1], \" \"))) : lookup(v, \"ipv6_cidr\")\n    }) if try(v.create, \"auto\") != \"never\"\n  } : { for k, v in var.subnets : k => merge(v, { \"ipv6_cidr\" : null }) if try(v.create, \"auto\") != \"never\" }\n\n  # Map of subnets for standard components with additional configuration derived\n  # TODO enumerate worker pools for public/private overrides, conditional subnets for both\n  subnet_info = {\n    bastion  = { create = var.create_bastion, is_public = var.bastion_is_public }\n    cp       = { create = var.create_cluster, is_public = var.enable_ipv6 == true ? true : var.control_plane_is_public }\n    workers  = { create = var.create_cluster, is_public = var.enable_ipv6 == true ? true : var.worker_is_public }\n    pods     = { create = var.create_cluster && var.cni_type == \"npn\", is_public = var.enable_ipv6 == true ? true : false }\n    operator = { create = var.create_operator }\n    fss      = { create = contains(keys(var.subnets), \"fss\") }\n    int_lb = {\n      create         = var.create_cluster && contains([\"both\", \"internal\"], var.load_balancers),\n      create_seclist = true, dns_label = \"ilb\",\n    }\n    pub_lb = {\n      create         = var.create_cluster && contains([\"both\", \"public\"], var.load_balancers),\n      create_seclist = true, is_public = true, dns_label = \"plb\",\n    }\n  }\n\n  # Map of configured subnets to specified/generated dns_label when enabled\n  # If `assign_dns = true`, use dns_label for subnet if specified or first 2 characters of subnet key\n  subnet_dns_labels = { for k, v in var.subnets :\n    k => coalesce(lookup(v, \"dns_label\", null), substr(k, 0, 2))\n    if var.assign_dns\n  }\n\n  # Create subnets if when all are true:\n  # - Associated component is enabled OR configured with create == 'always'\n  # - Subnet is configured with newbits and/or netnum/cidr\n  # - Not configured with create == 'never'\n  # - Not configured with an existing 'id'\n  subnets_to_create = merge(\n    { for k, v in local.subnet_info : k =>\n      # Override `create = true` if configured with \"always\"\n      merge(v, lookup(try(lookup(var.subnets, k), { create = \"never\" }), \"create\", \"auto\") == \"always\" ? { \"create\" = true } : {})\n      if alltrue([                                                                              # Filter disabled subnets from output\n        contains(keys(local.subnet_cidrs_all), k),                                              # has a calculated CIDR range (not id input)\n        lookup(try(lookup(var.subnets, k), { create = \"never\" }), \"create\", \"auto\") != \"never\", # not disabled\n        anytrue([\n          tobool(lookup(v, \"create\", true)),                                                      # automatically enabled\n          lookup(try(lookup(var.subnets, k), { create = \"never\" }), \"create\", \"auto\") == \"always\" # force enabled\n        ]),\n      ])\n    }\n  )\n\n  subnet_output = { for k, v in var.subnets :\n    k => lookup(v, \"id\", null) != null ? v.id : lookup(lookup(oci_core_subnet.oke, k, {}), \"id\", null)\n  }\n\n  create_mixed_igw_ngw_route_table = alltrue([\n    var.enable_ipv6 == true,\n    var.create_internet_gateway == true,\n    var.create_nat_gateway == true,\n    var.igw_ngw_mixed_route_id == null\n  ])\n}\n\nresource \"null_resource\" \"validate_subnets\" {\n  count = anytrue([for k, v in local.subnet_cidrs_new : contains([\"netnum\", \"newbits\", \"cidr\"], v.type)\n    if lookup(v, \"create\", \"auto\") != \"never\"\n  ]) ? 1 : 0\n\n  lifecycle {\n    precondition {\n      condition     = !contains([for k, v in local.subnet_cidrs_new : v.type], \"invalid\")\n      error_message = format(\"Invalid subnet specification: %s\", jsonencode({ for k, v in local.subnet_cidrs_new : k => v if v.type == \"invalid\" }))\n    }\n\n    precondition {\n      condition = !(contains([for k, v in local.subnet_cidrs_new : v.type], \"netnum\") && contains([for k, v in local.subnet_cidrs_new : v.type], \"newbits\"))\n      error_message = format(\n        \"Must omit or include `netnum` for all subnet defintions uniformely: %s\",\n        jsonencode({ for k, v in local.subnet_cidrs_new : k => v if contains([\"netnum\", \"newbits\"], v.type) })\n      )\n    }\n  }\n}\n\nresource \"oci_core_route_table\" \"igw_ngw_mixed_route_id\" {\n  count = local.create_mixed_igw_ngw_route_table ? 1 : 0\n\n  compartment_id = var.compartment_id\n  display_name   = format(\"%v-%v\", \"igw-ngw-mixed-rt\", var.state_id)\n  vcn_id         = var.vcn_id\n  defined_tags   = var.defined_tags\n  freeform_tags  = var.freeform_tags\n  route_rules {\n    #Required\n    network_entity_id = var.nat_gateway_id\n\n    description      = \"Default route for IPv4.\"\n    destination      = local.anywhere\n    destination_type = local.rule_type_cidr\n  }\n\n  route_rules {\n    #Required\n    network_entity_id = var.internet_gateway_id\n\n    description      = \"Default route for IPv6.\"\n    destination      = local.anywhere_ipv6\n    destination_type = local.rule_type_cidr\n  }\n\n  lifecycle {\n    ignore_changes = [\n      freeform_tags, defined_tags,\n    ]\n  }\n}\n\nresource \"oci_core_subnet\" \"oke\" {\n  for_each = local.subnets_to_create\n\n  compartment_id = var.compartment_id\n  vcn_id         = var.vcn_id\n  cidr_block     = lookup(local.subnet_cidrs_all, each.key)\n  display_name = (lookup(var.subnets, each.key, null) != null ?\n    (lookup(var.subnets[each.key], \"display_name\", null) != null ?\n      var.subnets[each.key][\"display_name\"] :\n      format(\"%v-%v\", each.key, var.state_id)\n    ) :\n    format(\"%v-%v\", each.key, var.state_id)\n  )\n  dns_label                  = lookup(local.subnet_dns_labels, each.key, null)\n  prohibit_public_ip_on_vnic = !tobool(lookup(each.value, \"is_public\", false))\n  route_table_id             = var.enable_ipv6 && var.cni_type == \"npn\" && each.key == \"pods\" ? coalesce(one(oci_core_route_table.igw_ngw_mixed_route_id[*].id), var.igw_ngw_mixed_route_id) : !tobool(lookup(each.value, \"is_public\", false)) ? var.nat_route_table_id : var.ig_route_table_id\n  security_list_ids          = compact([lookup(lookup(oci_core_security_list.oke, each.key, {}), \"id\", null)])\n  defined_tags               = var.defined_tags\n  freeform_tags              = var.freeform_tags\n  ipv6cidr_block             = var.enable_ipv6 ? lookup(local.subnets_ipv6_cidr[each.key], \"ipv6_cidr\", null) : null\n\n  lifecycle {\n    ignore_changes = [\n      freeform_tags, defined_tags,\n      cidr_block, dns_label, security_list_ids, vcn_id,\n    ]\n  }\n}\n\n# Create an associated security list for subnets when enabled\n# e.g. for load balancers to prevent CCM management of default security list\nresource \"oci_core_security_list\" \"oke\" {\n  for_each = {\n    for k, v in local.subnets_to_create : k => v\n    if tobool(lookup(v, \"create_seclist\", false))\n  }\n\n  compartment_id = var.compartment_id\n  display_name   = format(\"%v-%v\", each.key, var.state_id)\n  vcn_id         = var.vcn_id\n  defined_tags   = var.defined_tags\n  freeform_tags  = var.freeform_tags\n\n  lifecycle {\n    ignore_changes = [\n      freeform_tags, defined_tags, display_name, vcn_id,\n      ingress_security_rules, egress_security_rules, # ignore for CCM-management\n    ]\n  }\n}\n\n# Return configured/created subnet IDs and CIDRs when applicable\noutput \"bastion_subnet_id\" {\n  value = lookup(local.subnet_output, \"bastion\", null)\n}\noutput \"bastion_subnet_cidr\" {\n  value = contains(keys(local.subnet_output), \"bastion\") ? lookup(local.subnet_cidrs_all, \"bastion\", null) : null\n}\noutput \"operator_subnet_id\" {\n  value = lookup(local.subnet_output, \"operator\", null)\n}\noutput \"operator_subnet_cidr\" {\n  value = contains(keys(local.subnet_output), \"operator\") ? lookup(local.subnet_cidrs_all, \"operator\", null) : null\n}\noutput \"control_plane_subnet_id\" {\n  value = lookup(local.subnet_output, \"cp\", null)\n}\noutput \"control_plane_subnet_cidr\" {\n  value = contains(keys(local.subnet_output), \"cp\") ? lookup(local.subnet_cidrs_all, \"cp\", null) : null\n}\noutput \"int_lb_subnet_id\" {\n  value = lookup(local.subnet_output, \"int_lb\", null)\n}\noutput \"int_lb_subnet_cidr\" {\n  value = contains(keys(local.subnet_output), \"int_lb\") ? lookup(local.subnet_cidrs_all, \"int_lb\", null) : null\n}\noutput \"pub_lb_subnet_id\" {\n  value = lookup(local.subnet_output, \"pub_lb\", null)\n}\noutput \"pub_lb_subnet_cidr\" {\n  value = contains(keys(local.subnet_output), \"pub_lb\") ? lookup(local.subnet_cidrs_all, \"pub_lb\", null) : null\n}\noutput \"worker_subnet_id\" {\n  value = lookup(local.subnet_output, \"workers\", null)\n}\noutput \"worker_subnet_cidr\" {\n  value = contains(keys(local.subnet_output), \"workers\") ? lookup(local.subnet_cidrs_all, \"workers\", null) : null\n}\noutput \"pod_subnet_id\" {\n  value = lookup(local.subnet_output, \"pods\", null)\n}\noutput \"pod_subnet_cidr\" {\n  value = contains(keys(local.subnet_output), \"pods\") ? lookup(local.subnet_cidrs_all, \"pods\", null) : null\n}\noutput \"fss_subnet_id\" {\n  value = lookup(local.subnet_output, \"fss\", null)\n}\noutput \"fss_subnet_cidr\" {\n  value = contains(keys(local.subnet_output), \"fss\") ? lookup(local.subnet_cidrs_all, \"fss\", null) : null\n}"
  },
  {
    "path": "modules/network/variables.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# Common\nvariable \"compartment_id\" { type = string }\nvariable \"state_id\" { type = string }\n\n# Tags\nvariable \"defined_tags\" { type = map(string) }\nvariable \"freeform_tags\" { type = map(string) }\nvariable \"tag_namespace\" { type = string }\nvariable \"use_defined_tags\" { type = bool }\n\n# Network\nvariable \"allow_node_port_access\" { type = bool }\nvariable \"allow_pod_internet_access\" { type = bool }\nvariable \"allow_rules_cp\" { type = any }\nvariable \"allow_rules_internal_lb\" { type = any }\nvariable \"allow_rules_pods\" { type = any }\nvariable \"allow_rules_public_lb\" { type = any }\nvariable \"allow_rules_workers\" { type = any }\nvariable \"allow_worker_internet_access\" { type = bool }\nvariable \"allow_worker_ssh_access\" { type = bool }\nvariable \"allow_bastion_cluster_access\" { type = bool }\nvariable \"assign_dns\" { type = bool }\nvariable \"bastion_allowed_cidrs\" { type = set(string) }\nvariable \"bastion_is_public\" { type = bool }\nvariable \"cni_type\" { type = string }\nvariable \"control_plane_allowed_cidrs\" { type = set(string) }\nvariable \"control_plane_is_public\" { type = bool }\nvariable \"create_cluster\" { type = bool }\nvariable \"create_bastion\" { type = bool }\nvariable \"create_internet_gateway\" { type = bool }\nvariable \"create_nat_gateway\" { type = bool }\nvariable \"create_operator\" { type = bool }\nvariable \"drg_attachments\" { type = any }\nvariable \"enable_ipv6\" { type = bool }\nvariable \"enable_waf\" { type = bool }\nvariable \"ig_route_table_id\" { type = string }\nvariable \"igw_ngw_mixed_route_id\" { type = string }\nvariable \"internet_gateway_id\" { type = string }\nvariable \"load_balancers\" { type = string }\nvariable \"nat_gateway_id\" { type = string }\nvariable \"nat_route_table_id\" { type = string }\nvariable \"vcn_cidrs\" { type = list(string) }\nvariable \"vcn_ipv6_cidrs\" { type = list(string) }\nvariable \"vcn_id\" { type = string }\nvariable \"worker_is_public\" { type = bool }\n\nvariable \"subnets\" {\n  type = map(object({\n    create       = optional(string)\n    id           = optional(string)\n    newbits      = optional(string)\n    netnum       = optional(string)\n    cidr         = optional(string)\n    display_name = optional(string)\n    dns_label    = optional(string)\n    ipv6_cidr    = optional(string)\n  }))\n}\n\nvariable \"nsgs\" {\n  type = map(object({\n    create = optional(string)\n    id     = optional(string)\n  }))\n}\n\nvariable \"use_stateless_rules\" { type    = bool }\n"
  },
  {
    "path": "modules/network/versions.tf",
    "content": "# Copyright (c) 2017, 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nterraform {\n  required_version = \">= 1.2.0\"\n\n  required_providers {\n    oci = {\n      source  = \"oracle/oci\"\n      version = \">= 7.30.0\"\n    }\n  }\n}\n"
  },
  {
    "path": "modules/operator/README.md",
    "content": "# Operator\n\nThis sub-module creates an operator host in a private subnet pre-installed with kubectl, Helm, and optional tools.\n\n## Usage\n\nRefer to the [Operator section](../../docs/terraformoptions.md#operator) of the module documentation.\n"
  },
  {
    "path": "modules/operator/cloudinit.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  # https://cloudinit.readthedocs.io/en/latest/explanation/format.html#mime-multi-part-archive\n  default_cloud_init_content_type = \"text/x-shellscript\"\n\n  # https://canonical-cloud-init.readthedocs-hosted.com/en/latest/reference/merging.html\n  default_cloud_init_merge_type = \"list(append)+dict(no_replace,recurse_list)+str(append)\"\n\n  baserepo        = \"ol${var.operator_image_os_version}\"\n  developer_EPEL  = \"${local.baserepo}_developer_EPEL\"\n  olcne19         = \"${local.baserepo}_olcne19\"\n  developer_olcne = \"${local.baserepo}_developer_olcne\"\n  arch_amd        = \"amd64\"\n  arch_arm        = \"aarch64\"\n}\n\n# https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/cloudinit_config.html\ndata \"cloudinit_config\" \"operator\" {\n  gzip          = true\n  base64_encode = true\n\n  # Repository/package installation\n  part {\n    content_type = \"text/cloud-config\"\n    content = jsonencode({\n      # https://cloudinit.readthedocs.io/en/latest/reference/modules.html#package-update-upgrade-install\n      package_update  = true\n      package_upgrade = var.upgrade\n      packages = compact([\n        \"git\",\n        \"jq\",\n        \"python3-oci-cli\",\n        \"golang\",\n        var.install_helm ? \"helm\" : null,\n        var.install_istioctl ? \"istio-istioctl\" : null,\n        var.install_kubectl_from_repo ? \"kubectl\" : null,\n      ])\n      yum_repos = {\n        \"${local.developer_EPEL}\" = {\n          name     = \"Oracle Linux $releasever EPEL Packages for Development ($basearch)\"\n          baseurl  = \"https://yum$ociregion.$ocidomain/repo/OracleLinux/OL${var.operator_image_os_version}/developer/EPEL/$basearch/\"\n          gpgkey   = \"file:///etc/pki/rpm-gpg/RPM-GPG-KEY-oracle\"\n          gpgcheck = true\n          enabled  = true\n        }\n        \"${local.olcne19}\" = {\n          name     = \"Oracle Linux Cloud Native Environment 1.8 ($basearch)\"\n          baseurl  = \"https://yum$ociregion.$ocidomain/repo/OracleLinux/OL${var.operator_image_os_version}/olcne19/$basearch/\"\n          gpgkey   = \"file:///etc/pki/rpm-gpg/RPM-GPG-KEY-oracle\"\n          gpgcheck = true\n          enabled  = true\n        }\n        \"${local.developer_olcne}\" = {\n          name     = \"Developer Preview for Oracle Linux Cloud Native Environment ($basearch)\"\n          baseurl  = \"https://yum$ociregion.$ocidomain/repo/OracleLinux/OL${var.operator_image_os_version}/developer/olcne/$basearch/\"\n          gpgkey   = \"file:///etc/pki/rpm-gpg/RPM-GPG-KEY-oracle\"\n          gpgcheck = true\n          enabled  = false\n        }\n      }\n    })\n    filename   = \"10-packages.yml\"\n    merge_type = local.default_cloud_init_merge_type\n  }\n\n  # Set timezone\n  part {\n    # https://cloudinit.readthedocs.io/en/latest/reference/modules.html#timezone\n    content_type = \"text/cloud-config\"\n    content      = jsonencode({ timezone = var.timezone })\n    filename     = \"10-timezone.yml\"\n  }\n\n  # Create configured user\n  part {\n    content_type = \"text/cloud-config\"\n    # https://cloudinit.readthedocs.io/en/latest/reference/modules.html#users-and-groups\n    content  = jsonencode({ users = [\"default\", var.user] })\n    filename = \"10-user.yml\"\n  }\n\n  # Expand root filesystem to fill available space on volume\n  part {\n    content_type = \"text/cloud-config\"\n    content = jsonencode({\n      # https://cloudinit.readthedocs.io/en/latest/reference/modules.html#growpart\n      growpart = {\n        mode                     = \"auto\"\n        devices                  = [\"/\"]\n        ignore_growroot_disabled = false\n      }\n\n      # https://cloudinit.readthedocs.io/en/latest/reference/modules.html#resizefs\n      resize_rootfs = true\n\n      # Resize logical LVM root volume when utility is present\n      bootcmd = [\"if [[ -f /usr/libexec/oci-growfs ]]; then /usr/libexec/oci-growfs -y; fi\"]\n    })\n    filename   = \"10-growpart.yml\"\n    merge_type = local.default_cloud_init_merge_type\n  }\n\n\n  # OCI CLI installation from repo\n  dynamic \"part\" {\n    for_each = var.install_oci_cli_from_repo ? [1] : []\n    content {\n      content_type = \"text/cloud-config\"\n      content = jsonencode({\n        runcmd = [\n          \"curl -LO https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/install/install.sh\",\n          \"su -c 'bash /install.sh --accept-all-defaults' - ${var.user}\",\n        ]\n      })\n      filename   = \"20-oci_cli_from_repo.yml\"\n      merge_type = local.default_cloud_init_merge_type\n    }\n  }\n\n  # kubectl installation\n  dynamic \"part\" {\n    for_each = var.install_kubectl_from_repo ? [1] : []\n    content {\n      content_type = \"text/cloud-config\"\n      content = jsonencode({\n        runcmd = [\n          \"CLI_ARCH='${local.arch_amd}'\",\n          \"if [ \\\"$(uname -m)\\\" = ${local.arch_arm} ]; then CLI_ARCH='arm64'; fi\",\n          \"curl -LO https://dl.k8s.io/release/${var.kubernetes_version}/bin/linux/$CLI_ARCH/kubectl\",\n          \"install -o root -g root -m 0755 kubectl /usr/bin/kubectl\",\n        ]\n      })\n      filename   = \"20-kubectl.yml\"\n      merge_type = local.default_cloud_init_merge_type\n    }\n  }\n\n  # k8sgpt installation\n  dynamic \"part\" {\n    for_each = var.install_k8sgpt ? [1] : []\n    content {\n      content_type = \"text/cloud-config\"\n      content = jsonencode({\n        runcmd = [\n          \"CLI_ARCH='${local.arch_amd}'\",\n          \"if [ \\\"$(uname -m)\\\" = ${local.arch_arm} ]; then CLI_ARCH='arm64'; fi\",\n          \"if [ -f /etc/os-release ]; then os_id=$(grep '^ID=' /etc/os-release | awk -F= '{print $2}' | tr -d '\\\"'); fi\",\n          \"if [ \\\"$os_id\\\" == \\\"ubuntu\\\" ]; then curl -LO https://github.com/k8sgpt-ai/k8sgpt/releases/latest/download/k8sgpt_$CLI_ARCH.deb; dpkg -i k8sgpt_$CLI_ARCH.deb; rm k8sgpt_$CLI_ARCH.deb; fi\",\n          \"if [ \\\"$os_id\\\" == \\\"ol\\\" ]; then while fuser /var/lib/rpm/.rpm.lock >/dev/null 2>&1; do sleep 5; done; rpm -ivh https://github.com/k8sgpt-ai/k8sgpt/releases/latest/download/k8sgpt_$CLI_ARCH.rpm; fi\"\n        ]\n      })\n      filename   = \"20-k8sgpt.yml\"\n      merge_type = local.default_cloud_init_merge_type\n    }\n  }\n\n  # kubectx/kubens installation\n  dynamic \"part\" {\n    for_each = var.install_kubectx ? [1] : []\n    content {\n      content_type = \"text/cloud-config\"\n      content = jsonencode({\n        runcmd = [\n          \"git clone https://github.com/ahmetb/kubectx /opt/kubectx\",\n          \"ln -s /opt/kubectx/kubectx /usr/bin/kubectx\",\n          \"ln -s /opt/kubectx/kubens /usr/bin/kubens\",\n        ]\n      })\n      filename   = \"20-kubectx.yml\"\n      merge_type = local.default_cloud_init_merge_type\n    }\n  }\n\n  # Helm installation from repo\n  dynamic \"part\" {\n    for_each = var.install_helm_from_repo ? [1] : []\n    content {\n      content_type = \"text/cloud-config\"\n      content = jsonencode({\n        runcmd = [\n          \"curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3\",\n          \"chmod 700 get_helm.sh\",\n          \"./get_helm.sh\",\n        ]\n      })\n      filename   = \"20-helm_from_repo.yml\"\n      merge_type = local.default_cloud_init_merge_type\n    }\n  }\n\n  # Optional Helm installation bashrc\n  dynamic \"part\" {\n    for_each = var.install_helm ? [1] : []\n    content {\n      content_type = \"text/cloud-config\"\n      content = jsonencode({\n        # https://cloudinit.readthedocs.io/en/latest/reference/modules.html#write-files\n        write_files = [\n          {\n            content = <<-EOT\n              source <(helm completion bash)\n              alias h='helm'\n            EOT\n            path    = \"/tmp/helm.bashrc\" # see 30-bashrc.yml for final move\n          },\n        ]\n      })\n      filename   = \"20-helm.bashrc.yml\"\n      merge_type = local.default_cloud_init_merge_type\n    }\n  }\n\n  # Optional k9s installation\n  dynamic \"part\" {\n    for_each = var.install_k9s ? [1] : []\n    content {\n      content_type = \"text/cloud-config\"\n      content = jsonencode({\n        runcmd = [\n          \"curl -LO https://github.com/derailed/k9s/releases/latest/download/k9s_Linux_amd64.tar.gz\",\n          \"tar -xvzf k9s_Linux_amd64.tar.gz && mv ./k9s /usr/bin/k9s\",\n          \"echo 'export K9S_FEATURE_GATE_NODE_SHELL=true' | tee -a /home/${var.user}/.bashrc\",\n          \"mkdir -p /home/${var.user}/.config/k9s\",\n          <<-EOT\n            cat << 'EOF' | tee /home/${var.user}/.config/k9s/views.yaml\n            views:\n              v1/nodes:\n                columns:\n                  - NAME\n                  - HOSTNAME:.metadata.labels.hostname\n                  - SHAPE:.metadata.labels.node\\.kubernetes\\.io/instance-type\n                  - SERIAL:.metadata.labels.oci\\.oraclecloud\\.com/host\\.serial_number\n                  - ROLE:|H\n            EOF\n          EOT\n        ]\n      })\n      filename   = \"20-k9s.yml\"\n      merge_type = local.default_cloud_init_merge_type\n    }\n  }\n\n  # Optional cilium cli installation\n  dynamic \"part\" {\n    for_each = var.install_cilium ? [1] : []\n    content {\n      content_type = \"text/cloud-config\"\n      content = jsonencode({\n        runcmd = [\n          \"CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/master/stable.txt)\",\n          \"CLI_ARCH='${local.arch_amd}'\",\n          \"if [ \\\"$(uname -m)\\\" = ${local.arch_arm} ]; then CLI_ARCH='arm64'; fi\",\n          \"curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/$CILIUM_CLI_VERSION/cilium-linux-$CLI_ARCH.tar.gz\",\n          \"tar xzvfC cilium-linux-$CLI_ARCH.tar.gz /usr/local/bin\"\n        ]\n      })\n      filename   = \"20-cilium.yml\"\n      merge_type = local.default_cloud_init_merge_type\n    }\n  }\n\n  # stern installation\n  dynamic \"part\" {\n    for_each = var.install_stern ? [1] : []\n    content {\n      content_type = \"text/cloud-config\"\n      content = jsonencode({\n        runcmd = [\n          \"go install github.com/stern/stern@v1.30\",\n          \"mv $HOME/go/bin/stern /usr/local/bin/\",\n          \"ln -s /usr/local/bin/stern /usr/bin/stern\"\n        ]\n      })\n      filename   = \"20-stern.yml\"\n      merge_type = local.default_cloud_init_merge_type\n    }\n  }\n\n  # Write user bashrc to filesystem\n  part {\n    content_type = \"text/cloud-config\"\n    content = jsonencode({\n      # https://cloudinit.readthedocs.io/en/latest/reference/modules.html#write-files\n      write_files = [\n        {\n          content = <<-EOT\n            export OCI_CLI_AUTH=instance_principal\n            export TERM=xterm-256color\n            export OCI_PYTHON_SDK_NO_SERVICE_IMPORTS=True\n            source <(kubectl completion bash)\n            alias k='kubectl'\n            alias ktx='kubectx'\n            alias kns='kubens'\n          EOT\n          path    = \"/tmp/user.bashrc\" # see 30-home.yml for final move\n        },\n      ]\n    })\n    filename   = \"20-bashrc.yml\"\n    merge_type = local.default_cloud_init_merge_type\n  }\n\n  # Write user kubeconfig to filesystem\n  part {\n    content_type = \"text/cloud-config\"\n    content = jsonencode({\n      # https://cloudinit.readthedocs.io/en/latest/reference/modules.html#write-files\n      write_files = [\n        {\n          content = var.kubeconfig\n          path    = \"/tmp/kubeconfig\" # see 30-home.yml for final move\n        },\n      ]\n    })\n    filename   = \"20-kubeconfig.yml\"\n    merge_type = local.default_cloud_init_merge_type\n  }\n\n  # Bug w/ write_files defer: parent directory created as root if not present.\n  # https://github.com/canonical/cloud-init/pull/916#issuecomment-1254732400\n  # Or: defer not supported on older versions of cloud-init.\n  # Created in tmp first and moved into user's home directory using runcmd.\n  part {\n    content_type = \"text/cloud-config\"\n    content = jsonencode({\n      runcmd = [\n        \"cat /tmp/*.bashrc >> /home/${var.user}/.bashrc && rm /tmp/*.bashrc\",\n        \"chmod 600 /home/${var.user}/.bashrc\",\n        \"mkdir -p /home/${var.user}/.kube\",\n        \"mv /tmp/kubeconfig /home/${var.user}/.kube/config\",\n        \"chmod 700 /home/${var.user}/.kube\",\n        \"chmod 600 /home/${var.user}/.kube/config\",\n        \"chown -R ${var.user}:${var.user} /home/${var.user}\",\n      ]\n    })\n    filename   = \"30-home.yml\"\n    merge_type = local.default_cloud_init_merge_type\n  }\n\n  # Include custom cloud init MIME parts\n  dynamic \"part\" {\n    for_each = var.cloud_init\n    iterator = part\n    content {\n      # Load content from file if local path, attempt base64 decode, or use raw value\n      content = contains(keys(part.value), \"content\") ? (\n        try(fileexists(lookup(part.value, \"content\")), false) ? file(lookup(part.value, \"content\"))\n        : try(base64decode(lookup(part.value, \"content\")), lookup(part.value, \"content\"))\n      ) : \"\"\n      content_type = lookup(part.value, \"content_type\", local.default_cloud_init_content_type)\n      filename     = lookup(part.value, \"filename\", null)\n      merge_type   = lookup(part.value, \"merge_type\", local.default_cloud_init_merge_type)\n    }\n  }\n\n  lifecycle {\n    precondition {\n      condition     = alltrue([for c in var.cloud_init : trimspace(lookup(c, \"content\", \"\")) != \"\"])\n      error_message = <<-EOT\n      Each operator cloud_init map entry must include a non-empty 'content' field.\n      See https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/cloudinit_config.html.\n      var.cloud_init: ${try(jsonencode(var.cloud_init), \"invalid\")}\n      EOT\n    }\n\n    precondition {\n      condition = alltrue([for c in var.cloud_init :\n        length(regexall(\"^text/[a-z-]*$\", trimspace(lookup(c, \"content_type\", local.default_cloud_init_content_type)))) > 0\n      ])\n      error_message = <<-EOT\n      Each operator cloud_init map entry must include a 'content_type' field prefixed with 'text/'.\n      See https://cloudinit.readthedocs.io/en/latest/explanation/format.html#mime-multi-part-archive.\n      var.cloud_init: ${try(jsonencode(var.cloud_init), \"invalid\")}\n      EOT\n    }\n  }\n}\n\nresource \"null_resource\" \"await_cloudinit\" {\n  count = var.await_cloudinit ? 1 : 0\n  connection {\n    bastion_host        = var.bastion_host\n    bastion_user        = var.bastion_user\n    bastion_private_key = var.ssh_private_key\n    host                = oci_core_instance.operator.private_ip\n    user                = var.user\n    private_key         = var.ssh_private_key\n    timeout             = \"40m\"\n    type                = \"ssh\"\n  }\n\n  lifecycle {\n    replace_triggered_by = [oci_core_instance.operator]\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\"cloud-init status --wait &> /dev/null\"]\n  }\n}"
  },
  {
    "path": "modules/operator/compute.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  boot_volume_size = lookup(var.shape, \"boot_volume_size\", 50)\n  memory           = lookup(var.shape, \"memory\", 4)\n  ocpus            = max(1, lookup(var.shape, \"ocpus\", 1))\n  shape            = lookup(var.shape, \"shape\", \"VM.Standard.E4.Flex\")\n\n  baseline_ocpu_utilization_map = {\n    \"12.5\" = \"BASELINE_1_8\"\n    \"50\"   = \"BASELINE_1_2\"\n    \"100\"  = \"BASELINE_1_1\"\n  }\n  baseline_ocpu_utilization = lookup(local.baseline_ocpu_utilization_map, lookup(var.shape, \"baseline_ocpu_utilization\", \"100\"))\n}\n\noutput \"id\" {\n  value = oci_core_instance.operator.id\n}\n\noutput \"private_ip\" {\n  value = oci_core_instance.operator.private_ip\n}\n\nresource \"oci_core_instance\" \"operator\" {\n  availability_domain                 = var.availability_domain\n  compartment_id                      = var.compartment_id\n  display_name                        = \"operator-${var.state_id}\"\n  defined_tags                        = var.defined_tags\n  freeform_tags                       = var.freeform_tags\n  is_pv_encryption_in_transit_enabled = var.pv_transit_encryption\n  shape                               = local.shape\n\n  agent_config {\n    are_all_plugins_disabled = false\n    is_management_disabled   = false\n    is_monitoring_disabled   = false\n\n    plugins_config {\n      desired_state = \"ENABLED\"\n      name          = \"Bastion\"\n    }\n    plugins_config {\n      desired_state = \"DISABLED\"\n      name          = \"OS Management Service Agent\"\n    }\n  }\n\n  create_vnic_details {\n    assign_public_ip = false\n    display_name     = \"operator-${var.state_id}\"\n    hostname_label   = var.assign_dns ? \"o-${var.state_id}\" : null\n    nsg_ids          = var.nsg_ids\n    subnet_id        = var.subnet_id\n  }\n\n  launch_options {\n    boot_volume_type = \"PARAVIRTUALIZED\"\n    network_type     = \"PARAVIRTUALIZED\"\n  }\n\n  instance_options {\n    are_legacy_imds_endpoints_disabled = var.legacy_imds_endpoints_disabled\n  }\n\n  metadata = {\n    ssh_authorized_keys = var.ssh_public_key\n    user_data           = data.cloudinit_config.operator.rendered\n  }\n\n  dynamic \"shape_config\" {\n    for_each = length(regexall(\"Flex\", local.shape)) > 0 ? [1] : []\n    content {\n      baseline_ocpu_utilization = local.baseline_ocpu_utilization\n      ocpus                     = local.ocpus\n      memory_in_gbs             = (local.memory / local.ocpus) > 64 ? (local.ocpus * 4) : local.memory\n    }\n  }\n\n  source_details {\n    boot_volume_size_in_gbs = local.boot_volume_size\n    source_type             = \"image\"\n    source_id               = var.image_id\n    kms_key_id              = var.volume_kms_key_id\n  }\n\n  lifecycle {\n    ignore_changes = [\n      availability_domain,\n      defined_tags, freeform_tags, display_name,\n      create_vnic_details, metadata, source_details,\n    ]\n\n    replace_triggered_by = [null_resource.operator_changed]\n    precondition {\n      condition     = coalesce(var.image_id, \"none\") != \"none\"\n      error_message = \"Missing image_id for operator. Check provided value for image_id if image_type is 'custom', or image_os/image_os_version if image_type is 'platform'.\"\n    }\n  }\n\n  timeouts {\n    create = \"60m\"\n  }\n}\n\nresource \"null_resource\" \"operator_changed\" {\n  triggers = {\n    cloud_init      = jsonencode(var.cloud_init)\n    image_id        = var.image_id\n    install_helm    = var.install_helm\n    install_k9s     = var.install_k9s\n    install_kubectx = var.install_kubectx\n    ssh_public_key  = var.ssh_public_key\n  }\n}\n"
  },
  {
    "path": "modules/operator/variables.tf",
    "content": "# Copyright (c) 2019, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# Common\nvariable \"compartment_id\" { type = string }\nvariable \"state_id\" { type = string }\n\n# Bastion (to await cloud-init completion)\nvariable \"bastion_host\" { type = string }\nvariable \"bastion_user\" { type = string }\n\n# Operator\nvariable \"await_cloudinit\" { type = string }\nvariable \"assign_dns\" { type = bool }\nvariable \"availability_domain\" { type = string }\nvariable \"cloud_init\" { type = list(map(string)) }\nvariable \"image_id\" { type = string }\nvariable \"install_cilium\" { type = bool }\nvariable \"install_oci_cli_from_repo\" { type = bool }\nvariable \"install_helm\" { type = bool }\nvariable \"install_helm_from_repo\" { type = bool }\nvariable \"install_istioctl\" { type = bool }\nvariable \"install_k8sgpt\" { type = bool }\nvariable \"install_k9s\" { type = bool }\nvariable \"install_kubectl_from_repo\" {\n  type    = bool\n  default = true\n}\nvariable \"install_kubectx\" { type = bool }\nvariable \"install_stern\" { type = bool }\nvariable \"kubeconfig\" { type = string }\nvariable \"kubernetes_version\" { type = string }\nvariable \"nsg_ids\" { type = list(string) }\nvariable \"operator_image_os_version\" { type = string }\nvariable \"pv_transit_encryption\" { type = bool }\nvariable \"shape\" { type = map(any) }\nvariable \"legacy_imds_endpoints_disabled\" {\n  type    = bool\n  default = true\n}\nvariable \"ssh_private_key\" {\n  type      = string\n  sensitive = true\n}\nvariable \"ssh_public_key\" { type = string }\nvariable \"subnet_id\" { type = string }\nvariable \"timezone\" { type = string }\nvariable \"upgrade\" { type = bool }\nvariable \"user\" { type = string }\nvariable \"volume_kms_key_id\" { type = string }\n\n# Tags\nvariable \"defined_tags\" { type = map(string) }\nvariable \"freeform_tags\" { type = map(string) }\nvariable \"tag_namespace\" { type = string }\nvariable \"use_defined_tags\" { type = bool }"
  },
  {
    "path": "modules/operator/versions.tf",
    "content": "# Copyright (c) 2017, 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nterraform {\n  required_version = \">= 1.2.0\"\n\n  required_providers {\n    cloudinit = {\n      source  = \"hashicorp/cloudinit\"\n      version = \">= 2.2.0\"\n    }\n\n    null = {\n      source  = \"hashicorp/null\"\n      version = \">= 3.2.1\"\n    }\n\n    oci = {\n      source  = \"oracle/oci\"\n      version = \">= 7.30.0\"\n    }\n  }\n}\n"
  },
  {
    "path": "modules/utilities/README.md",
    "content": "# Utilities\n\nThis sub-module provides helper resources including node readiness checks, OCIR secret creation, and worker pool draining.\n\n## Usage\n\nRefer to the [Utilities section](../../docs/terraformoptions.md#utilities) of the module documentation.\n"
  },
  {
    "path": "modules/utilities/drain.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  drain_enabled = var.expected_drain_count > 0\n  drain_pools = (local.drain_enabled\n    ? tolist([for k, v in var.worker_pools : k if tobool(lookup(v, \"drain\", false))]) : []\n  )\n\n  drain_commands = formatlist(\n    format(\n      \"kubectl drain %v %v %v %v\",\n      format(\"--timeout=%vs\", var.worker_drain_timeout_seconds),\n      format(\"--ignore-daemonsets=%v\", var.worker_drain_ignore_daemonsets),\n      format(\"--delete-emptydir-data=%v\", var.worker_drain_delete_local_data),\n      \"-l oke.oraclecloud.com/pool.name=%v\" # interpolation deferred to formatlist\n    ),\n    local.drain_pools\n  )\n}\n\nresource \"null_resource\" \"drain_workers\" {\n  count = local.drain_enabled ? 1 : 0\n  triggers = {\n    drain_pools    = jsonencode(sort(local.drain_pools))\n    drain_commands = jsonencode(local.drain_commands)\n  }\n\n  connection {\n    bastion_host        = var.bastion_host\n    bastion_user        = var.bastion_user\n    bastion_private_key = var.ssh_private_key\n    host                = var.operator_host\n    user                = var.operator_user\n    private_key         = var.ssh_private_key\n    timeout             = \"40m\"\n    type                = \"ssh\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = local.drain_commands\n  }\n}\n"
  },
  {
    "path": "modules/utilities/nodeready.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  node_ready_script = \"/home/${var.operator_user}/await_node_ready.sh\"\n  node_ready_template = templatefile(\"${path.module}/resources/await_node_readiness.tpl.sh\",\n    {\n      await_node_readiness = var.await_node_readiness\n      expected_node_count  = var.expected_node_count\n    }\n  )\n}\n\nresource \"null_resource\" \"await_node_readiness\" {\n  count    = var.await_node_readiness != \"none\" && var.expected_node_count > 0 ? 1 : 0\n  triggers = { expected_node_count = var.expected_node_count }\n\n  connection {\n    bastion_host        = var.bastion_host\n    bastion_user        = var.bastion_user\n    bastion_private_key = var.ssh_private_key\n    host                = var.operator_host\n    user                = var.operator_user\n    private_key         = var.ssh_private_key\n    timeout             = \"40m\"\n    type                = \"ssh\"\n  }\n\n  provisioner \"file\" {\n    content     = local.node_ready_template\n    destination = local.node_ready_script\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\"bash ${local.node_ready_script}\"]\n  }\n}\n"
  },
  {
    "path": "modules/utilities/ocir.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# Retrieve object storage namespace for secret\ndata \"oci_objectstorage_namespace\" \"object_storage_namespace\" {\n  count = coalesce(var.ocir_secret_id, \"none\") != \"none\" ? 1 : 0\n}\n\nlocals {\n  oci_secret_query = \"'data.\\\"secret-bundle-content\\\".content'\"\n  oci_secret_get = format(\n    \"oci secrets secret-bundle get --raw-output --secret-id %s --query %s | base64 -d\",\n    coalesce(var.ocir_secret_id, \"none\"), local.oci_secret_query,\n  )\n\n  region_registry   = \"${var.region}.ocir.io\"\n  tenancy_namespace = one(data.oci_objectstorage_namespace.object_storage_namespace[*].namespace)\n}\n\nresource \"null_resource\" \"ocir_secret\" {\n  count    = coalesce(var.ocir_secret_id, \"none\") != \"none\" ? 1 : 0\n  triggers = { always_run = timestamp() }\n\n  connection {\n    bastion_host        = var.bastion_host\n    bastion_user        = var.bastion_user\n    bastion_private_key = var.ssh_private_key\n    host                = var.operator_host\n    user                = var.operator_user\n    private_key         = var.ssh_private_key\n    timeout             = \"40m\"\n    type                = \"ssh\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = formatlist(\"%s --dry-run=client -o yaml | kubectl apply -f -\", [\n      format(\"kubectl create ns %s\", var.ocir_secret_namespace),\n      format(\"kubectl create secret docker-registry %s\",\n        join(\" \", [\n          var.ocir_secret_name,\n          format(\"-n %s\", var.ocir_secret_namespace),\n          format(\"--docker-server=%s\", local.region_registry),\n          format(\"--docker-ocir_username=%s/%s\", join(\"/\", compact([local.tenancy_namespace, var.ocir_username]))),\n          format(\"--docker-email=%s\", var.ocir_email_address),\n          format(\"--docker-password=%s\", local.oci_secret_get)\n        ])\n      ),\n    ])\n  }\n\n  lifecycle {\n    precondition {\n      condition = alltrue([\n        local.region_registry != null,\n        local.tenancy_namespace != null,\n        var.ocir_email_address != null,\n        var.ocir_secret_name != null,\n        var.ocir_secret_namespace != null,\n        var.ocir_username != null,\n      ])\n      error_message = \"Missing required configuration for OCIR; check variables.\"\n    }\n  }\n}\n"
  },
  {
    "path": "modules/utilities/resources/await_node_readiness.tpl.sh",
    "content": "#!/usr/bin/env bash\n# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n# shellcheck disable=SC1083,SC2309,SC2154,SC2157,SC2034 # Ignore templated/escaped/unused file variables\nexport ALL_FILE=~/all_node.active ONE_FILE=~/one_node.active\n\nfunction clean_node_active() {\n  rm -f \"$${ALL_FILE}\" \"$${ONE_FILE}\"\n}\n\nfunction get_actual_node_count() (\n  (kubectl get --no-headers nodes | grep -v NotReady | awk '{print $1}' | wc -l) 2>/dev/null || echo '0'\n)\n\nfunction wait_for_active() {\n  clean_node_active\n\n  while true; do\n    local actual_node_count\n    actual_node_count=$(get_actual_node_count)\n    if [[ $${actual_node_count} -ge ${expected_node_count} ]]; then touch all_node.active; fi\n    if [[ $${actual_node_count} -ge 1 ]]; then touch one_node.active; fi\n\n    if [[ -f \"$${ONE_FILE}\" ]] && [[ \"${await_node_readiness}\" == 'one' ]]; then\n      echo \"$(date): Ready with $${actual_node_count} node(s)\" >&2\n      break\n    fi\n\n    if [[ -f \"$${ALL_FILE}\" ]] && [[ \"${await_node_readiness}\" == 'all' ]]; then\n      echo \"$(date): Ready with $${actual_node_count} node(s)\" >&2\n      break\n    fi\n\n    echo \"$(date): Waiting for ${await_node_readiness} of ${expected_node_count} node(s) to become ready ($${actual_node_count} found)\" >&2\n    sleep 30\n  done\n}\n\nif [[ ${expected_node_count} -ge 1 ]]; then time wait_for_active; fi"
  },
  {
    "path": "modules/utilities/variables.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# Common\nvariable \"region\" { type = string }\nvariable \"worker_pools\" { type = any }\n\n# Connection\nvariable \"bastion_host\" { type = string }\nvariable \"bastion_user\" { type = string }\nvariable \"operator_host\" { type = string }\nvariable \"operator_user\" { type = string }\nvariable \"ssh_private_key\" {\n  type      = string\n  sensitive = true\n}\n\n# OCIR\nvariable \"ocir_email_address\" { type = string }\nvariable \"ocir_secret_id\" { type = string }\nvariable \"ocir_secret_name\" { type = string }\nvariable \"ocir_secret_namespace\" { type = string }\nvariable \"ocir_username\" { type = string }\n\n# Node readiness check, drain\nvariable \"await_node_readiness\" { type = string }\nvariable \"expected_drain_count\" { type = number }\nvariable \"expected_node_count\" { type = number }\nvariable \"worker_drain_ignore_daemonsets\" { type = bool }\nvariable \"worker_drain_delete_local_data\" { type = bool }\nvariable \"worker_drain_timeout_seconds\" { type = number }\n"
  },
  {
    "path": "modules/utilities/versions.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nterraform {\n  required_version = \">= 1.2.0\"\n\n  required_providers {\n    null = {\n      source  = \"hashicorp/null\"\n      version = \">= 3.2.1\"\n    }\n\n    oci = {\n      source  = \"oracle/oci\"\n      version = \">= 7.30.0\"\n    }\n  }\n}\n"
  },
  {
    "path": "modules/workers/README.md",
    "content": "# Worker pools\n\nThis sub-module supports different modes of OKE worker node management with advanced configuration.\n\n## Usage\n\nRefer to the [Workers section](../../docs/terraformoptions.md#workers) of the module documentation.\n"
  },
  {
    "path": "modules/workers/cloudinit-oke.sh",
    "content": "#!/usr/bin/env bash\n# Copyright (c) 2022, 2025 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n# shellcheck disable=SC1091 # Ignore unresolved file path present on base images\nset -o pipefail\n\nfunction get_imds_base_url() {\n  imds_base_url=$(cat /tmp/imds_base_url || echo \"\")\n  \n  if [[ -z $imds_base_url ]]; then\n    for url in \"http://169.254.169.254/\" \"http://[fd00:c1::a9fe:a9fe]/\"; do\n      if curl -sSf -m 5 --retry 5 --retry-delay 1 -H 'Authorization: Bearer Oracle' -L0 \"${url}opc/v2/instance/state\" > /dev/null; then\n        imds_base_url=\"$url\"\n        echo \"$imds_base_url\" > /tmp/imds_base_url\n        break\n      fi\n    done\n  fi\n  \n  if [ -z \"${imds_base_url}\" ]; then\n    echo \"Unable to determine imds base url\" >&2\n    exit 1\n  fi\n  \n  echo \"${imds_base_url}\"\n}\n\nfunction curl_instance_metadata() {\n  local imds_base=\"$(get_imds_base_url)\"\n  local url=\"${imds_base}$1\"\n  local retries=10\n  local output\n  \n  while (( retries-- > 0 )); do\n    if output=$(curl -sSf -m 5 -H 'Authorization: Bearer Oracle' -L0 \"$url\"); then\n      echo \"$output\"\n      return 0\n    fi\n    sleep 1\n  done\n\n  echo \"Failed to fetch metadata from $url\" >&2\n  return 1\n}\n\nfunction get_imds_instance() {\n  find \"${INSTANCE_FILE}\" -mmin -1 -not -empty > /dev/null 2>&1 || (curl_instance_metadata 'opc/v2/instance' | jq -rcM '.' > \"${INSTANCE_FILE}\")\n  INSTANCE=\"$(cat \"${INSTANCE_FILE}\" || echo -n '')\"\n  \n  export INSTANCE\n  echo \"${INSTANCE}\"\n}\n\nfunction get_imds_metadata() {\n  get_imds_instance | jq -rcM '.metadata // {}'\n}\n\nfunction run_oke_init() { # Initialize OKE worker node\n  if [[ -f /etc/systemd/system/oke-init.service ]]; then\n    systemctl --no-block enable --now oke-init.service\n    return\n  fi\n\n  if [[ -f /etc/oke/oke-install.sh ]]; then\n    local apiserver_host cluster_ca\n\n    if [[ -f \"/etc/oke/oke-apiserver\" ]]; then\n      apiserver_host=$(< /etc/oke/oke-apiserver)\n    else\n      apiserver_host=$(get_imds_metadata | jq -rcM '.apiserver_host')\n    fi\n\n    if [[ -f \"/etc/kubernetes/ca.crt\" ]]; then\n      cluster_ca=$(base64 -w0 /etc/kubernetes/ca.crt)\n    else\n      cluster_ca=$(get_imds_metadata | jq -rcM '.cluster_ca_cert')\n    fi\n\n    bash /etc/oke/oke-install.sh \\\n      --apiserver-endpoint \"${apiserver_host}\" \\\n      --kubelet-ca-cert \"${cluster_ca}\"\n    return\n  fi\n   \n  local retries=5\n  local delay=2\n  local oke_init_relative_path=\"opc/v2/instance/metadata/oke_init_script\"\n  local script_path=\"/var/run/oke-init.sh\"\n\n  for (( i=0; i<retries; i++ )); do\n    for url in \"http://169.254.169.254/\" \"http://[fd00:c1::a9fe:a9fe]/\"; do\n      echo \"Attempting to fetch OKE init script from ${base_url}${oke_init_relative_path}\"\n      if curl -sSf -H 'Authorization: Bearer Oracle' -L0 \"${url}${oke_init_relative_path}\" | base64 --decode > \"${script_path}\"; then\n        bash \"${script_path}\"\n        exit 0\n      fi\n    done\n    echo \"Retry $((i+1)) failed, retrying in $delay seconds...\"\n  done\n}\n\nINSTANCE_FILE=\"/etc/oke/imds_instance.json\"\ntime run_oke_init || { echo \"Error in OKE startup\" >&2; exit 1; }"
  },
  {
    "path": "modules/workers/cloudinit-ubuntu.sh.tftpl",
    "content": "#!/bin/bash\nset -x\n\nsource /etc/os-release\n\noke_package_name=\"oci-oke-node-all-${oke_minor_version}\"\n\n# Add OKE Ubuntu package repo\ntee /etc/apt/sources.list.d/oke-node-client.sources <<EOF\nEnabled: yes\nTypes: deb\nURIs: https://odx-oke.objectstorage.us-sanjose-1.oci.customer-oci.com/n/odx-oke/b/okn-repositories/o/prod/ubuntu-${version_codename}/kubernetes-${oke_major_version}\nSuites: stable\nComponents: main\nTrusted: yes\nEOF\n\n# Wait for apt lock and install the package\nwhile fuser /var/{lib/{dpkg/{lock,lock-frontend},apt/lists},cache/apt/archives}/lock >/dev/null 2>&1; do\n   echo \"Waiting for dpkg/apt lock\"\n   sleep 1\ndone\n\napt-get -y update && apt-get -y install $oke_package_name\n\n# OKE bootstrap\noke bootstrap"
  },
  {
    "path": "modules/workers/cloudinit.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  # https://cloudinit.readthedocs.io/en/latest/explanation/format.html#mime-multi-part-archive\n  default_cloud_init_content_type = \"text/x-shellscript\"\n\n  # https://canonical-cloud-init.readthedocs-hosted.com/en/latest/reference/merging.html\n  default_cloud_init_merge_type = \"list(append)+dict(no_replace,recurse_list)+str(append)\"\n}\n\ndata \"oci_core_image\" \"workers\" {\n  for_each = { # Skip generation for mode = virtual-node-pool\n    for k, v in local.enabled_worker_pools : k => v\n    if lookup(v, \"mode\", var.worker_pool_mode) != \"virtual-node-pool\"\n  }\n  image_id = each.value.image_id\n}\n\n# https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/cloudinit_config.html\ndata \"cloudinit_config\" \"workers\" {\n  for_each = { # Skip generation for mode = virtual-node-pool\n    for k, v in local.enabled_worker_pools : k => v\n    if lookup(v, \"mode\", var.worker_pool_mode) != \"virtual-node-pool\"\n  }\n  gzip          = true\n  base64_encode = true\n\n  # Include global and pool-specific custom cloud init MIME parts\n  dynamic \"part\" {\n    for_each = each.value.cloud_init\n    iterator = part\n    content {\n      content      = lookup(part.value, \"content\", \"\")\n      content_type = lookup(part.value, \"content_type\", local.default_cloud_init_content_type)\n      filename     = lookup(part.value, \"filename\", null)\n      merge_type   = lookup(part.value, \"merge_type\", local.default_cloud_init_merge_type)\n    }\n  }\n\n  # Set timezone\n  dynamic \"part\" {\n    for_each = each.value.disable_default_cloud_init ? [] : [1]\n    content {\n      content_type = \"text/cloud-config\"\n      # https://cloudinit.readthedocs.io/en/latest/reference/modules.html#timezone\n      content  = jsonencode({ timezone = var.timezone })\n      filename = \"10-timezone.yml\"\n    }\n  }\n\n  # Expand root filesystem to fill available space on volume\n  dynamic \"part\" {\n    for_each = each.value.disable_default_cloud_init ? [] : [1]\n    content {\n      content_type = \"text/cloud-config\"\n      content = jsonencode({\n        # https://cloudinit.readthedocs.io/en/latest/reference/modules.html#growpart\n        growpart = {\n          mode                     = \"auto\"\n          devices                  = [\"/\"]\n          ignore_growroot_disabled = false\n        }\n\n        # https://cloudinit.readthedocs.io/en/latest/reference/modules.html#resizefs\n        resize_rootfs = true\n\n        # Resize logical LVM root volume when utility is present\n        bootcmd = [\"if [[ -f /usr/libexec/oci-growfs ]]; then /usr/libexec/oci-growfs -y; fi\"]\n      })\n      filename   = \"10-growpart.yml\"\n      merge_type = local.default_cloud_init_merge_type\n    }\n  }\n\n  # Write extra OKE configuration to filesystem\n  dynamic \"part\" {\n    for_each = each.value.disable_default_cloud_init ? [] : [1]\n    content {\n      content_type = \"text/cloud-config\"\n      content = jsonencode({\n        write_files = [\n          {\n            content = var.apiserver_private_host\n            path    = \"/etc/oke/oke-apiserver\"\n          },\n          {\n            content  = var.cluster_ca_cert\n            encoding = \"base64\"\n            path     = \"/etc/kubernetes/ca.crt\"\n          },\n        ]\n      })\n      filename   = \"50-oke-config.yml\"\n      merge_type = local.default_cloud_init_merge_type\n    }\n  }\n\n  # Disable CRI-O enforce shortnames mode (for versions greater than 1.34)\n  dynamic \"part\" {\n    for_each = tonumber(split(\".\", each.value.kubernetes_version)[1]) >= 34 && var.allow_short_container_image_names ? [1] : []\n    content {\n      content_type = \"text/cloud-config\"\n      content = jsonencode({\n        write_files = [\n          {\n            content = <<-EOT\n            [crio.image]\n            short_name_mode = \"disabled\"\n            EOT\n            path    = \"/etc/crio/crio.conf.d/11-default.conf\"\n          }\n        ]\n      })\n      filename   = \"50-crio-config.yml\"\n      merge_type = local.default_cloud_init_merge_type\n    }\n  }\n\n\n  # OKE setup and initialization for Ubuntu images\n  dynamic \"part\" {\n    for_each = !each.value.disable_default_cloud_init && lookup(local.ubuntu_worker_pools, each.key, null) != null ? [1] : []\n    content {\n      content_type = \"text/x-shellscript\"\n      content = templatefile(\n        \"${path.module}/cloudinit-ubuntu.sh.tftpl\",\n        {\n          version_codename  = lookup(local.ubuntu_supported_versions, lookup(lookup(local.ubuntu_worker_pools, each.key, {}), \"ubuntu_release\", lookup(each.value, \"os_version\")), \"unsupported_ubuntu_version\"),\n          oke_major_version = lookup(lookup(local.ubuntu_worker_pools, each.key, {}), \"kubernetes_major_version\", \"\")\n          oke_minor_version = lookup(lookup(local.ubuntu_worker_pools, each.key, {}), \"kubernetes_minor_version\", \"\")\n        }\n      )\n      filename   = \"50-oke-ubuntu.sh\"\n      merge_type = local.default_cloud_init_merge_type\n    }\n  }\n\n  # OKE startup initialization\n  dynamic \"part\" {\n    for_each = !each.value.disable_default_cloud_init && lookup(local.ubuntu_worker_pools, each.key, null) == null ? [1] : []\n    content {\n      content_type = \"text/x-shellscript\"\n      content      = file(\"${path.module}/cloudinit-oke.sh\")\n      filename     = \"50-oke.sh\"\n      merge_type   = local.default_cloud_init_merge_type\n    }\n  }\n\n  lifecycle {\n    precondition {\n      condition = alltrue([for c in var.cloud_init :\n        trimspace(lookup(c, \"content\", \"\")) != \"\"\n      ])\n      error_message = <<-EOT\n      Each global cloud_init map entry must include a non-empty 'content' field.\n      See https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/cloudinit_config.html.\n      var.cloud_init (${each.key}): ${try(jsonencode(var.cloud_init), \"invalid\")}\n      EOT\n    }\n\n    precondition {\n      condition = alltrue([for c in var.cloud_init :\n        length(regexall(\"^text/[a-z-]*$\", trimspace(lookup(c, \"content_type\", local.default_cloud_init_content_type)))) > 0\n      ])\n      error_message = <<-EOT\n      Each global cloud_init map entry must include a 'content_type' field prefixed with 'text/'.\n      See https://cloudinit.readthedocs.io/en/latest/explanation/format.html#mime-multi-part-archive.\n      var.cloud_init (${each.key}): ${try(jsonencode(var.cloud_init), \"invalid\")}\n      EOT\n    }\n\n    precondition {\n      condition = alltrue([for c in each.value.cloud_init :\n        trimspace(lookup(c, \"content\", \"\")) != \"\"\n      ])\n      error_message = <<-EOT\n      Each pool-specific cloud_init map entry must include a non-empty 'content' field.\n      See https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/cloudinit_config.html.\n      ${each.key}[\"cloud_init\"]: ${try(jsonencode(each.value.cloud_init), \"invalid\")}\n      EOT\n    }\n\n    precondition {\n      condition = alltrue([for c in each.value.cloud_init :\n        length(regexall(\"^text/[a-z-]+$\", trimspace(lookup(c, \"content_type\", local.default_cloud_init_content_type)))) > 0\n      ])\n      error_message = <<-EOT\n      Each pool-specific cloud_init map entry must include a 'content_type' field prefixed with 'text/'.\n      See https://cloudinit.readthedocs.io/en/latest/explanation/format.html#mime-multi-part-archive.\n      ${each.key}[\"cloud_init\"]: ${try(jsonencode(each.value.cloud_init), \"invalid\")}\n      EOT\n    }\n\n    precondition {\n      condition = lookup(local.ubuntu_worker_pools, each.key, null) == null || (\n        lookup(local.ubuntu_worker_pools, each.key, null) != null &&\n        contains(keys(local.ubuntu_supported_versions), lookup(lookup(local.ubuntu_worker_pools, each.key, {}), \"ubuntu_release\", \"\"))\n      )\n      error_message = <<-EOT\n      Supported Ubuntu versions are \"22.04\" and \"24.04\".\n      See https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengcreatingubuntubasedworkernodes.htm#contengcreatingubuntubasedworkernodes_availabilitycompatibility.\n      ${each.key}: ${jsonencode(lookup(local.ubuntu_worker_pools, each.key, {}))}\n      EOT\n    }\n  }\n}\n"
  },
  {
    "path": "modules/workers/clusternetworks.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# Dynamic resource block for Cluster Network groups defined in worker_pools\nresource \"oci_core_cluster_network\" \"workers\" {\n  # Create an OCI Cluster Network resource for each enabled entry of the worker_pools map with that mode.\n  for_each       = local.enabled_cluster_networks\n  compartment_id = each.value.compartment_id\n  display_name   = each.key\n  defined_tags   = each.value.defined_tags\n  freeform_tags  = each.value.freeform_tags\n\n  instance_pools {\n    instance_configuration_id = oci_core_instance_configuration.workers[each.key].id\n    display_name              = each.key\n    size                      = each.value.size\n    defined_tags              = each.value.defined_tags\n    freeform_tags             = each.value.freeform_tags\n  }\n\n  placement_configuration {\n    availability_domain = element(each.value.availability_domains, 1)\n    primary_subnet_id   = each.value.subnet_id\n\n    dynamic \"secondary_vnic_subnets\" {\n      for_each = lookup(each.value, \"secondary_vnics\", {})\n      iterator = vnic\n      content {\n        display_name = vnic.key\n        subnet_id    = lookup(vnic.value, \"subnet_id\", each.value.subnet_id)\n      }\n    }\n  }\n\n  lifecycle {\n    ignore_changes = [\n      display_name, defined_tags, freeform_tags,\n      instance_pools[0].defined_tags,\n      instance_pools[0].freeform_tags,\n    ]\n\n    precondition {\n      condition     = coalesce(each.value.image_id, \"none\") != \"none\"\n      error_message = \"Missing image_id for pool ${each.key}. Check provided value for image_id if image_type is 'custom', or image_os/image_os_version if image_type is 'oke' or 'platform'.\"\n    }\n\n    precondition {\n      condition     = each.value.autoscale == false\n      error_message = \"Cluster Networks do not support cluster autoscaler management.\"\n    }\n  }\n\n  # First-boot hardware config for bare metal instances takes extra time\n  timeouts {\n    create = \"2h\"\n  }\n}\n"
  },
  {
    "path": "modules/workers/computecluster.tf",
    "content": "# Copyright (c) 2022, 2025 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# Create the shared compute clusters defined in workers_compute_clusters\n\nresource \"oci_core_compute_cluster\" \"shared\" {\n  # Create an OCI Compute Cluster resource for each enabled entry of the worker_pools map with that mode.\n  for_each       = var.compute_clusters\n  compartment_id = lookup(each.value, \"compartment_id\", var.compartment_id)\n  display_name   = each.key\n  defined_tags = merge(\n    var.defined_tags,\n    lookup(each.value, \"defined_tags\", {})\n  )\n  freeform_tags = merge(\n    var.freeform_tags,\n    lookup(each.value, \"freeform_tags\", {})\n  )\n\n  availability_domain = lookup(var.ad_numbers_to_names, lookup(each.value, \"placement_ad\", 1))\n\n  lifecycle {\n    ignore_changes = [\n      display_name, defined_tags, freeform_tags,\n    ]\n  }\n}\n\n# Dynamic resource block for Compute Cluster groups defined in worker_pools\nresource \"oci_core_compute_cluster\" \"workers\" {\n  # Create an OCI Compute Cluster resource for each enabled entry of the worker_pools map with that mode.\n  for_each            = { for k, v in local.enabled_compute_clusters : k => v if length(lookup(v, \"instance_ids\", [])) > 0 && lookup(v, \"compute_cluster\", null) == null }\n  compartment_id      = each.value.compartment_id\n  display_name        = each.key\n  defined_tags        = each.value.defined_tags\n  freeform_tags       = each.value.freeform_tags\n  availability_domain = lookup(each.value, \"placement_ad\", null) != null ? lookup(var.ad_numbers_to_names, lookup(each.value, \"placement_ad\")) : element(each.value.availability_domains, 0)\n\n  lifecycle {\n    ignore_changes = [\n      display_name, defined_tags, freeform_tags,\n    ]\n  }\n}\n\nresource \"oci_core_instance\" \"compute_cluster_workers\" {\n  for_each = local.compute_cluster_instance_map\n\n  availability_domain = (lookup(oci_core_compute_cluster.shared, lookup(each.value, \"compute_cluster\", \"\"), null) != null ?\n    oci_core_compute_cluster.shared[lookup(each.value, \"compute_cluster\", \"\")].availability_domain :\n    lookup(each.value, \"placement_ad\", null) != null ? lookup(var.ad_numbers_to_names, lookup(each.value, \"placement_ad\")) : element(each.value.availability_domains, 0)\n  )\n  fault_domain         = try(each.value.placement_fds[0], null)\n  compartment_id       = each.value.compartment_id\n  display_name         = format(\"%s-%s\", element(split(\"###\", each.key), 0), element(split(\"###\", each.key), 1))\n  preserve_boot_volume = false\n  shape                = each.value.shape\n\n  defined_tags            = each.value.defined_tags\n  freeform_tags           = each.value.freeform_tags\n  extended_metadata       = each.value.extended_metadata\n  capacity_reservation_id = each.value.capacity_reservation_id\n  compute_cluster_id = (lookup(oci_core_compute_cluster.shared, lookup(each.value, \"compute_cluster\", \"\"), null) != null ?\n    oci_core_compute_cluster.shared[lookup(each.value, \"compute_cluster\", \"\")].id :\n    (lookup(oci_core_compute_cluster.workers, element(split(\"###\", each.key), 0), null) != null ?\n      oci_core_compute_cluster.workers[element(split(\"###\", each.key), 0)].id :\n      lookup(each.value, \"compute_cluster\", \"\")\n    )\n  )\n\n  dynamic \"platform_config\" {\n    for_each = each.value.platform_config != null ? [1] : []\n    content {\n      type = lookup(\n        # Attempt lookup against data source for the associated 'type' of configured worker shape\n        lookup(local.platform_config_by_shape, each.value.shape, {}), \"type\",\n        # Fall back to 'type' on pool with custom platform_config, or INTEL_VM default\n        lookup(each.value.platform_config, \"type\", \"INTEL_VM\")\n      )\n      # Remaining parameters as configured, validated by instance/instance config resource\n      are_virtual_instructions_enabled               = lookup(each.value.platform_config, \"are_virtual_instructions_enabled\", null)\n      is_access_control_service_enabled              = lookup(each.value.platform_config, \"is_access_control_service_enabled\", null)\n      is_input_output_memory_management_unit_enabled = lookup(each.value.platform_config, \"is_input_output_memory_management_unit_enabled\", null)\n      is_measured_boot_enabled                       = lookup(each.value.platform_config, \"is_measured_boot_enabled\", null)\n      is_memory_encryption_enabled                   = lookup(each.value.platform_config, \"is_memory_encryption_enabled\", null)\n      is_secure_boot_enabled                         = lookup(each.value.platform_config, \"is_secure_boot_enabled\", null)\n      is_symmetric_multi_threading_enabled           = lookup(each.value.platform_config, \"is_symmetric_multi_threading_enabled\", null)\n      is_trusted_platform_module_enabled             = lookup(each.value.platform_config, \"is_trusted_platform_module_enabled\", null)\n      numa_nodes_per_socket                          = lookup(each.value.platform_config, \"numa_nodes_per_socket\", null)\n      percentage_of_cores_enabled                    = lookup(each.value.platform_config, \"percentage_of_cores_enabled\", null)\n    }\n  }\n\n  agent_config {\n    are_all_plugins_disabled = each.value.agent_config.are_all_plugins_disabled\n    is_management_disabled   = each.value.agent_config.is_management_disabled\n    is_monitoring_disabled   = each.value.agent_config.is_monitoring_disabled\n    dynamic \"plugins_config\" {\n      for_each = merge(\n        {\n          \"Compute HPC RDMA Authentication\" : \"ENABLED\",\n          \"Compute HPC RDMA Auto-Configuration\" : \"ENABLED\"\n        },\n        each.value.agent_config.plugins_config\n      )\n      content {\n        name          = plugins_config.key\n        desired_state = plugins_config.value\n      }\n    }\n  }\n\n  create_vnic_details {\n    assign_private_dns_record = var.assign_dns\n    assign_public_ip          = each.value.assign_public_ip\n    nsg_ids                   = each.value.nsg_ids\n    subnet_id                 = each.value.subnet_id\n    defined_tags              = each.value.defined_tags\n    freeform_tags             = each.value.freeform_tags\n  }\n\n  instance_options {\n    are_legacy_imds_endpoints_disabled = each.value.legacy_imds_endpoints_disabled\n  }\n\n  metadata = merge(\n    {\n      apiserver_host           = var.apiserver_private_host\n      cluster_ca_cert          = var.cluster_ca_cert\n      oke-k8version            = var.kubernetes_version\n      oke-kubeproxy-proxy-mode = var.kubeproxy_mode\n      oke-tenancy-id           = var.tenancy_id\n      oke-initial-node-labels  = join(\",\", [for k, v in each.value.node_labels : format(\"%v=%v\", k, v)])\n      secondary_vnics          = jsonencode(lookup(each.value, \"secondary_vnics\", {}))\n      ssh_authorized_keys      = var.ssh_public_key\n      user_data                = lookup(lookup(data.cloudinit_config.workers, element(split(\"###\", each.key), 0), {}), \"rendered\", \"\")\n    },\n\n    # Add labels required for NPN CNI.\n    var.cni_type == \"npn\" ? {\n      oke-native-pod-networking = true\n      oke-max-pods              = each.value.max_pods_per_node\n      pod-subnets               = each.value.pod_subnet_id\n      pod-nsgids                = join(\",\", each.value.pod_nsg_ids)\n    } : {},\n\n    # Only provide cluster DNS service address if set explicitly; determined automatically in practice.\n    coalesce(var.cluster_dns, \"none\") == \"none\" ? {} : { kubedns_svc_ip = var.cluster_dns },\n\n    # Extra user-defined fields merged last\n    var.node_metadata,                       # global\n    lookup(each.value, \"node_metadata\", {}), # pool-specific\n  )\n\n  source_details {\n    boot_volume_size_in_gbs = each.value.boot_volume_size\n    boot_volume_vpus_per_gb = each.value.boot_volume_vpus_per_gb\n    source_id               = each.value.image_id\n    source_type             = \"image\"\n  }\n\n  lifecycle {\n    precondition {\n      condition     = coalesce(each.value.image_id, \"none\") != \"none\"\n      error_message = <<-EOT\n      Missing image_id; check provided value if image_type is 'custom', or image_os/image_os_version if image_type is 'oke' or 'platform'.\n        pool: ${element(split(\"###\", each.key), 0)}\n        image_type: ${coalesce(each.value.image_type, \"none\")}\n        image_id: ${coalesce(each.value.image_id, \"none\")}\n      EOT\n    }\n\n    ignore_changes = [\n      agent_config, # TODO Not updateable; remove when supported\n      defined_tags, freeform_tags, display_name,\n      metadata[\"cluster_ca_cert\"], metadata[\"user_data\"],\n      create_vnic_details[0].defined_tags,\n      create_vnic_details[0].freeform_tags,\n    ]\n  }\n}\n"
  },
  {
    "path": "modules/workers/data-faultdomains.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\ndata \"oci_identity_fault_domains\" \"all\" {\n  for_each            = var.ad_numbers_to_names\n  availability_domain = each.value\n  compartment_id      = var.compartment_id\n}\n"
  },
  {
    "path": "modules/workers/data-shapes.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\ndata \"oci_core_shapes\" \"oke\" {\n  compartment_id = var.compartment_id\n}\n\nlocals {\n  shapes_by_name = {\n    # Group by shape name, yielding a list of objects for each\n    for shape in data.oci_core_shapes.oke.shapes :\n    lookup(shape, \"name\") => shape... if contains(keys(shape), \"name\")\n  }\n\n  platform_config_by_shape = {\n    # Merge objects for each shape; we only need the consistent 'type'\n    for k, v in local.shapes_by_name :\n    k => merge(lookup(merge(v...), \"platform_config_options\", [])...)\n  }\n}\n"
  },
  {
    "path": "modules/workers/gpumemorycluster.tf",
    "content": "# Copyright (c) 2026 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# One shared compute cluster per gpu-memory-cluster pool. All GMCs in a pool bind to this compute cluster.\n# compute_cluster_id is not updatable on the GMC, so any replacement here cascades into a destroy+create of every GMC bound to it.\nresource \"oci_core_compute_cluster\" \"gmc\" {\n  for_each            = local.enabled_gmc_pools\n  compartment_id      = each.value.compartment_id\n  display_name        = each.key\n  defined_tags        = each.value.defined_tags\n  freeform_tags       = each.value.freeform_tags\n  availability_domain = element(each.value.availability_domains, 1)\n\n  lifecycle {\n    ignore_changes = [\n      display_name, defined_tags, freeform_tags,\n    ]\n  }\n}\n\n# One GPU Memory Cluster per (pool, GMF). Keyed by \"<pool_name>###<gmf_id>\" so list edits don't shift other GMCs.\n# Size is omitted: when unset, the OCI control plane sizes the GMC from the fabric's available_host_count.\n# lifecycle.ignore_changes keeps ongoing size management with the OCI scaler via gpu_memory_cluster_scale_config.\nresource \"oci_core_compute_gpu_memory_cluster\" \"workers\" {\n  for_each = local.enabled_gmc_fabric_map\n\n  availability_domain       = element(each.value.availability_domains, 1)\n  compartment_id            = each.value.compartment_id\n  compute_cluster_id        = oci_core_compute_cluster.gmc[each.value.pool_name].id\n  instance_configuration_id = oci_core_instance_configuration.workers[each.value.pool_name].id\n  gpu_memory_fabric_id      = each.value.gpu_memory_fabric_id\n  display_name              = format(\"%s-%s\", each.value.pool_name, substr(each.value.gpu_memory_fabric_id, -11, 11))\n\n  defined_tags  = each.value.defined_tags\n  freeform_tags = each.value.freeform_tags\n\n  gpu_memory_cluster_scale_config {\n    is_upsize_enabled   = lookup(each.value.gpu_memory_cluster_scale_config, \"is_upsize_enabled\", var.gmc_scale_is_upsize_enabled)\n    is_downsize_enabled = lookup(each.value.gpu_memory_cluster_scale_config, \"is_downsize_enabled\", var.gmc_scale_is_downsize_enabled)\n    target_size         = lookup(each.value.gpu_memory_cluster_scale_config, \"target_size\", var.gmc_scale_target_size)\n  }\n\n  lifecycle {\n    precondition {\n      condition     = length(each.value.gpu_memory_fabric_ids) == length(toset(each.value.gpu_memory_fabric_ids))\n      error_message = \"Duplicate GMF OCIDs detected in pool ${each.value.pool_name}'s gpu_memory_fabric_ids list. Each GMF must appear at most once.\"\n    }\n\n    precondition {\n      condition     = each.value.autoscale == false\n      error_message = \"GPU Memory Clusters do not support cluster autoscaler management; the OCI control plane manages scaling via gpu_memory_cluster_scale_config.\"\n    }\n\n    ignore_changes = [\n      size,\n      gpu_memory_cluster_scale_config,\n      defined_tags, freeform_tags, display_name,\n    ]\n  }\n}\n"
  },
  {
    "path": "modules/workers/instance.tf",
    "content": "resource \"oci_core_instance\" \"workers\" {\n  for_each             = local.enabled_instances\n  availability_domain  = element(each.value.availability_domains, 1)\n  fault_domain         = try(each.value.placement_fds[0], null)\n  compartment_id       = each.value.compartment_id\n  display_name         = each.key\n  preserve_boot_volume = false\n  shape                = each.value.shape\n\n  defined_tags            = each.value.defined_tags\n  freeform_tags           = each.value.freeform_tags\n  extended_metadata       = each.value.extended_metadata\n  capacity_reservation_id = each.value.capacity_reservation_id\n\n  dynamic \"shape_config\" {\n    for_each = length(regexall(\"Flex\", each.value.shape)) > 0 ? [1] : []\n    content {\n      baseline_ocpu_utilization = lookup(each.value, \"burst\", \"BASELINE_1_1\")\n      ocpus                     = each.value.ocpus\n      memory_in_gbs = ( # If > 64GB memory/core, correct input to exactly 64GB memory/core\n        (each.value.memory / each.value.ocpus) > 64 ? each.value.ocpus * 64 : each.value.memory\n      )\n    }\n  }\n\n  dynamic \"platform_config\" {\n    for_each = each.value.platform_config != null ? [1] : []\n    content {\n      type = lookup(\n        # Attempt lookup against data source for the associated 'type' of configured worker shape\n        lookup(local.platform_config_by_shape, each.value.shape, {}), \"type\",\n        # Fall back to 'type' on pool with custom platform_config, or INTEL_VM default\n        lookup(each.value.platform_config, \"type\", \"INTEL_VM\")\n      )\n      # Remaining parameters as configured, validated by instance/instance config resource\n      are_virtual_instructions_enabled               = lookup(each.value.platform_config, \"are_virtual_instructions_enabled\", null)\n      is_access_control_service_enabled              = lookup(each.value.platform_config, \"is_access_control_service_enabled\", null)\n      is_input_output_memory_management_unit_enabled = lookup(each.value.platform_config, \"is_input_output_memory_management_unit_enabled\", null)\n      is_measured_boot_enabled                       = lookup(each.value.platform_config, \"is_measured_boot_enabled\", null)\n      is_memory_encryption_enabled                   = lookup(each.value.platform_config, \"is_memory_encryption_enabled\", null)\n      is_secure_boot_enabled                         = lookup(each.value.platform_config, \"is_secure_boot_enabled\", null)\n      is_symmetric_multi_threading_enabled           = lookup(each.value.platform_config, \"is_symmetric_multi_threading_enabled\", null)\n      is_trusted_platform_module_enabled             = lookup(each.value.platform_config, \"is_trusted_platform_module_enabled\", null)\n      numa_nodes_per_socket                          = lookup(each.value.platform_config, \"numa_nodes_per_socket\", null)\n      percentage_of_cores_enabled                    = lookup(each.value.platform_config, \"percentage_of_cores_enabled\", null)\n    }\n  }\n\n  agent_config {\n    are_all_plugins_disabled = each.value.agent_config.are_all_plugins_disabled\n    is_management_disabled   = each.value.agent_config.is_management_disabled\n    is_monitoring_disabled   = each.value.agent_config.is_monitoring_disabled\n    dynamic \"plugins_config\" {\n      for_each = each.value.agent_config.plugins_config\n      content {\n        name          = plugins_config.key\n        desired_state = plugins_config.value\n      }\n    }\n  }\n\n  create_vnic_details {\n    assign_private_dns_record = var.assign_dns\n    assign_ipv6ip             = each.value.assign_ipv6ip\n    assign_public_ip          = each.value.assign_public_ip\n    nsg_ids                   = each.value.nsg_ids\n    subnet_id                 = each.value.subnet_id\n    defined_tags              = each.value.defined_tags\n    freeform_tags             = each.value.freeform_tags\n  }\n\n  instance_options {\n    are_legacy_imds_endpoints_disabled = each.value.legacy_imds_endpoints_disabled\n  }\n\n  metadata = merge(\n    {\n      apiserver_host           = var.apiserver_private_host\n      cluster_ca_cert          = var.cluster_ca_cert\n      oke-k8version            = var.kubernetes_version\n      oke-kubeproxy-proxy-mode = var.kubeproxy_mode\n      oke-tenancy-id           = var.tenancy_id\n      oke-initial-node-labels  = join(\",\", [for k, v in each.value.node_labels : format(\"%v=%v\", k, v)])\n      secondary_vnics          = jsonencode(lookup(each.value, \"secondary_vnics\", {}))\n      ssh_authorized_keys      = var.ssh_public_key\n      user_data                = lookup(lookup(data.cloudinit_config.workers, lookup(each.value, \"key\", \"\"), {}), \"rendered\", \"\")\n    },\n\n    # Add labels required for NPN CNI.\n    var.cni_type == \"npn\" ? merge(\n      {\n        oke-native-pod-networking = true\n        oke-max-pods              = each.value.max_pods_per_node\n        pod-subnets               = each.value.pod_subnet_id\n        pod-nsgids                = join(\",\", each.value.pod_nsg_ids)\n      },\n      var.enable_ipv6 ? \n      { \n        ip-families               = \"IPv4,IPv6\" \n      }: {} ) : {},\n\n    # Only provide cluster DNS service address if set explicitly; determined automatically in practice.\n    coalesce(var.cluster_dns, \"none\") == \"none\" ? {} : { kubedns_svc_ip = var.cluster_dns },\n\n    # Extra user-defined fields merged last\n    var.node_metadata,                       # global\n    lookup(each.value, \"node_metadata\", {}), # pool-specific\n  )\n\n  source_details {\n    boot_volume_size_in_gbs = each.value.boot_volume_size\n    boot_volume_vpus_per_gb = each.value.boot_volume_vpus_per_gb\n    source_id               = each.value.image_id\n    source_type             = \"image\"\n  }\n\n  lifecycle {\n    precondition {\n      condition     = coalesce(each.value.image_id, \"none\") != \"none\"\n      error_message = <<-EOT\n      Missing image_id; check provided value if image_type is 'custom', or image_os/image_os_version if image_type is 'oke' or 'platform'.\n        pool: ${each.key}\n        image_type: ${coalesce(each.value.image_type, \"none\")}\n        image_id: ${coalesce(each.value.image_id, \"none\")}\n      EOT\n    }\n\n    ignore_changes = [\n      agent_config, # TODO Not updateable; remove when supported\n      defined_tags, freeform_tags, display_name,\n      metadata[\"cluster_ca_cert\"], metadata[\"user_data\"],\n      create_vnic_details[0].defined_tags,\n      create_vnic_details[0].freeform_tags,\n    ]\n  }\n}\n"
  },
  {
    "path": "modules/workers/instanceconfig.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nresource \"oci_core_instance_configuration\" \"workers\" {\n  # Create an OCI Instance Configuration resource for each enabled entry of the worker_pools map with a mode that uses one.\n  for_each       = local.enabled_instance_configs\n  compartment_id = each.value.compartment_id\n  display_name   = each.key\n  defined_tags   = each.value.defined_tags\n  freeform_tags  = each.value.freeform_tags\n\n  instance_details {\n    instance_type = \"compute\"\n\n    launch_details {\n      agent_config {\n        are_all_plugins_disabled = each.value.agent_config.are_all_plugins_disabled\n        is_management_disabled   = each.value.agent_config.is_management_disabled\n        is_monitoring_disabled   = each.value.agent_config.is_monitoring_disabled\n        dynamic \"plugins_config\" {\n          for_each = each.value.agent_config.plugins_config\n          content {\n            name          = plugins_config.key\n            desired_state = plugins_config.value\n          }\n        }\n      }\n\n      availability_domain = element(each.value.availability_domains, 1)\n\n      # First value specified on pool, or null to select automatically\n      fault_domain = try(each.value.placement_fds[0], null)\n\n      compartment_id          = each.value.compartment_id\n      defined_tags            = each.value.defined_tags\n      freeform_tags           = each.value.freeform_tags\n      extended_metadata       = each.value.extended_metadata\n      capacity_reservation_id = each.value.capacity_reservation_id\n\n      instance_options {\n        are_legacy_imds_endpoints_disabled = each.value.legacy_imds_endpoints_disabled\n      }\n\n      create_vnic_details {\n        assign_private_dns_record = var.assign_dns\n        assign_ipv6ip             = each.value.assign_ipv6ip\n        assign_public_ip          = each.value.assign_public_ip\n        nsg_ids                   = each.value.nsg_ids\n        subnet_id                 = each.value.subnet_id\n        defined_tags              = each.value.defined_tags\n        freeform_tags             = each.value.freeform_tags\n      }\n\n      metadata = merge(\n        {\n          apiserver_host           = var.apiserver_private_host\n          cluster_ca_cert          = var.cluster_ca_cert\n          oke-k8version            = var.kubernetes_version\n          oke-kubeproxy-proxy-mode = var.kubeproxy_mode\n          oke-tenancy-id           = var.tenancy_id\n          oke-initial-node-labels  = join(\",\", [for k, v in each.value.node_labels : format(\"%v=%v\", k, v)])\n          secondary_vnics          = jsonencode(lookup(each.value, \"secondary_vnics\", {}))\n          ssh_authorized_keys      = var.ssh_public_key\n          user_data                = lookup(lookup(data.cloudinit_config.workers, each.key, {}), \"rendered\", \"\")\n        },\n\n        # Add labels required for NPN CNI.\n        var.cni_type == \"npn\" ? merge(\n          {\n            oke-native-pod-networking = true\n            oke-max-pods              = each.value.max_pods_per_node\n            pod-subnets               = each.value.pod_subnet_id\n            pod-nsgids                = join(\",\", each.value.pod_nsg_ids)\n          },\n          var.enable_ipv6 ? \n          { \n            ip-families               = \"IPv4,IPv6\" \n          }: {} ) : {},\n\n        # Only provide cluster DNS service address if set explicitly; determined automatically in practice.\n        coalesce(var.cluster_dns, \"none\") == \"none\" ? {} : { kubedns_svc_ip = var.cluster_dns },\n\n        # Extra user-defined fields merged last\n        var.node_metadata,                       # global\n        lookup(each.value, \"node_metadata\", {}), # pool-specific\n      )\n\n      shape = each.value.shape\n\n      dynamic \"shape_config\" {\n        for_each = length(regexall(\"Flex\", each.value.shape)) > 0 ? [1] : []\n        content {\n          baseline_ocpu_utilization = lookup(each.value, \"burst\", \"BASELINE_1_1\")\n          ocpus                     = each.value.ocpus\n          memory_in_gbs = ( # If > 64GB memory/core, correct input to exactly 64GB memory/core\n            (each.value.memory / each.value.ocpus) > 64 ? each.value.ocpus * 64 : each.value.memory\n          )\n        }\n      }\n\n      dynamic \"platform_config\" {\n        for_each = each.value.platform_config != null ? [1] : []\n        content {\n          type = lookup(\n            # Attempt lookup against data source for the associated 'type' of configured worker shape\n            lookup(local.platform_config_by_shape, each.value.shape, {}), \"type\",\n            # Fall back to 'type' on pool with custom platform_config, or INTEL_VM default\n            lookup(each.value.platform_config, \"type\", \"INTEL_VM\")\n          )\n          # Remaining parameters as configured, validated by instance/instance config resource\n          are_virtual_instructions_enabled               = lookup(each.value.platform_config, \"are_virtual_instructions_enabled\", null)\n          is_access_control_service_enabled              = lookup(each.value.platform_config, \"is_access_control_service_enabled\", null)\n          is_input_output_memory_management_unit_enabled = lookup(each.value.platform_config, \"is_input_output_memory_management_unit_enabled\", null)\n          is_measured_boot_enabled                       = lookup(each.value.platform_config, \"is_measured_boot_enabled\", null)\n          is_memory_encryption_enabled                   = lookup(each.value.platform_config, \"is_memory_encryption_enabled\", null)\n          is_secure_boot_enabled                         = lookup(each.value.platform_config, \"is_secure_boot_enabled\", null)\n          is_symmetric_multi_threading_enabled           = lookup(each.value.platform_config, \"is_symmetric_multi_threading_enabled\", null)\n          is_trusted_platform_module_enabled             = lookup(each.value.platform_config, \"is_trusted_platform_module_enabled\", null)\n          numa_nodes_per_socket                          = lookup(each.value.platform_config, \"numa_nodes_per_socket\", null)\n          percentage_of_cores_enabled                    = lookup(each.value.platform_config, \"percentage_of_cores_enabled\", null)\n        }\n      }\n\n      source_details {\n        boot_volume_size_in_gbs = each.value.boot_volume_size\n        boot_volume_vpus_per_gb = each.value.boot_volume_vpus_per_gb\n        image_id                = each.value.image_id\n        source_type             = \"image\"\n      }\n\n      is_pv_encryption_in_transit_enabled = each.value.pv_transit_encryption\n    }\n\n    dynamic \"block_volumes\" {\n      for_each = (lookup(each.value, \"disable_block_volume\", false) != true) ? [1] : []\n      content {\n        attach_details {\n          type                                = each.value.block_volume_type\n          is_pv_encryption_in_transit_enabled = each.value.pv_transit_encryption\n        }\n\n        create_details {\n          // Limit to first candidate placement AD for cluster-network and gpu-memory-cluster; undefined for all otherwise\n          availability_domain = contains([\"cluster-network\", \"gpu-memory-cluster\"], each.value.mode) ? element(each.value.availability_domains, 1) : null\n          compartment_id      = each.value.compartment_id\n          display_name        = each.key\n          kms_key_id          = each.value.volume_kms_key_id\n          size_in_gbs         = max(50, lookup(each.value, \"block_volume_size_in_gbs\", 50))\n        }\n      }\n    }\n\n    dynamic \"secondary_vnics\" {\n      for_each = lookup(each.value, \"secondary_vnics\", {})\n      iterator = vnic\n\n      content {\n        display_name = vnic.key\n        nic_index    = lookup(vnic.value, \"nic_index\", null)\n\n        create_vnic_details {\n          assign_private_dns_record = lookup(vnic.value, \"assign_private_dns_record\", null)\n          assign_ipv6ip             = lookup(vnic.value, \"assign_ipv6ip\", null)\n          assign_public_ip          = lookup(vnic.value, \"assign_public_ip\", null)\n          display_name              = vnic.key\n          defined_tags              = lookup(vnic.value, \"defined_tags\", null)\n          freeform_tags             = lookup(vnic.value, \"freeform_tags\", null)\n          hostname_label            = lookup(vnic.value, \"hostname_label\", null)\n          nsg_ids                   = lookup(vnic.value, \"nsg_ids\", null)\n          private_ip                = lookup(vnic.value, \"private_ip\", null)\n          skip_source_dest_check    = lookup(vnic.value, \"skip_source_dest_check\", null)\n          subnet_id                 = lookup(vnic.value, \"subnet_id\", each.value.subnet_id)\n        }\n      }\n    }\n  }\n\n  lifecycle {\n    # TODO Instance Configuration replacement without delete when supported:\n    # https://github.com/hashicorp/terraform/issues/15485\n    create_before_destroy = true\n    ignore_changes = [\n      defined_tags, freeform_tags, display_name,\n      instance_details[0].launch_details[0].defined_tags,\n      instance_details[0].launch_details[0].freeform_tags,\n      instance_details[0].launch_details[0].create_vnic_details[0].defined_tags,\n      instance_details[0].launch_details[0].create_vnic_details[0].freeform_tags,\n      instance_details[0].secondary_vnics,\n    ]\n  }\n}\n"
  },
  {
    "path": "modules/workers/instancepools.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# Dynamic resource block for Instance Pool groups defined in worker_pools\nresource \"oci_core_instance_pool\" \"tfscaled_workers\" {\n  # Create an OCI Instance Pool resource for each enabled entry of the worker_pools map with that mode.\n  for_each                  = { for key, value in local.enabled_instance_pools : key => value if tobool(lookup(value, \"ignore_initial_pool_size\", false)) == false }\n  compartment_id            = each.value.compartment_id\n  display_name              = each.key\n  size                      = each.value.size\n  instance_configuration_id = oci_core_instance_configuration.workers[each.key].id\n  defined_tags              = each.value.defined_tags\n  freeform_tags             = each.value.freeform_tags\n\n  dynamic \"placement_configurations\" {\n    for_each = each.value.availability_domains\n    iterator = ad\n\n    content {\n      availability_domain = ad.value\n      primary_subnet_id   = each.value.subnet_id\n\n      # Value(s) specified on pool, or null to select automatically\n      fault_domains = try(each.value.placement_fds, null)\n\n      dynamic \"secondary_vnic_subnets\" {\n        for_each = lookup(each.value, \"secondary_vnics\", {})\n        iterator = vnic\n        content {\n          display_name = vnic.key\n          subnet_id    = lookup(vnic.value, \"subnet_id\", each.value.subnet_id)\n        }\n      }\n    }\n  }\n\n  lifecycle {\n    ignore_changes = [\n      display_name, defined_tags, freeform_tags,\n      placement_configurations,\n    ]\n\n    precondition {\n      condition     = coalesce(each.value.image_id, \"none\") != \"none\"\n      error_message = <<-EOT\n      Missing image_id; check provided value if image_type is 'custom', or image_os/image_os_version if image_type is 'oke' or 'platform'.\n        pool: ${each.key}\n        image_type: ${coalesce(each.value.image_type, \"none\")}\n        image_id: ${coalesce(each.value.image_id, \"none\")}\n      EOT\n    }\n\n    precondition {\n      condition     = each.value.autoscale == false\n      error_message = \"Instance Pools do not support cluster autoscaler management.\"\n    }\n  }\n}\n\nresource \"oci_core_instance_pool\" \"autoscaled_workers\" {\n  # Create an OCI Instance Pool resource for each enabled entry of the worker_pools map with that mode.\n  for_each                  = { for key, value in local.enabled_instance_pools : key => value if tobool(lookup(value, \"ignore_initial_pool_size\", false)) == true }\n  compartment_id            = each.value.compartment_id\n  display_name              = each.key\n  size                      = each.value.size\n  instance_configuration_id = oci_core_instance_configuration.workers[each.key].id\n  defined_tags              = each.value.defined_tags\n  freeform_tags             = each.value.freeform_tags\n\n  dynamic \"placement_configurations\" {\n    for_each = each.value.availability_domains\n    iterator = ad\n\n    content {\n      availability_domain = ad.value\n      primary_subnet_id   = each.value.subnet_id\n\n      # Value(s) specified on pool, or null to select automatically\n      fault_domains = try(each.value.placement_fds, null)\n\n      dynamic \"secondary_vnic_subnets\" {\n        for_each = lookup(each.value, \"secondary_vnics\", {})\n        iterator = vnic\n        content {\n          display_name = vnic.key\n          subnet_id    = lookup(vnic.value, \"subnet_id\", each.value.subnet_id)\n        }\n      }\n    }\n  }\n\n  lifecycle {\n    ignore_changes = [\n      display_name, defined_tags, freeform_tags,\n      placement_configurations, size\n    ]\n\n    precondition {\n      condition     = coalesce(each.value.image_id, \"none\") != \"none\"\n      error_message = <<-EOT\n      Missing image_id; check provided value if image_type is 'custom', or image_os/image_os_version if image_type is 'oke' or 'platform'.\n        pool: ${each.key}\n        image_type: ${coalesce(each.value.image_type, \"none\")}\n        image_id: ${coalesce(each.value.image_id, \"none\")}\n      EOT\n    }\n\n    precondition {\n      condition     = each.value.autoscale == false\n      error_message = \"Instance Pools do not support cluster autoscaler management.\"\n    }\n  }\n}\n"
  },
  {
    "path": "modules/workers/locals.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  boot_volume_size        = lookup(var.shape, \"boot_volume_size\", 50)\n  boot_volume_vpus_per_gb = lookup(var.shape, \"boot_volume_vpus_per_gb\", 10)\n  memory                  = lookup(var.shape, \"memory\", 4)\n  ocpus                   = max(1, lookup(var.shape, \"ocpus\", 1))\n  shape                   = lookup(var.shape, \"shape\", \"VM.Standard.E4.Flex\")\n\n  # Used for default values of required input for virtual node pools\n  fault_domains_all = formatlist(\"FD-%v\", [1, 2, 3])\n  fault_domains_available = {\n    for ad, fd in data.oci_identity_fault_domains.all : ad => fd\n  }\n\n  worker_pool_defaults = {\n    agent_config = {\n      are_all_plugins_disabled = false\n      is_management_disabled   = false\n      is_monitoring_disabled   = false\n      plugins_config           = {}\n    }\n    allow_autoscaler               = false\n    legacy_imds_endpoints_disabled = var.legacy_imds_endpoints_disabled\n    assign_public_ip               = var.assign_public_ip\n    assign_ipv6ip                  = var.enable_ipv6 ? true : false\n    autoscale                      = false\n    block_volume_type              = var.block_volume_type\n    boot_volume_size               = local.boot_volume_size\n    boot_volume_vpus_per_gb        = local.boot_volume_vpus_per_gb\n    capacity_reservation_id        = var.capacity_reservation_id\n    cloud_init                     = [] # empty pool-specific default\n    compartment_id                 = var.compartment_id\n    create                         = true\n    disable_default_cloud_init     = var.disable_default_cloud_init\n    drain                          = false\n    eviction_grace_duration        = 300\n    force_node_action              = true\n    force_node_delete              = true\n    extended_metadata              = {} # empty pool-specific default\n    gpu_memory_cluster_scale_config = {\n      is_upsize_enabled   = var.gmc_scale_is_upsize_enabled\n      is_downsize_enabled = var.gmc_scale_is_downsize_enabled\n      target_size         = var.gmc_scale_target_size\n    }\n    gpu_memory_fabric_ids          = [] # empty pool-specific default; required for mode = \"gpu-memory-cluster\"\n    ignore_initial_pool_size       = false\n    image_id                       = var.image_id\n    image_type                     = var.image_type\n    kubernetes_version             = var.kubernetes_version\n    max_pods_per_node              = min(max(var.max_pods_per_node, 1), 110)\n    memory                         = local.memory\n    mode                           = var.worker_pool_mode\n    node_cycling_enabled           = false\n    node_cycling_max_surge         = 1\n    node_cycling_max_unavailable   = 0\n    node_cycling_mode              = [\"instance\"]\n    node_labels                    = var.node_labels\n    nsg_ids                        = [] # empty pool-specific default\n    ocpus                          = local.ocpus\n    os                             = var.image_os\n    os_version                     = var.image_os_version\n    placement_ads                  = var.ad_numbers\n    platform_config                = var.platform_config\n    pod_nsg_ids                    = var.pod_nsg_ids\n    pod_subnet_id                  = coalesce(var.pod_subnet_id, var.worker_subnet_id, \"none\")\n    preemptible_config             = var.preemptible_config\n    pv_transit_encryption          = var.pv_transit_encryption\n    shape                          = local.shape\n    size                           = var.worker_pool_size\n    subnet_id                      = var.worker_subnet_id\n    taints                         = [] # empty pool-specific default\n    volume_kms_key_id              = var.volume_kms_key_id\n  }\n\n  # Merge desired pool configuration onto default values\n  worker_pools_with_defaults = { for pool_name, pool in var.worker_pools :\n    pool_name => merge(local.worker_pool_defaults, pool)\n  }\n\n  # Filter worker_pools map for enabled entries and add derived configuration\n  enabled_worker_pools = { for pool_name, pool in local.worker_pools_with_defaults :\n    pool_name => merge(pool, {\n      preemptible_config = lookup(pool, \"preemptible_config\", pool.preemptible_config)\n      # Bare metal instances must use iSCSI block volume attachments, not paravirtualized\n      block_volume_type = length(regexall(\"^BM\", pool.shape)) > 0 ? \"iscsi\" : var.block_volume_type\n      pv_transit_encryption = alltrue([\n        var.pv_transit_encryption,\n        pool.block_volume_type == \"paravirtualized\",\n        length(regexall(\"^VM\", pool.shape)) > 0\n      ])\n\n      # Combine global and pool-specific cloud init parts\n      cloud_init = [for part in concat(var.cloud_init, pool.cloud_init) :\n        {\n          # Load content from file if local path, attempt base64 decode, or use raw value\n          content = contains(keys(part), \"content\") ? (\n            try(fileexists(lookup(part, \"content\")), false) ? file(lookup(part, \"content\"))\n            : try(base64decode(lookup(part, \"content\")), lookup(part, \"content\"))\n          ) : \"\"\n          content_type = lookup(part, \"content_type\", local.default_cloud_init_content_type)\n          filename     = lookup(part, \"filename\", null)\n          merge_type   = lookup(part, \"merge_type\", local.default_cloud_init_merge_type)\n        }\n      ]\n\n      agent_config = coalesce(var.agent_config, pool.agent_config, local.worker_pool_defaults.agent_config)\n\n      # Translate configured + available AD numbers e.g. 2 into tenancy/compartment-specific names\n      availability_domains = compact([for ad_number in tolist(setintersection(pool.placement_ads, var.ad_numbers)) :\n        lookup(var.ad_numbers_to_names, ad_number, null)\n      ])\n\n      # Use provided image_id for 'custom' type, or first match for all shape + OS criteria\n      image_id = (\n        pool.image_type == \"custom\" ?\n        pool.image_id :\n        element(split(\"###\", element(reverse(sort([for entry in tolist(setintersection([\n          pool.image_type == \"oke\" ?\n          setintersection(\n            lookup(var.image_ids, \"oke\", null),\n            lookup(var.image_ids, trimprefix(lower(pool.kubernetes_version), \"v\"), null)\n          ) :\n          lookup(var.image_ids, \"platform\", null),\n          lookup(var.image_ids, pool.image_type, null),\n          length(regexall(\"GPU\", pool.shape)) > 0 ? var.image_ids.gpu : var.image_ids.nongpu,\n          length(regexall(\"A[12]\\\\.\", pool.shape)) > 0 ? var.image_ids.aarch64 : var.image_ids.x86_64,\n          lookup(var.image_ids, format(\"%v %v\", pool.os, split(\".\", pool.os_version)[0]), null),\n        ]...)) : \"${var.indexed_images[entry].sort_key}###${entry}\"])), 0)), 1)\n      )\n\n      # Standard tags as defined if enabled for use\n      # User-provided freeform tags are merged and take precedence\n      defined_tags = merge(\n        var.use_defined_tags ? merge(\n          {\n            \"${var.tag_namespace}.state_id\"           = var.state_id,\n            \"${var.tag_namespace}.role\"               = \"worker\",\n            \"${var.tag_namespace}.pool\"               = pool_name,\n            \"${var.tag_namespace}.cluster_autoscaler\" = pool.allow_autoscaler ? \"allowed\" : \"disabled\",\n          },\n          pool.autoscale ? { \"${var.tag_namespace}.cluster_autoscaler\" = \"managed\" } : {},\n        ) : {},\n        var.defined_tags,\n        lookup(pool, \"defined_tags\", {})\n      )\n\n      # Standard tags as freeform if defined tags are disabled\n      # User-provided freeform tags are merged and take precedence\n      freeform_tags = merge(\n        var.use_defined_tags ? {} : merge(\n          {\n            \"state_id\"           = var.state_id,\n            \"role\"               = \"worker\",\n            \"pool\"               = pool_name,\n            \"cluster_autoscaler\" = pool.allow_autoscaler ? \"allowed\" : \"disabled\",\n          },\n          pool.autoscale ? { \"cluster_autoscaler\" = \"managed\" } : {},\n        ),\n        var.freeform_tags,\n        lookup(pool, \"freeform_tags\", {})\n      )\n\n      # Combine global and pool-specific NSGs\n      nsg_ids      = compact(concat(var.worker_nsg_ids, pool.nsg_ids))\n      pods_nsg_ids = compact(concat(var.pod_nsg_ids, pool.pod_nsg_ids))\n\n      # Add a node label for cluster autoscaler where scheduling is supported\n      node_labels = merge(\n        {\n          \"oke.oraclecloud.com/tf.module\"          = \"terraform-oci-oke\"\n          \"oke.oraclecloud.com/tf.state_id\"        = var.state_id\n          \"oke.oraclecloud.com/pool.name\"          = pool_name\n          \"oke.oraclecloud.com/pool.mode\"          = pool.mode\n          \"oke.oraclecloud.com/cluster_autoscaler\" = pool.allow_autoscaler ? \"allowed\" : \"disabled\"\n          \"oci.oraclecloud.com/vcn-native-ip-cni\"  = var.cni_type == \"npn\" ? true : false\n        },\n        pool.autoscale ? { \"oke.oraclecloud.com/cluster_autoscaler\" = \"managed\" } : {},\n        pool.node_labels,\n      )\n\n      # Override Node-cycling mode\n      node_cycling_mode = pool.node_cycling_mode != null ? [for entry in pool.node_cycling_mode : lookup(local.supported_node_cycling_mode, lower(entry))] : null\n\n    }) if tobool(pool.create)\n  }\n\n  supported_node_cycling_mode = {\n    instance    = \"INSTANCE_REPLACE\"\n    boot_volume = \"BOOT_VOLUME_REPLACE\"\n  }\n\n  enabled_modes = distinct([for w in values(local.enabled_worker_pools) : w.mode])\n\n  # Number of nodes expected from enabled worker pools\n  expected_node_count = length(local.enabled_worker_pools) == 0 ? 0 : sum([\n    for k, v in local.enabled_worker_pools : lookup(v, \"size\", var.worker_pool_size)\n  ])\n\n  # Number of nodes expected to be draining in worker pools\n  expected_drain_count = length(local.enabled_worker_pools) == 0 ? 0 : sum([\n    for k, v in local.enabled_worker_pools : tobool(v.drain) ? lookup(v, \"size\", var.worker_pool_size) : 0\n  ])\n\n  # Number of work pools in the worker pools with autoscale enabled\n  expected_autoscale_worker_pools = length(local.enabled_worker_pools) == 0 ? 0 : sum([\n    for k, v in local.enabled_worker_pools : tobool(v.autoscale) ? 1 : 0\n  ])\n\n  # Enabled worker_pool map entries for node pools\n  enabled_node_pools = {\n    for k, v in local.enabled_worker_pools : k => v\n    if lookup(v, \"mode\", \"\") == \"node-pool\"\n  }\n\n  # Enabled worker_pool map entries for virtual node pools\n  enabled_virtual_node_pools = {\n    for k, v in local.enabled_worker_pools : k => v\n    if lookup(v, \"mode\", \"\") == \"virtual-node-pool\"\n  }\n\n  # Enabled worker_pool map entries for instance pools\n  enabled_instance_configs = {\n    for k, v in local.enabled_worker_pools : k => v\n    if contains([\"cluster-network\", \"instance-pool\", \"gpu-memory-cluster\"], lookup(v, \"mode\", \"\"))\n  }\n\n  # Enabled worker_pool map entries for instance pools\n  enabled_instance_pools = {\n    for k, v in local.enabled_worker_pools : k => v if lookup(v, \"mode\", \"\") == \"instance-pool\"\n  }\n\n  # Enabled worker_pool map entries for individual instances\n  enabled_instances = { for e in concat([], [\n    for k, v in local.enabled_worker_pools : [\n      for i in range(0, lookup(v, \"size\", 0)) : merge(v, { \"key\" = k, \"index\" = i })\n    ] if lookup(v, \"mode\", \"\") == \"instance\"\n  ]...) : format(\"%v-%v\", lookup(e, \"key\"), lookup(e, \"index\")) => e }\n\n  # Enabled worker_pool map entries for cluster networks\n  enabled_cluster_networks = {\n    for k, v in local.enabled_worker_pools : k => v if lookup(v, \"mode\", \"\") == \"cluster-network\"\n  }\n\n  # Enabled worker_pool map entries for compute clusters\n  enabled_compute_clusters = {\n    for k, v in local.enabled_worker_pools : k => v if lookup(v, \"mode\", \"\") == \"compute-cluster\"\n  }\n\n  # Enabled worker_pool map entries for GPU memory clusters\n  enabled_gmc_pools = {\n    for k, v in local.enabled_worker_pools : k => v if lookup(v, \"mode\", \"\") == \"gpu-memory-cluster\"\n  }\n\n  # Map keyed by \"<pool_name>###<gmf_id>\" of merged pool config + pool_name + gpu_memory_fabric_id, used to drive the GMC resource for_each.\n  # Keying off OCID (not list index) keeps adds/removes stable.\n  enabled_gmc_fabric_map = { for entry in flatten([\n    for k, v in local.enabled_gmc_pools : [\n      for gmf_id in lookup(v, \"gpu_memory_fabric_ids\", []) : merge(v, {\n        pool_name            = k\n        gpu_memory_fabric_id = gmf_id\n      })\n    ]\n  ]) : format(\"%s###%s\", entry.pool_name, entry.gpu_memory_fabric_id) => entry }\n\n  # Prepare a map workers node enabled for compute_clusters { \"pool_id###worker_id\" => pool_values }\n  compute_cluster_instance_ids_map = { for k, v in local.enabled_compute_clusters : k => toset(lookup(v, \"instance_ids\", [])) }\n  compute_cluster_instance_ids     = toset(concat(flatten([for k, v in local.compute_cluster_instance_ids_map : [for id in v : format(\"%s###%s\", k, id)]])))\n  compute_cluster_instance_map     = { for id in local.compute_cluster_instance_ids : id => lookup(local.enabled_compute_clusters, element(split(\"###\", id), 0), {}) }\n\n  # Sanitized worker_pools output; some conditionally-used defaults would be misleading\n  worker_pools_final = {\n    for pool_name, pool in local.enabled_worker_pools : pool_name => { for a, b in pool : a => b\n      if a != \"create\"                                                                    # implied\n      && b != null && try(length(b), -1) != 0 && try(!!tobool(b), true)                   # exclude empty/disabled values\n      && !(contains([\"os\", \"os_version\"], a) && pool.image_type == \"custom\")              # unused defaults for custom\n      && !(contains([\"pod_nsg_ids\", \"pod_subnet_id\"], a) && var.cni_type != \"npn\")        # unused defaults for NPN\n      && !(contains([\"ocpus\", \"memory\"], a) && length(regexall(\"Flex\", pool.shape)) == 0) # unused defaults for non-Flex shapes\n    }\n  }\n\n  # Maps of worker pool OCI resources by pool name enriched with desired/custom parameters for various modes\n  worker_node_pools         = { for k, v in merge(oci_containerengine_node_pool.tfscaled_workers, oci_containerengine_node_pool.autoscaled_workers) : k => merge(lookup(local.worker_pools_final, k, {}), v) }\n  worker_virtual_node_pools = { for k, v in oci_containerengine_virtual_node_pool.workers : k => merge(lookup(local.worker_pools_final, k, {}), v) }\n  worker_instance_pools     = { for k, v in merge(oci_core_instance_pool.tfscaled_workers, oci_core_instance_pool.autoscaled_workers) : k => merge(lookup(local.worker_pools_final, k, {}), v) }\n  worker_cluster_networks   = { for k, v in oci_core_cluster_network.workers : k => merge(lookup(local.worker_pools_final, k, {}), v) }\n  worker_instances          = { for k, v in oci_core_instance.workers : k => merge(lookup(local.worker_pools_final, k, {}), v) }\n\n  # Combined map of outputs by pool name for all modes excluding 'instance' (output separately)\n  worker_pools_output = merge(\n    local.worker_node_pools,\n    local.worker_virtual_node_pools,\n    local.worker_instance_pools,\n    local.worker_cluster_networks,\n  )\n\n  # OCIDs of pool resources by pool name for modes: 'node-pool', 'virtual-node-pool', 'instance-pool', 'cluster-network'\n  worker_pool_ids = { for k, v in local.worker_pools_output : k => v.id }\n\n  # Map of pool name to list of instance IP addresses for modes: 'instance'\n  worker_instance_ips = {\n    for x, y in {\n      for k, v in local.worker_instances : replace(k, \"/-[^-]*$/\", \"\") => # remove index suffix\n      { lookup(v, \"id\", \"\") = lookup(v, \"private_ip\", null) }...          # instances grouped by \"pool\"\n    } : x => merge(y...)\n  }\n\n  # Map of pool name to list of instance IP addresses for modes: 'node-pool'\n  worker_nodepool_ips = {\n    for k, v in local.worker_node_pools : k => {\n      for n in lookup(v, \"nodes\", []) : lookup(n, \"id\", \"\") => lookup(n, \"private_ip\", null)\n    }\n  }\n\n  # Yields {<pool name> = {<instance id> = <instance ip>}} for modes: 'node-pool', 'instance'\n  worker_pool_ips = merge(local.worker_instance_ips, local.worker_nodepool_ips)\n\n  # Map of nodepools using Ubuntu images.\n\n  ubuntu_supported_versions = {\n    \"22.04\"                 = \"jammy\"\n    \"24.04\"                 = \"noble\"\n    \"22.04 Minimal\"         = \"jammy\"\n    \"22.04 Minimal aarch64\" = \"jammy\"\n    \"24.04 Minimal\"         = \"noble\"\n    \"24.04 Minimal aarch64\" = \"noble\"\n  }\n\n  ubuntu_worker_pools = {\n    for k, v in local.enabled_worker_pools : k => {\n      kubernetes_major_version = substr(lookup(v, \"kubernetes_version\", \"\"), 1, 4)\n      kubernetes_minor_version = substr(lookup(v, \"kubernetes_version\", \"\"), 1, -1)\n      ubuntu_release           = lookup(lookup(data.oci_core_image.workers, k, {}), \"operating_system_version\", null) != null ? lookup(lookup(data.oci_core_image.workers, k, {}), \"operating_system_version\") : lookup(v, \"os_version\", null)\n    }\n    if lookup(v, \"mode\", var.worker_pool_mode) != \"virtual-node-pool\" &&\n    contains(coalescelist(split(\" \", lookup(lookup(data.oci_core_image.workers, k, {}), \"operating_system\", \"\")), [lookup(v, \"os\", \"\")]), \"Ubuntu\")\n  }\n}\n"
  },
  {
    "path": "modules/workers/nodepools.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# Dynamic resource block for Node Pool groups defined in worker_pools\nresource \"oci_containerengine_node_pool\" \"tfscaled_workers\" {\n  # Create an OKE node pool resource for each enabled entry of the worker_pools map with that mode.\n  for_each           = { for key, value in local.enabled_node_pools : key => value if tobool(lookup(value, \"ignore_initial_pool_size\", false)) == false }\n  cluster_id         = var.cluster_id\n  compartment_id     = each.value.compartment_id\n  defined_tags       = each.value.defined_tags\n  freeform_tags      = each.value.freeform_tags\n  kubernetes_version = each.value.kubernetes_version\n  name               = each.key\n  node_shape         = each.value.shape\n  ssh_public_key     = var.ssh_public_key\n\n  node_config_details {\n    size                                = each.value.size\n    is_pv_encryption_in_transit_enabled = each.value.pv_transit_encryption\n    kms_key_id                          = each.value.volume_kms_key_id\n    nsg_ids                             = each.value.nsg_ids\n    defined_tags                        = each.value.defined_tags\n    freeform_tags                       = each.value.freeform_tags\n\n    dynamic \"placement_configs\" {\n      for_each = each.value.availability_domains\n      iterator = ad\n\n      content {\n        availability_domain     = ad.value\n        capacity_reservation_id = each.value.capacity_reservation_id\n        subnet_id               = each.value.subnet_id\n\n        # Value(s) specified on pool, or null to select automatically\n        fault_domains = try(each.value.placement_fds, null)\n\n        dynamic \"preemptible_node_config\" {\n          for_each = each.value.preemptible_config.enable ? [1] : []\n          content {\n            preemption_action {\n              type                    = \"TERMINATE\"\n              is_preserve_boot_volume = each.value.preemptible_config.is_preserve_boot_volume\n            }\n          }\n        }\n      }\n    }\n\n    dynamic \"node_pool_pod_network_option_details\" {\n      for_each = var.cni_type == \"flannel\" ? [1] : []\n      content { # Flannel requires cni type only\n        cni_type = \"FLANNEL_OVERLAY\"\n      }\n    }\n\n    dynamic \"node_pool_pod_network_option_details\" {\n      for_each = var.cni_type == \"npn\" ? [1] : []\n      content { # VCN-Native requires max pods/node, nsg ids, subnet ids\n        cni_type          = \"OCI_VCN_IP_NATIVE\"\n        max_pods_per_node = each.value.max_pods_per_node\n        pod_nsg_ids       = compact(tolist(each.value.pod_nsg_ids))\n        pod_subnet_ids    = compact(tolist([each.value.pod_subnet_id]))\n      }\n    }\n  }\n\n  node_metadata = merge(\n    {\n      apiserver_host           = var.apiserver_private_host\n      oke-kubeproxy-proxy-mode = var.kubeproxy_mode\n      user_data                = lookup(lookup(data.cloudinit_config.workers, each.key, {}), \"rendered\", \"\")\n    },\n\n    # Only provide cluster DNS service address if set explicitly; determined automatically in practice.\n    coalesce(var.cluster_dns, \"none\") == \"none\" ? {} : { kubedns_svc_ip = var.cluster_dns },\n\n    # Extra user-defined fields merged last\n    var.node_metadata,                       # global\n    lookup(each.value, \"node_metadata\", {}), # pool-specific\n  )\n\n  node_eviction_node_pool_settings {\n    eviction_grace_duration = (floor(tonumber(each.value.eviction_grace_duration) / 60) > 0 ?\n      (each.value.eviction_grace_duration > 3600 ?\n        format(\"PT%dM\", 60) :\n        (each.value.eviction_grace_duration % 60 == 0 ?\n          format(\"PT%dM\", floor(each.value.eviction_grace_duration / 60)) :\n          format(\"PT%dM%dS\", floor(each.value.eviction_grace_duration / 60), each.value.eviction_grace_duration % 60)\n        )\n      ) :\n      format(\"PT%dS\", each.value.eviction_grace_duration)\n    )\n    is_force_delete_after_grace_duration = tobool(each.value.force_node_delete)\n    is_force_action_after_grace_duration = tobool(each.value.force_node_action)\n  }\n\n  dynamic \"node_shape_config\" {\n    for_each = length(regexall(\"Flex\", each.value.shape)) > 0 ? [1] : []\n    content {\n      ocpus = each.value.ocpus\n      memory_in_gbs = ( # If > 64GB memory/core, correct input to exactly 64GB memory/core\n        (each.value.memory / each.value.ocpus) > 64 ? each.value.ocpus * 64 : each.value.memory\n      )\n    }\n  }\n\n  node_pool_cycling_details {\n    is_node_cycling_enabled = each.value.node_cycling_enabled\n    maximum_surge           = each.value.node_cycling_max_surge\n    maximum_unavailable     = each.value.node_cycling_max_unavailable\n    cycle_modes             = each.value.node_cycling_mode\n  }\n\n  node_source_details {\n    boot_volume_size_in_gbs = each.value.boot_volume_size\n    image_id                = each.value.image_id\n    source_type             = \"image\"\n  }\n\n  lifecycle { # prevent resources changes for changed fields\n    ignore_changes = [\n      # kubernetes_version, # e.g. if changed as part of an upgrade\n      name, defined_tags, freeform_tags,\n      node_config_details[0].placement_configs, # dynamic placement configs\n      # node_source_details[0],                   # dynamic image lookup\n    ]\n\n    precondition {\n      condition     = coalesce(each.value.image_id, \"none\") != \"none\"\n      error_message = <<-EOT\n      Missing image_id; check provided value if image_type is 'custom', or image_os/image_os_version if image_type is 'oke' or 'platform'.\n        pool: ${each.key}\n        image_type: ${coalesce(each.value.image_type, \"none\")}\n        image_id: ${coalesce(each.value.image_id, \"none\")}\n      EOT\n    }\n\n    precondition {\n      condition = anytrue([\n        contains([\"instance-pool\", \"cluster-network\"], each.value.mode), # supported modes\n        length(lookup(each.value, \"secondary_vnics\", {})) == 0,          # unrestricted when empty/unset\n      ])\n      error_message = \"Unsupported option for mode=${each.value.mode}: secondary_vnics\"\n    }\n\n    precondition {\n      condition     = coalesce(each.value.capacity_reservation_id, \"none\") == \"none\" || length(each.value.availability_domains) == 1\n      error_message = \"A single availability domain must be specified when using a capacity reservation with mode=${each.value.mode}\"\n    }\n  }\n\n  dynamic \"initial_node_labels\" {\n    for_each = each.value.node_labels\n    content {\n      key   = initial_node_labels.key\n      value = initial_node_labels.value\n    }\n  }\n}\n\nresource \"oci_containerengine_node_pool\" \"autoscaled_workers\" {\n  # Create an OKE node pool resource for each enabled entry of the worker_pools map with that mode.\n  for_each           = { for key, value in local.enabled_node_pools : key => value if tobool(lookup(value, \"ignore_initial_pool_size\", false)) == true }\n  cluster_id         = var.cluster_id\n  compartment_id     = each.value.compartment_id\n  defined_tags       = each.value.defined_tags\n  freeform_tags      = each.value.freeform_tags\n  kubernetes_version = each.value.kubernetes_version\n  name               = each.key\n  node_shape         = each.value.shape\n  ssh_public_key     = var.ssh_public_key\n\n  node_config_details {\n    size                                = each.value.size\n    is_pv_encryption_in_transit_enabled = each.value.pv_transit_encryption\n    kms_key_id                          = each.value.volume_kms_key_id\n    nsg_ids                             = each.value.nsg_ids\n    defined_tags                        = each.value.defined_tags\n    freeform_tags                       = each.value.freeform_tags\n\n    dynamic \"placement_configs\" {\n      for_each = each.value.availability_domains\n      iterator = ad\n\n      content {\n        availability_domain     = ad.value\n        capacity_reservation_id = each.value.capacity_reservation_id\n        subnet_id               = each.value.subnet_id\n\n        # Value(s) specified on pool, or null to select automatically\n        fault_domains = try(each.value.placement_fds, null)\n\n        dynamic \"preemptible_node_config\" {\n          for_each = each.value.preemptible_config.enable ? [1] : []\n          content {\n            preemption_action {\n              type                    = \"TERMINATE\"\n              is_preserve_boot_volume = each.value.preemptible_config.is_preserve_boot_volume\n            }\n          }\n        }\n      }\n    }\n\n    dynamic \"node_pool_pod_network_option_details\" {\n      for_each = var.cni_type == \"flannel\" ? [1] : []\n      content { # Flannel requires cni type only\n        cni_type = \"FLANNEL_OVERLAY\"\n      }\n    }\n\n    dynamic \"node_pool_pod_network_option_details\" {\n      for_each = var.cni_type == \"npn\" ? [1] : []\n      content { # VCN-Native requires max pods/node, nsg ids, subnet ids\n        cni_type          = \"OCI_VCN_IP_NATIVE\"\n        max_pods_per_node = each.value.max_pods_per_node\n        pod_nsg_ids       = compact(tolist(each.value.pod_nsg_ids))\n        pod_subnet_ids    = compact(tolist([each.value.pod_subnet_id]))\n      }\n    }\n  }\n\n  node_metadata = merge(\n    {\n      apiserver_host           = var.apiserver_private_host\n      oke-kubeproxy-proxy-mode = var.kubeproxy_mode\n      user_data                = lookup(lookup(data.cloudinit_config.workers, each.key, {}), \"rendered\", \"\")\n    },\n\n    # Only provide cluster DNS service address if set explicitly; determined automatically in practice.\n    coalesce(var.cluster_dns, \"none\") == \"none\" ? {} : { kubedns_svc_ip = var.cluster_dns },\n\n    # Extra user-defined fields merged last\n    var.node_metadata,                       # global\n    lookup(each.value, \"node_metadata\", {}), # pool-specific\n  )\n\n  node_eviction_node_pool_settings {\n    eviction_grace_duration = (floor(tonumber(each.value.eviction_grace_duration) / 60) > 0 ?\n      (each.value.eviction_grace_duration > 3600 ?\n        format(\"PT%dM\", 60) :\n        (each.value.eviction_grace_duration % 60 == 0 ?\n          format(\"PT%dM\", floor(each.value.eviction_grace_duration / 60)) :\n          format(\"PT%dM%dS\", floor(each.value.eviction_grace_duration / 60), each.value.eviction_grace_duration % 60)\n        )\n      ) :\n      format(\"PT%dS\", each.value.eviction_grace_duration)\n    )\n    is_force_delete_after_grace_duration = tobool(each.value.force_node_delete)\n    is_force_action_after_grace_duration = tobool(each.value.force_node_action)\n  }\n\n  dynamic \"node_shape_config\" {\n    for_each = length(regexall(\"Flex\", each.value.shape)) > 0 ? [1] : []\n    content {\n      ocpus = each.value.ocpus\n      memory_in_gbs = ( # If > 64GB memory/core, correct input to exactly 64GB memory/core\n        (each.value.memory / each.value.ocpus) > 64 ? each.value.ocpus * 64 : each.value.memory\n      )\n    }\n  }\n\n  node_pool_cycling_details {\n    is_node_cycling_enabled = each.value.node_cycling_enabled\n    maximum_surge           = each.value.node_cycling_max_surge\n    maximum_unavailable     = each.value.node_cycling_max_unavailable\n    cycle_modes             = each.value.node_cycling_mode\n  }\n\n  node_source_details {\n    boot_volume_size_in_gbs = each.value.boot_volume_size\n    image_id                = each.value.image_id\n    source_type             = \"image\"\n  }\n\n  lifecycle { # prevent resources changes for changed fields\n    ignore_changes = [\n      # kubernetes_version, # e.g. if changed as part of an upgrade\n      name, defined_tags, freeform_tags,\n      node_config_details[0].placement_configs, # dynamic placement configs\n      node_config_details[0].size               # size\n    ]\n\n    precondition {\n      condition     = coalesce(each.value.image_id, \"none\") != \"none\"\n      error_message = <<-EOT\n      Missing image_id; check provided value if image_type is 'custom', or image_os/image_os_version if image_type is 'oke' or 'platform'.\n        pool: ${each.key}\n        image_type: ${coalesce(each.value.image_type, \"none\")}\n        image_id: ${coalesce(each.value.image_id, \"none\")}\n      EOT\n    }\n\n    precondition {\n      condition = anytrue([\n        contains([\"instance-pool\", \"cluster-network\"], each.value.mode), # supported modes\n        length(lookup(each.value, \"secondary_vnics\", {})) == 0,          # unrestricted when empty/unset\n      ])\n      error_message = \"Unsupported option for mode=${each.value.mode}: secondary_vnics\"\n    }\n\n    precondition {\n      condition     = coalesce(each.value.capacity_reservation_id, \"none\") == \"none\" || length(each.value.availability_domains) == 1\n      error_message = \"A single availability domain must be specified when using a capacity reservation with mode=${each.value.mode}\"\n    }\n  }\n\n  dynamic \"initial_node_labels\" {\n    for_each = each.value.node_labels\n    content {\n      key   = initial_node_labels.key\n      value = initial_node_labels.value\n    }\n  }\n}\n"
  },
  {
    "path": "modules/workers/outputs.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\noutput \"worker_pools\" {\n  description = \"Created worker pools (mode != 'instance')\"\n  value       = local.worker_pools_output\n}\n\noutput \"worker_instances\" {\n  description = \"Created worker pools (mode == 'instance')\"\n  value       = local.worker_instances\n}\n\noutput \"worker_pool_ids\" {\n  description = \"Created worker pool IDs\"\n  value       = local.worker_pool_ids\n}\n\noutput \"worker_pool_ips\" {\n  description = \"Created worker instance private IPs by pool for available modes ('node-pool', 'instance').\"\n  value       = local.worker_pool_ips\n}\n\noutput \"worker_count_expected\" {\n  description = \"# of nodes expected from created worker pools\"\n  value       = local.expected_node_count\n}\n\noutput \"worker_drain_expected\" {\n  description = \"# of nodes expected to be draining in worker pools\"\n  value       = local.expected_drain_count\n}\n\noutput \"worker_pool_autoscale_expected\" {\n  description = \"# of worker pools expected with autoscale enabled from created worker pools\"\n  value       = local.expected_autoscale_worker_pools\n}\n\noutput \"worker_gpu_memory_clusters\" {\n  description = \"Created GPU Memory Clusters keyed by '<pool_name>###<gpu_memory_fabric_id>'.\"\n  value       = oci_core_compute_gpu_memory_cluster.workers\n}\n\noutput \"worker_gpu_memory_cluster_ids\" {\n  description = \"OCIDs of created GPU Memory Clusters keyed by '<pool_name>###<gpu_memory_fabric_id>'.\"\n  value       = { for k, v in oci_core_compute_gpu_memory_cluster.workers : k => v.id }\n}"
  },
  {
    "path": "modules/workers/variables.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# Common\n\nvariable \"state_id\" {\n  default     = null\n  description = \"Optional Terraform state_id from an existing deployment of the module to re-use with created resources.\"\n  type        = string\n}\n\nvariable \"compartment_id\" {\n  default     = null\n  description = \"The compartment id where resources will be created.\"\n  type        = string\n}\n\nvariable \"tenancy_id\" {\n  default     = null\n  description = \"The tenancy id of the OCI Cloud Account in which to create the resources.\"\n  type        = string\n}\n\n# Tags\n\nvariable \"freeform_tags\" {\n  default     = {}\n  description = \"Freeform tags to be applied to created resources.\"\n  type        = map(string)\n}\n\nvariable \"defined_tags\" {\n  default     = {}\n  description = \"Defined tags to be applied to created resources. Must already exist in the tenancy.\"\n  type        = map(string)\n}\n\nvariable \"use_defined_tags\" {\n  default     = false\n  description = \"Whether to apply defined tags to created resources for IAM policy and tracking.\"\n  type        = bool\n}\n\nvariable \"tag_namespace\" {\n  default     = \"oke\"\n  description = \"The tag namespace for standard OKE defined tags.\"\n  type        = string\n}\n\n# Cluster\n\nvariable \"apiserver_private_host\" { type = string }\n\nvariable \"cluster_id\" {\n  default     = null\n  description = \"An existing OKE cluster OCID when `create_cluster = false`.\"\n  type        = string\n}\n\nvariable \"cluster_type\" {\n  default     = \"basic\"\n  description = \"The cluster type. See <a href=https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengworkingwithenhancedclusters.htm>Working with Enhanced Clusters and Basic Clusters</a> for more information.\"\n  type        = string\n  validation {\n    condition     = contains([\"basic\", \"enhanced\"], lower(var.cluster_type))\n    error_message = \"Accepted values are 'basic' or 'enhanced'.\"\n  }\n}\n\nvariable \"cluster_ca_cert\" {\n  default     = null\n  description = \"Base64+PEM-encoded cluster CA certificate for unmanaged instance pools. Determined automatically when 'create_cluster' = true or 'cluster_id' is provided.\"\n  type        = string\n}\n\nvariable \"cluster_dns\" {\n  default     = null\n  description = \"Cluster DNS resolver IP address. Determined automatically when not set (recommended).\"\n  type        = string\n}\n\nvariable \"kubernetes_version\" {\n  default     = \"v1.26.2\"\n  description = \"The version of Kubernetes used for worker nodes.\"\n  type        = string\n}\n\n# Network\n\nvariable \"assign_dns\" { type = bool }\nvariable \"assign_public_ip\" { type = bool }\n\nvariable \"cni_type\" {\n  default     = \"flannel\"\n  description = \"The CNI for the cluster: 'flannel' or 'npn'. See <a href=https://docs.oracle.com/en-us/iaas/Content/ContEng/Concepts/contengpodnetworking.htm>Pod Networking</a>.\"\n  type        = string\n  validation {\n    condition     = contains([\"flannel\", \"npn\"], var.cni_type)\n    error_message = \"Accepted values are flannel or npn\"\n  }\n}\n\nvariable \"enable_ipv6\" {\n  default     = false\n  description = \"Whether to create a dual-stack (IPv4/IPv6) cluster.\"\n  type        = bool\n}\n\nvariable \"pod_subnet_id\" { type = string }\nvariable \"worker_subnet_id\" { type = string }\n\n# Worker pools\n\nvariable \"worker_pools\" {\n  default     = {}\n  description = \"Tuple of OKE worker pools where each key maps to the OCID of an OCI resource, and value contains its definition.\"\n  type        = any\n}\n\nvariable \"worker_pool_mode\" {\n  default     = \"node-pool\"\n  description = \"Default management mode for workers when unspecified on a pool. Only 'node-pool' is currently supported.\"\n  type        = string\n  validation {\n    condition     = contains([\"node-pool\", \"instance\", \"instance-pool\", \"cluster-network\", \"gpu-memory-cluster\"], var.worker_pool_mode)\n    error_message = \"Accepted values are node-pool, instance-pool, cluster-network, or gpu-memory-cluster\"\n  }\n}\n\nvariable \"worker_pool_size\" {\n  default     = 0\n  description = \"Default size for worker pools when unspecified on a pool.\"\n  type        = number\n}\n\n# GPU memory cluster scale config defaults\n\nvariable \"gmc_scale_is_upsize_enabled\" {\n  default     = true\n  description = \"Default gpu_memory_cluster_scale_config.is_upsize_enabled when unspecified on a 'gpu-memory-cluster' pool.\"\n  type        = bool\n}\n\nvariable \"gmc_scale_is_downsize_enabled\" {\n  default     = true\n  description = \"Default gpu_memory_cluster_scale_config.is_downsize_enabled when unspecified on a 'gpu-memory-cluster' pool.\"\n  type        = bool\n}\n\nvariable \"gmc_scale_target_size\" {\n  default     = 18\n  description = \"Default gpu_memory_cluster_scale_config.target_size when unspecified on a 'gpu-memory-cluster' pool.\"\n  type        = number\n}\n\n# Workers: instance\n\nvariable \"ad_numbers_to_names\" { type = map(string) }\nvariable \"ad_numbers\" { type = list(number) }\n\nvariable \"image_ids\" {\n  default     = {}\n  description = \"Map of images for filtering with image_os and image_os_version.\"\n  type        = any\n}\n\nvariable \"indexed_images\" {\n  default     = {}\n  description = \"Map of images.\"\n  type        = any\n}\n\nvariable \"ssh_public_key\" {\n  default     = null\n  description = \"The contents of the SSH public key file. Used to allow login for workers/bastion/operator with corresponding private key.\"\n  type        = string\n}\n\nvariable \"timezone\" { type = string }\n\nvariable \"worker_nsg_ids\" {\n  default     = []\n  description = \"An additional list of network security group (NSG) IDs for node security. Combined with 'nsg_ids' specified on each pool.\"\n  type        = list(string)\n}\n\nvariable \"pod_nsg_ids\" {\n  default     = []\n  description = \"An additional list of network security group (NSG) IDs for pod security. Combined with 'pod_nsg_ids' specified on each pool.\"\n  type        = list(string)\n}\n\nvariable \"kubeproxy_mode\" {\n  default     = \"iptables\"\n  description = \"The mode in which to run kube-proxy when unspecified on a pool.\"\n  type        = string\n\n  validation {\n    condition     = contains([\"iptables\", \"ipvs\"], var.kubeproxy_mode)\n    error_message = \"Accepted values are iptables or ipvs.\"\n  }\n}\n\n#\n# Workers: instance\n#\n\nvariable \"block_volume_type\" {\n  default     = \"paravirtualized\"\n  description = \"Default block volume attachment type for Instance Configurations when unspecified on a pool.\"\n  type        = string\n  validation {\n    condition     = contains([\"iscsi\", \"paravirtualized\"], var.block_volume_type)\n    error_message = \"Accepted values are 'iscsi' or 'paravirtualized'.\"\n  }\n}\n\nvariable \"node_labels\" {\n  default     = {}\n  description = \"Default worker node labels. Merged with labels defined on each pool.\"\n  type        = map(string)\n}\n\n\nvariable \"node_metadata\" {\n  default     = {}\n  description = \"Map of additional worker node instance metadata. Merged with metadata defined on each pool.\"\n  type        = map(string)\n}\n\nvariable \"image_id\" {\n  default     = null\n  description = \"Default image for worker pools  when unspecified on a pool.\"\n  type        = string\n}\n\nvariable \"image_type\" {\n  default     = \"oke\"\n  description = \"Whether to use a platform, OKE, or custom image for worker nodes by default when unspecified on a pool. When custom is set, the worker_image_id must be specified.\"\n  type        = string\n  validation {\n    condition     = contains([\"custom\", \"oke\", \"platform\"], var.image_type)\n    error_message = \"Accepted values are custom, oke, platform\"\n  }\n}\n\nvariable \"image_os\" {\n  default     = \"Oracle Linux\"\n  description = \"Default worker image operating system name when worker_image_type = 'oke' or 'platform' and unspecified on a pool.\"\n  type        = string\n}\n\nvariable \"image_os_version\" {\n  default     = \"8\"\n  description = \"Default worker image operating system version when worker_image_type = 'oke' or 'platform' and unspecified on a pool.\"\n  type        = string\n}\n\nvariable \"shape\" {\n  default = {\n    shape            = \"VM.Standard.E4.Flex\",\n    ocpus            = 2,\n    memory           = 16,\n    boot_volume_size = 50\n  }\n  description = \"Default shape of the created worker instance when unspecified on a pool.\"\n  type        = map(any)\n}\n\nvariable \"capacity_reservation_id\" {\n  default     = null\n  description = \"The ID of the Compute capacity reservation the worker node will be launched under. See <a href=https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/reserve-capacity.htm>Capacity Reservations</a> for more information.\"\n  type        = string\n}\n\nvariable \"preemptible_config\" {\n  default = {\n    enable                  = false,\n    is_preserve_boot_volume = false\n  }\n  description = \"Default preemptible Compute configuration when unspecified on a pool. See <a href=https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengusingpreemptiblecapacity.htm>Preemptible Worker Nodes</a> for more information.\"\n  type        = map(any)\n}\n\nvariable \"cloud_init\" {\n  default     = []\n  description = \"List of maps containing cloud init MIME part configuration for worker nodes. Merged with pool-specific definitions. See https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/cloudinit_config.html#part for expected schema of each element.\"\n  type        = list(map(string))\n}\n\nvariable \"disable_default_cloud_init\" {\n  default     = false\n  description = \"Whether to disable the default OKE cloud init and only use the cloud init explicitly passed to the worker pool in 'worker_cloud_init'.\"\n  type        = bool\n}\n\nvariable \"volume_kms_key_id\" {\n  default     = null\n  description = \"The ID of the OCI KMS key to be used as the master encryption key for Boot Volume and Block Volume encryption by default when unspecified on a pool.\"\n  type        = string\n}\n\nvariable \"pv_transit_encryption\" {\n  default     = false\n  description = \"Whether to enable in-transit encryption for the data volume's paravirtualized attachment by default when unspecified on a pool.\"\n  type        = bool\n}\n\nvariable \"max_pods_per_node\" {\n  default     = 31\n  description = \"The default maximum number of pods to deploy per node when unspecified on a pool. Absolute maximum is 110. Ignored when when cni_type != 'npn'.\"\n  type        = number\n\n  validation {\n    condition     = var.max_pods_per_node > 0 && var.max_pods_per_node <= 110\n    error_message = \"Must be between 1 and 110.\"\n  }\n}\n\nvariable \"legacy_imds_endpoints_disabled\" {\n  default     = false\n  description = \"Whether to disable requests to the IMDSv1 endpoint and only allow requests to the IMDSv2 endpoint.  See <a href=https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengconfiguringimds.htm>Instance Metadata</a> for more information.\"\n  type        = bool\n}\n\nvariable \"allow_short_container_image_names\" {\n  default     = false\n  description = \"Whether to allow short container image names for K8s version >= 1.34.0. See <a href=https://github.com/cri-o/cri-o/pull/9401>CRI-O pull request</a> for more information.\"\n  type        = bool\n}\n\nvariable \"platform_config\" {\n  default     = null\n  description = \"Default platform_config for self-managed worker pools created with mode: 'instance', 'instance-pool', or 'cluster-network'. See <a href=https://docs.oracle.com/en-us/iaas/api/#/en/iaas/20160918/datatypes/PlatformConfig>PlatformConfig</a> for more information.\"\n  type = object({\n    type                                           = optional(string),\n    are_virtual_instructions_enabled               = optional(bool),\n    is_access_control_service_enabled              = optional(bool),\n    is_input_output_memory_management_unit_enabled = optional(bool),\n    is_measured_boot_enabled                       = optional(bool),\n    is_memory_encryption_enabled                   = optional(bool),\n    is_secure_boot_enabled                         = optional(bool),\n    is_symmetric_multi_threading_enabled           = optional(bool),\n    is_trusted_platform_module_enabled             = optional(bool),\n    numa_nodes_per_socket                          = optional(number),\n    percentage_of_cores_enabled                    = optional(bool),\n  })\n}\n\nvariable \"agent_config\" {\n  description = \"Default agent_config for self-managed worker pools created with mode: 'instance', 'instance-pool', or 'cluster-network'. See <a href=https://docs.oracle.com/en-us/iaas/api/#/en/iaas/20160918/datatypes/InstanceAgentConfig>InstanceConfig</a> for more information.\"\n  type = object({\n    are_all_plugins_disabled = bool,\n    is_management_disabled   = bool,\n    is_monitoring_disabled   = bool,\n    plugins_config           = map(string),\n  })\n}\n\n#\n# Workers: compute-cluster\n#\n\nvariable \"compute_clusters\" {\n  default     = {}\n  description = \"Whether to create compute clusters shared by nodes across multiple worker pools enabled for 'compute-cluster'.\"\n  type        = map(any)\n}\n\n"
  },
  {
    "path": "modules/workers/versions.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nterraform {\n  required_version = \">= 1.2.0\"\n\n  required_providers {\n    cloudinit = {\n      source  = \"hashicorp/cloudinit\"\n      version = \">= 2.2.0\"\n    }\n\n    oci = {\n      source  = \"oracle/oci\"\n      version = \">= 8.2.0\"\n    }\n  }\n}\n\n"
  },
  {
    "path": "modules/workers/virtualnodepools.tf",
    "content": "# Copyright (c) 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# Dynamic resource block for Virtual Node Pool groups defined in worker_pools\nresource \"oci_containerengine_virtual_node_pool\" \"workers\" {\n  # Create an OKE Virtual Node Pool resource for each enabled entry of the worker_pools map with that mode.\n  for_each       = local.enabled_virtual_node_pools\n  cluster_id     = var.cluster_id\n  compartment_id = each.value.compartment_id\n  display_name   = each.key\n  size           = each.value.size\n  defined_tags   = each.value.defined_tags\n  freeform_tags  = each.value.freeform_tags\n  nsg_ids        = each.value.nsg_ids\n\n  dynamic \"placement_configurations\" {\n    for_each = each.value.availability_domains\n    iterator = ad\n\n    content {\n      availability_domain = ad.value\n      subnet_id           = each.value.subnet_id\n\n      # Intersect the list of available and configured FDs for this AD\n      fault_domain = tolist(setintersection(\n        try(each.value.placement_fds, local.fault_domains_all),\n        lookup(local.fault_domains_available, ad.value, local.fault_domains_all)\n      ))\n    }\n  }\n\n  dynamic \"initial_virtual_node_labels\" {\n    for_each = each.value.node_labels\n    content {\n      key   = initial_virtual_node_labels.key\n      value = initial_virtual_node_labels.value\n    }\n  }\n\n  pod_configuration {\n    shape     = each.value.shape\n    subnet_id = coalesce(each.value.pod_subnet_id, each.value.subnet_id)\n    nsg_ids   = toset(compact(coalescelist(each.value.pod_nsg_ids, each.value.nsg_ids, [])))\n  }\n\n  dynamic \"taints\" {\n    for_each = each.value.taints\n    content {\n      effect = lookup(taints.value, \"effect\", \"NoSchedule\")\n      key    = taints.key\n      value  = lookup(taints.value, \"value\", null)\n    }\n  }\n\n  virtual_node_tags {\n    defined_tags  = each.value.defined_tags\n    freeform_tags = each.value.freeform_tags\n  }\n\n  lifecycle {\n    ignore_changes = [\n      display_name, virtual_node_tags,\n      placement_configurations,\n      defined_tags, freeform_tags,\n    ]\n\n    precondition {\n      condition     = var.cni_type == \"npn\"\n      error_message = \"Virtual Node Pools require a cluster with `cni_type = npn`.\"\n    }\n\n    precondition {\n      condition     = each.value.autoscale == false\n      error_message = \"Virtual Node Pools do not support cluster autoscaler management.\"\n    }\n\n    precondition {\n      condition     = var.cluster_type == \"enhanced\"\n      error_message = \"Virtual Node Pools require `cluster_type = enhanced`.\"\n    }\n\n    precondition {\n      condition     = contains([\"Pod.Standard.E3.Flex\", \"Pod.Standard.E4.Flex\", \"Pod.Standard.A1.Flex\"], each.value.shape)\n      error_message = \"Virtual Node Pools must be 'Pod.Standard.E3.Flex', 'Pod.Standard.E4.Flex' or 'Pod.Standard.A1.Flex'.\"\n    }\n  }\n}\n"
  },
  {
    "path": "variables-bastion.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nvariable \"create_bastion\" {\n  default     = true\n  description = \"Whether to create a bastion host.\"\n  type        = bool\n}\n\nvariable \"bastion_public_ip\" {\n  default     = null\n  description = \"The IP address of an existing bastion host, if create_bastion = false.\"\n  type        = string\n}\n\nvariable \"bastion_allowed_cidrs\" {\n  default     = []\n  description = \"A list of CIDR blocks to allow SSH access to the bastion host. NOTE: Default is empty i.e. no access permitted. Allow access from anywhere with '0.0.0.0/0'.\"\n  type        = list(string)\n}\n\nvariable \"bastion_availability_domain\" {\n  default     = null\n  description = \"The availability domain for bastion placement. Defaults to first available.\"\n  type        = string\n}\n\nvariable \"bastion_nsg_ids\" {\n  description = \"An additional list of network security group (NSG) IDs for bastion security.\"\n  default     = []\n  type        = list(string)\n}\n\nvariable \"bastion_user\" {\n  default     = \"opc\"\n  description = \"User for SSH access through bastion host.\"\n  type        = string\n}\n\nvariable \"bastion_image_id\" {\n  default     = null\n  description = \"Image ID for created bastion instance.\"\n  type        = string\n}\n\nvariable \"bastion_image_type\" {\n  default     = \"platform\"\n  description = \"Whether to use a platform or custom image for the created bastion instance. When custom is set, the bastion_image_id must be specified.\"\n  type        = string\n  validation {\n    condition     = contains([\"custom\", \"platform\"], var.bastion_image_type)\n    error_message = \"Accepted values are custom or platform\"\n  }\n}\n\nvariable \"bastion_image_os\" {\n  default     = \"Oracle Autonomous Linux\"\n  description = \"Bastion image operating system name when bastion_image_type = 'platform'.\"\n  type        = string\n}\n\nvariable \"bastion_image_os_version\" {\n  default     = \"8\"\n  description = \"Bastion image operating system version when bastion_image_type = 'platform'.\"\n  type        = string\n}\n\nvariable \"bastion_shape\" {\n  default = {\n    shape                     = \"VM.Standard.E4.Flex\",\n    ocpus                     = 1,\n    memory                    = 4,\n    boot_volume_size          = 50,\n    baseline_ocpu_utilization = 100\n  }\n  description = \"The shape of bastion instance. Baseline OCPU utilization can be used to provision <a href=https://docs.oracle.com/en-us/iaas/Content/Compute/References/burstable-instances.htm>burstable shapes.</a>\"\n  type        = map(any)\n}\n\nvariable \"bastion_is_public\" {\n  default     = true\n  description = \"Whether to create allocate a public IP and subnet for the created bastion host.\"\n  type        = bool\n}\n\nvariable \"bastion_upgrade\" {\n  default     = false\n  description = \"Whether to upgrade bastion packages after provisioning.\"\n  type        = bool\n}\n\nvariable \"bastion_await_cloudinit\" {\n  default     = true\n  description = \"Whether to block until successful connection to bastion and completion of cloud-init.\"\n  type        = bool\n}\n\nvariable \"bastion_volume_kms_key_id\" {\n  default     = null\n  description = \"The OCID of the OCI KMS key to assign as the master encryption key for the bastion host boot volume.\"\n  type        = string\n}\n\nvariable \"bastion_legacy_imds_endpoints_disabled\" {\n  default     = true\n  description = \"Whether to disable requests to the IMDSv1 endpoint and only allow requests to the IMDSv2 endpoint for the bastion instance.\"\n  type        = bool\n}"
  },
  {
    "path": "variables-cluster-addons.tf",
    "content": "# Copyright (c) 2017, 2024 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nvariable \"cluster_addons\" {\n  description = \"Map with cluster addons that should be enabled.  See <a href=https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengconfiguringclusteraddons-configurationarguments.htm#contengconfiguringclusteraddons-supportedarguments>ClusterAddon documentation</a> for the supported configuration of each addon.\"\n  type        = any\n  default     = {}\n}\n\nvariable \"cluster_addons_to_remove\" {\n  description = \"Map with cluster addons not created by Terraform that should be removed. This operation is performed using oci-cli and requires the operator host to be deployed.\"\n  type        = any\n  default     = {}\n}"
  },
  {
    "path": "variables-cluster.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nvariable \"create_cluster\" {\n  default     = true\n  description = \"Whether to create the OKE cluster and dependent resources.\"\n  type        = bool\n}\n\nvariable \"cluster_name\" {\n  default     = \"oke\"\n  description = \"The name of oke cluster.\"\n  type        = string\n}\n\nvariable \"cluster_type\" {\n  default     = \"basic\"\n  description = \"The cluster type. See <a href=https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengworkingwithenhancedclusters.htm>Working with Enhanced Clusters and Basic Clusters</a> for more information.\"\n  type        = string\n  validation {\n    condition     = contains([\"basic\", \"enhanced\"], lower(var.cluster_type))\n    error_message = \"Accepted values are 'basic' or 'enhanced'.\"\n  }\n}\n\nvariable \"control_plane_is_public\" {\n  default     = false\n  description = \"Whether the Kubernetes control plane endpoint should be allocated a public IP address to enable access over public internet.\"\n  type        = bool\n}\n\nvariable \"assign_public_ip_to_control_plane\" {\n  default     = false\n  description = \"Whether to assign a public IP address to the API endpoint for public access. Requires the control plane subnet to be public to assign a public IP address.\"\n  type        = bool\n}\n\nvariable \"control_plane_nsg_ids\" {\n  default     = []\n  description = \"An additional list of network security groups (NSG) ids for the cluster endpoint.\"\n  type        = set(string)\n}\n\nvariable \"backend_nsg_ids\" {\n  default     = []\n  description = \"An additional list of network security groups (NSG) ids for the LB backends. Used when the service rule management mode is set to NSG via annotations. See <a href=https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengconfiguringloadbalancersnetworkloadbalancers-subtopic.htm#contengcreatingloadbalancer_topic-Specifying_Load_Balancer_Security_Rule_Management_Options>Security Rule Management Options for Load Balancers and Network Load Balancers</a> for more information.\"\n  type        = set(string)\n}\n\nvariable \"cni_type\" {\n  default     = \"flannel\"\n  description = \"The CNI for the cluster: 'flannel' or 'npn'. See <a href=https://docs.oracle.com/en-us/iaas/Content/ContEng/Concepts/contengpodnetworking.htm>Pod Networking</a>.\"\n  type        = string\n  validation {\n    condition     = contains([\"flannel\", \"npn\"], var.cni_type)\n    error_message = \"Accepted values are flannel or npn\"\n  }\n}\n\nvariable \"enable_ipv6\" {\n  default     = false\n  description = \"Whether to create a dual-stack (IPv4/IPv6) cluster.\"\n  type        = bool\n}\n\nvariable \"oke_ip_families\" {\n  default     = []\n  type        = list(string)\n  description = \"Override the ip_families attribute for the OKE cluster. Supported values: ['IPv4'] or ['IPV4', 'IPv6']\"\n}\n\nvariable \"pods_cidr\" {\n  default     = \"10.244.0.0/16\"\n  description = \"The CIDR range used for IP addresses by the pods. A /16 CIDR is generally sufficient. This CIDR should not overlap with any subnet range in the VCN (it can also be outside the VCN CIDR range). Ignored when cni_type = 'npn'.\"\n  type        = string\n}\n\nvariable \"services_cidr\" {\n  default     = \"10.96.0.0/16\"\n  description = \"The CIDR range used within the cluster by Kubernetes services (ClusterIPs). This CIDR should not overlap with the VCN CIDR range.\"\n  type        = string\n}\n\nvariable \"kubernetes_version\" {\n  default     = \"v1.34.2\"\n  description = \"The version of kubernetes to use when provisioning OKE or to upgrade an existing OKE cluster to.\"\n  type        = string\n}\n\nvariable \"cluster_kms_key_id\" {\n  default     = \"\"\n  description = \"The id of the OCI KMS key to be used as the master encryption key for Kubernetes secrets encryption.\"\n  type        = string\n}\n\nvariable \"use_signed_images\" {\n  default     = false\n  description = \"Whether to enforce the use of signed images. If set to true, at least 1 RSA key must be provided through image_signing_keys.\"\n  type        = bool\n}\n\nvariable \"image_signing_keys\" {\n  default     = []\n  description = \"A list of KMS key ids used by the worker nodes to verify signed images. The keys must use RSA algorithm.\"\n  type        = set(string)\n}\n\nvariable \"load_balancers\" {\n  default     = \"both\"\n  description = \"The type of subnets to create for load balancers.\"\n  type        = string\n  validation {\n    condition     = contains([\"public\", \"internal\", \"both\"], var.load_balancers)\n    error_message = \"Accepted values are public, internal or both.\"\n  }\n}\n\nvariable \"preferred_load_balancer\" {\n  default     = \"public\"\n  description = \"The preferred load balancer subnets that OKE will automatically choose when creating a load balancer. Valid values are 'public' or 'internal'. If 'public' is chosen, the value for load_balancers must be either 'public' or 'both'. If 'private' is chosen, the value for load_balancers must be either 'internal' or 'both'. NOTE: Service annotations for internal load balancers must still be specified regardless of this setting. See <a href=https://github.com/oracle/oci-cloud-controller-manager/blob/master/docs/load-balancer-annotations.md>Load Balancer Annotations</a> for more information.\"\n  type        = string\n  validation {\n    condition     = contains([\"public\", \"internal\"], var.preferred_load_balancer)\n    error_message = \"Accepted values are public or internal.\"\n  }\n}\n\nvariable \"oidc_discovery_enabled\" {\n  default     = false\n  description = \"Whether the cluster has OIDC Discovery enabled. See <a href=https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengOpenIDConnect-Discovery.htm>OIDC Discovery configuration documentation</a>.\"\n  type        = bool\n}\n\nvariable \"oidc_token_auth_enabled\" {\n  default     = false\n  description = \"Whether the cluster has OIDC Auth Config enabled.\"\n  type        = bool\n}\n\nvariable \"oidc_token_authentication_config\" {\n  default     = {}\n  description = \"The properties that configure OIDC token authentication in kube-apiserver. See <a href=https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengOpenIDConnect-Authentication.htm>OIDC Token Authentication configuration documentation</a>.\"\n  type        = any\n}"
  },
  {
    "path": "variables-common.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  # SSH key precedence: base64-encoded PEM > raw PEM > file PEM > null\n  ssh_key_arg = (coalesce(var.ssh_private_key_path, \"none\") != \"none\"\n  ? join(\" \", [\"-i\", var.ssh_private_key_path]) : null)\n  ssh_private_key = sensitive(\n    coalesce(var.ssh_private_key, \"none\") != \"none\"\n    ? try(base64decode(var.ssh_private_key), var.ssh_private_key)\n    : coalesce(var.ssh_private_key_path, \"none\") != \"none\" ? file(var.ssh_private_key_path) : null\n  )\n  ssh_public_key = (\n    coalesce(var.ssh_public_key, \"none\") != \"none\"\n    ? try(base64decode(var.ssh_public_key), var.ssh_public_key)\n    : coalesce(var.ssh_public_key_path, \"none\") != \"none\" ? file(var.ssh_public_key_path) : null\n  )\n}\n\nvariable \"state_id\" {\n  default     = null\n  description = \"Optional Terraform state_id from an existing deployment of the module to re-use with created resources.\"\n  type        = string\n}\n\nvariable \"output_detail\" {\n  default     = false\n  description = \"Whether to include detailed output in state.\"\n  type        = bool\n}\n\nvariable \"timezone\" {\n  default     = \"Etc/UTC\"\n  description = \"The preferred timezone for workers, operator, and bastion instances.\"\n  type        = string\n}\n\nvariable \"ssh_private_key\" {\n  default     = null\n  description = \"The contents of the SSH private key file, optionally base64-encoded. May be provided via SSH agent when unset.\"\n  sensitive   = true\n  type        = string\n}\n\nvariable \"ssh_private_key_path\" {\n  default     = null\n  description = \"A path on the local filesystem to the SSH private key. May be provided via SSH agent when unset.\"\n  type        = string\n}\n\nvariable \"ssh_public_key\" {\n  default     = null\n  description = \"The contents of the SSH public key file, optionally base64-encoded. Used to allow login for workers/bastion/operator with corresponding private key.\"\n  type        = string\n}\n\nvariable \"ssh_public_key_path\" {\n  default     = null\n  description = \"A path on the local filesystem to the SSH public key. Used to allow login for workers/bastion/operator with corresponding private key.\"\n  type        = string\n}\n"
  },
  {
    "path": "variables-extensions.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n# CNI: Cilium\n\nvariable \"cilium_install\" {\n  default     = false\n  description = \"Whether to deploy the Cilium Helm chart. May only be enabled when cni_type = 'flannel'. See https://docs.cilium.io. NOTE: Provided only as a convenience and not supported by or sourced from Oracle - use at your own risk.\"\n  type        = bool\n}\n\nvariable \"cilium_reapply\" {\n  default     = false\n  description = \"Whether to force reapply of the chart when no changes are detected, e.g. with state modified externally.\"\n  type        = bool\n}\n\nvariable \"cilium_namespace\" {\n  default     = \"kube-system\"\n  description = \"Kubernetes namespace for deployed resources.\"\n  type        = string\n}\n\nvariable \"cilium_helm_version\" {\n  default     = \"1.16.3\"\n  description = \"Version of the Helm chart to install. List available releases using `helm search repo [keyword] --versions`.\"\n  type        = string\n}\n\nvariable \"cilium_helm_values\" {\n  default     = {}\n  description = \"Map of individual Helm chart values. See https://registry.terraform.io/providers/hashicorp/helm/latest/docs/data-sources/template.\"\n  type        = any\n}\n\nvariable \"cilium_helm_values_files\" {\n  default     = []\n  description = \"Paths to a local YAML files with Helm chart values (as with `helm install -f` which supports multiple). Generate with defaults using `helm show values [CHART] [flags]`.\"\n  type        = list(string)\n}\n\n# CNI: Multus\n\nvariable \"multus_install\" {\n  default     = false\n  description = \"Whether to deploy Multus. See <a href=https://github.com/k8snetworkplumbingwg/multus-cni>k8snetworkplumbingwg/multus-cni</a>. NOTE: Provided only as a convenience and not supported by or sourced from Oracle - use at your own risk.\"\n  type        = bool\n}\n\nvariable \"multus_namespace\" {\n  default     = \"network\"\n  description = \"Kubernetes namespace for deployed resources.\"\n  type        = string\n}\n\nvariable \"multus_daemonset_url\" {\n  default     = null\n  description = \"The URL path to the Multus manifest. Leave unset for tags of <a href=https://github.com/k8snetworkplumbingwg/multus-cni>k8snetworkplumbingwg/multus-cni</a> using multus_version.\"\n  type        = string\n}\n\nvariable \"multus_version\" {\n  default     = \"3.9.3\"\n  description = \"Version of Multus to install. Ignored when an explicit value for multus_daemonset_url is provided.\"\n  type        = string\n}\n\n# SR-IOV Device Plugin\n\nvariable \"sriov_device_plugin_install\" {\n  default     = false\n  description = \"Whether to deploy the SR-IOV Network Device Plugin. See <a href=https://github.com/k8snetworkplumbingwg/sriov-network-device-plugin>k8snetworkplumbingwg/sriov-network-device-plugin</a>. NOTE: Provided only as a convenience and not supported by or sourced from Oracle - use at your own risk.\"\n  type        = bool\n}\n\nvariable \"sriov_device_plugin_namespace\" {\n  default     = \"network\"\n  description = \"Kubernetes namespace for deployed resources.\"\n  type        = string\n}\n\nvariable \"sriov_device_plugin_daemonset_url\" {\n  default     = null\n  description = \"The URL path to the manifest. Leave unset for tags of <a href=https://github.com/k8snetworkplumbingwg/sriov-network-device-plugin>k8snetworkplumbingwg/sriov-network-device-plugin</a> using sriov_device_plugin_version.\"\n  type        = string\n}\n\nvariable \"sriov_device_plugin_version\" {\n  default     = \"master\"\n  description = \"Version to install. Ignored when an explicit value for sriov_device_plugin_daemonset_url is provided.\"\n  type        = string\n}\n\n# SR-IOV CNI Plugin\n\nvariable \"sriov_cni_plugin_install\" {\n  default     = false\n  description = \"Whether to deploy the SR-IOV CNI Plugin. See <a href=https://github.com/openshift/sriov-cni</a>. NOTE: Provided only as a convenience and not supported by or sourced from Oracle - use at your own risk.\"\n  type        = bool\n}\n\nvariable \"sriov_cni_plugin_namespace\" {\n  default     = \"network\"\n  description = \"Kubernetes namespace for deployed resources.\"\n  type        = string\n}\n\nvariable \"sriov_cni_plugin_daemonset_url\" {\n  default     = null\n  description = \"The URL path to the manifest. Leave unset for tags of <a href=https://github.com/openshift/sriov-cni</a> using sriov_cni_plugin_version.\"\n  type        = string\n}\n\nvariable \"sriov_cni_plugin_version\" {\n  default     = \"master\"\n  description = \"Version to install. Ignored when an explicit value for sriov_cni_plugin_daemonset_url is provided.\"\n  type        = string\n}\n\n# RDMA CNI Plugin\n\nvariable \"rdma_cni_plugin_install\" {\n  default     = false\n  description = \"Whether to deploy the RDMA CNI Plugin. See <a href=https://github.com/Mellanox/rdma-cni>Mellanox/rdma-cni</a>. NOTE: Provided only as a convenience and not supported by or sourced from Oracle - use at your own risk.\"\n  type        = bool\n}\n\nvariable \"rdma_cni_plugin_namespace\" {\n  default     = \"network\"\n  description = \"Kubernetes namespace for deployed resources.\"\n  type        = string\n}\n\nvariable \"rdma_cni_plugin_daemonset_url\" {\n  default     = null\n  description = \"The URL path to the manifest. Leave unset for tags of <a href=https://github.com/Mellanox/rdma-cni>Mellanox/rdma-cni</a> using rdma_cni_plugin_version.\"\n  type        = string\n}\n\nvariable \"rdma_cni_plugin_version\" {\n  default     = \"master\"\n  description = \"Version to install. Ignored when an explicit value for rdma_cni_plugin_daemonset_url is provided.\"\n  type        = string\n}\n\n# Metrics server\n\nvariable \"metrics_server_install\" {\n  default     = false\n  description = \"Whether to deploy the Kubernetes Metrics Server Helm chart. See <a href=https://github.com/kubernetes-sigs/metrics-server>kubernetes-sigs/metrics-server</a>. NOTE: Provided only as a convenience and not supported by or sourced from Oracle - use at your own risk.\"\n  type        = bool\n}\n\nvariable \"metrics_server_namespace\" {\n  default     = \"metrics\"\n  description = \"Kubernetes namespace for deployed resources.\"\n  type        = string\n}\n\nvariable \"metrics_server_helm_version\" {\n  default     = \"3.8.3\"\n  description = \"Version of the Helm chart to install. List available releases using `helm search repo [keyword] --versions`.\"\n  type        = string\n}\n\nvariable \"metrics_server_helm_values\" {\n  default     = {}\n  description = \"Map of individual Helm chart values. See <a href=https://registry.terraform.io/providers/hashicorp/helm/latest/docs/data-sources/template>data.helm_template</a>.\"\n  type        = map(string)\n}\n\nvariable \"metrics_server_helm_values_files\" {\n  default     = []\n  description = \"Paths to a local YAML files with Helm chart values (as with `helm install -f` which supports multiple). Generate with defaults using `helm show values [CHART] [flags]`.\"\n  type        = list(string)\n}\n\n# Cluster autoscaler\n\nvariable \"cluster_autoscaler_install\" {\n  default     = false\n  description = \"Whether to deploy the Kubernetes Cluster Autoscaler Helm chart. See <a href=https://github.com/kubernetes/autoscaler>kubernetes/autoscaler</a>. NOTE: Provided only as a convenience and not supported by or sourced from Oracle - use at your own risk.\"\n  type        = bool\n}\n\nvariable \"cluster_autoscaler_namespace\" {\n  default     = \"kube-system\"\n  description = \"Kubernetes namespace for deployed resources.\"\n  type        = string\n}\n\nvariable \"cluster_autoscaler_helm_version\" {\n  default     = \"9.24.0\"\n  description = \"Version of the Helm chart to install. List available releases using `helm search repo [keyword] --versions`.\"\n  type        = string\n}\n\nvariable \"cluster_autoscaler_helm_values\" {\n  default     = {}\n  description = \"Map of individual Helm chart values. See <a href=https://registry.terraform.io/providers/hashicorp/helm/latest/docs/data-sources/template>data.helm_template</a>.\"\n  type        = map(string)\n}\n\nvariable \"cluster_autoscaler_helm_values_files\" {\n  default     = []\n  description = \"Paths to a local YAML files with Helm chart values (as with `helm install -f` which supports multiple). Generate with defaults using `helm show values [CHART] [flags]`.\"\n  type        = list(string)\n}\n\n# Prometheus\n\nvariable \"prometheus_install\" {\n  default     = false\n  description = \"Whether to deploy the Prometheus Helm chart. See https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack. NOTE: Provided only as a convenience and not supported by or sourced from Oracle - use at your own risk.\"\n  type        = bool\n}\n\nvariable \"prometheus_reapply\" {\n  default     = false\n  description = \"Whether to force reapply of the Prometheus Helm chart when no changes are detected, e.g. with state modified externally.\"\n  type        = bool\n}\n\nvariable \"prometheus_namespace\" {\n  default     = \"metrics\"\n  description = \"Kubernetes namespace for deployed resources.\"\n  type        = string\n}\n\nvariable \"prometheus_helm_version\" {\n  default     = \"45.2.0\"\n  description = \"Version of the Helm chart to install. List available releases using `helm search repo [keyword] --versions`.\"\n  type        = string\n}\n\nvariable \"prometheus_helm_values\" {\n  default     = {}\n  description = \"Map of individual Helm chart values. See <a href=https://registry.terraform.io/providers/hashicorp/helm/latest/docs/data-sources/template>data.helm_template</a>.\"\n  type        = map(string)\n}\n\nvariable \"prometheus_helm_values_files\" {\n  default     = []\n  description = \"Paths to a local YAML files with Helm chart values (as with `helm install -f` which supports multiple). Generate with defaults using `helm show values [CHART] [flags]`.\"\n  type        = list(string)\n}\n\n# DCGM exporter\n\nvariable \"dcgm_exporter_install\" {\n  default     = false\n  description = \"Whether to deploy the DCGM exporter Helm chart. See <a href=https://docs.nvidia.com/datacenter/cloud-native/gpu-telemetry/dcgm-exporter.html>DCGM-Exporter</a>. NOTE: Provided only as a convenience and not supported by or sourced from Oracle - use at your own risk.\"\n  type        = bool\n}\n\nvariable \"dcgm_exporter_reapply\" {\n  default     = false\n  description = \"Whether to force reapply of the Helm chart when no changes are detected, e.g. with state modified externally.\"\n  type        = bool\n}\n\nvariable \"dcgm_exporter_namespace\" {\n  default     = \"metrics\"\n  description = \"Kubernetes namespace for deployed resources.\"\n  type        = string\n}\n\nvariable \"dcgm_exporter_helm_version\" {\n  default     = \"3.1.5\"\n  description = \"Version of the Helm chart to install. List available releases using `helm search repo [keyword] --versions`.\"\n  type        = string\n}\n\nvariable \"dcgm_exporter_helm_values\" {\n  default     = {}\n  description = \"Map of individual Helm chart values. See <a href=https://registry.terraform.io/providers/hashicorp/helm/latest/docs/data-sources/template>data.helm_template</a>.\"\n  type        = map(string)\n}\n\nvariable \"dcgm_exporter_helm_values_files\" {\n  default     = []\n  description = \"Paths to a local YAML files with Helm chart values (as with `helm install -f` which supports multiple). Generate with defaults using `helm show values [CHART] [flags]`.\"\n  type        = list(string)\n}\n\n# MPI Operator\n\nvariable \"mpi_operator_install\" {\n  default     = false\n  description = \"Whether to deploy the MPI Operator. See <a href=https://github.com/kubeflow/mpi-operator>kubeflow/mpi-operator</a>. NOTE: Provided only as a convenience and not supported by or sourced from Oracle - use at your own risk.\"\n  type        = bool\n}\n\nvariable \"mpi_operator_namespace\" {\n  default     = \"default\"\n  description = \"Kubernetes namespace for deployed resources.\"\n  type        = string\n}\n\nvariable \"mpi_operator_deployment_url\" {\n  default     = null\n  description = \"The URL path to the manifest. Leave unset for tags of <a href=https://github.com/kubeflow/mpi-operator>kubeflow/mpi-operator</a> using mpi_operator_version.\"\n  type        = string\n}\n\nvariable \"mpi_operator_version\" {\n  default     = \"0.4.0\"\n  description = \"Version to install. Ignored when an explicit value for mpi_operator_deployment_url is provided.\"\n  type        = string\n}\n\n# Whereabouts\n\nvariable \"whereabouts_install\" {\n  default     = false\n  description = \"Whether to deploy Whereabouts IPAM. See <a href=https://github.com/k8snetworkplumbingwg/whereabouts>k8snetworkplumbingwg/whereabouts</a>. NOTE: Provided only as a convenience and not supported by or sourced from Oracle - use at your own risk.\"\n  type        = bool\n}\n\nvariable \"whereabouts_namespace\" {\n  default     = \"default\"\n  description = \"Kubernetes namespace for deployed resources.\"\n  type        = string\n}\n\nvariable \"whereabouts_daemonset_url\" {\n  default     = null\n  description = \"The URL path to the manifest. Leave unset for tags of <a href=https://github.com/k8snetworkplumbingwg/whereabouts>k8snetworkplumbingwg/whereabouts</a> using whereabouts_version.\"\n  type        = string\n}\n\nvariable \"whereabouts_version\" {\n  default     = \"master\"\n  description = \"Version to install. Ignored when an explicit value for whereabouts_daemonset_url is provided.\"\n  type        = string\n}\n\n# Gatekeeper\n\nvariable \"gatekeeper_install\" {\n  default     = false\n  description = \"Whether to deploy the Gatekeeper Helm chart. See https://github.com/open-policy-agent/gatekeeper. NOTE: Provided only as a convenience and not supported by or sourced from Oracle - use at your own risk.\"\n  type        = bool\n}\n\nvariable \"gatekeeper_namespace\" {\n  default     = \"kube-system\"\n  description = \"Kubernetes namespace for deployed resources.\"\n  type        = string\n}\n\nvariable \"gatekeeper_helm_version\" {\n  default     = \"3.11.0\"\n  description = \"Version of the Helm chart to install. List available releases using `helm search repo [keyword] --versions`.\"\n  type        = string\n}\n\nvariable \"gatekeeper_helm_values\" {\n  default     = {}\n  description = \"Map of individual Helm chart values. See <a href=https://registry.terraform.io/providers/hashicorp/helm/latest/docs/data-sources/template>data.helm_template</a>.\"\n  type        = map(string)\n}\n\nvariable \"gatekeeper_helm_values_files\" {\n  default     = []\n  description = \"Paths to a local YAML files with Helm chart values (as with `helm install -f` which supports multiple). Generate with defaults using `helm show values [CHART] [flags]`.\"\n  type        = list(string)\n}\n\n# Service Account\n\nvariable \"create_service_account\" {\n  default     = false\n  description = \"Whether to create a service account or not.\"\n  type        = bool\n}\n\nvariable \"service_accounts\" {\n  default = {\n    kubeconfigsa = {\n      sa_name                 = \"kubeconfigsa\"\n      sa_namespace            = \"kube-system\"\n      sa_cluster_role         = \"cluster-admin\"\n      sa_cluster_role_binding = \"kubeconfigsa-crb\"\n    }\n  }\n  description = \"Map of service accounts and associated parameters.\"\n  type        = map(any)\n}\n\n# Argocd\n\nvariable \"argocd_install\" {\n  default     = false\n  description = \"Whether to deploy the Argocd Helm chart. See https://github.com/argoproj/argo-cd. NOTE: Provided only as a convenience and not supported by or sourced from Oracle - use at your own risk.\"\n  type        = bool\n}\n\nvariable \"argocd_namespace\" {\n  default     = \"argocd\"\n  description = \"Kubernetes namespace for deployed resources.\"\n  type        = string\n}\n\nvariable \"argocd_helm_version\" {\n  default     = \"8.1.2\"\n  description = \"Version of the Helm chart to install. List available releases using `helm search repo [keyword] --versions`.\"\n  type        = string\n}\n\nvariable \"argocd_helm_values\" {\n  default     = {}\n  description = \"Map of individual Helm chart values. See <a href=https://registry.terraform.io/providers/hashicorp/helm/latest/docs/data-sources/template>data.helm_template</a>.\"\n  type        = map(string)\n}\n\nvariable \"argocd_helm_values_files\" {\n  default     = []\n  description = \"Paths to a local YAML files with Helm chart values (as with `helm install -f` which supports multiple). Generate with defaults using `helm show values [CHART] [flags]`.\"\n  type        = list(string)\n}\n"
  },
  {
    "path": "variables-iam.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nlocals {\n  tenancy_id            = coalesce(var.tenancy_id, var.tenancy_ocid, \"unknown\")\n  compartment_id        = coalesce(var.compartment_id, var.compartment_ocid, var.tenancy_id)\n  worker_compartment_id = coalesce(var.worker_compartment_id, var.compartment_id)\n  user_id               = var.user_id != \"\" ? var.user_id : var.current_user_ocid\n  home_region           = coalesce(var.home_region, var.region)\n\n  api_private_key = sensitive(\n    var.api_private_key != \"\"\n    ? try(base64decode(var.api_private_key), var.api_private_key)\n    : var.api_private_key_path != \"\"\n    ? file(var.api_private_key_path)\n    : null\n  )\n\n  # Merge freeform tags from map & individual inputs better suited to Resource Manager\n  bastion_freeform_tags           = merge(lookup(var.freeform_tags, \"bastion\", {}), var.bastion_freeform_tags)\n  cluster_freeform_tags           = merge(lookup(var.freeform_tags, \"cluster\", {}), var.cluster_freeform_tags)\n  iam_freeform_tags               = merge(lookup(var.freeform_tags, \"iam\", {}), var.iam_freeform_tags)\n  network_freeform_tags           = merge(lookup(var.freeform_tags, \"network\", {}), var.network_freeform_tags)\n  operator_freeform_tags          = merge(lookup(var.freeform_tags, \"operator\", {}), var.operator_freeform_tags)\n  persistent_volume_freeform_tags = merge(lookup(var.freeform_tags, \"persistent_volume\", {}), var.persistent_volume_freeform_tags)\n  service_lb_freeform_tags        = merge(lookup(var.freeform_tags, \"service_lb\", {}), var.service_lb_freeform_tags)\n  workers_freeform_tags           = merge(lookup(var.freeform_tags, \"workers\", {}), var.workers_freeform_tags)\n\n  # Merge defined tags from map & individual inputs better suited to Resource Manager\n  bastion_defined_tags           = merge(lookup(var.defined_tags, \"bastion\", {}), var.bastion_defined_tags)\n  cluster_defined_tags           = merge(lookup(var.defined_tags, \"cluster\", {}), var.cluster_defined_tags)\n  iam_defined_tags               = merge(lookup(var.defined_tags, \"iam\", {}), var.iam_defined_tags)\n  network_defined_tags           = merge(lookup(var.defined_tags, \"network\", {}), var.network_defined_tags)\n  operator_defined_tags          = merge(lookup(var.defined_tags, \"operator\", {}), var.operator_defined_tags)\n  persistent_volume_defined_tags = merge(lookup(var.defined_tags, \"persistent_volume\", {}), var.persistent_volume_defined_tags)\n  service_lb_defined_tags        = merge(lookup(var.defined_tags, \"service_lb\", {}), var.service_lb_defined_tags)\n  workers_defined_tags           = merge(lookup(var.defined_tags, \"workers\", {}), var.workers_defined_tags)\n}\n\n# Overrides Resource Manager\nvariable \"tenancy_id\" {\n  default     = null\n  description = \"The tenancy id of the OCI Cloud Account in which to create the resources.\"\n  type        = string\n}\n\nvariable \"tenancy_ocid\" {\n  default     = null\n  description = \"A tenancy OCID automatically populated by Resource Manager.\"\n  type        = string\n}\n\n# Overrides Resource Manager\nvariable \"user_id\" {\n  default     = null\n  description = \"The id of the user that terraform will use to create the resources.\"\n  type        = string\n}\n\n# Automatically populated by Resource Manager\nvariable \"current_user_ocid\" {\n  default     = null\n  description = \"A user OCID automatically populated by Resource Manager.\"\n  type        = string\n}\n\n# Overrides Resource Manager\nvariable \"compartment_id\" {\n  default     = null\n  description = \"The compartment id where resources will be created.\"\n  type        = string\n}\n\n# Automatically populated by Resource Manager\nvariable \"compartment_ocid\" {\n  default     = null\n  description = \"A compartment OCID automatically populated by Resource Manager.\"\n  type        = string\n}\n\n# Overrides compartment_[oc]id\nvariable \"worker_compartment_id\" {\n  default     = null\n  description = \"The compartment id where worker group resources will be created.\"\n  type        = string\n}\n\nvariable \"network_compartment_id\" {\n  default     = null\n  description = \"The compartment id where network resources will be created.\"\n  type        = string\n}\n\n# Automatically populated by Resource Manager\n# List of regions: https://docs.cloud.oracle.com/iaas/Content/General/Concepts/regions.htm#ServiceAvailabilityAcrossRegions\nvariable \"region\" {\n  default     = \"us-ashburn-1\"\n  description = \"The OCI region where OKE resources will be created.\"\n  type        = string\n}\n\n# List of regions: https://docs.cloud.oracle.com/iaas/Content/General/Concepts/regions.htm#ServiceAvailabilityAcrossRegions\nvariable \"home_region\" {\n  default     = null\n  description = \"The tenancy's home region. Required to perform identity operations.\"\n  type        = string\n}\n\nvariable \"api_fingerprint\" {\n  default     = null\n  description = \"Fingerprint of the API private key to use with OCI API.\"\n  type        = string\n}\n\nvariable \"api_private_key\" {\n  default     = null\n  description = \"The contents of the private key file to use with OCI API, optionally base64-encoded. This takes precedence over private_key_path if both are specified in the provider.\"\n  sensitive   = true\n  type        = string\n}\n\nvariable \"api_private_key_password\" {\n  default     = null\n  description = \"The corresponding private key password to use with the api private key if it is encrypted.\"\n  sensitive   = true\n  type        = string\n}\n\nvariable \"api_private_key_path\" {\n  default     = null\n  description = \"The path to the OCI API private key.\"\n  type        = string\n}\n\nvariable \"config_file_profile\" {\n  default     = \"DEFAULT\"\n  description = \"The profile within the OCI config file to use.\"\n  type        = string\n}\n\nvariable \"create_iam_resources\" {\n  default     = false\n  description = \"Whether to create IAM dynamic groups, policies, and tags. Resources for components may be controlled individually with 'create_iam_*' variables when enabled. Ignored when 'create_iam_resources' is false.\"\n  type        = bool\n}\n\nvariable \"create_iam_autoscaler_policy\" {\n  default     = \"auto\"\n  description = \"Whether to create an IAM dynamic group and policy rules for Cluster Autoscaler management. Depends on configuration of associated component when set to 'auto'. Ignored when 'create_iam_resources' is false.\"\n  type        = string\n  validation {\n    condition     = contains([\"never\", \"auto\", \"always\"], var.create_iam_autoscaler_policy)\n    error_message = \"Accepted values are never, auto, or always\"\n  }\n}\n\nvariable \"create_iam_kms_policy\" {\n  default     = \"auto\"\n  description = \"Whether to create an IAM dynamic group and policy rules for KMS encryption. Depends on configuration of associated components when set to 'auto'. Ignored when 'create_iam_resources' is false.\"\n  type        = string\n  validation {\n    condition     = contains([\"never\", \"auto\", \"always\"], var.create_iam_kms_policy)\n    error_message = \"Accepted values are never, auto, or always\"\n  }\n}\n\nvariable \"create_iam_operator_policy\" {\n  default     = \"auto\"\n  description = \"Whether to create an IAM dynamic group and policy rules for operator access to the OKE control plane. Depends on configuration of associated components when set to 'auto'. Ignored when 'create_iam_resources' is false.\"\n  type        = string\n  validation {\n    condition     = contains([\"never\", \"auto\", \"always\"], var.create_iam_operator_policy)\n    error_message = \"Accepted values are never, auto, or always\"\n  }\n}\n\nvariable \"create_iam_worker_policy\" {\n  default     = \"auto\"\n  description = \"Whether to create an IAM dynamic group and policy rules for self-managed worker nodes. Depends on configuration of associated components when set to 'auto'. Ignored when 'create_iam_resources' is false.\"\n  type        = string\n  validation {\n    condition     = contains([\"never\", \"auto\", \"always\"], var.create_iam_worker_policy)\n    error_message = \"Accepted values are never, auto, or always\"\n  }\n}\n\n# Tagging\n\nvariable \"create_iam_tag_namespace\" {\n  default     = false\n  description = \"Whether to create a namespace for defined tags used for IAM policy and tracking. Ignored when 'create_iam_resources' is false.\"\n  type        = bool\n}\n\nvariable \"create_iam_defined_tags\" {\n  default     = false\n  description = \"Whether to create defined tags used for IAM policy and tracking. Ignored when 'create_iam_resources' is false.\"\n  type        = bool\n}\n\nvariable \"use_defined_tags\" {\n  default     = false\n  description = \"Whether to apply defined tags to created resources for IAM policy and tracking.\"\n  type        = bool\n}\n\nvariable \"tag_namespace\" {\n  default     = \"oke\"\n  description = \"The tag namespace for standard OKE defined tags.\"\n  type        = string\n}\n\nvariable \"freeform_tags\" {\n  default = {\n    bastion           = {}\n    cluster           = {}\n    iam               = {}\n    network           = {}\n    operator          = {}\n    persistent_volume = {}\n    service_lb        = {}\n    workers           = {}\n  }\n  description = \"Freeform tags to be applied to created resources.\"\n  type        = any\n}\n\nvariable \"defined_tags\" {\n  default = {\n    bastion           = {}\n    cluster           = {}\n    iam               = {}\n    network           = {}\n    operator          = {}\n    persistent_volume = {}\n    service_lb        = {}\n    workers           = {}\n  }\n  description = \"Defined tags to be applied to created resources. Must already exist in the tenancy.\"\n  type        = any\n}\n\n# Individual inputs better suited to Resource Manager are merged in locals\n\nvariable \"bastion_defined_tags\" {\n  type        = map(string)\n  description = \"Defined tags applied to created resources.\"\n  default     = {}\n}\nvariable \"bastion_freeform_tags\" {\n  type        = map(string)\n  description = \"Freeform tags applied to created resources.\"\n  default     = {}\n}\nvariable \"cluster_defined_tags\" {\n  type        = map(string)\n  description = \"Defined tags applied to created resources.\"\n  default     = {}\n}\nvariable \"cluster_freeform_tags\" {\n  type        = map(string)\n  description = \"Freeform tags applied to created resources.\"\n  default     = {}\n}\nvariable \"iam_defined_tags\" {\n  type        = map(string)\n  description = \"Defined tags applied to created resources.\"\n  default     = {}\n}\nvariable \"iam_freeform_tags\" {\n  type        = map(string)\n  description = \"Freeform tags applied to created resources.\"\n  default     = {}\n}\nvariable \"network_defined_tags\" {\n  type        = map(string)\n  description = \"Defined tags applied to created resources.\"\n  default     = {}\n}\nvariable \"network_freeform_tags\" {\n  type        = map(string)\n  description = \"Freeform tags applied to created resources.\"\n  default     = {}\n}\nvariable \"operator_defined_tags\" {\n  type        = map(string)\n  description = \"Defined tags applied to created resources.\"\n  default     = {}\n}\nvariable \"operator_freeform_tags\" {\n  type        = map(string)\n  description = \"Freeform tags applied to created resources.\"\n  default     = {}\n}\nvariable \"persistent_volume_defined_tags\" {\n  type        = map(string)\n  description = \"Defined tags applied to created resources.\"\n  default     = {}\n}\nvariable \"persistent_volume_freeform_tags\" {\n  type        = map(string)\n  description = \"Freeform tags applied to created resources.\"\n  default     = {}\n}\nvariable \"service_lb_defined_tags\" {\n  type        = map(string)\n  description = \"Defined tags applied to created resources.\"\n  default     = {}\n}\nvariable \"service_lb_freeform_tags\" {\n  type        = map(string)\n  description = \"Freeform tags applied to created resources.\"\n  default     = {}\n}\nvariable \"workers_defined_tags\" {\n  type        = map(string)\n  description = \"Defined tags applied to created resources.\"\n  default     = {}\n}\nvariable \"workers_freeform_tags\" {\n  type        = map(string)\n  description = \"Freeform tags applied to created resources.\"\n  default     = {}\n}\n"
  },
  {
    "path": "variables-network.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nvariable \"create_vcn\" {\n  default     = true\n  description = \"Whether to create a Virtual Cloud Network.\"\n  type        = bool\n}\n\nvariable \"vcn_name\" {\n  default     = null\n  description = \"Display name for the created VCN. Defaults to 'oke' suffixed with the generated Terraform 'state_id' value.\"\n  type        = string\n}\n\nvariable \"vcn_id\" {\n  default     = null\n  description = \"Optional ID of existing VCN. Takes priority over vcn_name filter. Ignored when `create_vcn = true`.\"\n  type        = string\n}\n\nvariable \"vcn_create_nat_gateway\" {\n  default     = \"auto\"\n  description = \"Whether to create a NAT gateway with the VCN. Defaults to automatic creation when private network resources are expected to utilize it.\"\n  type        = string\n  validation {\n    condition     = contains([\"never\", \"auto\", \"always\"], var.vcn_create_nat_gateway)\n    error_message = \"Accepted values are never, auto, or always\"\n  }\n}\n\nvariable \"vcn_create_internet_gateway\" {\n  default     = \"auto\"\n  description = \"Whether to create an internet gateway with the VCN. Defaults to automatic creation when public network resources are expected to utilize it.\"\n  type        = string\n  validation {\n    condition     = contains([\"never\", \"auto\", \"always\"], var.vcn_create_internet_gateway)\n    error_message = \"Accepted values are never, auto, or always\"\n  }\n}\n\nvariable \"vcn_create_service_gateway\" {\n  default     = \"always\"\n  description = \"Whether to create a service gateway with the VCN. Defaults to always created.\"\n  type        = string\n  validation {\n    condition     = contains([\"never\", \"auto\", \"always\"], var.vcn_create_service_gateway)\n    error_message = \"Accepted values are never, auto, or always\"\n  }\n}\n\nvariable \"vcn_enable_ipv6_gua\" {\n  default     = true\n  description = \"Whether to enable IPv6 GUA when IPv6 is enabled.\"\n  type        = bool\n}\n\nvariable \"vcn_ipv6_ula_cidrs\" {\n  default     = []\n  description = \"IPv6 ULA CIDR blocks to be used for the VCN.\"\n  type        = list(string)\n}\n\nvariable \"internet_gateway_id\" {\n  default     = null\n  description = \"Optional ID of existing Internet gateway in VCN.\"\n  type        = string\n}\n\nvariable \"ig_route_table_id\" {\n  default     = null\n  description = \"Optional ID of existing internet gateway route table in VCN.\"\n  type        = string\n}\n\nvariable \"nat_gateway_id\" {\n  default     = null\n  description = \"Optional ID of existing NAT gateway in VCN.\"\n  type        = string\n}\n\nvariable \"nat_route_table_id\" {\n  default     = null\n  description = \"Optional ID of existing NAT gateway route table in VCN.\"\n  type        = string\n}\n\nvariable \"igw_ngw_mixed_route_id\" {\n  default     = null\n  description = \"Optional ID of the existing route table in VCN using IGW for IPv6 and NGW for IPv4.\"\n  type        = string\n}\n\nvariable \"create_drg\" {\n  default     = false\n  description = \"Whether to create a Dynamic Routing Gateway and attach it to the VCN.\"\n  type        = bool\n}\n\nvariable \"drg_display_name\" {\n  default     = null\n  description = \"(Updatable) Name of the created Dynamic Routing Gateway. Does not have to be unique. Defaults to 'oke' suffixed with the generated Terraform 'state_id' value.\"\n  type        = string\n}\n\nvariable \"drg_id\" {\n  default     = null\n  description = \"ID of an external created Dynamic Routing Gateway to be attached to the VCN.\"\n  type        = string\n}\n\nvariable \"drg_compartment_id\" {\n  default     = null\n  description = \"Compartment for the DRG resource. Can be used to override network_compartment_id.\"\n  type        = string\n}\n\nvariable \"drg_attachments\" {\n  description = \"DRG attachment configurations.\"\n  type        = any\n  default     = {}\n}\n\nvariable \"remote_peering_connections\" {\n  description = \"Map of parameters to add and optionally to peer to remote peering connections. Key-only items represent local acceptors and no peering attempted; items containing key and values represent local requestor and must have the OCID and region of the remote acceptor to peer to\"\n  type        = map(any)\n  default     = {}\n}\n\nvariable \"internet_gateway_route_rules\" {\n  default     = null\n  description = \"(Updatable) List of routing rules to add to Internet Gateway Route Table.\"\n  type        = list(map(string))\n}\n\nvariable \"local_peering_gateways\" {\n  default     = null\n  description = \"Map of Local Peering Gateways to attach to the VCN.\"\n  type        = map(any)\n}\n\nvariable \"lockdown_default_seclist\" {\n  default     = true\n  description = \"Whether to remove all default security rules from the VCN Default Security List.\"\n  type        = bool\n}\n\nvariable \"nat_gateway_route_rules\" {\n  default     = null\n  description = \"(Updatable) List of routing rules to add to NAT Gateway Route Table.\"\n  type        = list(map(string))\n}\n\nvariable \"nat_gateway_public_ip_id\" {\n  default     = null\n  description = \"OCID of reserved IP address for NAT gateway. The reserved public IP address needs to be manually created.\"\n  type        = string\n}\n\nvariable \"subnets\" {\n  default = {\n    bastion  = { newbits = 13, ipv6_cidr = \"8, 0\" }\n    operator = { newbits = 13, ipv6_cidr = \"8, 1\" }\n    cp       = { newbits = 13, ipv6_cidr = \"8, 2\" }\n    int_lb   = { newbits = 11, ipv6_cidr = \"8, 3\" }\n    pub_lb   = { newbits = 11, ipv6_cidr = \"8, 4\" }\n    workers  = { newbits = 4, ipv6_cidr = \"8, 5\" }\n    pods     = { newbits = 2, ipv6_cidr = \"8, 6\" }\n  }\n  description = \"Configuration for standard subnets. The 'create' parameter of each entry defaults to 'auto', creating subnets when other enabled components are expected to utilize them, and may be configured with 'never' or 'always' to force disabled/enabled.\"\n  type = map(object({\n    create       = optional(string)\n    id           = optional(string)\n    newbits      = optional(string)\n    netnum       = optional(string)\n    cidr         = optional(string)\n    display_name = optional(string)\n    dns_label    = optional(string)\n    ipv6_cidr    = optional(string)\n  }))\n  validation {\n    condition = alltrue([\n      for k, v in var.subnets : contains([\"never\", \"auto\", \"always\"], coalesce(v.create, \"auto\"))\n    ])\n    error_message = \"Accepted values for 'create' are 'never', 'auto', or 'always'.\"\n  }\n  validation {\n    condition = alltrue([\n      for v in flatten([for k, v in var.subnets : keys(v)]) : contains([\"create\", \"id\", \"cidr\", \"netnum\", \"newbits\", \"display_name\", \"dns_label\", \"ipv6_cidr\"], v)\n    ])\n    error_message = format(\"Invalid subnet configuration keys: %s\", jsonencode(distinct([\n      for v in flatten([for k, v in var.subnets : keys(v)]) : v if !contains([\"create\", \"id\", \"cidr\", \"netnum\", \"newbits\", \"display_name\", \"dns_label\", \"ipv6_cidr\"], v)\n    ])))\n  }\n}\n\nvariable \"nsgs\" {\n  default = {\n    bastion  = {}\n    operator = {}\n    cp       = {}\n    int_lb   = {}\n    pub_lb   = {}\n    workers  = {}\n    pods     = {}\n  }\n  description = \"Configuration for standard network security groups (NSGs).  The 'create' parameter of each entry defaults to 'auto', creating NSGs when other enabled components are expected to utilize them, and may be configured with 'never' or 'always' to force disabled/enabled.\"\n  type = map(object({\n    create = optional(string)\n    id     = optional(string)\n  }))\n  validation {\n    condition = alltrue([\n      for k, v in values(var.nsgs) : contains([\"never\", \"auto\", \"always\"], coalesce(v.create, \"auto\"))\n    ])\n    error_message = \"Accepted values for 'create' are 'never', 'auto', or 'always'.\"\n  }\n  validation {\n    condition = alltrue([\n      for v in flatten([for k, v in var.nsgs : keys(v)]) : contains([\"create\", \"id\"], v)\n    ])\n    error_message = format(\"Invalid NSG configuration keys: %s\", jsonencode(distinct([\n      for v in flatten([for k, v in var.nsgs : keys(v)]) : v if !contains([\"create\", \"id\"], v)\n    ])))\n  }\n  validation {\n    condition = alltrue([\n      for k, v in var.nsgs :\n      contains([\"bastion\", \"operator\", \"cp\", \"int_lb\", \"pub_lb\", \"workers\", \"pods\", \"fss\"], k)\n    ])\n    error_message = format(\"Invalid NSG keys: %s\", jsonencode([for k, v in var.nsgs : k\n      if !contains([\"bastion\", \"operator\", \"cp\", \"int_lb\", \"pub_lb\", \"workers\", \"pods\", \"fss\"], k)\n    ]))\n  }\n}\n\nvariable \"vcn_cidrs\" {\n  default     = [\"10.0.0.0/16\"]\n  description = \"The list of IPv4 CIDR blocks the VCN will use.\"\n  type        = list(string)\n}\n\nvariable \"vcn_dns_label\" {\n  default     = null\n  description = \"A DNS label for the VCN, used in conjunction with the VNIC's hostname and subnet's DNS label to form a fully qualified domain name (FQDN) for each VNIC within this subnet. Defaults to the generated Terraform 'state_id' value.\"\n  type        = string\n}\n\nvariable \"assign_dns\" {\n  default     = true\n  description = \"Whether to assign DNS records to created instances or disable DNS resolution of hostnames in the VCN.\"\n  type        = bool\n}\n\nvariable \"allow_node_port_access\" {\n  default     = false\n  description = \"Whether to allow access from worker NodePort range to load balancers.\"\n  type        = bool\n}\n\nvariable \"allow_worker_internet_access\" {\n  default     = true\n  description = \"Allow worker nodes to egress to internet. Required if container images are in a registry other than OCIR.\"\n  type        = bool\n}\n\nvariable \"allow_pod_internet_access\" {\n  default     = true\n  description = \"Allow pods to egress to internet. Ignored when cni_type != 'npn'.\"\n  type        = bool\n}\n\nvariable \"allow_worker_ssh_access\" {\n  default     = false\n  description = \"Whether to allow SSH access to worker nodes.\"\n  type        = bool\n}\n\nvariable \"allow_bastion_cluster_access\" {\n  default     = false\n  description = \"Whether to allow access to the Kubernetes cluster endpoint from the bastion host.\"\n  type        = bool\n}\n\nvariable \"allow_rules_cp\" {\n  default     = {}\n  description = \"A map of additional rules to allow traffic for the OKE control plane.\"\n  type        = any\n}\n\nvariable \"allow_rules_internal_lb\" {\n  default     = {}\n  description = \"A map of additional rules to allow incoming traffic for internal load balancers.\"\n  type        = any\n}\n\nvariable \"allow_rules_pods\" {\n  default     = {}\n  description = \"A map of additional rules to allow traffic for the pods.\"\n  type        = any\n}\n\nvariable \"allow_rules_public_lb\" {\n  default     = {}\n  description = \"A map of additional rules to allow incoming traffic for public load balancers.\"\n  type        = any\n}\n\nvariable \"allow_rules_workers\" {\n  default     = {}\n  description = \"A map of additional rules to allow traffic for the workers.\"\n  type        = any\n}\n\nvariable \"control_plane_allowed_cidrs\" {\n  default     = []\n  description = \"The list of CIDR blocks from which the control plane can be accessed.\"\n  type        = list(string)\n}\n\nvariable \"enable_waf\" {\n  description = \"Whether to enable WAF monitoring of load balancers.\"\n  type        = bool\n  default     = false\n}\n\nvariable \"use_stateless_rules\" {\n  description = \"(experimental) Create NSGs with stateless rules instead of the default stateful rules.\"\n  type        = bool\n  default     = false\n}"
  },
  {
    "path": "variables-operator.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nvariable \"create_operator\" {\n  default     = true\n  description = \"Whether to create an operator server in a private subnet.\"\n  type        = bool\n}\n\nvariable \"operator_availability_domain\" {\n  default     = null\n  description = \"The availability domain for operator placement. Defaults to first available.\"\n  type        = string\n}\n\nvariable \"operator_cloud_init\" {\n  default     = []\n  description = \"List of maps containing cloud init MIME part configuration for operator host. See https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/cloudinit_config.html#part for expected schema of each element.\"\n  type        = list(map(string))\n}\n\nvariable \"operator_nsg_ids\" {\n  description = \"An optional and updatable list of network security groups that the operator will be part of.\"\n  default     = []\n  type        = list(string)\n}\n\nvariable \"operator_user\" {\n  default     = \"opc\"\n  description = \"User for SSH access to operator host.\"\n  type        = string\n}\n\nvariable \"operator_image_id\" {\n  default     = null\n  description = \"Image ID for created operator instance.\"\n  type        = string\n}\n\nvariable \"operator_image_os\" {\n  default     = \"Oracle Linux\"\n  description = \"Operator image operating system name when operator_image_type = 'platform'.\"\n  type        = string\n}\n\nvariable \"operator_image_os_version\" {\n  default     = \"8\"\n  description = \"Operator image operating system version when operator_image_type = 'platform'.\"\n  type        = string\n}\n\nvariable \"operator_image_type\" {\n  default     = \"platform\"\n  description = \"Whether to use a platform or custom image for the created operator instance. When custom is set, the operator_image_id must be specified.\"\n  type        = string\n  validation {\n    condition     = contains([\"custom\", \"platform\"], var.operator_image_type)\n    error_message = \"Accepted values are custom or platform\"\n  }\n}\n\nvariable \"operator_install_helm\" {\n  default     = true\n  description = \"Whether to install Helm on the created operator host.\"\n  type        = bool\n}\n\nvariable \"operator_install_helm_from_repo\" {\n  default     = false\n  description = \"Whether to install Helm from the repo on the created operator host.\"\n  type        = bool\n}\n\nvariable \"operator_install_oci_cli_from_repo\" {\n  default     = false\n  description = \"Whether to install OCI from repo on the created operator host.\"\n  type        = bool\n}\n\nvariable \"operator_install_istioctl\" {\n  default     = false\n  description = \"Whether to install istioctl on the created operator host.\"\n  type        = bool\n}\n\nvariable \"operator_install_k8sgpt\" {\n  default     = false\n  description = \"Whether to install k8sgpt on the created operator host. NOTE: Provided only as a convenience and not supported by or sourced from Oracle - use at your own risk.\"\n  type        = bool\n}\n\nvariable \"operator_install_k9s\" {\n  default     = false\n  description = \"Whether to install k9s on the created operator host. NOTE: Provided only as a convenience and not supported by or sourced from Oracle - use at your own risk.\"\n  type        = bool\n}\n\nvariable \"operator_install_kubectl_from_repo\" {\n  default     = true\n  description = \"Whether to install kubectl from the repo on the created operator host.\"\n  type        = bool\n}\n\nvariable \"operator_install_kubectx\" {\n  default     = true\n  description = \"Whether to install kubectx/kubens on the created operator host. NOTE: Provided only as a convenience and not supported by or sourced from Oracle - use at your own risk.\"\n  type        = bool\n}\n\nvariable \"operator_install_stern\" {\n  default     = false\n  description = \"Whether to install stern on the created operator host. NOTE: Provided only as a convenience and not supported by or sourced from Oracle - use at your own risk.\"\n  type        = bool\n}\n\nvariable \"operator_shape\" {\n  default = {\n    shape                     = \"VM.Standard.E4.Flex\",\n    ocpus                     = 1,\n    memory                    = 4,\n    boot_volume_size          = 50,\n    baseline_ocpu_utilization = 100\n  }\n  description = \"Shape of the created operator instance. Baseline OCPU utilization can be used to provision <a href=https://docs.oracle.com/en-us/iaas/Content/Compute/References/burstable-instances.htm>burstable shapes.</a>\"\n  type        = map(any)\n}\n\nvariable \"operator_volume_kms_key_id\" {\n  default     = null\n  description = \"The OCID of the OCI KMS key to assign as the master encryption key for the operator host boot volume.\"\n  type        = string\n}\n\nvariable \"operator_pv_transit_encryption\" {\n  default     = false\n  description = \"Whether to enable in-transit encryption for the data volume's paravirtualized attachment.\"\n  type        = bool\n}\n\nvariable \"operator_upgrade\" {\n  default     = false\n  description = \"Whether to upgrade operator packages after provisioning.\"\n  type        = bool\n}\n\nvariable \"operator_private_ip\" {\n  default     = null\n  description = \"The IP address of an existing operator host. Ignored when create_operator = true.\"\n  type        = string\n}\n\nvariable \"operator_await_cloudinit\" {\n  default     = true\n  description = \"Whether to block until successful connection to operator and completion of cloud-init.\"\n  type        = bool\n}\n\nvariable \"operator_legacy_imds_endpoints_disabled\" {\n  default     = true\n  description = \"Whether to disable requests to the IMDSv1 endpoint and only allow requests to the IMDSv2 endpoint for the operator instance.\"\n  type        = bool\n}"
  },
  {
    "path": "variables-utilities.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nvariable \"await_node_readiness\" {\n  default     = \"none\"\n  description = \"Optionally block completion of Terraform apply until one/all worker nodes become ready.\"\n  type        = string\n\n  validation {\n    condition     = contains([\"none\", \"one\", \"all\"], var.await_node_readiness)\n    error_message = \"Accepted values are 'none', 'one' or 'all'.\"\n  }\n}\n\n# Oracle Container Image Registry (OCIR)\n\nvariable \"ocir_email_address\" {\n  default     = null\n  description = \"The email address used for the Oracle Container Image Registry (OCIR).\"\n  type        = string\n}\n\nvariable \"ocir_secret_id\" {\n  default     = null\n  description = \"The OCI Vault secret ID for the OCIR authentication token.\"\n  type        = string\n}\n\nvariable \"ocir_secret_name\" {\n  default     = \"ocirsecret\"\n  description = \"The name of the Kubernetes secret to be created with the OCIR authentication token.\"\n  type        = string\n}\n\nvariable \"ocir_secret_namespace\" {\n  default     = \"default\"\n  description = \"The Kubernetes namespace in which to create the OCIR secret.\"\n  type        = string\n}\n\nvariable \"ocir_username\" {\n  default     = null\n  description = \"A username with access to the OCI Vault secret for OCIR access. Required when 'ocir_secret_id' is provided.\"\n  type        = string\n}\n\n# Worker pool draining\n\nvariable \"worker_drain_ignore_daemonsets\" {\n  default     = true\n  description = \"Whether to ignore DaemonSet-managed Pods when draining worker pools. See <a href=https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#drain>kubectl drain</a> for more information.\"\n  type        = bool\n}\n\nvariable \"worker_drain_delete_local_data\" {\n  default     = true\n  description = \"Whether to accept removal of data stored locally on draining worker pools. See <a href=https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#drain>kubectl drain</a> for more information.\"\n  type        = bool\n}\n\nvariable \"worker_drain_timeout_seconds\" {\n  default     = 900\n  description = \"The length of time to wait before giving up on draining nodes in a pool. See <a href=https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#drain>kubectl drain</a> for more information.\"\n  type        = number\n}\n"
  },
  {
    "path": "variables-workers.tf",
    "content": "# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\n#\n# Cluster\n#\n\nvariable \"cluster_id\" {\n  default     = null\n  description = \"An existing OKE cluster OCID when `create_cluster = false`.\"\n  type        = string\n}\n\nvariable \"cluster_ca_cert\" {\n  default     = null\n  description = \"Base64+PEM-encoded cluster CA certificate for unmanaged instance pools. Determined automatically when 'create_cluster' = true or 'cluster_id' is provided.\"\n  type        = string\n}\n\nvariable \"cluster_dns\" {\n  default     = null\n  description = \"Cluster DNS resolver IP address. Determined automatically when not set (recommended).\"\n  type        = string\n}\n\n#\n# Worker pools\n#\n\nvariable \"worker_pools\" {\n  default     = {}\n  description = \"Tuple of OKE worker pools where each key maps to the OCID of an OCI resource, and value contains its definition.\"\n  type        = any\n}\n\nvariable \"worker_pool_mode\" {\n  default     = \"node-pool\"\n  description = \"Default management mode for workers when unspecified on a pool.\"\n  type        = string\n  validation {\n    condition = contains([\n      \"node-pool\",\n      \"virtual-node-pool\",\n      \"instance\",\n      \"instance-pool\",\n      \"cluster-network\",\n      \"compute-cluster\",\n      \"gpu-memory-cluster\"\n    ], var.worker_pool_mode)\n    error_message = \"Accepted values are node-pool, virtual-node-pool, instance, instance-pool, cluster-network, compute-cluster, or gpu-memory-cluster.\"\n  }\n}\n\nvariable \"worker_pool_size\" {\n  default     = 0\n  description = \"Default size for worker pools when unspecified on a pool.\"\n  type        = number\n}\n\n#\n# Workers: Compute clusters\n#\n\nvariable \"worker_compute_clusters\" {\n  default     = {}\n  description = \"Whether to create compute clusters shared by nodes across multiple worker pools enabled for 'compute-cluster'.\"\n  type        = map(any)\n}\n\n#\n# Workers: GPU memory clusters\n#\n\nvariable \"worker_gmc_scale_is_upsize_enabled\" {\n  default     = true\n  description = \"Default for gpu_memory_cluster_scale_config.is_upsize_enabled when unspecified on a 'gpu-memory-cluster' pool. When true, the OCI control plane may grow the GPU Memory Cluster toward target_size.\"\n  type        = bool\n}\n\nvariable \"worker_gmc_scale_is_downsize_enabled\" {\n  default     = true\n  description = \"Default for gpu_memory_cluster_scale_config.is_downsize_enabled when unspecified on a 'gpu-memory-cluster' pool. When true, the OCI control plane may shrink the GPU Memory Cluster toward target_size.\"\n  type        = bool\n}\n\nvariable \"worker_gmc_scale_target_size\" {\n  default     = 18\n  description = \"Default for gpu_memory_cluster_scale_config.target_size when unspecified on a 'gpu-memory-cluster' pool. The desired GPU Memory Cluster size that the OCI control plane converges toward.\"\n  type        = number\n}\n\n#\n# Workers: network\n#\n\nvariable \"worker_is_public\" {\n  default     = false\n  description = \"Whether to provision workers with public IPs allocated by default when unspecified on a pool. It should be true when creating dual-stack clusters.\"\n  type        = bool\n}\n\nvariable \"worker_nsg_ids\" {\n  default     = []\n  description = \"An additional list of network security group (NSG) IDs for node security. Combined with 'nsg_ids' specified on each pool.\"\n  type        = list(string)\n}\n\nvariable \"pod_nsg_ids\" {\n  default     = []\n  description = \"An additional list of network security group (NSG) IDs for pod security. Combined with 'pod_nsg_ids' specified on each pool.\"\n  type        = list(string)\n}\n\nvariable \"kubeproxy_mode\" {\n  default     = \"iptables\"\n  description = \"The mode in which to run kube-proxy when unspecified on a pool.\"\n  type        = string\n\n  validation {\n    condition     = contains([\"iptables\", \"ipvs\"], var.kubeproxy_mode)\n    error_message = \"Accepted values are iptables or ipvs.\"\n  }\n}\n\n#\n# Workers: instance\n#\n\nvariable \"worker_block_volume_type\" {\n  default     = \"paravirtualized\"\n  description = \"Default block volume attachment type for Instance Configurations when unspecified on a pool.\"\n  type        = string\n  validation {\n    condition     = contains([\"iscsi\", \"paravirtualized\"], var.worker_block_volume_type)\n    error_message = \"Accepted values are 'iscsi' or 'paravirtualized'.\"\n  }\n}\n\nvariable \"worker_node_labels\" {\n  default     = {}\n  description = \"Default worker node labels. Merged with labels defined on each pool.\"\n  type        = map(string)\n}\n\nvariable \"worker_node_metadata\" {\n  default     = {}\n  description = \"Map of additional worker node instance metadata. Merged with metadata defined on each pool.\"\n  type        = map(string)\n}\n\nvariable \"worker_image_id\" {\n  default     = null\n  description = \"Default image for worker pools  when unspecified on a pool.\"\n  type        = string\n}\n\nvariable \"worker_image_type\" {\n  default     = \"oke\"\n  description = \"Whether to use a platform, OKE, or custom image for worker nodes by default when unspecified on a pool. When custom is set, the worker_image_id must be specified.\"\n  type        = string\n  validation {\n    condition     = contains([\"custom\", \"oke\", \"platform\"], var.worker_image_type)\n    error_message = \"Accepted values are custom, oke, platform\"\n  }\n}\n\nvariable \"worker_image_os\" {\n  default     = \"Oracle Linux\"\n  description = \"Default worker image operating system name when worker_image_type = 'oke' or 'platform' and unspecified on a pool.\"\n  type        = string\n}\n\nvariable \"worker_image_os_version\" {\n  default     = \"8\"\n  description = \"Default worker image operating system version when worker_image_type = 'oke' or 'platform' and unspecified on a pool.\"\n  type        = string\n}\n\nvariable \"worker_shape\" {\n  default = {\n    shape            = \"VM.Standard.E4.Flex\"\n    ocpus            = 2\n    memory           = 16\n    boot_volume_size = 50\n\n    # https://docs.oracle.com/en-us/iaas/Content/Block/Concepts/blockvolumeperformance.htm\n    # Supported for mode = \"cluster-network\" | \"instance-pool\" | \"instance\" (self-managed) only\n    boot_volume_vpus_per_gb = 10 # 10: Balanced, 20: High, 30-120: Ultra High (requires multipath)\n  }\n  description = \"Default shape of the created worker instance when unspecified on a pool.\"\n  type        = map(any)\n}\n\nvariable \"worker_capacity_reservation_id\" {\n  default     = null\n  description = \"The ID of the Compute capacity reservation the worker node will be launched under. See <a href=https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/reserve-capacity.htm>Capacity Reservations</a> for more information.\"\n  type        = string\n}\n\nvariable \"worker_preemptible_config\" {\n  default = {\n    enable                  = false,\n    is_preserve_boot_volume = false\n  }\n  description = \"Default preemptible Compute configuration when unspecified on a pool. See <a href=https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengusingpreemptiblecapacity.htm>Preemptible Worker Nodes</a> for more information.\"\n  type        = map(any)\n}\n\nvariable \"worker_cloud_init\" {\n  default     = []\n  description = \"List of maps containing cloud init MIME part configuration for worker nodes. Merged with pool-specific definitions. See https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/cloudinit_config.html#part for expected schema of each element.\"\n  type        = list(map(string))\n}\n\nvariable \"worker_disable_default_cloud_init\" {\n  default     = false\n  description = \"Whether to disable the default OKE cloud init and only use the cloud init explicitly passed to the worker pool in 'worker_cloud_init'.\"\n  type        = bool\n}\n\nvariable \"worker_volume_kms_key_id\" {\n  default     = null\n  description = \"The ID of the OCI KMS key to be used as the master encryption key for Boot Volume and Block Volume encryption by default when unspecified on a pool.\"\n  type        = string\n}\n\nvariable \"worker_pv_transit_encryption\" {\n  default     = false\n  description = \"Whether to enable in-transit encryption for the data volume's paravirtualized attachment by default when unspecified on a pool.\"\n  type        = bool\n}\n\nvariable \"worker_legacy_imds_endpoints_disabled\" {\n  default     = false\n  description = \"Whether to disable requests to the IMDSv1 endpoint and only allow requests to the IMDSv2 endpoint.  See <a href=https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengconfiguringimds.htm>Instance Metadata</a> for more information.\"\n  type        = bool\n}\n\nvariable \"max_pods_per_node\" {\n  default     = 31\n  description = \"The default maximum number of pods to deploy per node when unspecified on a pool. Absolute maximum is 110. Ignored when when cni_type != 'npn'.\"\n  type        = number\n\n  validation {\n    condition     = var.max_pods_per_node > 0 && var.max_pods_per_node <= 110\n    error_message = \"Must be between 1 and 110.\"\n  }\n}\n\nvariable \"platform_config\" {\n  default     = null\n  description = \"Default platform_config for self-managed worker pools created with mode: 'instance', 'instance-pool', or 'cluster-network'. See <a href=https://docs.oracle.com/en-us/iaas/api/#/en/iaas/20160918/datatypes/PlatformConfig>PlatformConfig</a> for more information.\"\n  type = object({\n    type                                           = optional(string),\n    are_virtual_instructions_enabled               = optional(bool),\n    is_access_control_service_enabled              = optional(bool),\n    is_input_output_memory_management_unit_enabled = optional(bool),\n    is_measured_boot_enabled                       = optional(bool),\n    is_memory_encryption_enabled                   = optional(bool),\n    is_secure_boot_enabled                         = optional(bool),\n    is_symmetric_multi_threading_enabled           = optional(bool),\n    is_trusted_platform_module_enabled             = optional(bool),\n    numa_nodes_per_socket                          = optional(number),\n    percentage_of_cores_enabled                    = optional(bool),\n  })\n}\n\nvariable \"agent_config\" {\n  default     = null\n  description = \"Default agent_config for self-managed worker pools created with mode: 'instance', 'instance-pool', or 'cluster-network'. See <a href=https://docs.oracle.com/en-us/iaas/api/#/en/iaas/20160918/datatypes/InstanceAgentConfig for more information.\"\n  type = object({\n    are_all_plugins_disabled = bool,\n    is_management_disabled   = bool,\n    is_monitoring_disabled   = bool,\n    plugins_config           = map(string),\n  })\n}\n\nvariable \"allow_short_container_image_names\" {\n  default     = false\n  description = \"Whether to allow short container image names for K8s version >= 1.34.0. See <a href=https://github.com/cri-o/cri-o/pull/9401>CRI-O pull request</a> for more information.\"\n  type        = bool\n}"
  },
  {
    "path": "versions.tf",
    "content": "# Copyright (c) 2017, 2023 Oracle Corporation and/or its affiliates.\n# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl\n\nterraform {\n  required_version = \">= 1.3.0\"\n\n  required_providers {\n    cloudinit = {\n      source  = \"hashicorp/cloudinit\"\n      version = \">= 2.2.0\"\n    }\n\n    helm = {\n      source  = \"hashicorp/helm\"\n      version = \">= 3.0.1\"\n    }\n\n    null = {\n      source  = \"hashicorp/null\"\n      version = \">= 3.2.1\"\n    }\n\n    oci = {\n      configuration_aliases = [oci.home]\n      source                = \"oracle/oci\"\n      version               = \">= 8.2.0\"\n    }\n\n    random = {\n      source  = \"hashicorp/random\"\n      version = \">= 3.4.3\"\n    }\n\n    time = {\n      source  = \"hashicorp/time\"\n      version = \">= 0.9.1\"\n    }\n  }\n}\n"
  }
]