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

Azure SQL Server module #13

Merged
merged 11 commits into from
Sep 17, 2024
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 1.0.6 (TBD)

### Features
- Azure SQL Server module

## 1.0.5 (2024-08-29)

### Features
Expand Down
4 changes: 4 additions & 0 deletions DSF_VERSION_COMPATABILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,9 @@ The following table lists the DSF versions that each module is tested and mainta
<td>onboard-aws-rds-redshift</td>
<td>4.17+</td>
</tr>
<tr>
<td>onboard-azure-ms-sql-server</td>
<td>4.17+</td>
</tr>

</table>
48 changes: 48 additions & 0 deletions examples/onboard-azure-ms-sql-server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Onboard Azure SQL Server example
This example includes additional prerequisites that will need to be completed to fully utilize the module. More details can be found in the [onboarding documentation](https://docs.imperva.com/bundle/onboarding-databases-to-sonar-reference-guide/page/Azure-SQL-Server-Onboarding-Steps_48367377.html).

This example creates both 'azurerm' and 'dsfhub' resources. More information regarding authentication to each can be found in the relevant provider documentation:
- [azurerm](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs)
- [dsfhub](https://registry.terraform.io/providers/imperva/dsfhub/latest/docs)

## Prerequisites
This module expects an Event Hub and a Storage Account Container to have been created in advance, in addition to a corresponding existing AZURE EVENTHUB asset in DSF. Both of these prerequisites and all related resources are handled in the ``onboard-azure-eventhub`` module.

### Azure Event Hub Namespace and Event Hub
SQL Server audit logs are sent to an Azure Event Hub and are retrieved by DSF. The Event Hubs are created within an Event Hub Namespace, which can contain one or more Event Hubs. Audit logs of multiple SQL Server instances can be sent to a single Event Hub.

### Azure Storage Account and Container
Storage Containers are used to store transactional data for the Event Hub import processes, and one Storage Container is required for each Event Hub. These Storage Containers exists within a Storage Account, which may contain multiple Storage Containers.

<!-- BEGIN_TF_DOCS -->
## Requirements

No requirements.

## Providers

No providers.

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_azure-ms-sql-server-1"></a> [azure-ms-sql-server-1](#module\_azure-ms-sql-server-1) | ../../modules/onboard-azure-ms-sql-server | n/a |
| <a name="module_azure-ms-sql-server-2"></a> [azure-ms-sql-server-2](#module\_azure-ms-sql-server-2) | ../../modules/onboard-azure-ms-sql-server | n/a |
| <a name="module_onboard-azure-sql-server-eventhub-1"></a> [onboard-azure-sql-server-eventhub-1](#module\_onboard-azure-sql-server-eventhub-1) | ../../modules/onboard-azure-eventhub | n/a |

## Resources

No resources.

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_dsfhub_host"></a> [dsfhub\_host](#input\_dsfhub\_host) | n/a | `any` | n/a | yes |
| <a name="input_dsfhub_token"></a> [dsfhub\_token](#input\_dsfhub\_token) | n/a | `any` | n/a | yes |

## Outputs

No outputs.
<!-- END_TF_DOCS -->
120 changes: 120 additions & 0 deletions examples/onboard-azure-ms-sql-server/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
locals {
azure_location = "East US"
azure_resource_group_name = "My_Resource_Group"
azure_subscription_id = "123456790-wxyz-g8h9-e5f6-a1b2c3d4"

admin_email = "test@example.com"
gateway_id = "a1b2c3d4-e5f6-g8h9-wxyz-123456790"
}

################################################################################
# Providers
################################################################################
terraform {
required_providers {
dsfhub = {
source = "imperva/dsfhub"
}
}
}

provider "azurerm" {
features {}
subscription_id = local.azure_subscription_id
}

variable "dsfhub_host" {} # TF_VAR_dsfhub_host env variable
variable "dsfhub_token" {} # TF_VAR_dsfhub_token env variable

provider "dsfhub" {
dsfhub_host = var.dsfhub_host
dsfhub_token = var.dsfhub_token
}

################################################################################
# Prerequisites
# 1. Azure Event Hub Namespace and Event Hub. Includes authorization rules for
# reading and writing to the Event Hub.
# 2. Storage Account and Container
################################################################################
module "onboard-azure-sql-server-eventhub-1" {
source = "../../modules/onboard-azure-eventhub"

azure_eventhub_admin_email = local.admin_email
azure_eventhub_format = "Sql"
azure_eventhub_gateway_id = local.gateway_id

eventhub_name = "sqlservereventhub"
eventhub_namespace_location = local.azure_location
eventhub_namespace_name = "sqlservereventhubns"
eventhub_namespace_resource_group_name = local.azure_resource_group_name

eventhub_resource_group_name = local.azure_resource_group_name

storage_account_location = local.azure_location
storage_account_name = "sqlserverstorageacc"
storage_account_resource_group_name = local.azure_resource_group_name
storage_container_name = "sqlserverstoragecon"
}

################################################################################
# Azure SQL Server
################################################################################
module "azure-ms-sql-server-1" {
source = "../../modules/onboard-azure-ms-sql-server"

depends_on = [module.onboard-azure-sql-server-eventhub-1]

azure_ms_sql_server_admin_email = local.admin_email
azure_ms_sql_server_audit_pull_enabled = true
azure_ms_sql_server_gateway_id = local.gateway_id
azure_ms_sql_server_location = local.azure_location
azure_ms_sql_server_logs_destination_asset_id = module.onboard-azure-sql-server-eventhub-1.azure-eventhub-asset.asset_id

diagnostic_setting_eventhub_authorization_rule_id = module.onboard-azure-sql-server-eventhub-1.eventhub-write-authorization.id
diagnostic_setting_eventhub_name = module.onboard-azure-sql-server-eventhub-1.eventhub.name
diagnostic_setting_name = "dsfhubdiagnostic"

server_administrator_login = "exampleadmin"
server_administrator_login_password = "Abcd1234"
server_location = local.azure_location
server_name = "example-azure-sql-server"
server_public_network_access_enabled = true
server_resource_group_name = local.azure_resource_group_name
}

################################################################################
# Azure SQL Server Many-to-One
################################################################################
locals {
sql_server_types = toset([
"dev",
"prod",
"uat"
])
}

module "azure-ms-sql-server-2" {
source = "../../modules/onboard-azure-ms-sql-server"

depends_on = [module.onboard-azure-sql-server-eventhub-1]

for_each = local.sql_server_types

azure_ms_sql_server_admin_email = local.admin_email
azure_ms_sql_server_audit_pull_enabled = true
azure_ms_sql_server_gateway_id = local.gateway_id
azure_ms_sql_server_location = local.azure_location
azure_ms_sql_server_logs_destination_asset_id = module.onboard-azure-sql-server-eventhub-1.azure-eventhub-asset.asset_id

diagnostic_setting_eventhub_authorization_rule_id = module.onboard-azure-sql-server-eventhub-1.eventhub-write-authorization.id
diagnostic_setting_eventhub_name = module.onboard-azure-sql-server-eventhub-1.eventhub.name
diagnostic_setting_name = "dsfhubdiagnostic"

server_administrator_login = "exampleadmin"
server_administrator_login_password = "Abcd1234"
server_location = local.azure_location
server_name = "example-azure-sql-server-${each.key}"
server_public_network_access_enabled = true
server_resource_group_name = local.azure_resource_group_name
}
38 changes: 38 additions & 0 deletions modules/azurerm-eventhub-namespace-authorization-rule/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!-- BEGIN_TF_DOCS -->
## Requirements

No requirements.

## Providers

| Name | Version |
|------|---------|
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | n/a |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [azurerm_eventhub_namespace_authorization_rule.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/eventhub_namespace_authorization_rule) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_listen"></a> [listen](#input\_listen) | Grants listen access to this Authorization Rule. Defaults to false. | `bool` | `false` | no |
| <a name="input_manage"></a> [manage](#input\_manage) | Grants manage access to this Authorization Rule. When this property is true - both listen and send must be too. Defaults to false. | `bool` | `false` | no |
| <a name="input_name"></a> [name](#input\_name) | Specifies the name of the Authorization Rule. Changing this forces a new resource to be created. | `string` | n/a | yes |
| <a name="input_namespace_name"></a> [namespace\_name](#input\_namespace\_name) | Specifies the name of the Event Hub Namespace. Changing this forces a new resource to be created. | `string` | n/a | yes |
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | The name of the resource group in which the Event Hub Namespace exists. Changing this forces a new resource to be created. | `string` | n/a | yes |
| <a name="input_send"></a> [send](#input\_send) | Grants send access to this Authorization Rule. Defaults to false. | `bool` | `false` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_this"></a> [this](#output\_this) | Authorization Rule for an Event Hub Namespace |
<!-- END_TF_DOCS -->
17 changes: 17 additions & 0 deletions modules/azurerm-eventhub-namespace-authorization-rule/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
resource "azurerm_eventhub_namespace_authorization_rule" "this" {
lifecycle {
# todo: add precondition ensuring atleast one of manage, send, listen is defined

precondition {
condition = var.manage == true ? (var.listen == true && var.send == true) : true
error_message = "When manage is set to true, both listen and send must be too."
}
}

listen = var.listen
manage = var.manage
name = var.name
namespace_name = var.namespace_name
resource_group_name = var.resource_group_name
send = var.send
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
output "this" {
description = "Authorization Rule for an Event Hub Namespace"
value = azurerm_eventhub_namespace_authorization_rule.this
}
32 changes: 32 additions & 0 deletions modules/azurerm-eventhub-namespace-authorization-rule/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
variable "listen" {
description = "Grants listen access to this Authorization Rule. Defaults to false."
type = bool
default = false
}

variable "manage" {
description = "Grants manage access to this Authorization Rule. When this property is true - both listen and send must be too. Defaults to false."
type = bool
default = false
}

variable "name" {
description = "Specifies the name of the Authorization Rule. Changing this forces a new resource to be created."
type = string
}

variable "namespace_name" {
description = "Specifies the name of the Event Hub Namespace. Changing this forces a new resource to be created."
type = string
}

variable "resource_group_name" {
description = "The name of the resource group in which the Event Hub Namespace exists. Changing this forces a new resource to be created."
type = string
}

variable "send" {
description = "Grants send access to this Authorization Rule. Defaults to false."
type = bool
default = false
}
39 changes: 39 additions & 0 deletions modules/azurerm-eventhub-namespace/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!-- BEGIN_TF_DOCS -->
## Requirements

No requirements.

## Providers

| Name | Version |
|------|---------|
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | n/a |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [azurerm_eventhub_namespace.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/eventhub_namespace) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_capacity"></a> [capacity](#input\_capacity) | Specifies the Capacity / Throughput Units for a Standard SKU namespace. Defaults to 1. | `number` | `1` | no |
| <a name="input_location"></a> [location](#input\_location) | Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. | `string` | n/a | yes |
| <a name="input_name"></a> [name](#input\_name) | Specifies the name of the Event Hub Namespace resource. Changing this forces a new resource to be created. | `string` | n/a | yes |
| <a name="input_public_network_access_enabled"></a> [public\_network\_access\_enabled](#input\_public\_network\_access\_enabled) | Is public network access enabled for the Event Hub Namespace? Defaults to true. | `bool` | `true` | no |
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | The name of the resource group in which to create the namespace. Changing this forces a new resource to be created. | `string` | n/a | yes |
| <a name="input_sku"></a> [sku](#input\_sku) | Defines which tier to use. Valid options are Basic, Standard, and Premium. Please note that setting this field to Premium will force the creation of a new resource. | `string` | `"Basic"` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A mapping of tags to assign to the resource. | `map(string)` | `null` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_this"></a> [this](#output\_this) | Azure Event Hub Namespace |
<!-- END_TF_DOCS -->
9 changes: 9 additions & 0 deletions modules/azurerm-eventhub-namespace/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
resource "azurerm_eventhub_namespace" "this" {
capacity = var.capacity
location = var.location
name = var.name
public_network_access_enabled = var.public_network_access_enabled
resource_group_name = var.resource_group_name
sku = var.sku
tags = var.tags
}
4 changes: 4 additions & 0 deletions modules/azurerm-eventhub-namespace/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
output "this" {
description = "Azure Event Hub Namespace"
value = azurerm_eventhub_namespace.this
}
42 changes: 42 additions & 0 deletions modules/azurerm-eventhub-namespace/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
variable "capacity" {
description = "Specifies the Capacity / Throughput Units for a Standard SKU namespace. Defaults to 1."
type = number
default = 1
}

variable "location" {
description = "Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created."
type = string
}

variable "name" {
description = "Specifies the name of the Event Hub Namespace resource. Changing this forces a new resource to be created."
type = string
}

variable "public_network_access_enabled" {
description = "Is public network access enabled for the Event Hub Namespace? Defaults to true."
type = bool
default = true
}

variable "resource_group_name" {
description = "The name of the resource group in which to create the namespace. Changing this forces a new resource to be created."
type = string
}

variable "sku" {
description = "Defines which tier to use. Valid options are Basic, Standard, and Premium. Please note that setting this field to Premium will force the creation of a new resource."
type = string
default = "Basic"
validation {
condition = contains(["Basic", "Standard", "Premium"], var.sku)
error_message = "Invalid sku. Valid options are Basic, Standard, and Premium."
}
}

variable "tags" {
description = "A mapping of tags to assign to the resource."
type = map(string)
default = null
}
Loading