Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CES-456] Definition of a module that create a base environment for development #163

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/six-geese-pretend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"azure_core_infra": patch
---

Added common_environment module for base environment
84 changes: 84 additions & 0 deletions infra/modules/azure_core_infra/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Core Infrastructure module
The module provisions all the resources required for the initial configuration of a subscription, which can be utilized for testing or other purposes.

The module, named `azure_core_infra`, includes the following:

- A virtual network (`VNet`) with subnets for private endpoints.
- A VPN, if specified.
- Resource groups for the VNet, common resources, and testing.
- A common Key Vault with a private endpoint.
- Private DNS zones for all resource types.

## Examples

```hcl
module "core" {
source = "github.com/pagopa/dx//infra/modules/azure_core_infra?ref=main"

test_enable = true # set to false if you want to create all resources
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: I think this should be test_enabled


environment = local.environment

virtual_network_cidr = "10.50.0.0/16"
pep_subnet_cidr = "10.50.2.0/23"

vpn = {
cidr_subnet = "10.50.133.0/24"
dnsforwarder_cidr_subnet = "10.50.252.8/29"
}

tags = local.tags
}
```

<!-- BEGIN_TF_DOCS -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | <= 4.10.0 |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_dns"></a> [dns](#module\_dns) | ./_modules/dns | n/a |
| <a name="module_key_vault"></a> [key\_vault](#module\_key\_vault) | ./_modules/key_vault | n/a |
| <a name="module_naming_convention"></a> [naming\_convention](#module\_naming\_convention) | ../azure_naming_convention | n/a |
| <a name="module_nat_gateway"></a> [nat\_gateway](#module\_nat\_gateway) | ./_modules/nat_gateway | n/a |
| <a name="module_network"></a> [network](#module\_network) | ./_modules/networking | n/a |
| <a name="module_vpn"></a> [vpn](#module\_vpn) | ./_modules/vpn | n/a |

## Resources

| Name | Type |
|------|------|
| [azurerm_resource_group.common](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
| [azurerm_resource_group.network](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
| [azurerm_resource_group.test](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
| [azuread_client_config.current](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/client_config) | data source |
| [azurerm_client_config.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_environment"></a> [environment](#input\_environment) | Values which are used to generate resource names and location short names. They are all mandatory except for domain, which should not be used only in the case of a resource used by multiple domains. | <pre>object({<br/> prefix = string<br/> env_short = string<br/> location = string<br/> domain = optional(string)<br/> app_name = string<br/> instance_number = string<br/> })</pre> | n/a | yes |
| <a name="input_nat_enabled"></a> [nat\_enabled](#input\_nat\_enabled) | Flag to enable nat gateway creation | `bool` | `false` | no |
| <a name="input_pep_subnet_cidr"></a> [pep\_subnet\_cidr](#input\_pep\_subnet\_cidr) | CIDR block for the private endpoint subnet | `string` | `"10.0.2.0/23"` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Resources tags | `map(any)` | n/a | yes |
| <a name="input_test_enabled"></a> [test\_enabled](#input\_test\_enabled) | Flag to enable testing resources | `bool` | `false` | no |
| <a name="input_virtual_network_cidr"></a> [virtual\_network\_cidr](#input\_virtual\_network\_cidr) | CIDR block for the virtual network | `string` | `"10.0.0.0/16"` | no |
| <a name="input_vpn"></a> [vpn](#input\_vpn) | VPN configuration. Both 'cidr\_subnet' and 'dnsforwarder\_cidr\_subnet' must be specified together or not at all. | <pre>object({<br/> cidr_subnet = optional(string, "")<br/> dnsforwarder_cidr_subnet = optional(string, "")<br/> })</pre> | `{}` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_common_nat_gateways"></a> [common\_nat\_gateways](#output\_common\_nat\_gateways) | n/a |
| <a name="output_common_pep_snet"></a> [common\_pep\_snet](#output\_common\_pep\_snet) | n/a |
| <a name="output_common_resource_group_name"></a> [common\_resource\_group\_name](#output\_common\_resource\_group\_name) | n/a |
| <a name="output_common_vnet"></a> [common\_vnet](#output\_common\_vnet) | n/a |
| <a name="output_network_resource_group_name"></a> [network\_resource\_group\_name](#output\_network\_resource\_group\_name) | n/a |
| <a name="output_test_resource_group_name"></a> [test\_resource\_group\_name](#output\_test\_resource\_group\_name) | n/a |
<!-- END_TF_DOCS -->
33 changes: 33 additions & 0 deletions infra/modules/azure_core_infra/_modules/dns/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# dns

<!-- BEGIN_TF_DOCS -->
## Requirements

No requirements.

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [azurerm_private_dns_zone.private_dns_zones](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_dns_zone) | resource |
| [azurerm_private_dns_zone_virtual_network_link.private_dns_links](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_dns_zone_virtual_network_link) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_private_dns_zones"></a> [private\_dns\_zones](#input\_private\_dns\_zones) | Private DNS zones | `map(any)` | `{}` | no |
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | Resource group name | `string` | n/a | yes |
| <a name="input_tags"></a> [tags](#input\_tags) | Resources tags | `map(any)` | n/a | yes |
| <a name="input_virtual_network"></a> [virtual\_network](#input\_virtual\_network) | Virtual network where to attach private dns zones | <pre>object({<br/> id = string<br/> name = string<br/> })</pre> | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_private_dns_zones"></a> [private\_dns\_zones](#output\_private\_dns\_zones) | n/a |
<!-- END_TF_DOCS -->
3 changes: 3 additions & 0 deletions infra/modules/azure_core_infra/_modules/dns/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "private_dns_zones" {
value = { for k, v in azurerm_private_dns_zone.private_dns_zones : k => v }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
resource "azurerm_private_dns_zone" "private_dns_zones" {
for_each = var.private_dns_zones
name = each.value
resource_group_name = var.resource_group_name

tags = var.tags
}

resource "azurerm_private_dns_zone_virtual_network_link" "private_dns_links" {
for_each = var.private_dns_zones

name = var.virtual_network.name
resource_group_name = var.resource_group_name
private_dns_zone_name = azurerm_private_dns_zone.private_dns_zones[each.key].name
virtual_network_id = var.virtual_network.id
registration_enabled = false

tags = var.tags
}
23 changes: 23 additions & 0 deletions infra/modules/azure_core_infra/_modules/dns/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
variable "resource_group_name" {
type = string
description = "Resource group name"
}

variable "tags" {
type = map(any)
description = "Resources tags"
}

variable "virtual_network" {
type = object({
id = string
name = string
})
description = "Virtual network where to attach private dns zones"
}

variable "private_dns_zones" {
type = map(any)
description = "Private DNS zones"
default = {}
}
36 changes: 36 additions & 0 deletions infra/modules/azure_core_infra/_modules/key_vault/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# key_vault

<!-- BEGIN_TF_DOCS -->
## Requirements

No requirements.

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [azurerm_key_vault.common](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault) | resource |
| [azurerm_private_endpoint.vault](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_location"></a> [location](#input\_location) | Location | `string` | n/a | yes |
| <a name="input_prefix"></a> [prefix](#input\_prefix) | IO prefix, short environment, short location and domain | `string` | n/a | yes |
| <a name="input_private_dns_zone"></a> [private\_dns\_zone](#input\_private\_dns\_zone) | Private dns zone id and resource group name | <pre>object({<br/> id = string<br/> resource_group_name = string<br/> })</pre> | n/a | yes |
| <a name="input_project"></a> [project](#input\_project) | IO prefix, short environment and short location | `string` | n/a | yes |
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | Resource group name | `string` | n/a | yes |
| <a name="input_subnet_pep_id"></a> [subnet\_pep\_id](#input\_subnet\_pep\_id) | Private endpoint subnet id | `string` | n/a | yes |
| <a name="input_suffix"></a> [suffix](#input\_suffix) | Suffix for resource names | `string` | `"01"` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Resources tags | `map(any)` | n/a | yes |
| <a name="input_tenant_id"></a> [tenant\_id](#input\_tenant\_id) | Tenant ID | `string` | n/a | yes |

## Outputs

No outputs.
<!-- END_TF_DOCS -->
20 changes: 20 additions & 0 deletions infra/modules/azure_core_infra/_modules/key_vault/kv.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#tfsec:ignore:AVD-AZU-0013
resource "azurerm_key_vault" "common" {
name = "${var.project}-common-kv-01"
location = var.location
resource_group_name = var.resource_group_name
tenant_id = var.tenant_id
sku_name = "standard"

enabled_for_disk_encryption = true
purge_protection_enabled = true
soft_delete_retention_days = 7
enable_rbac_authorization = true

network_acls {
bypass = "AzureServices"
default_action = "Allow" #tfsec:ignore:AZU020
}

tags = var.tags
}
21 changes: 21 additions & 0 deletions infra/modules/azure_core_infra/_modules/key_vault/networking.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#
# Private endpoints
#
resource "azurerm_private_endpoint" "vault" {
name = "${var.prefix}-kv-pep-${var.suffix}"
location = var.location
resource_group_name = var.private_dns_zone.resource_group_name
subnet_id = var.subnet_pep_id

private_service_connection {
name = "${var.prefix}-kv-pep-${var.suffix}"
private_connection_resource_id = azurerm_key_vault.common.id
is_manual_connection = false
subresource_names = ["vault"]
}

private_dns_zone_group {
name = "private-dns-zone-group"
private_dns_zone_ids = [var.private_dns_zone.id]
}
}
48 changes: 48 additions & 0 deletions infra/modules/azure_core_infra/_modules/key_vault/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
variable "project" {
type = string
description = "IO prefix, short environment and short location"
}

variable "prefix" {
type = string
description = "IO prefix, short environment, short location and domain"
}

variable "suffix" {
type = string
description = "Suffix for resource names"
default = "01"
}

variable "resource_group_name" {
type = string
description = "Resource group name"
}

variable "location" {
type = string
description = "Location"
}

variable "tags" {
type = map(any)
description = "Resources tags"
}

variable "subnet_pep_id" {
type = string
description = "Private endpoint subnet id"
}

variable "private_dns_zone" {
type = object({
id = string
resource_group_name = string
})
description = "Private dns zone id and resource group name"
}

variable "tenant_id" {
type = string
description = "Tenant ID"
}
37 changes: 37 additions & 0 deletions infra/modules/azure_core_infra/_modules/nat_gateway/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# nat_gateway

<!-- BEGIN_TF_DOCS -->
## Requirements

No requirements.

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [azurerm_nat_gateway.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/nat_gateway) | resource |
| [azurerm_nat_gateway_public_ip_prefix_association.this_ippres](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/nat_gateway_public_ip_prefix_association) | resource |
| [azurerm_public_ip_prefix.ng](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip_prefix) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_location"></a> [location](#input\_location) | Location | `string` | n/a | yes |
| <a name="input_ng_ippres_number"></a> [ng\_ippres\_number](#input\_ng\_ippres\_number) | Number of Public IP Prefix assigned to the nat gateway | `number` | `3` | no |
| <a name="input_ng_number"></a> [ng\_number](#input\_ng\_number) | Number of nat gateways to deploy | `number` | `1` | no |
| <a name="input_project"></a> [project](#input\_project) | IO prefix, short environment and short location | `string` | n/a | yes |
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | Resource group name | `string` | n/a | yes |
| <a name="input_tags"></a> [tags](#input\_tags) | Resources tags | `map(any)` | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_nat_gateways"></a> [nat\_gateways](#output\_nat\_gateways) | n/a |
| <a name="output_public_ip_prefix"></a> [public\_ip\_prefix](#output\_public\_ip\_prefix) | n/a |
<!-- END_TF_DOCS -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
resource "azurerm_public_ip_prefix" "ng" {
count = var.ng_ippres_number

name = format("%s-ippre-%02d", "${var.project}-ng", count.index + 1)
location = var.location
resource_group_name = var.resource_group_name

prefix_length = 31
zones = [count.index + 1]

tags = var.tags
}

resource "azurerm_nat_gateway" "this" {
count = var.ng_number

name = "${var.project}-ng-0${count.index + 1}"
location = var.location
resource_group_name = var.resource_group_name
sku_name = "Standard"
idle_timeout_in_minutes = 4
zones = [count.index + 1]

tags = var.tags
}

resource "azurerm_nat_gateway_public_ip_prefix_association" "this_ippres" {
count = var.ng_ippres_number
nat_gateway_id = azurerm_nat_gateway.this[0].id
public_ip_prefix_id = azurerm_public_ip_prefix.ng[count.index].id
}
15 changes: 15 additions & 0 deletions infra/modules/azure_core_infra/_modules/nat_gateway/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
output "nat_gateways" {
value = [for key, ng in azurerm_nat_gateway.this : {
id = azurerm_nat_gateway.this[key].id
name = azurerm_nat_gateway.this[key].name
resource_group_name = azurerm_nat_gateway.this[key].resource_group_name
}]
}

output "public_ip_prefix" {
value = [for key, ng in azurerm_public_ip_prefix.ng : {
id = azurerm_public_ip_prefix.ng[key].id
name = azurerm_public_ip_prefix.ng[key].name
resource_group_name = azurerm_public_ip_prefix.ng[key].resource_group_name
}]
}
Loading