From e87a95fe791132bb4c22291ee17778182cff37d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ig=C5=82a?= Date: Thu, 15 Dec 2022 14:00:58 +0100 Subject: [PATCH] feat: Add public IP resources (#1) * feat: Add public IP resources * feat: Add public IP outputs * fix: Allow null values and fix descriptor name * improvement: set nullable to false for objects --- .pre-commit-config.yaml | 2 +- README.md | 45 +++++++--------- examples/complete/README.md | 36 +++++++++++-- examples/complete/fixtures.west-europe.tfvars | 4 ++ examples/complete/main.tf | 9 +++- examples/complete/outputs.tf | 6 +-- examples/simple/README.md | 19 +++++-- examples/simple/main.tf | 17 ++++-- examples/simple/outputs.tf | 6 +-- locals.tf | 2 +- main.tf | 10 +++- outputs.tf | 16 ++++-- variables.tf | 52 ++++++++++++++++++- 13 files changed, 174 insertions(+), 50 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 66616ea..476692e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: ["."] - repo: https://github.com/bridgecrewio/checkov.git - rev: '2.2.130' # Get the latest from: https://github.com/bridgecrewio/checkov/releases + rev: '2.2.158' # Get the latest from: https://github.com/bridgecrewio/checkov/releases hooks: - id: checkov args: [--skip-check, "CKV2_GHA_1"] #Flase positive for top-level permissions diff --git a/README.md b/README.md index 864e283..fe619bd 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,10 @@ -# Terraform Azure Module Template - - -> **Warning**: -> This is a template document. Remember to **remove** all text in _italics_ and **update** Module name, Repo name and links/badges to the acual name of your GitHub repository/module!!! +# Azure Public IP Terraform Module ![Azure](https://img.shields.io/badge/azure-%230072C6.svg?style=for-the-badge&logo=microsoftazure&logoColor=white) ![Terraform](https://img.shields.io/badge/terraform-%235835CC.svg?style=for-the-badge&logo=terraform&logoColor=white) - -![License](https://badgen.net/github/license/getindata/terraform-azurerm-module-tempate/) -![Release](https://badgen.net/github/release/getindata/terraform-azurerm-module-tempate/) +![License](https://badgen.net/github/license/getindata/terraform-azurerm-public-ip/) +![Release](https://badgen.net/github/release/getindata/terraform-azurerm-public-ip/)

@@ -18,28 +13,21 @@ --- -_Brief Description of MODULE:_ - -* _What it does_ -* _What techonlogies it uses_ +This module is managing Azure Public IP instance. ## USAGE -_Example usage of the module - terraform code snippet_ - ```terraform -module "template" { - source = "github.com/getindata/terraform-azurerm-module-tempate" +module "public_ip" { + source = "github.com/getindata/terraform-azurerm-public-ip" location = "West Europe" resource_group_name = "example-rg" + + allocation_method = "Dynamic" } ``` -## NOTES - -_Additional information that should be made public, for ex. how to solve known issues, additional descriptions/suggestions_ - ## EXAMPLES - [Simple](examples/simple) @@ -55,6 +43,7 @@ _Additional information that should be made public, for ex. how to solve known i | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [additional\_tag\_map](#input\_additional\_tag\_map) | Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`.
This is for some rare cases where resources want additional configuration of tags
and therefore take a list of maps with tag key, value, and additional configuration. | `map(string)` | `{}` | no | +| [allocation\_method](#input\_allocation\_method) | Defines the allocation method for this IP address. Possible values are Static or Dynamic | `string` | n/a | yes | | [attributes](#input\_attributes) | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,
in the order they appear in the list. New attributes are appended to the
end of the list. The elements of the list are joined by the `delimiter`
and treated as a single ID element. | `list(string)` | `[]` | no | | [context](#input\_context) | Single object for setting entire context at once.
See description of individual variables for details.
Leave string and numeric variables as `null` to use default value.
Individual variable settings (non-null) override settings in context object,
except for attributes, tags, and additional\_tag\_map, which are merged. | `any` |

{
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
| no | | [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no | @@ -64,6 +53,7 @@ _Additional information that should be made public, for ex. how to solve known i | [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no | | [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no | | [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).
Set to `0` for unlimited length.
Set to `null` for keep the existing setting, which defaults to `0`.
Does not affect `id_full`. | `number` | `null` | no | +| [ip\_version](#input\_ip\_version) | The IP Version to use, IPv6 or IPv4 | `string` | `null` | no | | [label\_key\_case](#input\_label\_key\_case) | Controls the letter case of the `tags` keys (label names) for tags generated by this module.
Does not affect keys of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper`.
Default value: `title`. | `string` | `null` | no | | [label\_order](#input\_label\_order) | The order in which the labels (ID elements) appear in the `id`.
Defaults to ["namespace", "environment", "stage", "name", "attributes"].
You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no | | [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of ID elements (labels) as included in `id`,
set as tag values, and output by this module individually.
Does not affect values of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper` and `none` (no transformation).
Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.
Default value: `lower`. | `string` | `null` | no | @@ -73,9 +63,12 @@ _Additional information that should be made public, for ex. how to solve known i | [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `null` | no | | [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.
Characters matching the regex will be removed from the ID elements.
If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no | | [resource\_group\_name](#input\_resource\_group\_name) | Azure resource group name where resources will be deployed | `string` | n/a | yes | +| [sku](#input\_sku) | The SKU of the Public IP. Accepted values are Basic and Standard. Defaults to Basic. Public IP Standard SKUs require allocation\_method to be set to Static | `string` | `null` | no | +| [sku\_tier](#input\_sku\_tier) | The SKU Tier that should be used for the Public IP. Possible values are Regional and Global. Defaults to Regional. When sku\_tier is set to Global, sku must be set to Standard | `string` | `null` | no | | [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no | | [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
Neither the tag keys nor the tag values will be modified by this module. | `map(string)` | `{}` | no | | [tenant](#input\_tenant) | ID element \_(Rarely used, not included by default)\_. A customer identifier, indicating who this instance of a resource is for | `string` | `null` | no | +| [zones](#input\_zones) | A collection containing the availability zone to allocate the Public IP in | `list(string)` | `null` | no | ## Modules @@ -88,9 +81,11 @@ _Additional information that should be made public, for ex. how to solve known i | Name | Description | |------|-------------| -| [id](#output\_id) | ID of the resource | -| [name](#output\_name) | Name of the resource | -| [resource\_group\_name](#output\_resource\_group\_name) | Name of the resource resource group | +| [fqdn](#output\_fqdn) | Fully qualified domain name of the A DNS record associated with the public IP | +| [id](#output\_id) | ID of the Azure Public IP | +| [ip\_address](#output\_ip\_address) | The IP address value that was allocated | +| [name](#output\_name) | Name of the Azure Public IP | +| [resource\_group\_name](#output\_resource\_group\_name) | Name of the Azure Public IP resource group | ## Providers @@ -126,8 +121,8 @@ Apache 2 Licensed. See [LICENSE](LICENSE) for full details. ## AUTHORS - - + + Made with [contrib.rocks](https://contrib.rocks). diff --git a/examples/complete/README.md b/examples/complete/README.md index a9baa5d..6d40452 100644 --- a/examples/complete/README.md +++ b/examples/complete/README.md @@ -1,12 +1,42 @@ # Complete Example ```terraform -module "terraform_module_template" { - source = "../../" +module "resource_group" { + source = "github.com/getindata/terraform-azurerm-resource-group?ref=v1.2.0" context = module.this.context + name = var.resource_group_name location = var.location - resource_group_name = var.resource_group_name +} + +resource "azurerm_log_analytics_workspace" "this" { + name = module.this.id + location = module.resource_group.location + resource_group_name = module.resource_group.name + tags = module.this.tags + sku = "PerGB2018" +} + +module "public_ip" { + source = "../../" + context = module.this.context + + location = module.resource_group.location + resource_group_name = module.resource_group.name + + allocation_method = "Static" + zones = ["1", "2", "3"] + ip_version = "IPv4" + + sku = "Standard" + sku_tier = "Regional" + + diagnostic_settings = { + enabled = true + logs_destinations_ids = [ + azurerm_log_analytics_workspace.this.id + ] + } } ``` diff --git a/examples/complete/fixtures.west-europe.tfvars b/examples/complete/fixtures.west-europe.tfvars index d7e2c5a..a361a4d 100644 --- a/examples/complete/fixtures.west-europe.tfvars +++ b/examples/complete/fixtures.west-europe.tfvars @@ -8,6 +8,10 @@ descriptor_formats = { labels = ["name"] format = "%v-rg" } + azure-public-ip = { + labels = ["namespace", "environment", "stage", "name", "attributes"] + format = "%v-%v-%v-%v-%v-pip" + } } tags = { diff --git a/examples/complete/main.tf b/examples/complete/main.tf index 303d442..00fde40 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -14,13 +14,20 @@ resource "azurerm_log_analytics_workspace" "this" { sku = "PerGB2018" } -module "terraform_module_template" { +module "public_ip" { source = "../../" context = module.this.context location = module.resource_group.location resource_group_name = module.resource_group.name + allocation_method = "Static" + zones = ["1", "2", "3"] + ip_version = "IPv4" + + sku = "Standard" + sku_tier = "Regional" + diagnostic_settings = { enabled = true logs_destinations_ids = [ diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf index c15735a..d258bd2 100644 --- a/examples/complete/outputs.tf +++ b/examples/complete/outputs.tf @@ -1,4 +1,4 @@ -output "terraform_module_template" { - description = "Output of the template module" - value = module.terraform_module_template +output "public_ip" { + description = "Output of the public ip module" + value = module.public_ip } diff --git a/examples/simple/README.md b/examples/simple/README.md index ad81e10..6a35b61 100644 --- a/examples/simple/README.md +++ b/examples/simple/README.md @@ -1,11 +1,22 @@ # Simple Example ```terraform -module "terraform_module_template" { - source = "../../" +module "resource_group" { + source = "github.com/getindata/terraform-azurerm-resource-group?ref=v1.2.0" - location = var.location - resource_group_name = var.resource_group_name + name = var.resource_group_name + location = var.location +} + +module "public_ip" { + source = "../../" + + name = "public-ip" + + location = module.resource_group.location + resource_group_name = module.resource_group.name + + allocation_method = "Dynamic" } ``` diff --git a/examples/simple/main.tf b/examples/simple/main.tf index a213eab..449080c 100644 --- a/examples/simple/main.tf +++ b/examples/simple/main.tf @@ -1,6 +1,17 @@ -module "terraform_module_template" { +module "resource_group" { + source = "github.com/getindata/terraform-azurerm-resource-group?ref=v1.2.0" + + name = var.resource_group_name + location = var.location +} + +module "public_ip" { source = "../../" - location = var.location - resource_group_name = var.resource_group_name + name = "public-ip" + + location = module.resource_group.location + resource_group_name = module.resource_group.name + + allocation_method = "Dynamic" } diff --git a/examples/simple/outputs.tf b/examples/simple/outputs.tf index c15735a..d258bd2 100644 --- a/examples/simple/outputs.tf +++ b/examples/simple/outputs.tf @@ -1,4 +1,4 @@ -output "terraform_module_template" { - description = "Output of the template module" - value = module.terraform_module_template +output "public_ip" { + description = "Output of the public ip module" + value = module.public_ip } diff --git a/locals.tf b/locals.tf index 9e2959f..e2a57a0 100644 --- a/locals.tf +++ b/locals.tf @@ -2,7 +2,7 @@ locals { # Get a name from the descriptor. If not available, use default naming convention. # Trim and replace function are used to avoid bare delimiters on both ends of the name and situation of adjacent delimiters. name_from_descriptor = trim(replace( - lookup(module.this.descriptors, var.descriptor_name, module.this.id), "/${module.this.delimiter}${module.this.delimiter}+/", "" + lookup(module.this.descriptors, var.descriptor_name, module.this.id), "/${module.this.delimiter}${module.this.delimiter}+/", module.this.delimiter ), module.this.delimiter) location = coalesce(one(data.azurerm_resource_group.this[*].location), var.location) diff --git a/main.tf b/main.tf index 60008d4..1ec0757 100644 --- a/main.tf +++ b/main.tf @@ -4,7 +4,6 @@ data "azurerm_resource_group" "this" { name = var.resource_group_name } -#This is a sample resource resource "azurerm_public_ip" "this" { count = module.this.enabled ? 1 : 0 @@ -12,7 +11,14 @@ resource "azurerm_public_ip" "this" { location = local.location resource_group_name = local.resource_group_name - allocation_method = "Dynamic" + allocation_method = var.allocation_method + zones = var.zones + ip_version = var.ip_version + + sku = var.sku + sku_tier = var.sku_tier + + tags = module.this.tags } module "diagnostic_settings" { diff --git a/outputs.tf b/outputs.tf index 71bca43..ae233cd 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,14 +1,24 @@ output "name" { - description = "Name of the resource" + description = "Name of the Azure Public IP" value = one(azurerm_public_ip.this[*].name) } output "id" { - description = "ID of the resource" + description = "ID of the Azure Public IP" value = one(azurerm_public_ip.this[*].id) } output "resource_group_name" { - description = "Name of the resource resource group" + description = "Name of the Azure Public IP resource group" value = one(azurerm_public_ip.this[*].resource_group_name) } + +output "ip_address" { + description = "The IP address value that was allocated" + value = one(azurerm_public_ip.this[*].ip_address) +} + +output "fqdn" { + description = "Fully qualified domain name of the A DNS record associated with the public IP" + value = one(azurerm_public_ip.this[*].fqdn) +} diff --git a/variables.tf b/variables.tf index f114763..294b3c0 100644 --- a/variables.tf +++ b/variables.tf @@ -21,5 +21,55 @@ variable "diagnostic_settings" { enabled = optional(bool, false) logs_destinations_ids = optional(list(string), []) }) - default = {} + default = {} + nullable = false +} + +variable "allocation_method" { + description = "Defines the allocation method for this IP address. Possible values are Static or Dynamic" + type = string + + validation { + condition = contains(["Static", "Dynamic"], var.allocation_method) + error_message = "Possible values are Static or Dynamic for the allocation_method variable" + } +} + +variable "zones" { + description = "A collection containing the availability zone to allocate the Public IP in" + type = list(string) + default = null +} + +variable "ip_version" { + description = "The IP Version to use, IPv6 or IPv4" + type = string + default = null + + validation { + condition = contains(["IPv4", "IPv6", "[null]"], coalesce(var.ip_version, "[null]")) + error_message = "Possible values are IPv6 or IPv6 for the ip_version variable" + } +} + +variable "sku" { + description = "The SKU of the Public IP. Accepted values are Basic and Standard. Defaults to Basic. Public IP Standard SKUs require allocation_method to be set to Static" + type = string + default = null + + validation { + condition = contains(["Basic", "Standard", "[null]"], coalesce(var.sku, "[null]")) + error_message = "Possible values are Basic or Standard for the sku variable" + } +} + +variable "sku_tier" { + description = "The SKU Tier that should be used for the Public IP. Possible values are Regional and Global. Defaults to Regional. When sku_tier is set to Global, sku must be set to Standard" + type = string + default = null + + validation { + condition = contains(["Regional", "Global", "[null]"], coalesce(var.sku_tier, "[null]")) + error_message = "Possible values are Regional or Global for the sku_tier variable" + } }