diff --git a/modules/azure-flexible-server-postgresql/.terraform-docs.yml b/modules/azure-flexible-server-postgresql/.terraform-docs.yml new file mode 100644 index 000000000..bce3ca3a9 --- /dev/null +++ b/modules/azure-flexible-server-postgresql/.terraform-docs.yml @@ -0,0 +1,48 @@ +formatter: "markdown" # this is required + +version: "" + +header-from: docs/header.md +footer-from: docs/footer.md + +recursive: + enabled: false + path: modules + include-main: true + +sections: + hide: [] + show: [] + +content: "" + +output: + file: "README.md" + mode: inject + template: |- + + {{ .Content }} + + +output-values: + enabled: false + from: "" + +sort: + enabled: true + by: name + +settings: + anchor: true + color: true + default: true + description: false + escape: true + hide-empty: false + html: true + indent: 2 + lockfile: true + read-comments: true + required: true + sensitive: true + type: true \ No newline at end of file diff --git a/modules/azure-flexible-server-postgresql/README.md b/modules/azure-flexible-server-postgresql/README.md index dcc33e236..de36c052d 100644 --- a/modules/azure-flexible-server-postgresql/README.md +++ b/modules/azure-flexible-server-postgresql/README.md @@ -1,105 +1,22 @@ -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.7.0 | -| [azurerm](#requirement\_azurerm) | >= 4.35.0 | - -To create the postgresql flexible server you must have: - - A resource group. - - A virtual network. - - A keyvault to store/read a secret with the PostgreSQL admin pass. - - The dns and the subnet will be necesary when `public_network_access_enabled=false`. - -## Providers - -| Name | Version | -|------|---------| -| [azurerm](#provider\_azurerm) | >= 4.35.0 | -| [random](#provider\_random) | n/a | - -## Resources - -| Name | Type | -|------|------| -| [azurerm_key_vault_secret.password_create](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret) | resource | -| [azurerm_postgresql_flexible_server.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/postgresql_flexible_server) | resource | -| [azurerm_postgresql_flexible_server_configuration.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/postgresql_flexible_server_configuration) | resource | -| [azurerm_postgresql_flexible_server_firewall_rule.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/postgresql_flexible_server_firewall_rule) | resource | -| [random_password.password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | -| [azurerm_key_vault_secret.administrator_password](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/key_vault_secret) | data source | -| [azurerm_private_dns_zone.dns_private_zone](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/private_dns_zone) | data source | -| [azurerm_resource_group.resource_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resource_group) | data source | -| [azurerm_resources.key_vault_from_name](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resources) | data source | -| [azurerm_resources.key_vault_from_tags](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resources) | data source | -| [azurerm_resources.vnet_from_name](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resources) | data source | -| [azurerm_resources.vnet_from_tags](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resources) | data source | -| [azurerm_subnet.subnet](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subnet) | data source | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [administrator\_password\_key\_vault\_secret\_name](#input\_administrator\_password\_key\_vault\_secret\_name) | Name of the Key Vault secret containing the administrator password | `string` | `null` | no | -| [dns\_private\_zone\_name](#input\_dns\_private\_zone\_name) | Name of the private DNS zone for the PostgreSQL server | `string` | `null` | no | -| [firewall\_rule](#input\_firewall\_rule) | List of firewall rules to allow access to the server |
list(object({
name = optional(string)
start_ip_address = optional(string)
end_ip_address = optional(string)
}))
| `[]` | no | -| [key\_vault](#input\_key\_vault) | Key Vault configuration object (name, resource group, tags) |
object({
name = optional(string)
resource_group_name = optional(string)
tags = optional(map(string))
})
| `{}` | no | -| [password\_length](#input\_password\_length) | Length of the generated administrator password | `number` | `20` | no | -| [postgresql\_flexible\_server](#input\_postgresql\_flexible\_server) | Configuration object for the PostgreSQL Flexible Server |
object({
name = string
location = string
version = optional(number)
public_network_access_enabled = optional(bool)
administrator_login = optional(string)
zone = optional(string)
storage_tier = optional(string)
storage_mb = optional(number)
sku_name = optional(string)
replication_role = optional(string)
create_mode = optional(string)
source_server_id = optional(string)
point_in_time_restore_time_in_utc = optional(string)
backup_retention_days = optional(number)
maintenance_window = optional(object({
day_of_week = number
start_hour = number
start_minute = number
}))
authentication = optional(object({
active_directory_auth_enabled = bool
password_auth_enabled = bool
tenant_id = optional(string)
}))
})
| n/a | yes | -| [postgresql\_flexible\_server\_configuration](#input\_postgresql\_flexible\_server\_configuration) | Map of configuration parameters for the PostgreSQL Flexible Server |
map(object({
name = optional(string)
value = optional(string)
}))
| n/a | yes | -| [resource\_group](#input\_resource\_group) | Name of the resource group where resources will be created | `string` | n/a | yes | -| [subnet\_name](#input\_subnet\_name) | Name of the subnet for the PostgreSQL Flexible Server | `string` | `null` | no | -| [tags](#input_tags) | Map of tags to assign to resources | `map(string)` | `{}` | no | -| [tags\_from\_rg](#input_tags_from_rg) | Whether to inherit tags from the resource group | `bool` | `false` | no | -| [vnet](#input_vnet) | Virtual Network configuration object (name, resource group, tags) |
object({
name = optional(string)
resource_group_name = optional(string)
tags = optional(map(string))
})
| `{}` | no | - -### Notes -You can create the `administrator_password_key_vault_secret_name` with the `random_password` resource or you can add it as a input. Also, if you create the password with this resource, you will need to do a `terraform apply` on the resource `azurerm_key_vault_secret.password_create` before create the postresql flexible server. - -You can use `name` and `resource_group_name` in `vnet` and `key_vault` variables as inputs to get the `data.azurerm_resource` or you can use `tags` as a input (`vnet.tags` and `key_vault.tags`) to get the data. - -If you set `public_network_access_enabled: true` you won't need the inputs `subnet_name` and `dns_private_zone_name`. You will need to add a list of IP's in `firewall_rule` to have access to the postresql flexible server instead. - -When you set `create_mode` to `PointInTimeRestore` you will need to add the outputs `source_server_id` and `point_in_time_restore_time_in_utc`. Read more about the PITR in the next paragraph (`create_mode` is set to `default` by default). - + +# Azure PostgreSQL Flexible Server Terraform Module -## PITR creation explanation - -When `create_mode = PointInTimeRestore`, you need to provide: - - 1. source_server_id: The resource ID of the original server from which to restore. - - 2. point_in_time_restore_time_in_utc: The timestamp (UTC) to restore from. - -PointInTimeRestore will do: - - 1. **Creates a new server**: This does not modify the original server, it creates a new one with a different name instead. - - 2. **Requieres a `source_server_id`**: The original server must have avaliable backups. - - 3. **Must provide a restore timestamp**: `point_in_time_restore_time_in_utc` must be within the backup retention period. - - 4. Once restored, you may want to change `create_mode` to `Default` to avoid reapplying the restore when running `terraform apply` again. - - 5. If the original server is deleted, the PITR server remains unafected. - - 6. If `point_in_time_restore_time_in_utc` is not within the retention period, the restore will fail. - - 7. The format of `point_in_time_restore_time_in_utc` must be `Year-Month-DayTHour:Min:sec+00:00` or the restore will fail, for example `2025-03-14T08:26:31Z`(https://en.wikipedia.org/wiki/ISO_8601). - -## Get list of PiTRs backups - -```yaml -az postgres flexible-server backup list --resource-group my-resource-group --name my-server-name -``` +## Overview -## Outputs +Este módulo de Terraform permite crear y gestionar un servidor PostgreSQL Flexible en Azure, con soporte para: +- Creación de servidor, configuraciones, firewall y restauración PITR. +- Integración con Key Vault para contraseñas seguras. +- Soporte para redes privadas, subredes y DNS privados. +- Configuración avanzada de autenticación, backup y mantenimiento. -| Name | Description | -|------|-------------| -| [id](#output\_id) | The ID of the postgresql flexible server | +## Características principales +- Creación de PostgreSQL Flexible Server con opciones avanzadas. +- Soporte para restauración Point-in-Time (PITR). +- Gestión de configuraciones y reglas de firewall. +- Integración con Key Vault y redes privadas. +- Ejemplo realista de configuración. -## Example Usage +## Ejemplo completo de uso ```yaml values: @@ -146,3 +63,90 @@ values: name: "example-configuration" value: "TRUE" ``` + +## Notas +- Puedes usar Key Vault para gestionar la contraseña del administrador. +- Si usas red privada, debes especificar subnet y DNS privado. +- Para restauración PITR, consulta la sección de la documentación sobre create\_mode. + +## Estructura de archivos + +``` +. +├── main.tf +├── variables.tf +├── outputs.tf +├── README.md +├── CHANGELOG.md +└── docs/ + ├── header.md + └── footer.md +``` + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.7.0 | +| [azurerm](#requirement\_azurerm) | >= 4.35.0 | + +## Providers + +| Name | Version | +|------|---------| +| [azurerm](#provider\_azurerm) | >= 4.35.0 | +| [random](#provider\_random) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [azurerm_key_vault_secret.password_create](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret) | resource | +| [azurerm_postgresql_flexible_server.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/postgresql_flexible_server) | resource | +| [azurerm_postgresql_flexible_server_configuration.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/postgresql_flexible_server_configuration) | resource | +| [azurerm_postgresql_flexible_server_firewall_rule.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/postgresql_flexible_server_firewall_rule) | resource | +| [random_password.password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | +| [azurerm_key_vault_secret.administrator_password](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/key_vault_secret) | data source | +| [azurerm_private_dns_zone.dns_private_zone](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/private_dns_zone) | data source | +| [azurerm_resource_group.resource_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resource_group) | data source | +| [azurerm_resources.key_vault_from_name](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resources) | data source | +| [azurerm_resources.key_vault_from_tags](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resources) | data source | +| [azurerm_resources.vnet_from_name](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resources) | data source | +| [azurerm_resources.vnet_from_tags](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resources) | data source | +| [azurerm_subnet.subnet](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subnet) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [administrator\_password\_key\_vault\_secret\_name](#input\_administrator\_password\_key\_vault\_secret\_name) | n/a | `string` | `null` | no | +| [dns\_private\_zone\_name](#input\_dns\_private\_zone\_name) | n/a | `string` | `null` | no | +| [firewall\_rule](#input\_firewall\_rule) | n/a |
list(object({
name = optional(string)
start_ip_address = optional(string)
end_ip_address = optional(string)
}))
| `[]` | no | +| [key\_vault](#input\_key\_vault) | n/a |
object({
name = optional(string)
resource_group_name = optional(string)
tags = optional(map(string))
})
| `{}` | no | +| [password\_length](#input\_password\_length) | n/a | `number` | `20` | no | +| [postgresql\_flexible\_server](#input\_postgresql\_flexible\_server) | n/a |
object({
name = string
location = string
version = optional(number)
public_network_access_enabled = optional(bool)
administrator_login = optional(string)
zone = optional(string)
storage_tier = optional(string)
storage_mb = optional(number)
sku_name = optional(string)
replication_role = optional(string)
create_mode = optional(string)
source_server_id = optional(string)
point_in_time_restore_time_in_utc = optional(string)
backup_retention_days = optional(number)
maintenance_window = optional(object({
day_of_week = number
start_hour = number
start_minute = number
}))
authentication = optional(object({
active_directory_auth_enabled = bool
password_auth_enabled = bool
tenant_id = optional(string)
}))
})
| n/a | yes | +| [postgresql\_flexible\_server\_configuration](#input\_postgresql\_flexible\_server\_configuration) | n/a |
map(object({
name = optional(string)
value = optional(string)
}))
| n/a | yes | +| [resource\_group](#input\_resource\_group) | n/a | `string` | n/a | yes | +| [subnet\_name](#input\_subnet\_name) | n/a | `string` | `null` | no | +| [tags](#input\_tags) | n/a | `map(string)` | `{}` | no | +| [tags\_from\_rg](#input\_tags\_from\_rg) | n/a | `bool` | `false` | no | +| [vnet](#input\_vnet) | n/a |
object({
name = optional(string)
resource_group_name = optional(string)
tags = optional(map(string))
})
| `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [id](#output\_id) | n/a | + +## Recursos y soporte + +- [Documentación oficial de Azure PostgreSQL Flexible Server](https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/) +- [Referencia de Terraform para azurerm\_postgresql\_flexible\_server](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/postgresql_flexible_server) +- [Soporte de la comunidad](https://github.com/prefapp/terraform-modules/discussions) + +¿Necesitas ayuda? Abre un issue o participa en la comunidad Prefapp. + \ No newline at end of file diff --git a/modules/azure-flexible-server-postgresql/_examples/basic/main.tf b/modules/azure-flexible-server-postgresql/_examples/basic/main.tf new file mode 100644 index 000000000..01cd853fd --- /dev/null +++ b/modules/azure-flexible-server-postgresql/_examples/basic/main.tf @@ -0,0 +1,60 @@ +module "azure_flexible_server_postgresql" { + source = "../../" + + resource_group = "example-resource-group" + tags_from_rg = true + + key_vault = { + tags = { + value = "tag1" + } + } + + vnet = { + tags = { + value = "tag1" + } + } + + subnet_name = "example-subnet" + dns_private_zone_name = "dns.private.zone.example.com" + administrator_password_key_vault_secret_name = "flexible-server-secret-example-test" + password_length = 10 + + postgresql_flexible_server = { + location = "westeurope" + name = "example-flexible-server" + version = 15 + administrator_login = "psqladmin" + public_network_access_enabled = false + storage_mb = 65536 + sku_name = "GP_Standard_D2ds_v5" + backup_retention_days = 30 + maintenance_window = { + day_of_week = 6 + start_hour = 0 + start_minute = 0 + } + authentication = { + active_directory_auth_enabled = false + password_auth_enabled = true + } + } + + postgresql_flexible_server_configuration = { + "azure.extensions" = { + name = "azure.extensions" + value = "extension1,extension2" + } + "configuration1" = { + name = "example-configuration" + value = "TRUE" + } + } + + firewall_rule = [] + + tags = { + environment = "dev" + } +} diff --git a/modules/azure-flexible-server-postgresql/_examples/basic/values.yaml b/modules/azure-flexible-server-postgresql/_examples/basic/values.yaml new file mode 100644 index 000000000..b21b1a14f --- /dev/null +++ b/modules/azure-flexible-server-postgresql/_examples/basic/values.yaml @@ -0,0 +1,45 @@ +resource_group: example-resource-group +tags_from_rg: true + +key_vault: + tags: + value: tag1 + +vnet: + tags: + value: tag1 + +subnet_name: example-subnet +dns_private_zone_name: dns.private.zone.example.com +administrator_password_key_vault_secret_name: flexible-server-secret-example-test +password_length: 10 + +postgresql_flexible_server: + location: westeurope + name: example-flexible-server + version: 15 + administrator_login: psqladmin + public_network_access_enabled: false + storage_mb: 65536 + sku_name: GP_Standard_D2ds_v5 + backup_retention_days: 30 + maintenance_window: + day_of_week: 6 + start_hour: 0 + start_minute: 0 + authentication: + active_directory_auth_enabled: false + password_auth_enabled: true + +postgresql_flexible_server_configuration: + azure.extensions: + name: azure.extensions + value: extension1,extension2 + configuration1: + name: example-configuration + value: "TRUE" + +firewall_rule: [] + +tags: + environment: dev diff --git a/modules/azure-flexible-server-postgresql/docs/footer.md b/modules/azure-flexible-server-postgresql/docs/footer.md new file mode 100644 index 000000000..f8d72d11f --- /dev/null +++ b/modules/azure-flexible-server-postgresql/docs/footer.md @@ -0,0 +1,7 @@ +## Recursos y soporte + +- [Documentación oficial de Azure PostgreSQL Flexible Server](https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/) +- [Referencia de Terraform para azurerm_postgresql_flexible_server](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/postgresql_flexible_server) +- [Soporte de la comunidad](https://github.com/prefapp/terraform-modules/discussions) + +¿Necesitas ayuda? Abre un issue o participa en la comunidad Prefapp. \ No newline at end of file diff --git a/modules/azure-flexible-server-postgresql/docs/header.md b/modules/azure-flexible-server-postgresql/docs/header.md new file mode 100644 index 000000000..bf15fe4c6 --- /dev/null +++ b/modules/azure-flexible-server-postgresql/docs/header.md @@ -0,0 +1,83 @@ +# Azure PostgreSQL Flexible Server Terraform Module + +## Overview + +Este módulo de Terraform permite crear y gestionar un servidor PostgreSQL Flexible en Azure, con soporte para: +- Creación de servidor, configuraciones, firewall y restauración PITR. +- Integración con Key Vault para contraseñas seguras. +- Soporte para redes privadas, subredes y DNS privados. +- Configuración avanzada de autenticación, backup y mantenimiento. + +## Características principales +- Creación de PostgreSQL Flexible Server con opciones avanzadas. +- Soporte para restauración Point-in-Time (PITR). +- Gestión de configuraciones y reglas de firewall. +- Integración con Key Vault y redes privadas. +- Ejemplo realista de configuración. + +## Ejemplo completo de uso + +```yaml +values: + resource_group: "example-resource-group" + tags_from_rg: true + key_vault: + tags: + value: "tag1" + #name: "key-vault-name" + #resource_group_name: "key-vault-resource-group-name" + vnet: + tags: + value: "tag1" + #name: "example-vnet" + #resource_group_name: "vnet-resource-group-name" + subnet_name: "example-subnet" + dns_private_zone_name: "dns.private.zone.example.com" + administrator_password_key_vault_secret_name: "flexible-server-secret-example-test" + password_length: 10 + postgresql_flexible_server: + location: "westeurope" + name: "example-flexible-server" + version: "15" + administrator_login: "psqladmin" + public_network_access_enabled: false + storage_mb: "65536" + sku_name: "GP_Standard_D2ds_v5" + backup_retention_days: 30 + #create_mode: "PointInTimeRestore" + #source_server_id: "/subscriptions/xxxxxx-xxxx-xxxx-xxxxxx/resourceGroups/example-resource-group/providers/Microsoft.DBforPostgreSQL/flexibleServers/example-flexible-server" + #point_in_time_restore_time_in_utc: "2025-02-21T09:35:43Z" + maintenance_window: + day_of_week: 6 + start_hour: 0 + start_minute: 0 + authentication: + active_directory_auth_enabled: false + password_auth_enabled: true + postgresql_flexible_server_configuration: + azure.extensions: + name: "azure.extensions" + value: "extension1,extension2" + configuration1: + name: "example-configuration" + value: "TRUE" +``` + +## Notas +- Puedes usar Key Vault para gestionar la contraseña del administrador. +- Si usas red privada, debes especificar subnet y DNS privado. +- Para restauración PITR, consulta la sección de la documentación sobre create_mode. + +## Estructura de archivos + +``` +. +├── main.tf +├── variables.tf +├── outputs.tf +├── README.md +├── CHANGELOG.md +└── docs/ + ├── header.md + └── footer.md +```