From 80207c4158a521f1c66cfeaf2d70769164f994bd Mon Sep 17 00:00:00 2001 From: schadalawada Date: Mon, 29 Apr 2024 11:36:06 -0700 Subject: [PATCH 1/2] feat: onboarding NGINX module --- CONTRIBUTING.md | 30 ---- LICENSE | 201 ---------------------- README.md | 131 +++----------- examples/nginx/nginx-cluster/README.md | 28 +++ examples/nginx/nginx-cluster/main.tf | 43 +++++ examples/nginx/nginx-cluster/outputs.tf | 4 + examples/nginx/nginx-cluster/variables.tf | 18 ++ examples/nginx/nginx-cluster/versions.tf | 9 + examples/nginx/nginx-ha/README.md | 28 +++ examples/nginx/nginx-ha/main.tf | 57 ++++++ examples/nginx/nginx-ha/outputs.tf | 4 + examples/nginx/nginx-ha/variables.tf | 21 +++ examples/nginx/nginx-ha/versions.tf | 9 + examples/nginx/nginx-single/README.md | 28 +++ examples/nginx/nginx-single/main.tf | 38 ++++ examples/nginx/nginx-single/outputs.tf | 4 + examples/nginx/nginx-single/variables.tf | 18 ++ examples/nginx/nginx-single/versions.tf | 9 + examples/simple/README.md | 47 ----- examples/simple/main.tf | 12 -- examples/simple/outputs.tf | 24 --- examples/simple/variables.tf | 21 --- main.tf | 50 ------ modules/inline-module/README.md | 49 ------ modules/inline-module/main.tf | 37 ---- modules/inline-module/outputs.tf | 17 -- modules/inline-module/variables.tf | 14 -- modules/nginx/README.md | 89 ++++++++++ modules/nginx/main.tf | 99 +++++++++++ modules/nginx/outputs.tf | 74 ++++++++ modules/nginx/variables.tf | 144 ++++++++++++++++ modules/nginx/versions.tf | 9 + outputs.tf | 24 --- scripts/template-script.sh | 1 - templates/template-file.tftpl | 1 - variables.tf | 21 --- 36 files changed, 756 insertions(+), 657 deletions(-) delete mode 100644 CONTRIBUTING.md delete mode 100644 LICENSE create mode 100644 examples/nginx/nginx-cluster/README.md create mode 100644 examples/nginx/nginx-cluster/main.tf create mode 100644 examples/nginx/nginx-cluster/outputs.tf create mode 100644 examples/nginx/nginx-cluster/variables.tf create mode 100644 examples/nginx/nginx-cluster/versions.tf create mode 100644 examples/nginx/nginx-ha/README.md create mode 100644 examples/nginx/nginx-ha/main.tf create mode 100644 examples/nginx/nginx-ha/outputs.tf create mode 100644 examples/nginx/nginx-ha/variables.tf create mode 100644 examples/nginx/nginx-ha/versions.tf create mode 100644 examples/nginx/nginx-single/README.md create mode 100644 examples/nginx/nginx-single/main.tf create mode 100644 examples/nginx/nginx-single/outputs.tf create mode 100644 examples/nginx/nginx-single/variables.tf create mode 100644 examples/nginx/nginx-single/versions.tf delete mode 100644 examples/simple/README.md delete mode 100644 examples/simple/main.tf delete mode 100644 examples/simple/outputs.tf delete mode 100644 examples/simple/variables.tf delete mode 100644 main.tf delete mode 100644 modules/inline-module/README.md delete mode 100644 modules/inline-module/main.tf delete mode 100644 modules/inline-module/outputs.tf delete mode 100644 modules/inline-module/variables.tf create mode 100644 modules/nginx/README.md create mode 100644 modules/nginx/main.tf create mode 100644 modules/nginx/outputs.tf create mode 100644 modules/nginx/variables.tf create mode 100644 modules/nginx/versions.tf delete mode 100644 outputs.tf delete mode 100644 scripts/template-script.sh delete mode 100644 templates/template-file.tftpl delete mode 100644 variables.tf diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index e4e0f87..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,30 +0,0 @@ -# Contributing - -This document provides guidelines for contributing to the module. - -Contributors to this project must abide by the [Contributor Covenant Code of Conduct](CODE_OF_CONDUCT.md). - -## File structure - -The project has the following folders and files: - -- /: root folder. -- /docs: Examples for using this module. -- /examples: Examples for using this module. -- /files: Static files referenced but not executed by Terraform. -- /helpers: Helper scripts NOT called by Terraform. -- /modules: Inline local modules called by this module. -- /scripts: Scripts for specific tasks on module. -- /templates: Template files used to be execute by data sources. -- /main.tf: Main file for this module, contains all the resources to operate the module. -- /variables.tf: All the variables necessary for run the module. -- /output.tf: The outputs generate from the module. -- /README.md: Main repo README document. -- /CHANGELOG.md: Module release changelog file. -- /CODEOWNERS: Module contributing developers. -- /CODE_OF_CONDUCT.md: Code of Conduct file. -- /CONTRIBUTING.md: This file. - -## Issues and Change Requests - -Please submit change requests and / or features via [Issues](https://github.com/equinix-labs/equinix-labs/issues). diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 261eeb9..0000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/README.md b/README.md index e700a23..dc1a606 100644 --- a/README.md +++ b/README.md @@ -1,120 +1,35 @@ -# terraform-equinix-template +# terraform-equinix-network-edge - - -[![Experimental](https://img.shields.io/badge/Stability-Experimental-red.svg)](https://github.com/equinix-labs/standards#about-uniform-standards) -[![run-pre-commit-hooks](https://github.com/equinix-labs/terraform-equinix-template/actions/workflows/pre-commit.yaml/badge.svg)](https://github.com/equinix-labs/terraform-equinix-template/actions/workflows/pre-commit.yaml) -[![generate-terraform-docs](https://github.com/equinix-labs/terraform-equinix-template/actions/workflows/documentation.yaml/badge.svg)](https://github.com/equinix-labs/terraform-equinix-template/actions/workflows/documentation.yaml) +[![Maintainer](https://img.shields.io/badge/maintained%20by-equinix-red?style=flat-square)](https://www.equinix.com/) +[![License](https://img.shields.io/github/license/equinix/terraform-equinix-network-edge?style=flat-square)](LICENSE) +[![Release](https://img.shields.io/github/v/release/equinix/terraform-equinix-network-edge?style=flat-square)](https://github.com/equinix/terraform-equinix-network-edge/releases) +[![Terraform version](https://img.shields.io/badge/terraform-%3E%3D1.5.4-623CE4.svg?style=flat-square&logo=terraform)](https://github.com/hashicorp/terraform) +[![Terraform registry](https://img.shields.io/badge/terraform-registry-623CE4.svg?style=flat-square&logo=terraform)](https://registry.terraform.io/modules/equinix/network-edge/equinix/latest) -`terraform-equinix-template` is a minimal Terraform module that utilizes [Terraform providers for Equinix](https://registry.terraform.io/namespaces/equinix) to provision digital infrastructure and demonstrate higher level integrations. +> This is a empty module that houses multiple submodules for Equinix Network Edge Terraform usage. Please view the Submodules +> and the Examples in this module's registry to view details on what they are and how to leverage them. - +## Equinix Network Edge Developer Documentation -## Usage - -This project is experimental and supported by the user community. Equinix does not provide support for this project. - -Install Terraform using the [tfenv](https://github.com/tfutils/tfenv) utility. - -This project may be forked, cloned, or downloaded and modified as needed as the base in your integrations and deployments. - -This project may also be used as a [Terraform module](https://learn.hashicorp.com/collections/terraform/modules). - -To use this module in a new project, create a file such as: - -```hcl -# main.tf -terraform { - required_providers { - equinix = { - source = "equinix/equinix" - } -} - -module "example" { - source = "github.com/equinix-labs/template" - # TEMPLATE: replace "template" with the name of the repo after the terraform-equinix- prefix. - - # Published modules can be sourced as: - # source = "equinix-labs/template/equinix" - # See https://www.terraform.io/docs/registry/modules/publish.html for details. - - # version = "0.1.0" - - # TEMPLATE: insert required variables here -} -``` - -Install [pre-commit](https://pre-commit.com/#install) with its prerequesites: [python](https://docs.python.org/3/using/index.html) and [pip](https://pip.pypa.io/en/stable/installation/). - -Configure pre-commit: `pre-commit install`. - -Install required packages: [tflint](https://github.com/terraform-linters/tflint), [tfsec](https://aquasecurity.github.io/tfsec/v1.0.11/getting-started/installation/), [shfmt](https://github.com/mvdan/sh), [shellcheck](https://github.com/koalaman/shellcheck), and [markdownlint](https://github.com/markdownlint/markdownlint). - -Run `terraform init -upgrade` and `terraform apply`. - -## Module Documentation - -The main README.md, the modules README.md and the examples README.md are populated by [terraform-docs worflow job](.github/workflows/documentation.yaml). The following sections are appended between the terraform-docs delimeters: Requiremenents, Providers, Modules, Resources, Inputs, and Outputs. - -## Module Release and Changelog Generation - -The module git release and [changelog](CHANGELOG.md) are generated by the [release workflow job](.github/workflows/release.yaml). The release worflow follows the [conventional commits convention](https://www.conventionalcommits.org/). To submit a commit, please follow the [commit message format guidelines](https://www.conventionalcommits.org/en/v1.0.0/#specification). This job is set to run manually by default. - -Example commit message: `fix: disabled log generation for system services` - -For more examples, please see [conventional commit message examples](https://www.conventionalcommits.org/en/v1.0.0/#examples). - -## Examples - -To view examples for how you can leverage this module, please see the [examples](examples/) directory. - - - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.3 | -| [equinix](#requirement\_equinix) | >= 1.8.0 | - -## Providers - -| Name | Version | -|------|---------| -| [equinix](#provider\_equinix) | >= 1.8.1 | +To see the documentation for the APIs that the Network Edge Terraform Provider is built on +and to learn how to procure your own Client_Id and Client_Secret follow the link below: +[Equinix Network Edge Developer Portal](https://developer.equinix.com/docs?page=/dev-docs/NE/overview) ## Modules -| Name | Source | Version | -|------|--------|---------| -| [inline-module](#module\_inline-module) | ./modules/inline-module | n/a | - -## Resources +This repository consists of a collection of modules designed to accelerate your adoption of Equinix Terraform for Network Edge use cases. +Each module is fully independent and dedicated for use as individual modules. They are placed here to organize all Network Edge use cases +and to facilitate efficient discovery and selection of product offerings beyond the base Network Edge data sources and resources. -| Name | Type | -|------|------| -| [equinix_metal_device.example](https://registry.terraform.io/providers/equinix/equinix/latest/docs/resources/metal_device) | resource | +Each module has: -## Inputs +* Terraform source code to be used as a module +* README.md file containing instructions and specific notes to work with the module -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [example\_auth\_token](#input\_example\_auth\_token) | The example auth token value defines what will be included in the example resource in main.tf. This example is descriptive. | `string` | n/a | yes | -| [example\_project\_id](#input\_example\_project\_id) | The example project id value defines what will be included in the example resource in main.tf. This example is descriptive. | `string` | n/a | yes | - -## Outputs - -| Name | Description | -|------|-------------| -| [example\_device\_hostname](#output\_example\_device\_hostname) | The example output. In practice, output value reference implicit resource attributes declared in main.tf | -| [example\_gateway\_id](#output\_example\_gateway\_id) | The example output. In practice, output value reference implicit resource attributes declared in main.tf | - -## Contributing - -If you would like to contribute to this module, see [CONTRIBUTING](CONTRIBUTING.md) page. +## Examples -## License +Each example is a specific use case in Equinix Network Edge that the specific sub-module can be used for. Each example has the following: -Apache License, Version 2.0. See [LICENSE](LICENSE). - +* Terraform code leveraging the module for a simple use case +* Example definition of .tfvars file +* README.md explaining multiple ways the example can be leveraged. diff --git a/examples/nginx/nginx-cluster/README.md b/examples/nginx/nginx-cluster/README.md new file mode 100644 index 0000000..f048f04 --- /dev/null +++ b/examples/nginx/nginx-cluster/README.md @@ -0,0 +1,28 @@ +# Network Edge Device Nginx cluster Device Example + +This example demonstrates creation of Network Edge NGINX HA pair device. It will: + +- Create a management ACL template +- Create a SSH key +- Provision NGINX cluster device + +## Usage + +To provision this example, you should clone the github repository and run terraform from within this directory: + +```bash +git clone https://github.com/equinix-labs/terraform-equinix-nework-edge-device-nginx.git +cd terraform-equinix-nework-edge-device-nginx/examples/nginx-cluster +terraform init +terraform apply +``` + +Note that this example may create resources which cost money. Run 'terraform destroy' when you don't need these resources. + +## Variables + +See for a description of all variables. + +## Outputs + +See for a description of all outputs. diff --git a/examples/nginx/nginx-cluster/main.tf b/examples/nginx/nginx-cluster/main.tf new file mode 100644 index 0000000..854ac27 --- /dev/null +++ b/examples/nginx/nginx-cluster/main.tf @@ -0,0 +1,43 @@ +provider "equinix" { + client_id = var.equinix_client_id + client_secret = var.equinix_client_secret +} + +module "nginx_cluster" { + source = "../../../modules/nginx" + name = "terraform-test-NGINX-cluster1" + metro_code = var.metro_code_primary + account_number = "123456" + platform = "small" + software_package = "STD" + term_length = 1 + notifications = ["test@test.com"] + additional_bandwidth = 50 + mgmt_acl_template_uuid = equinix_network_acl_template.nginx_cluster.id + ssh_key = { + userName = "johndoe" + keyName = equinix_network_ssh_key.jd_cluster.name + } + cluster = { + enabled = true + name = "test-nginx-cluster" + node0_vendor_configuration_hostname = "node0" + node1_vendor_configuration_hostname = "node1" + } +} + +resource "equinix_network_ssh_key" "jd_cluster" { + name = "jd-cluster" + public_key = var.ssh_rsa_public_key +} + +resource "equinix_network_acl_template" "nginx_cluster" { + name = "tf-nginx-cluster" + description = "Cluster NGINX ACL template" + inbound_rule { + subnet = "172.16.25.0/24" + protocol = "TCP" + src_port = "any" + dst_port = "22" + } +} diff --git a/examples/nginx/nginx-cluster/outputs.tf b/examples/nginx/nginx-cluster/outputs.tf new file mode 100644 index 0000000..6302d68 --- /dev/null +++ b/examples/nginx/nginx-cluster/outputs.tf @@ -0,0 +1,4 @@ +output "device_details" { + description = "Virtual device details" + value = module.nginx_cluster +} diff --git a/examples/nginx/nginx-cluster/variables.tf b/examples/nginx/nginx-cluster/variables.tf new file mode 100644 index 0000000..f342f6e --- /dev/null +++ b/examples/nginx/nginx-cluster/variables.tf @@ -0,0 +1,18 @@ +variable "equinix_client_id" { + type = string + description = "API Consumer Key available under 'My Apps' in developer portal. This argument can also be specified with the EQUINIX_API_CLIENTID shell environment variable." +} + +variable "equinix_client_secret" { + type = string + description = "API Consumer secret available under 'My Apps' in developer portal. This argument can also be specified with the EQUINIX_API_CLIENTSECRET shell environment variable." +} + +variable "metro_code_primary" { + description = "Device location metro code" + type = string +} +variable "ssh_rsa_public_key" { + description = "SSH RSA public key" + type = string +} diff --git a/examples/nginx/nginx-cluster/versions.tf b/examples/nginx/nginx-cluster/versions.tf new file mode 100644 index 0000000..8401ebe --- /dev/null +++ b/examples/nginx/nginx-cluster/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.3" + required_providers { + equinix = { + source = "equinix/equinix" + version = "~> 1.34.0" + } + } +} diff --git a/examples/nginx/nginx-ha/README.md b/examples/nginx/nginx-ha/README.md new file mode 100644 index 0000000..a7dd788 --- /dev/null +++ b/examples/nginx/nginx-ha/README.md @@ -0,0 +1,28 @@ +# Network Edge Device Nginx HA pair Device Example + +This example demonstrates creation of Network Edge NGINX HA pair device. It will: + +- Create a management ACL template for primary and secondary device +- Create a SSH key +- Provision NGINX HA pair device + +## Usage + +To provision this example, you should clone the github repository and run terraform from within this directory: + +```bash +git clone https://github.com/equinix-labs/terraform-equinix-nework-edge-device-nginx.git +cd terraform-equinix-nework-edge-device-nginx/examples/nginx-ha +terraform init +terraform apply +``` + +Note that this example may create resources which cost money. Run 'terraform destroy' when you don't need these resources. + +## Variables + +See for a description of all variables. + +## Outputs + +See for a description of all outputs. diff --git a/examples/nginx/nginx-ha/main.tf b/examples/nginx/nginx-ha/main.tf new file mode 100644 index 0000000..fafdf98 --- /dev/null +++ b/examples/nginx/nginx-ha/main.tf @@ -0,0 +1,57 @@ +provider "equinix" { + client_id = var.equinix_client_id + client_secret = var.equinix_client_secret +} + +module "nginx_ha" { + source = "../../../modules/nginx" + name = "terraform-test-NGINX-ha" + hostname = "nginx-pri" + metro_code = var.metro_code_primary + account_number = "123456" + platform = "small" + software_package = "STD" + term_length = 1 + notifications = ["test@test.com"] + additional_bandwidth = 50 + mgmt_acl_template_uuid = equinix_network_acl_template.nginx_pri.id + ssh_key = { + userName = "johndoe-primary" + keyName = equinix_network_ssh_key.johndoe.name + } + secondary = { + enabled = true + metro_code = var.metro_code_secondary + hostname = "nginx-sec" + account_number = "135887" + additional_bandwidth = 50 + mgmt_acl_template_uuid = equinix_network_acl_template.nginx_sec.id + } +} + +resource "equinix_network_ssh_key" "johndoe" { + name = "johndoe-secondary" + public_key = var.ssh_rsa_public_key +} + +resource "equinix_network_acl_template" "nginx_pri" { + name = "tf-nginx-pri" + description = "Primary NGINX management ACL template" + inbound_rule { + subnet = "172.16.25.0/24" + protocol = "TCP" + src_port = "any" + dst_port = "22" + } +} + +resource "equinix_network_acl_template" "nginx_sec" { + name = "tf-vsrx-sec" + description = "Secondary NGINX management ACL template" + inbound_rule { + subnet = "193.39.0.0/16" + protocol = "TCP" + src_port = "any" + dst_port = "22" + } +} diff --git a/examples/nginx/nginx-ha/outputs.tf b/examples/nginx/nginx-ha/outputs.tf new file mode 100644 index 0000000..527c91c --- /dev/null +++ b/examples/nginx/nginx-ha/outputs.tf @@ -0,0 +1,4 @@ +output "device_details" { + description = "Virtual device details" + value = module.nginx_ha +} diff --git a/examples/nginx/nginx-ha/variables.tf b/examples/nginx/nginx-ha/variables.tf new file mode 100644 index 0000000..3483a7e --- /dev/null +++ b/examples/nginx/nginx-ha/variables.tf @@ -0,0 +1,21 @@ +variable "equinix_client_id" { + type = string + description = "API Consumer Key available under 'My Apps' in developer portal. This argument can also be specified with the EQUINIX_API_CLIENTID shell environment variable." +} + +variable "equinix_client_secret" { + type = string + description = "API Consumer secret available under 'My Apps' in developer portal. This argument can also be specified with the EQUINIX_API_CLIENTSECRET shell environment variable." +} +variable "metro_code_primary" { + description = "Primary device location metro code" + type = string +} +variable "metro_code_secondary" { + description = "Secondary device location metro code" + type = string +} +variable "ssh_rsa_public_key" { + description = "SSH RSA public key" + type = string +} diff --git a/examples/nginx/nginx-ha/versions.tf b/examples/nginx/nginx-ha/versions.tf new file mode 100644 index 0000000..8401ebe --- /dev/null +++ b/examples/nginx/nginx-ha/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.3" + required_providers { + equinix = { + source = "equinix/equinix" + version = "~> 1.34.0" + } + } +} diff --git a/examples/nginx/nginx-single/README.md b/examples/nginx/nginx-single/README.md new file mode 100644 index 0000000..a7f7cbb --- /dev/null +++ b/examples/nginx/nginx-single/README.md @@ -0,0 +1,28 @@ +# Network Edge Device Nginx Single Device Example + +This example demonstrates creation of Network Edge NGINX single device. It will: + +- Create a management ACL template +- Create a SSH key +- Provision NGINX single device + +## Usage + +To provision this example, you should clone the github repository and run terraform from within this directory: + +```bash +git clone https://github.com/equinix-labs/terraform-equinix-nework-edge-device-nginx.git +cd terraform-equinix-nework-edge-device-nginx/examples/nginx-single +terraform init +terraform apply +``` + +Note that this example may create resources which cost money. Run 'terraform destroy' when you don't need these resources. + +## Variables + +See for a description of all variables. + +## Outputs + +See for a description of all outputs. diff --git a/examples/nginx/nginx-single/main.tf b/examples/nginx/nginx-single/main.tf new file mode 100644 index 0000000..4c2cf67 --- /dev/null +++ b/examples/nginx/nginx-single/main.tf @@ -0,0 +1,38 @@ +provider "equinix" { + client_id = var.equinix_client_id + client_secret = var.equinix_client_secret +} + +module "nginx_single" { + source = "../../../modules/nginx" + name = "terraform-test-NGINX-primary" + hostname = "nginx-pri" + metro_code = var.metro_code_primary + account_number = "123456" + platform = "small" + software_package = "STD" + term_length = 1 + notifications = ["test@test.com"] + additional_bandwidth = 50 + mgmt_acl_template_uuid = equinix_network_acl_template.nginx_pri.id + ssh_key = { + userName = "johndoe-primary" + keyName = equinix_network_ssh_key.johndoe.name + } +} + +resource "equinix_network_ssh_key" "johndoe" { + name = "johndoe-pri1" + public_key = var.ssh_rsa_public_key +} + +resource "equinix_network_acl_template" "nginx_pri" { + name = "tf-nginx-pri" + description = "Primary NGINX management ACL template" + inbound_rule { + subnet = "172.16.25.0/24" + protocol = "TCP" + src_port = "any" + dst_port = "22" + } +} diff --git a/examples/nginx/nginx-single/outputs.tf b/examples/nginx/nginx-single/outputs.tf new file mode 100644 index 0000000..37d692d --- /dev/null +++ b/examples/nginx/nginx-single/outputs.tf @@ -0,0 +1,4 @@ +output "device_details" { + description = "Virtual device details" + value = module.nginx_single +} diff --git a/examples/nginx/nginx-single/variables.tf b/examples/nginx/nginx-single/variables.tf new file mode 100644 index 0000000..f342f6e --- /dev/null +++ b/examples/nginx/nginx-single/variables.tf @@ -0,0 +1,18 @@ +variable "equinix_client_id" { + type = string + description = "API Consumer Key available under 'My Apps' in developer portal. This argument can also be specified with the EQUINIX_API_CLIENTID shell environment variable." +} + +variable "equinix_client_secret" { + type = string + description = "API Consumer secret available under 'My Apps' in developer portal. This argument can also be specified with the EQUINIX_API_CLIENTSECRET shell environment variable." +} + +variable "metro_code_primary" { + description = "Device location metro code" + type = string +} +variable "ssh_rsa_public_key" { + description = "SSH RSA public key" + type = string +} diff --git a/examples/nginx/nginx-single/versions.tf b/examples/nginx/nginx-single/versions.tf new file mode 100644 index 0000000..8401ebe --- /dev/null +++ b/examples/nginx/nginx-single/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.3" + required_providers { + equinix = { + source = "equinix/equinix" + version = "~> 1.34.0" + } + } +} diff --git a/examples/simple/README.md b/examples/simple/README.md deleted file mode 100644 index 6a41ec3..0000000 --- a/examples/simple/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# Simple Example - -This example demonstrates usage of the Equinix Template module. - -## Usage - -```bash -terraform init -terraform apply -``` - - - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.3 | - -## Providers - -No providers. - -## Modules - -| Name | Source | Version | -|------|--------|---------| -| [example](#module\_example) | ../../ | n/a | - -## Resources - -No resources. - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [example\_metal\_auth\_token](#input\_example\_metal\_auth\_token) | The example auth token value defines what will be included in the example resource in main.tf. This example is descriptive. | `string` | n/a | yes | -| [example\_metal\_project\_id](#input\_example\_metal\_project\_id) | The example project id value defines what will be included in the example resource in main.tf. This example is descriptive. | `string` | n/a | yes | - -## Outputs - -| Name | Description | -|------|-------------| -| [example\_device\_hostname](#output\_example\_device\_hostname) | The example output. In practice, output value reference implicit resource attributes declared in main.tf | -| [example\_gateway\_id](#output\_example\_gateway\_id) | The example output. In practice, output value reference implicit resource attributes declared in main.tf | - diff --git a/examples/simple/main.tf b/examples/simple/main.tf deleted file mode 100644 index 43c115c..0000000 --- a/examples/simple/main.tf +++ /dev/null @@ -1,12 +0,0 @@ -terraform { - required_version = ">= 1.3" -} - -module "example" { - # TEMPLATE: Replace this path with the Git repo path or Terraform Registry path - source = "../../" - - # Define any required variables - metal_project_id = var.example_metal_project_id - metal_auth_token = var.example_metal_auth_token -} diff --git a/examples/simple/outputs.tf b/examples/simple/outputs.tf deleted file mode 100644 index 50d8eb0..0000000 --- a/examples/simple/outputs.tf +++ /dev/null @@ -1,24 +0,0 @@ -# TEMPLATE: Consider the attributes users of this module will need to take advantage of this module -# TEMPLATE: in a new module that depends on this module (addresses, credentials, filenames). -# TEMPLATE: All outputs must have a description. Do not include descriptions or help text in the -# TEMPLATE: value, use the description field. -# TEMPLATE: -# TEMPLATE: Declare all outputs in this file, sprawling declarations are difficult to identify. -# TEMPLATE: -# TEMPLATE: https://www.terraform.io/docs/language/values/outputs.html -# TEMPLATE: https://www.terraform.io/docs/language/expressions/types.html -# TEMPLATE: - -# TEMPLATE: Replace sample output described below with your own. -output "example_device_hostname" { - description = "The example output. In practice, output value reference implicit resource attributes declared in main.tf" - sensitive = false - value = module.example.device_hostname -} - -# TEMPLATE: Replace sample output described below with your own. -output "example_gateway_id" { - description = "The example output. In practice, output value reference implicit resource attributes declared in main.tf" - sensitive = false - value = module.example.gateway_id -} diff --git a/examples/simple/variables.tf b/examples/simple/variables.tf deleted file mode 100644 index 878ff3d..0000000 --- a/examples/simple/variables.tf +++ /dev/null @@ -1,21 +0,0 @@ -# TEMPLATE: All variables must have a description and should declare their type. -# TEMPLATE: Set defaults whenever possible but do not set defaults for required properties. -# TEMPLATE: Declare all variables in this file, sprawling declarations are difficult to identify. -# TEMPLATE: -# TEMPLATE: https://www.terraform.io/docs/language/values/variables.html -# TEMPLATE: https://www.terraform.io/docs/language/expressions/types.html -# TEMPLATE: - -# TEMPLATE: Replace sample variable described below with your own. -variable "example_metal_project_id" { - type = string - description = "The example project id value defines what will be included in the example resource in main.tf. This example is descriptive." - sensitive = false -} - -# TEMPLATE: Replace sample variable described below with your own. -variable "example_metal_auth_token" { - type = string - description = "The example auth token value defines what will be included in the example resource in main.tf. This example is descriptive." - sensitive = true -} diff --git a/main.tf b/main.tf deleted file mode 100644 index 5eb376a..0000000 --- a/main.tf +++ /dev/null @@ -1,50 +0,0 @@ -# TEMPLATE: Before using "provider" blocks, consider https://www.terraform.io/docs/language/modules/develop/providers.html#implicit-provider-inheritance -# TEMPLATE: -# TEMPLATE: All ".tf" files are parsed at once. There is no benefit to numerically prefixed filenames. Keep all resource definitions in "main.tf". -# TEMPLATE: -# TEMPLATE: When main.tf becomes unwieldy, consider submodules (https://www.terraform.io/docs/language/modules/develop/structure.html) -# TEMPLATE: and dependency inversion (https://www.terraform.io/docs/language/modules/develop/composition.html). -# TEMPLATE: - -# TEMPLATE: Replace sample provider described below with your own. -terraform { - required_version = ">= 1.3" - - provider_meta "equinix" { - # TEMPLATE: Replace the module name with your own. - module_name = "template" - } - - required_providers { - equinix = { - source = "equinix/equinix" - version = ">= 1.8.0" - } - } -} - -# TEMPLATE: Replace sample provider described below with your own. -provider "equinix" { - auth_token = var.metal_auth_token -} - -# TEMPLATE: Replace sample resource described below with your own. -resource "equinix_metal_device" "example_device" { - hostname = "example-device" - plan = "c3.small.x86" - metro = "sv" - operating_system = "ubuntu_20_04" - billing_cycle = "hourly" - project_id = var.metal_project_id -} - -# TEMPLATE: Run `terraform get` to install local module -# TEMPLATE: Run `terraform init` to initialize backends and install plugins -# TEMPLATE: Replace sample in-line local module described below with your own. -# TEMPLATE -module "inline_module" { - source = "./modules/inline-module" - - # Define any required variables - inline_module_project_id = var.metal_project_id -} diff --git a/modules/inline-module/README.md b/modules/inline-module/README.md deleted file mode 100644 index 52db438..0000000 --- a/modules/inline-module/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# In-line Module - -This example demonstrates usage of an in-line module. - -## Usage - -```bash -terraform init -terraform apply -``` - - - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.3 | -| [equinix](#requirement\_equinix) | >= 1.8.0 | - -## Providers - -| Name | Version | -|------|---------| -| [equinix](#provider\_equinix) | >= 1.8.0 | - -## Modules - -No modules. - -## Resources - -| Name | Type | -|------|------| -| [equinix_metal_gateway.inline_module_gateway](https://registry.terraform.io/providers/equinix/equinix/latest/docs/resources/metal_gateway) | resource | -| [equinix_metal_vlan.inline_module_vlan](https://registry.terraform.io/providers/equinix/equinix/latest/docs/resources/metal_vlan) | resource | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [inline\_module\_project\_id](#input\_inline\_module\_project\_id) | The example project id value defines what will be included in the example resource in main.tf. This example is descriptive. | `string` | n/a | yes | - -## Outputs - -| Name | Description | -|------|-------------| -| [metal\_gateway\_id](#output\_metal\_gateway\_id) | The example output. In practice, output value reference implicit resource attributes declared in main.tf | - diff --git a/modules/inline-module/main.tf b/modules/inline-module/main.tf deleted file mode 100644 index 65dcb41..0000000 --- a/modules/inline-module/main.tf +++ /dev/null @@ -1,37 +0,0 @@ -# TEMPLATE: Before using "provider" blocks, consider https://www.terraform.io/docs/language/modules/develop/providers.html#implicit-provider-inheritance -# TEMPLATE: -# TEMPLATE: All ".tf" files are parsed at once. There is no benefit to numerically prefixed filenames. Keep all resource definitions in "main.tf". -# TEMPLATE: -# TEMPLATE: When main.tf becomes unwieldy, consider submodules (https://www.terraform.io/docs/language/modules/develop/structure.html) -# TEMPLATE: and dependency inversion (https://www.terraform.io/docs/language/modules/develop/composition.html). - -# TEMPLATE: Replace sample provider described below with your own. -terraform { - required_version = ">= 1.3" - - provider_meta "equinix" { - # TEMPLATE: Replace the module name with your own. - module_name = "inline-module" - } - - required_providers { - equinix = { - source = "equinix/equinix" - version = ">= 1.8.0" - } - } -} - -# TEMPLATE: Replace sample resource described below with your own. -resource "equinix_metal_vlan" "inline_module_vlan" { - description = "VLAN in SV" - metro = "sv" - project_id = var.inline_module_project_id -} - -# TEMPLATE: Replace sample resource described below with your own. -resource "equinix_metal_gateway" "inline_module_gateway" { - project_id = var.inline_module_project_id - vlan_id = equinix_metal_vlan.inline_module_vlan.id - private_ipv4_subnet_size = 8 -} diff --git a/modules/inline-module/outputs.tf b/modules/inline-module/outputs.tf deleted file mode 100644 index 58deb9d..0000000 --- a/modules/inline-module/outputs.tf +++ /dev/null @@ -1,17 +0,0 @@ -# TEMPLATE: Consider the attributes users of this module will need to take advantage of this module -# TEMPLATE: in a new module that depends on this module (addresses, credentials, filenames). -# TEMPLATE: All outputs must have a description. Do not include descriptions or help text in the -# TEMPLATE: value, use the description field. -# TEMPLATE: -# TEMPLATE: Declare all outputs in this file, sprawling declarations are difficult to identify. -# TEMPLATE: -# TEMPLATE: https://www.terraform.io/docs/language/values/outputs.html -# TEMPLATE: https://www.terraform.io/docs/language/expressions/types.html -# - -# TEMPLATE: Replace sample output described below with your own. -output "metal_gateway_id" { - description = "The example output. In practice, output value reference implicit resource attributes declared in main.tf" - sensitive = false - value = equinix_metal_gateway.inline_module_gateway.id -} diff --git a/modules/inline-module/variables.tf b/modules/inline-module/variables.tf deleted file mode 100644 index 770ebc4..0000000 --- a/modules/inline-module/variables.tf +++ /dev/null @@ -1,14 +0,0 @@ -# TEMPLATE: All variables must have a description and should declare their type. -# TEMPLATE: Set defaults whenever possible but do not set defaults for required properties. -# TEMPLATE: Declare all variables in this file, sprawling declarations are difficult to identify. -# TEMPLATE: -# TEMPLATE: https://www.terraform.io/docs/language/values/variables.html -# TEMPLATE: https://www.terraform.io/docs/language/expressions/types.html -# - -# TEMPLATE: Replace sample variable described below with your own. -variable "inline_module_project_id" { - type = string - description = "The example project id value defines what will be included in the example resource in main.tf. This example is descriptive." - sensitive = false -} diff --git a/modules/nginx/README.md b/modules/nginx/README.md new file mode 100644 index 0000000..c7af74d --- /dev/null +++ b/modules/nginx/README.md @@ -0,0 +1,89 @@ +# Equinix Network Edge NGINX device creation Terraform module + +[![Experimental](https://img.shields.io/badge/Stability-Experimental-red.svg)](https://github.com/equinix-labs/standards#about-uniform-standards) +[![terraform](https://github.com/equinix-labs/terraform-equinix-template/actions/workflows/integration.yaml/badge.svg)](https://github.com/equinix-labs/terraform-equinix-template/actions/workflows/integration.yaml) + +`terraform-equinix-network-edge-nginx` is a Terraform module that +utilizes[Terraform provider for Equinix][equinix_terraform_provider_url] to +create Network Edge NGINX device. + +This module creates a NGINX single device, HA pair and Cluster based on configuration. + +## Usage + +This project is experimental and supported by the user +community. Equinix does not provide support for this project. + +Install Terraform using the official guides at . + +This project may be forked, cloned, or downloaded and +modified as needed as the base in your integrations and deployments. + +This project may also be used as a [Terraform module](https://learn.hashicorp.com/collections/terraform/modules). + +To use this module in a new project, create a file such as: + +```hcl +# main.tf +provider "equinix" { + client_id = var.equinix_client_id + client_secret = var.equinix_client_secret +} + +module "nginx-single" { + source = "equinix-labs/network-edge-device-nginx/equinix" + name = "terraform-test-NGINX" + hostname = "terraform-nginx" + metro_code = "AT" + account_number = "123456" + platform = "small" + software_package = "STD" + term_length = 1 + notifications = ["test@test.com"] + additional_bandwidth = 50 + mgmt_acl_template_uuid = equinix_network_acl_template.nginx-pri.id + ssh_key = { + userName = "johndoe" + keyName = equinix_network_ssh_key.johndoe.name + } +} + +``` + +Run `terraform init -upgrade` and `terraform apply`. + +## Variables + +See +for a description of all variables. + +## Outputs + +See +for a description of all outputs. + +## Resources + +| Name | Type | +|------|------| +| [equinix_network_device.this][equinix_network_device_data_source_url] | resource | +| [equinix_network_device_type.this][equinix_network_device_type_data_source_url] | data source | +| [equinix_network_device_platform.this][equinix_network_device_platform_data_source_url] | data source | +| [equinix_network_device_software.this][equinix_network_device_software_data_source_url] | data source | + +## Examples + + + + +- [Network Edge NGINX single device](https://registry.terraform.io/modules/equinix-labs/network-edge-device-nginx/equinix/latest/examples/nginx-single/) +- [Network Edge NGINX HA pair device](https://registry.terraform.io/modules/equinix-labs/network-edge-device-nginx/equinix/latest/examples/nginx-ha/) +- [Network Edge cluster device](https://registry.terraform.io/modules/equinix-labs/network-edge-device-nginx/equinix/latest/examples/nginx-cluster/) + + + +[equinix_network_device_data_source_url]: (https://registry.terraform.io/providersequinix/equinix/latest/docs/resources/equinix_network_device) +[equinix_network_device_type_data_source_url]: (https://registry.terraform.io/providers/equinix/equinix/latest/docs/data-sources/equinix_network_device_type) +[equinix_network_device_platform_data_source_url]: (https://registry.terraform.io/providers/equinix/equinix/latest/docs/data-sources/equinix_network_device_platform) +[equinix_network_device_software_data_source_url]: (https://registry.terraform.io/providers/equinix/equinix/latest/docs/data-sources/equinix_network_device_software) +[equinix_terraform_provider_url]: (https://registry.terraform.io/providers/equinix/equinix/latest) diff --git a/modules/nginx/main.tf b/modules/nginx/main.tf new file mode 100644 index 0000000..84b8336 --- /dev/null +++ b/modules/nginx/main.tf @@ -0,0 +1,99 @@ +data "equinix_network_device_type" "this" { + name = "Nginx" +} + +data "equinix_network_device_platform" "this" { + device_type = data.equinix_network_device_type.this.code + flavor = var.platform +} + +data "equinix_network_device_software" "this" { + device_type = data.equinix_network_device_type.this.code + packages = [var.software_package] + stable = true + most_recent = true +} + +resource "equinix_network_device" "non_cluster" { + + count = !var.cluster.enabled ? 1 : 0 + lifecycle { + ignore_changes = [version, core_count] + precondition { + condition = length(var.hostname) >= 2 && length(var.hostname) <= 10 + error_message = "Device hostname should consist of 2 to 10 characters." + } + } + self_managed = true + name = var.name + hostname = var.hostname + type_code = data.equinix_network_device_type.this.code + package_code = var.software_package + version = data.equinix_network_device_software.this.version + core_count = data.equinix_network_device_platform.this.core_count + metro_code = var.metro_code + account_number = var.account_number + term_length = var.term_length + interface_count = var.interface_count + notifications = var.notifications + mgmt_acl_template_uuid = var.mgmt_acl_template_uuid != "" ? var.mgmt_acl_template_uuid : null + additional_bandwidth = var.additional_bandwidth > 0 ? var.additional_bandwidth : null + ssh_key { + username = var.ssh_key.userName + key_name = var.ssh_key.keyName + } + + dynamic "secondary_device" { + for_each = var.secondary.enabled ? [1] : [] + content { + name = "${var.name}-secondary" + hostname = var.secondary.hostname + metro_code = var.secondary.metro_code + account_number = var.secondary.account_number + notifications = var.notifications + mgmt_acl_template_uuid = try(var.secondary.mgmt_acl_template_uuid, null) + ssh_key { + username = var.ssh_key.userName + key_name = var.ssh_key.keyName + } + } + } +} + +resource "equinix_network_device" "cluster" { + count = var.cluster.enabled ? 1 : 0 + lifecycle { + ignore_changes = [version, core_count] + } + self_managed = true + name = var.name + type_code = data.equinix_network_device_type.this.code + package_code = var.software_package + version = data.equinix_network_device_software.this.version + core_count = data.equinix_network_device_platform.this.core_count + metro_code = var.metro_code + account_number = var.account_number + term_length = var.term_length + interface_count = var.interface_count + notifications = var.notifications + mgmt_acl_template_uuid = var.mgmt_acl_template_uuid != "" ? var.mgmt_acl_template_uuid : null + additional_bandwidth = var.additional_bandwidth > 0 ? var.additional_bandwidth : null + ssh_key { + username = var.ssh_key.userName + key_name = var.ssh_key.keyName + } + cluster_details { + cluster_name = var.cluster.name + node0 { + vendor_configuration { + hostname = var.cluster.node0_vendor_configuration_hostname + } + } + node1 { + vendor_configuration { + hostname = var.cluster.node1_vendor_configuration_hostname + } + } + + } +} diff --git a/modules/nginx/outputs.tf b/modules/nginx/outputs.tf new file mode 100644 index 0000000..4364f1f --- /dev/null +++ b/modules/nginx/outputs.tf @@ -0,0 +1,74 @@ +output "id" { + description = "Device identifier" + value = !var.cluster.enabled ? equinix_network_device.non_cluster[0].uuid : equinix_network_device.cluster[0].uuid +} + +output "status" { + description = "Device provisioning status" + value = !var.cluster.enabled ? equinix_network_device.non_cluster[0].status : equinix_network_device.cluster[0].status +} + +output "license_status" { + description = "Device license status" + value = !var.cluster.enabled ? equinix_network_device.non_cluster[0].license_status : equinix_network_device.cluster[0].license_status +} + +output "account_number" { + description = "Device billing account number" + value = !var.cluster.enabled ? equinix_network_device.non_cluster[0].account_number : equinix_network_device.cluster[0].account_number +} + +output "cpu_count" { + description = "Device CPU cores count" + value = data.equinix_network_device_platform.this.core_count +} + +output "memory" { + description = "Device memory amount" + value = join(" ", [data.equinix_network_device_platform.this.memory, data.equinix_network_device_platform.this.memory_unit]) +} + +output "software_version" { + description = "Device software version" + value = data.equinix_network_device_software.this.version +} + +output "region" { + description = "Device region" + value = !var.cluster.enabled ? equinix_network_device.non_cluster[0].region : equinix_network_device.cluster[0].region +} + +output "ibx" { + description = "Device IBX center" + value = !var.cluster.enabled ? equinix_network_device.non_cluster[0].ibx : equinix_network_device.cluster[0].ibx +} + +output "ssh_ip_address" { + description = "Device SSH interface IP address" + value = !var.cluster.enabled ? equinix_network_device.non_cluster[0].ssh_ip_address : equinix_network_device.cluster[0].ssh_ip_address +} + +output "ssh_ip_fqdn" { + description = "Device SSH interface FQDN" + value = !var.cluster.enabled ? equinix_network_device.non_cluster[0].ssh_ip_fqdn : equinix_network_device.cluster[0].ssh_ip_fqdn +} + +output "interfaces" { + description = "Device interfaces" + value = !var.cluster.enabled ? equinix_network_device.non_cluster[0].interface : equinix_network_device.cluster[0].interface +} + +output "secondary" { + description = "Secondary device attributes" + value = !var.cluster.enabled && var.secondary.enabled ? { + id = equinix_network_device.non_cluster[0].secondary_device[0].uuid + status = equinix_network_device.non_cluster[0].secondary_device[0].status + license_status = equinix_network_device.non_cluster[0].secondary_device[0].license_status + account_number = equinix_network_device.non_cluster[0].secondary_device[0].account_number + region = equinix_network_device.non_cluster[0].secondary_device[0].region + ibx = equinix_network_device.non_cluster[0].secondary_device[0].ibx + ssh_ip_address = equinix_network_device.non_cluster[0].secondary_device[0].ssh_ip_address + ssh_ip_fqdn = equinix_network_device.non_cluster[0].secondary_device[0].ssh_ip_fqdn + interfaces = equinix_network_device.non_cluster[0].secondary_device[0].interface + } : null +} diff --git a/modules/nginx/variables.tf b/modules/nginx/variables.tf new file mode 100644 index 0000000..06a3e13 --- /dev/null +++ b/modules/nginx/variables.tf @@ -0,0 +1,144 @@ +variable "metro_code" { + description = "Device location metro code" + type = string + validation { + condition = can(regex("^[A-Z]{2}$", var.metro_code)) + error_message = "Valid metro code consits of two capital leters, i.e. SV, DC." + } +} + +variable "account_number" { + description = "Billing account number for a device" + type = string + default = 0 +} + +variable "platform" { + description = "Device platform flavor that determines number of CPU cores and memory" + type = string + validation { + condition = can(regex("^(small|medium|large)$", var.platform)) + error_message = "One of following platform flavors are supported: small, medium, large." + } +} + +variable "software_package" { + description = "Device software package" + type = string + validation { + condition = can(regex("^(STD)$", var.software_package)) + error_message = "One of following software packages are supported: STD." + } +} + +variable "name" { + description = "Device name" + type = string + validation { + condition = length(var.name) >= 2 && length(var.name) <= 50 + error_message = "Device name should consist of 2 to 50 characters." + } +} + +variable "hostname" { + description = "Device hostname" + type = string + default = "" +} + +variable "term_length" { + description = "Term length in months" + type = number + validation { + condition = can(regex("^(1|12|24|36)$", var.term_length)) + error_message = "One of following term lengths are available: 1, 12, 24, 36 months." + } +} + +variable "notifications" { + description = "List of email addresses that will receive device status notifications" + type = list(string) + validation { + condition = length(var.notifications) > 0 + error_message = "Notification list cannot be empty." + } +} + +variable "mgmt_acl_template_uuid" { + description = "Identifier of an management ACL template that will be applied on a device" + type = string + default = "" +} + +variable "additional_bandwidth" { + description = "Additional internet bandwidth for a device" + type = number + default = 0 + validation { + condition = var.additional_bandwidth == 0 || (var.additional_bandwidth >= 25 && var.additional_bandwidth <= 2001) + error_message = "Additional internet bandwidth should be between 25 and 2001 Mbps." + } +} +variable "ssh_key" { + description = "SSH public key for a device" + type = object({ + userName = string + keyName = string + }) +} + +variable "interface_count" { + description = "Number of network interfaces on a device. If not specified, default number for a given device type will be used." + type = number + default = 10 +} + +variable "secondary" { + description = "Secondary device attributes" + type = map(any) + default = { enabled = false } + validation { + condition = can(var.secondary.enabled) + error_message = "Key 'enabled' has to be defined for secondary device." + } + validation { + condition = !try(var.secondary.enabled, false) || can(regex("^[A-Z]{2}$", var.secondary.metro_code)) + error_message = "Key 'metro_code' has to be defined for secondary device. Valid metro code consits of two capital leters, i.e. SV, DC." + } + validation { + condition = !try(var.secondary.enabled, false) || try(length(var.secondary.hostname) >= 2 && length(var.secondary.hostname) <= 10, false) + error_message = "Key 'hostname' has to be defined for secondary device. Valid hostname has to be from 2 to 10 characters long." + } + validation { + condition = !try(var.secondary.enabled, false) || try(var.secondary.additional_bandwidth >= 25 && var.secondary.additional_bandwidth <= 2001, true) + error_message = "Key 'additional_bandwidth' has to be between 25 and 2001 Mbps." + } + validation { + condition = !try(var.secondary.enabled, false) || try(var.secondary.mgmt_acl_template_uuid != null, true) + error_message = "Secondary management Acl template is required." + } +} +variable "cluster" { + description = "cluster device attributes" + type = map(any) + default = { enabled = false } + + validation { + condition = !try(var.cluster.enabled, false) || try(var.cluster.name != null, true) + error_message = "Cluster name is required." + } + validation { + condition = can(var.cluster.enabled) + error_message = "Key 'enabled' has to be defined for secondary device." + } + validation { + condition = !try(var.cluster.enabled, false) || try(length(var.cluster.node0_vendor_configuration_hostname) >= 2 && length(var.cluster.node0_vendor_configuration_hostname) <= 10, false) + error_message = "Key 'node0.vendorConfig.hostname' has to be defined for cluster device. Valid hostname has to be from 2 to 10 characters long." + } + + validation { + condition = !try(var.cluster.enabled, false) || try(length(var.cluster.node1_vendor_configuration_hostname) >= 2 && length(var.cluster.node1_vendor_configuration_hostname) <= 10, false) + error_message = "Key 'node0.vendorConfig.hostname' has to be defined for cluster device. Valid hostname has to be from 2 to 10 characters long." + } + +} diff --git a/modules/nginx/versions.tf b/modules/nginx/versions.tf new file mode 100644 index 0000000..9cd09c8 --- /dev/null +++ b/modules/nginx/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.3" + required_providers { + equinix = { + source = "equinix/equinix" + version = ">= 1.34.0" + } + } +} diff --git a/outputs.tf b/outputs.tf deleted file mode 100644 index 4bdfbc6..0000000 --- a/outputs.tf +++ /dev/null @@ -1,24 +0,0 @@ -# TEMPLATE: Consider the attributes users of this module will need to take advantage of this module -# TEMPLATE: in a new module that depends on this module (addresses, credentials, filenames). -# TEMPLATE: All outputs must have a description. Do not include descriptions or help text in the -# TEMPLATE: value, use the description field. -# TEMPLATE: -# TEMPLATE: Declare all outputs in this file, sprawling declarations are difficult to identify. -# TEMPLATE: -# TEMPLATE: https://www.terraform.io/docs/language/values/outputs.html -# TEMPLATE: https://www.terraform.io/docs/language/expressions/types.html -# TEMPLATE: - -# TEMPLATE: Replace sample output described below with your own. -output "device_hostname" { - description = "The example output. In practice, output value reference implicit resource attributes declared in main.tf" - sensitive = false - value = equinix_metal_device.example_device.hostname -} - -# TEMPLATE: Replace sample output described below with your own. -output "gateway_id" { - description = "The example output. In practice, output value reference implicit resource attributes declared in main.tf" - sensitive = false - value = module.inline_module.metal_gateway_id -} diff --git a/scripts/template-script.sh b/scripts/template-script.sh deleted file mode 100644 index ac9101c..0000000 --- a/scripts/template-script.sh +++ /dev/null @@ -1 +0,0 @@ -# TEMPLATE: Place your beskope script called by Terraform here. diff --git a/templates/template-file.tftpl b/templates/template-file.tftpl deleted file mode 100644 index b87e591..0000000 --- a/templates/template-file.tftpl +++ /dev/null @@ -1 +0,0 @@ -# TEMPLATE: Place your template here. This will be called by the templatefile function. For more info: https://developer.hashicorp.com/terraform/language/functions/templatefile diff --git a/variables.tf b/variables.tf deleted file mode 100644 index 5334a3c..0000000 --- a/variables.tf +++ /dev/null @@ -1,21 +0,0 @@ -# TEMPLATE: All variables must have a description and should declare their type. -# TEMPLATE: Set defaults whenever possible but do not set defaults for required properties. -# TEMPLATE: Declare all variables in this file, sprawling declarations are difficult to identify. -# TEMPLATE: -# TEMPLATE: https://www.terraform.io/docs/language/values/variables.html -# TEMPLATE: https://www.terraform.io/docs/language/expressions/types.html -# TEMPLATE: - -# TEMPLATE: Replace sample variable described below with your own. -variable "metal_project_id" { - type = string - description = "The example project id value defines what will be included in the example resource in main.tf. This example is descriptive." - sensitive = false -} - -# TEMPLATE: Replace sample variable described below with your own. -variable "metal_auth_token" { - type = string - description = "The example auth token value defines what will be included in the example resource in main.tf. This example is descriptive." - sensitive = true -} From 9ffc88535673b89a163090b31f9da8f6fd8e5b91 Mon Sep 17 00:00:00 2001 From: schadalawada Date: Mon, 29 Apr 2024 13:34:09 -0700 Subject: [PATCH 2/2] feat: onbarding NGINX module --- LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License.