diff --git a/CHANGELOG.md b/CHANGELOG.md index 34993d9..cee09e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 1.0.6 (TBD) + +### Features +- Amazon RDS SQL Server module + ## 1.0.4 (2024-07-25) ### Features diff --git a/DSF_VERSION_COMPATABILITY.md b/DSF_VERSION_COMPATABILITY.md index 2724c10..6e08340 100644 --- a/DSF_VERSION_COMPATABILITY.md +++ b/DSF_VERSION_COMPATABILITY.md @@ -20,14 +20,6 @@ The following table lists the DSF versions that each module is tested and mainta 4.17+ - onboard-aws-rds-neptune - 4.17+ - - - onboard-aws-rds-neptune-slow-query - 4.17+ - - onboard-aws-rds-aurora-mysql 4.17+ @@ -54,10 +46,22 @@ The following table lists the DSF versions that each module is tested and mainta onboard-aws-rds-mysql 4.16+ + + + onboard-aws-rds-ms-sql-server + 4.17+ onboard-aws-rds-mysql-slow-query 4.16+ + + + onboard-aws-rds-neptune + 4.17+ + + + onboard-aws-rds-neptune-slow-query + 4.17+ onboard-aws-rds-oracle-standard diff --git a/examples/onboard-aws-rds-ms-sql-server/README.md b/examples/onboard-aws-rds-ms-sql-server/README.md new file mode 100644 index 0000000..693bce1 --- /dev/null +++ b/examples/onboard-aws-rds-ms-sql-server/README.md @@ -0,0 +1,64 @@ +# Onboard Amazon RDS for 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/Amazon-RDS-for-SQL-Server-Onboarding-Steps_48367099.html). + +It creates both 'aws' and 'dsfhub' resources. More information regarding authentication to each one can be found in the relevant provider documentation: +- [aws](https://registry.terraform.io/providers/hashicorp/aws/latest/docs) +- [dsfhub](https://registry.terraform.io/providers/imperva/dsfhub/latest/docs) + +## Prerequisites +### Database Configuration +Part of the onboarding process involves connecting to your RDS MS SQL Server instance and running SQL commands to create an audit policy. This module includes an example for how to connect to the instance from your local machine and create it. + +**Note:** This example requires the ``sqlcmd`` client to be installed, as well as for the newly created RDS MS SQL Server instance to be accessible from your local machine. + +### Account Asset Permissions +An AWS account asset will need to be onboarded to your DSF hub prior to using this module. The account asset will need to be granted permissions to be able to read from the newly created S3 bucket. In addition, the cloud account should be granted these additional permissions: + +``` +rds:DescribeOptionGroups +s3:GetObject +s3:ListBucket +s3:ListAllMyBuckets +``` + + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | n/a | +| [terraform](#provider\_terraform) | n/a | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [aws-default-account-asset](#module\_aws-default-account-asset) | imperva/agentless-onboarding/dsfhub//modules/dsfhub-aws-cloud-account | n/a | +| [aws-rds-ms-sql-server-1](#module\_aws-rds-ms-sql-server-1) | ../../modules/onboard-aws-rds-ms-sql-server | n/a | +| [aws-rds-ms-sql-server-2](#module\_aws-rds-ms-sql-server-2) | ../../modules/onboard-aws-rds-ms-sql-server | n/a | +| [aws-rds-ms-sql-server-3](#module\_aws-rds-ms-sql-server-3) | ../../modules/onboard-aws-rds-ms-sql-server | n/a | + +## Resources + +| Name | Type | +|------|------| +| [terraform_data.configure_database-1](https://registry.terraform.io/providers/hashicorp/terraform/latest/docs/resources/data) | resource | +| [terraform_data.configure_database-2](https://registry.terraform.io/providers/hashicorp/terraform/latest/docs/resources/data) | resource | +| [terraform_data.configure_database-3](https://registry.terraform.io/providers/hashicorp/terraform/latest/docs/resources/data) | resource | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [dsfhub\_host](#input\_dsfhub\_host) | n/a | `any` | n/a | yes | +| [dsfhub\_token](#input\_dsfhub\_token) | n/a | `any` | n/a | yes | + +## Outputs + +No outputs. + \ No newline at end of file diff --git a/examples/onboard-aws-rds-ms-sql-server/configure_audit_policy.sql b/examples/onboard-aws-rds-ms-sql-server/configure_audit_policy.sql new file mode 100644 index 0000000..bf436b6 --- /dev/null +++ b/examples/onboard-aws-rds-ms-sql-server/configure_audit_policy.sql @@ -0,0 +1,101 @@ +DECLARE + @server_audit AS VARCHAR(50) = '$(server_audit)', + @server_audit_spec_name AS VARCHAR(50) = '$(audit_spec_name)', + @server_audit_spec AS VARCHAR(3000), + @server_audit_status INT, + @sql_command AS VARCHAR(3000) + +USE master; + +-- Create server audit +IF (EXISTS (SELECT * FROM sys.dm_server_audit_status where name = @server_audit)) + BEGIN + PRINT 'Server audit "' + @server_audit + '" already exists.'; + END +ELSE + BEGIN + PRINT 'Creating server audit "' + @server_audit + '"'; + + SET @sql_command = 'CREATE SERVER AUDIT ' + @server_audit + ' TO FILE (FILEPATH = ''D:\rdsdbdata\SQLAudit\'', MAXSIZE = 2 MB) WITH (QUEUE_DELAY = 1000, ON_FAILURE = CONTINUE)'; + EXECUTE(@sql_command); + END; + +-- Enable server audit +select @server_audit_status = status FROM sys.dm_server_audit_status where name = @server_audit; + +IF (@server_audit_status = 1) + BEGIN + PRINT 'Server audit "' + @server_audit + '" is already enabled.'; + END; +ELSE + BEGIN + PRINT 'Enabling server audit "' + @server_audit + '"'; + + SET @sql_command = 'ALTER SERVER AUDIT ' + @server_audit + ' WITH (STATE = ON)'; + EXECUTE(@sql_command); + END; + + +-- Create server audit specification +IF (EXISTS (SELECT * FROM sys.server_audit_specifications where name = @server_audit_spec_name)) + BEGIN + PRINT 'Server audit specification "' + @server_audit_spec_name + '" already exists.'; + END; +ELSE + BEGIN + PRINT 'Creating server audit specification "' + @server_audit_spec_name + '"'; + + -- This creates a server audit specification that captures all server-level and database-level events. + -- Modify or add additional groups as needed. + -- For all action groups available, see https://learn.microsoft.com/en-us/sql/relational-databases/security/auditing/sql-server-audit-action-groups-and-actions?view=sql-server-ver15 + SET @server_audit_spec = 'ADD (APPLICATION_ROLE_CHANGE_PASSWORD_GROUP), +ADD (AUDIT_CHANGE_GROUP), +ADD (BACKUP_RESTORE_GROUP), +ADD (BATCH_COMPLETED_GROUP), +ADD (BATCH_STARTED_GROUP), +ADD (BROKER_LOGIN_GROUP), +ADD (DATABASE_CHANGE_GROUP), +ADD (DATABASE_LOGOUT_GROUP), +ADD (DATABASE_MIRRORING_LOGIN_GROUP), +ADD (DATABASE_OBJECT_ACCESS_GROUP), +ADD (DATABASE_OBJECT_CHANGE_GROUP), +ADD (DATABASE_OBJECT_OWNERSHIP_CHANGE_GROUP), +ADD (DATABASE_OBJECT_PERMISSION_CHANGE_GROUP), +ADD (DATABASE_OPERATION_GROUP), +ADD (DATABASE_OWNERSHIP_CHANGE_GROUP), +ADD (DATABASE_PERMISSION_CHANGE_GROUP), +ADD (DATABASE_PRINCIPAL_CHANGE_GROUP), +ADD (DATABASE_PRINCIPAL_IMPERSONATION_GROUP), +ADD (DATABASE_ROLE_MEMBER_CHANGE_GROUP), +ADD (DBCC_GROUP), +ADD (FAILED_DATABASE_AUTHENTICATION_GROUP), +ADD (FAILED_LOGIN_GROUP), +ADD (FULLTEXT_GROUP), +ADD (LOGIN_CHANGE_PASSWORD_GROUP), +ADD (LOGOUT_GROUP), +ADD (SCHEMA_OBJECT_ACCESS_GROUP), +ADD (SCHEMA_OBJECT_CHANGE_GROUP), +ADD (SCHEMA_OBJECT_OWNERSHIP_CHANGE_GROUP), +ADD (SCHEMA_OBJECT_PERMISSION_CHANGE_GROUP), +ADD (SERVER_OBJECT_CHANGE_GROUP), +ADD (SERVER_OBJECT_OWNERSHIP_CHANGE_GROUP), +ADD (SERVER_OBJECT_PERMISSION_CHANGE_GROUP), +ADD (SERVER_OPERATION_GROUP), +ADD (SERVER_PERMISSION_CHANGE_GROUP), +ADD (SERVER_PRINCIPAL_CHANGE_GROUP), +ADD (SERVER_PRINCIPAL_IMPERSONATION_GROUP), +ADD (SERVER_ROLE_MEMBER_CHANGE_GROUP), +ADD (SERVER_STATE_CHANGE_GROUP), +ADD (SUCCESSFUL_DATABASE_AUTHENTICATION_GROUP), +ADD (SUCCESSFUL_LOGIN_GROUP), +ADD (TRACE_CHANGE_GROUP), +ADD (TRANSACTION_GROUP), +ADD (USER_CHANGE_PASSWORD_GROUP), +ADD (USER_DEFINED_AUDIT_GROUP) +WITH (STATE = ON)'; + + SET @sql_command = 'CREATE SERVER AUDIT SPECIFICATION ' + @server_audit_spec_name + ' FOR SERVER AUDIT ' + @server_audit + ' ' + @server_audit_spec; + EXECUTE(@sql_command); + END; + +GO \ No newline at end of file diff --git a/examples/onboard-aws-rds-ms-sql-server/configure_database.sh b/examples/onboard-aws-rds-ms-sql-server/configure_database.sh new file mode 100644 index 0000000..89f63c8 --- /dev/null +++ b/examples/onboard-aws-rds-ms-sql-server/configure_database.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# Creates an audit policy on an SQL Server instance using the 'sqlcmd' client + +# Settings +current_directory=$(dirname "$(realpath "${BASH_SOURCE[0]}")") +policy_sql_file="${current_directory}/configure_audit_policy.sql" + +# Functions +function is_pkg_installed { + local pkg="$1" + if ! command -v "${pkg}" &> /dev/null + then + echo "Package '${pkg}' is not installed." + echo "Please see https://learn.microsoft.com/en-us/sql/tools/sqlcmd/sqlcmd-utility for installation instructions for your OS." + echo "Exiting..." + exit 1 + else + return 0 + fi +} + +is_pkg_installed "sqlcmd" + +# Create server audit with server audit specification +if [ ! -r "${policy_sql_file}" ]; then + echo "Unable to read ${policy_sql_file}" + echo "Exiting..." + exit 1 +else + sqlcmd -S tcp:${ENDPOINT} -U ${ADMIN_USER} -P ${ADMIN_PASSWORD} -v server_audit=${SERVER_AUDIT_NAME} -v audit_spec_name=${SERVER_AUDIT_SPEC_NAME} -C < ${policy_sql_file} +fi \ No newline at end of file diff --git a/examples/onboard-aws-rds-ms-sql-server/main.tf b/examples/onboard-aws-rds-ms-sql-server/main.tf new file mode 100644 index 0000000..509aac6 --- /dev/null +++ b/examples/onboard-aws-rds-ms-sql-server/main.tf @@ -0,0 +1,244 @@ +locals { + aws_region = "us-east-1" + apply_immediately = true + master_user = "admin" + master_password = "Abcd1234" + + server_audit_name = "tfmssqls3serveraudit" + server_audit_spec_name = "tfmssqls3serverauditspec" + + admin_email = "test@example.com" + gateway_id = "a1b2c3d4-e5f6-g8h9-wxyz-123456790" +} + + +################################################################################ +# Providers +################################################################################ +terraform { + required_providers { + dsfhub = { + source = "imperva/dsfhub" + } + } +} + +provider "aws" { + region = local.aws_region +} + +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. Method to create the server audit and server audit specification +# 2. AWS cloud account +################################################################################ +# 1. Run shell script locally to create the server audit and server audit specification +resource "terraform_data" "configure_database-1" { + count = length(module.aws-rds-ms-sql-server-1.rds-sql-server-instance) + + depends_on = [module.aws-rds-ms-sql-server-1] + + provisioner "local-exec" { + environment = { + ADMIN_USER = local.master_user + ADMIN_PASSWORD = local.master_password + ENDPOINT = module.aws-rds-ms-sql-server-1.rds-sql-server-instance[count.index].endpoint + + SERVER_AUDIT_NAME = local.server_audit_name + SERVER_AUDIT_SPEC_NAME = local.server_audit_spec_name + } + + command = "./configure_database.sh" + + on_failure = fail + } +} + +resource "terraform_data" "configure_database-2" { + count = length(module.aws-rds-ms-sql-server-2.rds-sql-server-instance) + + depends_on = [module.aws-rds-ms-sql-server-2] + + provisioner "local-exec" { + environment = { + ADMIN_USER = local.master_user + ADMIN_PASSWORD = local.master_password + ENDPOINT = module.aws-rds-ms-sql-server-2.rds-sql-server-instance[count.index].endpoint + + SERVER_AUDIT_NAME = local.server_audit_name + SERVER_AUDIT_SPEC_NAME = local.server_audit_spec_name + } + + command = "./configure_database.sh" + + on_failure = fail + } +} + +resource "terraform_data" "configure_database-3" { + count = length(module.aws-rds-ms-sql-server-3.rds-sql-server-instance) + + depends_on = [module.aws-rds-ms-sql-server-3] + + provisioner "local-exec" { + environment = { + ADMIN_USER = local.master_user + ADMIN_PASSWORD = local.master_password + ENDPOINT = module.aws-rds-ms-sql-server-3.rds-sql-server-instance[count.index].endpoint + + SERVER_AUDIT_NAME = local.server_audit_name + SERVER_AUDIT_SPEC_NAME = local.server_audit_spec_name + } + + command = "./configure_database.sh" + + on_failure = fail + } +} + +# 2. AWS cloud account +# Note that the following additional privileges are required for the AWS cloud account: +# rds:DescribeOptionGroups +# s3:GetObject +# s3:ListBucket +# s3:ListAllMyBuckets +module "aws-default-account-asset" { + source = "imperva/agentless-onboarding/dsfhub//modules/dsfhub-aws-cloud-account" + + admin_email = local.admin_email + asset_display_name = "aws-account-asset" + asset_id = "arn:aws:iam::1234567890" + auth_mechanism = "default" + gateway_id = local.gateway_id + region = local.aws_region +} + +################################################################################ +# Amazon RDS MS SQL Server +################################################################################ +module "aws-rds-ms-sql-server-1" { + source = "../../modules/onboard-aws-rds-ms-sql-server" + # source = "imperva/agentless-onboarding/dsfhub//modules/onboard-aws-rds-ms-sql-server" + + aws_rds_mssql_audit_pull_enabled = true + aws_rds_mssql_admin_email = local.admin_email + aws_rds_mssql_gateway_id = local.gateway_id + aws_rds_mssql_region = local.aws_region + + aws_s3_admin_email = local.admin_email + aws_s3_audit_pull_enabled = true + aws_s3_gateway_id = local.gateway_id + aws_s3_parent_asset_id = module.aws-default-account-asset.this.asset_id + aws_s3_region = local.aws_region + + rds_mssql_apply_immediately = local.apply_immediately + rds_mssql_identifier = "tf-rds-mssql" + rds_mssql_password = local.master_password + rds_mssql_username = local.master_user + rds_mssql_skip_final_snapshot = true + rds_mssql_subnet_group_name = "default" + rds_mssql_vpc_security_group_ids = ["sg-0123456789abcdefg"] + + option_group_engine_name = "sqlserver-se" + option_group_major_engine_version = "15.00" + option_group_name = "tf-sql-server-option-group" + + iam_role_name = "tf-rds-sql-server-role" + iam_role_path = "/service-role/" + iam_policy_name = "tf-rds-sql-server-policy" + + s3_bucket = "tf-s3-bucket" + s3_force_destroy = true +} + +################################################################################ +# Amazon RDS MS SQL Server Many-to-One +################################################################################ +module "aws-rds-ms-sql-server-2" { + source = "../../modules/onboard-aws-rds-ms-sql-server" + # source = "imperva/agentless-onboarding/dsfhub//modules/onboard-aws-rds-ms-sql-server" + + aws_rds_mssql_audit_pull_enabled = true + aws_rds_mssql_admin_email = local.admin_email + aws_rds_mssql_gateway_id = local.gateway_id + aws_rds_mssql_region = local.aws_region + + aws_s3_admin_email = local.admin_email + aws_s3_audit_pull_enabled = true + aws_s3_gateway_id = local.gateway_id + aws_s3_parent_asset_id = module.aws-default-account-asset.this.asset_id + aws_s3_region = local.aws_region + + db_instance_count = 2 + + rds_mssql_apply_immediately = local.apply_immediately + rds_mssql_identifier = "tf-rds-mssql-many-to-one" + rds_mssql_password = local.master_password + rds_mssql_username = local.master_user + rds_mssql_skip_final_snapshot = true + rds_mssql_subnet_group_name = "default" + rds_mssql_vpc_security_group_ids = ["sg-0123456789abcdefg"] + + option_group_engine_name = "sqlserver-se" + option_group_major_engine_version = "15.00" + option_group_name = "tf-sql-server-option-group" + + iam_role_name = "tf-rds-sql-server-role" + iam_role_path = "/service-role/" + iam_policy_name = "tf-rds-sql-server-policy" + + s3_bucket = "tf-s3-bucket" + s3_force_destroy = true +} + +################################################################################ +# Amazon RDS MS SQL Server with S3 Prefix +# +# The additional prefix is required when multiple RDS SQL Servers have the same +# "DB Identifier" across various regions or accounts. +################################################################################ +data "aws_caller_identity" "current" {} + +module "aws-rds-ms-sql-server-3" { + source = "../../modules/onboard-aws-rds-ms-sql-server" + # source = "imperva/agentless-onboarding/dsfhub//modules/onboard-aws-rds-ms-sql-server" + + aws_rds_mssql_audit_pull_enabled = true + aws_rds_mssql_admin_email = local.admin_email + aws_rds_mssql_gateway_id = local.gateway_id + aws_rds_mssql_region = local.aws_region + + aws_s3_admin_email = local.admin_email + aws_s3_audit_pull_enabled = true + aws_s3_gateway_id = local.gateway_id + aws_s3_parent_asset_id = module.aws-default-account-asset.this.asset_id + aws_s3_region = local.aws_region + + rds_mssql_apply_immediately = local.apply_immediately + rds_mssql_identifier = "tf-rds-mssql-with-s3-prefix" + rds_mssql_password = local.master_password + rds_mssql_username = local.master_user + rds_mssql_skip_final_snapshot = true + rds_mssql_subnet_group_name = "default" + rds_mssql_vpc_security_group_ids = ["sg-0123456789abcdefg"] + + option_group_engine_name = "sqlserver-se" + option_group_major_engine_version = "15.00" + option_group_name = "tf-sql-server-option-group" + + iam_role_name = "tf-rds-sql-server-role" + iam_role_path = "/service-role/" + iam_policy_name = "tf-rds-sql-server-policy" + + s3_bucket = "tf-s3-bucket" + s3_force_destroy = true + s3_bucket_prefix = "/${local.aws_region}/${data.aws_caller_identity.current.account_id}" +} diff --git a/examples/onboard-aws-redshift/main.tf b/examples/onboard-aws-redshift/main.tf index 84012e6..5316501 100644 --- a/examples/onboard-aws-redshift/main.tf +++ b/examples/onboard-aws-redshift/main.tf @@ -121,7 +121,6 @@ module "aws-redshift-1" { aws_s3_admin_email = local.admin_email aws_s3_audit_pull_enabled = true - aws_s3_asset_display_name = "tf-aws-s3-asset" aws_s3_bucket_account_id = data.aws_caller_identity.current.account_id aws_s3_gateway_id = local.gateway_id aws_s3_parent_asset_id = module.aws-default-account-asset.this.asset_id diff --git a/modules/aws-docdb-cluster-instance/output.tf b/modules/aws-docdb-cluster-instance/outputs.tf similarity index 100% rename from modules/aws-docdb-cluster-instance/output.tf rename to modules/aws-docdb-cluster-instance/outputs.tf diff --git a/modules/aws-docdb-cluster-parameter-group/output.tf b/modules/aws-docdb-cluster-parameter-group/outputs.tf similarity index 100% rename from modules/aws-docdb-cluster-parameter-group/output.tf rename to modules/aws-docdb-cluster-parameter-group/outputs.tf diff --git a/modules/aws-docdb-cluster/output.tf b/modules/aws-docdb-cluster/outputs.tf similarity index 100% rename from modules/aws-docdb-cluster/output.tf rename to modules/aws-docdb-cluster/outputs.tf diff --git a/modules/aws-iam-policy/output.tf b/modules/aws-iam-policy/outputs.tf similarity index 100% rename from modules/aws-iam-policy/output.tf rename to modules/aws-iam-policy/outputs.tf diff --git a/modules/aws-iam-role-policy-attachment/output.tf b/modules/aws-iam-role-policy-attachment/outputs.tf similarity index 100% rename from modules/aws-iam-role-policy-attachment/output.tf rename to modules/aws-iam-role-policy-attachment/outputs.tf diff --git a/modules/aws-iam-role/output.tf b/modules/aws-iam-role/outputs.tf similarity index 100% rename from modules/aws-iam-role/output.tf rename to modules/aws-iam-role/outputs.tf diff --git a/modules/aws-rds-instance/README.md b/modules/aws-rds-instance/README.md index 95ca674..b613dc7 100644 --- a/modules/aws-rds-instance/README.md +++ b/modules/aws-rds-instance/README.md @@ -33,6 +33,7 @@ No modules. | [final\_snapshot\_identifier](#input\_final\_snapshot\_identifier) | The name of your final DB snapshot when this DB instance is deleted. Must be provided if skip\_final\_snapshot is set to false. | `string` | `null` | no | | [identifier](#input\_identifier) | Identifier of RDS instance | `string` | n/a | yes | | [instance\_class](#input\_instance\_class) | The instance type of the RDS instance. | `string` | `"db.t3.small"` | no | +| [license\_model](#input\_license\_model) | License model information for this DB instance. | `string` | `null` | no | | [max\_allocated\_storage](#input\_max\_allocated\_storage) | When configured, the upper limit to which Amazon RDS can automatically scale the storage of the DB instance. Configuring this will automatically ignore differences to allocated\_storage. | `number` | `null` | no | | [option\_group\_name](#input\_option\_group\_name) | Name of the option group to associate with the RDS instance. | `string` | `null` | no | | [parameter\_group\_name](#input\_parameter\_group\_name) | Name of the parameter group to associate with the RDS instance. | `string` | `null` | no | diff --git a/modules/aws-rds-instance/main.tf b/modules/aws-rds-instance/main.tf index 2036d1a..662aba5 100644 --- a/modules/aws-rds-instance/main.tf +++ b/modules/aws-rds-instance/main.tf @@ -12,6 +12,7 @@ resource "aws_db_instance" "this" { final_snapshot_identifier = var.final_snapshot_identifier identifier = var.identifier instance_class = var.instance_class + license_model = var.license_model max_allocated_storage = var.max_allocated_storage option_group_name = var.option_group_name parameter_group_name = var.parameter_group_name diff --git a/modules/aws-rds-instance/variables.tf b/modules/aws-rds-instance/variables.tf index cecc522..25cc299 100644 --- a/modules/aws-rds-instance/variables.tf +++ b/modules/aws-rds-instance/variables.tf @@ -60,6 +60,12 @@ variable "instance_class" { default = "db.t3.small" } +variable "license_model" { + description = "License model information for this DB instance." + type = string + default = null +} + variable "max_allocated_storage" { description = "When configured, the upper limit to which Amazon RDS can automatically scale the storage of the DB instance. Configuring this will automatically ignore differences to allocated_storage." type = number diff --git a/modules/aws-redshift-cluster/output.tf b/modules/aws-redshift-cluster/outputs.tf similarity index 100% rename from modules/aws-redshift-cluster/output.tf rename to modules/aws-redshift-cluster/outputs.tf diff --git a/modules/aws-redshift-logging/output.tf b/modules/aws-redshift-logging/outputs.tf similarity index 100% rename from modules/aws-redshift-logging/output.tf rename to modules/aws-redshift-logging/outputs.tf diff --git a/modules/aws-redshift-parameter-group/output.tf b/modules/aws-redshift-parameter-group/outputs.tf similarity index 100% rename from modules/aws-redshift-parameter-group/output.tf rename to modules/aws-redshift-parameter-group/outputs.tf diff --git a/modules/aws-s3-bucket-policy/output.tf b/modules/aws-s3-bucket-policy/outputs.tf similarity index 100% rename from modules/aws-s3-bucket-policy/output.tf rename to modules/aws-s3-bucket-policy/outputs.tf diff --git a/modules/aws-s3-bucket/output.tf b/modules/aws-s3-bucket/outputs.tf similarity index 100% rename from modules/aws-s3-bucket/output.tf rename to modules/aws-s3-bucket/outputs.tf diff --git a/modules/dsfhub-aws-rds-ms-sql-server/README.md b/modules/dsfhub-aws-rds-ms-sql-server/README.md new file mode 100644 index 0000000..cd1c609 --- /dev/null +++ b/modules/dsfhub-aws-rds-ms-sql-server/README.md @@ -0,0 +1,45 @@ + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +|------|---------| +| [dsfhub](#provider\_dsfhub) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [dsfhub_data_source.this](https://registry.terraform.io/providers/imperva/dsfhub/latest/docs/resources/data_source) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [admin\_email](#input\_admin\_email) | The email address to notify about this asset | `string` | n/a | yes | +| [asset\_display\_name](#input\_asset\_display\_name) | User-friendly name of the asset, defined by user | `string` | n/a | yes | +| [asset\_id](#input\_asset\_id) | AWS ARN, e.g. "arn:aws:rds:us-east-2:123456790:db:db-name" | `string` | n/a | yes | +| [audit\_pull\_enabled](#input\_audit\_pull\_enabled) | If true, sonargateway will collect the audit logs for this system if it can. | `bool` | `false` | no | +| [database\_name](#input\_database\_name) | Specifies the name of the database you are connected to (or default DB). | `string` | `null` | no | +| [db\_engine\_version](#input\_db\_engine\_version) | Denotes the major version of the DB engine of the asset, e.g. 2015 vs. 2019 | `string` | `null` | no | +| [db\_instance\_count](#input\_db\_instance\_count) | Number of database instances. | `number` | `1` | no | +| [gateway\_id](#input\_gateway\_id) | Unique identifier (UID) attached to the jSonar machine controlling the asset | `string` | n/a | yes | +| [logs\_destination\_asset\_id](#input\_logs\_destination\_asset\_id) | asset\_id of the S3 bucket asset where the logs for this database can be found. | `string` | `null` | no | +| [parent\_asset\_id](#input\_parent\_asset\_id) | The asset\_id that contains this asset (e.g. Asset ID of the database sending audit events) | `string` | `null` | no | +| [region](#input\_region) | AWS region containing the instance. | `string` | `null` | no | +| [server\_host\_name](#input\_server\_host\_name) | Endpoint URL, e.g. .amazon.com | `string` | n/a | yes | +| [server\_port](#input\_server\_port) | Endpoint URL, e.g. .amazon.com | `string` | `null` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [this](#output\_this) | AWS RDS MS SQL Server asset | + \ No newline at end of file diff --git a/modules/dsfhub-aws-rds-ms-sql-server/main.tf b/modules/dsfhub-aws-rds-ms-sql-server/main.tf new file mode 100644 index 0000000..54b569e --- /dev/null +++ b/modules/dsfhub-aws-rds-ms-sql-server/main.tf @@ -0,0 +1,27 @@ +terraform { + required_providers { + dsfhub = { + source = "imperva/dsfhub" + } + } +} + +resource "dsfhub_data_source" "this" { + count = var.db_instance_count + + server_type = "AWS RDS MS SQL SERVER" + + admin_email = var.admin_email + asset_display_name = var.asset_display_name + asset_id = var.asset_id + audit_pull_enabled = var.audit_pull_enabled + database_name = var.database_name + gateway_id = var.gateway_id + logs_destination_asset_id = var.logs_destination_asset_id + parent_asset_id = var.parent_asset_id + region = var.region + server_host_name = var.server_host_name + server_port = var.server_port + service_name = "MSSQLSERVER" + version = var.db_engine_version +} diff --git a/modules/dsfhub-aws-rds-ms-sql-server/outputs.tf b/modules/dsfhub-aws-rds-ms-sql-server/outputs.tf new file mode 100644 index 0000000..ca4d236 --- /dev/null +++ b/modules/dsfhub-aws-rds-ms-sql-server/outputs.tf @@ -0,0 +1,4 @@ +output "this" { + description = "AWS RDS MS SQL Server asset" + value = dsfhub_data_source.this +} diff --git a/modules/dsfhub-aws-rds-ms-sql-server/variables.tf b/modules/dsfhub-aws-rds-ms-sql-server/variables.tf new file mode 100644 index 0000000..75e24be --- /dev/null +++ b/modules/dsfhub-aws-rds-ms-sql-server/variables.tf @@ -0,0 +1,72 @@ +variable "admin_email" { + description = "The email address to notify about this asset" + type = string +} + +variable "asset_display_name" { + description = "User-friendly name of the asset, defined by user" + type = string +} + +variable "asset_id" { + description = "AWS ARN, e.g. \"arn:aws:rds:us-east-2:123456790:db:db-name\"" + type = string +} + +variable "audit_pull_enabled" { + description = "If true, sonargateway will collect the audit logs for this system if it can." + type = bool + default = false +} + +variable "database_name" { + description = "Specifies the name of the database you are connected to (or default DB)." + type = string + default = null +} + +variable "db_engine_version" { + description = "Denotes the major version of the DB engine of the asset, e.g. 2015 vs. 2019" + type = string + default = null +} + +variable "db_instance_count" { + description = "Number of database instances." + type = number + default = 1 +} + +variable "gateway_id" { + description = "Unique identifier (UID) attached to the jSonar machine controlling the asset" + type = string +} + +variable "logs_destination_asset_id" { + description = "asset_id of the S3 bucket asset where the logs for this database can be found." + type = string + default = null +} + +variable "parent_asset_id" { + description = "The asset_id that contains this asset (e.g. Asset ID of the database sending audit events)" + type = string + default = null +} + +variable "region" { + description = "AWS region containing the instance." + type = string + default = null +} + +variable "server_host_name" { + description = "Endpoint URL, e.g. .amazon.com" + type = string +} + +variable "server_port" { + description = "Endpoint URL, e.g. .amazon.com" + type = string + default = null +} diff --git a/modules/dsfhub-aws-redshift-cluster/output.tf b/modules/dsfhub-aws-redshift-cluster/outputs.tf similarity index 100% rename from modules/dsfhub-aws-redshift-cluster/output.tf rename to modules/dsfhub-aws-redshift-cluster/outputs.tf diff --git a/modules/dsfhub-aws-s3-bucket-ds/output.tf b/modules/dsfhub-aws-s3-bucket-ds/outputs.tf similarity index 100% rename from modules/dsfhub-aws-s3-bucket-ds/output.tf rename to modules/dsfhub-aws-s3-bucket-ds/outputs.tf diff --git a/modules/dsfhub-aws-s3-bucket-la/README.md b/modules/dsfhub-aws-s3-bucket-la/README.md index 77e053e..88d3245 100644 --- a/modules/dsfhub-aws-s3-bucket-la/README.md +++ b/modules/dsfhub-aws-s3-bucket-la/README.md @@ -27,7 +27,7 @@ No modules. | [asset\_display\_name](#input\_asset\_display\_name) | User-friendly name of the asset, defined by the user | `string` | n/a | yes | | [asset\_id](#input\_asset\_id) | AWS ARN, e.g. "arn:aws:s3:::bucket-name" | `string` | n/a | yes | | [audit\_pull\_enabled](#input\_audit\_pull\_enabled) | Whether the DSFHUB should pull logs from the asset. | `bool` | `false` | no | -| [audit\_type](#input\_audit\_type) | Used to indicate what type of audit will be pulled on systems supporting multiple audit types. Valid values: LOG\_GROUP (default), KINESIS, CLOUDWATCH, REDSHIFT, DYNAMODB | `string` | `"LOG_GROUP"` | no | +| [audit\_type](#input\_audit\_type) | Used to indicate what type of audit will be pulled on systems supporting multiple audit types. Default is null. Valid values: LOG\_GROUP, KINESIS, CLOUDWATCH, REDSHIFT, DYNAMODB | `string` | `null` | no | | [bucket\_account\_id](#input\_bucket\_account\_id) | Mandatory for audit types: REDSHIFT and DYNAMODB. Account number found in the prefix of the files we are pulling. e.g: `123456789012` out of `redshift/AWSLogs/123456789012/redshift/us-east-1/2024/06/25/my_file.gz` | `string` | `null` | no | | [gateway\_id](#input\_gateway\_id) | Unique identifier (UID) attached to the jSonar machine controlling the asset | `string` | n/a | yes | | [parent\_asset\_id](#input\_parent\_asset\_id) | The asset\_id of AWS cloud account being used. E.g. Key-pair, iam\_role, profile or default | `string` | n/a | yes | diff --git a/modules/dsfhub-aws-s3-bucket-la/output.tf b/modules/dsfhub-aws-s3-bucket-la/outputs.tf similarity index 100% rename from modules/dsfhub-aws-s3-bucket-la/output.tf rename to modules/dsfhub-aws-s3-bucket-la/outputs.tf diff --git a/modules/dsfhub-aws-s3-bucket-la/variables.tf b/modules/dsfhub-aws-s3-bucket-la/variables.tf index 5b9b7c1..edb427f 100644 --- a/modules/dsfhub-aws-s3-bucket-la/variables.tf +++ b/modules/dsfhub-aws-s3-bucket-la/variables.tf @@ -20,11 +20,11 @@ variable "audit_pull_enabled" { } variable "audit_type" { - description = "Used to indicate what type of audit will be pulled on systems supporting multiple audit types. Valid values: LOG_GROUP (default), KINESIS, CLOUDWATCH, REDSHIFT, DYNAMODB" + description = "Used to indicate what type of audit will be pulled on systems supporting multiple audit types. Default is null. Valid values: LOG_GROUP, KINESIS, CLOUDWATCH, REDSHIFT, DYNAMODB" type = string - default = "LOG_GROUP" + default = null validation { - condition = can(regex("LOG_GROUP|KINESIS|CLOUDWATCH|REDSHIFT|DYNAMODB", var.audit_type)) + condition = (var.audit_type == null ? true : (can(regex("LOG_GROUP|KINESIS|CLOUDWATCH|REDSHIFT|DYNAMODB", var.audit_type)))) error_message = "audit_type must be one of LOG_GROUP, KINESIS, CLOUDWATCH, REDSHIFT, DYNAMODB" } } diff --git a/modules/onboard-aws-rds-ms-sql-server/README.md b/modules/onboard-aws-rds-ms-sql-server/README.md new file mode 100644 index 0000000..c3d0237 --- /dev/null +++ b/modules/onboard-aws-rds-ms-sql-server/README.md @@ -0,0 +1,103 @@ +# onboard-aws-rds-ms-sql-server +Onboard Amazon RDS for SQL Server to DSF Hub. + +## Notes +There is one prerequisite for using this module: +1. A method to create an audit policy on the RDS SQL Server instance. + +See the corresponding example for more details. + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | n/a | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [attach-rds-sql-server-iam-policy](#module\_attach-rds-sql-server-iam-policy) | ../aws-iam-role-policy-attachment | n/a | +| [aws-rds-ms-sql-server-asset](#module\_aws-rds-ms-sql-server-asset) | ../dsfhub-aws-rds-ms-sql-server | n/a | +| [rds-sql-server-db](#module\_rds-sql-server-db) | ../aws-rds-instance | n/a | +| [rds-sql-server-option-group](#module\_rds-sql-server-option-group) | ../aws-rds-option-group | n/a | +| [rds-sql-server-policy](#module\_rds-sql-server-policy) | ../aws-iam-policy | n/a | +| [rds-sql-server-role](#module\_rds-sql-server-role) | ../aws-iam-role | n/a | +| [s3-bucket](#module\_s3-bucket) | ../aws-s3-bucket | n/a | +| [s3-bucket-asset](#module\_s3-bucket-asset) | ../dsfhub-aws-s3-bucket-la | n/a | + +## Resources + +| Name | Type | +|------|------| +| [aws_iam_policy_document.rds-policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.rds-sql-server-policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [aws\_rds\_mssql\_admin\_email](#input\_aws\_rds\_mssql\_admin\_email) | The email address to notify about this asset. | `string` | n/a | yes | +| [aws\_rds\_mssql\_audit\_pull\_enabled](#input\_aws\_rds\_mssql\_audit\_pull\_enabled) | If true, sonargateway will collect the audit logs for this system if it can. Default is false. | `bool` | `false` | no | +| [aws\_rds\_mssql\_db\_engine\_version](#input\_aws\_rds\_mssql\_db\_engine\_version) | Denotes the major version of the asset, e.g. 2017 or 2019. | `string` | `null` | no | +| [aws\_rds\_mssql\_gateway\_id](#input\_aws\_rds\_mssql\_gateway\_id) | Unique identifier (UID) attached to the jSonar machine controlling the asset | `string` | n/a | yes | +| [aws\_rds\_mssql\_parent\_asset\_id](#input\_aws\_rds\_mssql\_parent\_asset\_id) | The asset\_id of the AWS cloud account that contains this asset. | `string` | `null` | no | +| [aws\_rds\_mssql\_region](#input\_aws\_rds\_mssql\_region) | AWS region containing the instance. | `string` | `null` | no | +| [aws\_s3\_admin\_email](#input\_aws\_s3\_admin\_email) | The email address to notify about the S3 asset. | `string` | n/a | yes | +| [aws\_s3\_audit\_pull\_enabled](#input\_aws\_s3\_audit\_pull\_enabled) | A boolean that indicates whether the asset should be audited. Default is true. | `bool` | `true` | no | +| [aws\_s3\_bucket\_account\_id](#input\_aws\_s3\_bucket\_account\_id) | The account\_id of the bucket owner | `string` | `null` | no | +| [aws\_s3\_gateway\_id](#input\_aws\_s3\_gateway\_id) | Unique identifier (UID) attached to the jSonar machine controlling the S3 asset | `string` | n/a | yes | +| [aws\_s3\_parent\_asset\_id](#input\_aws\_s3\_parent\_asset\_id) | The asset\_id of AWS cloud account being used. | `string` | n/a | yes | +| [aws\_s3\_region](#input\_aws\_s3\_region) | AWS region containing the S3 bucket. | `string` | n/a | yes | +| [aws\_s3\_server\_port](#input\_aws\_s3\_server\_port) | Port used by the source server. Default: 443 | `number` | `443` | no | +| [db\_instance\_count](#input\_db\_instance\_count) | The number of RDS instances to create. Default is 1. | `number` | `1` | no | +| [iam\_policy\_name](#input\_iam\_policy\_name) | Friendly name of the IAM policy that grants SQL Server access to write to an S3 bucket. Forces new resource. | `string` | `"tf_rds_mssql_s3_audit_policy"` | no | +| [iam\_role\_name](#input\_iam\_role\_name) | Friendly name of the IAM role that grants SQL Server access to write to an S3 bucket. Forces new resource. | `string` | `"tf_rds_mssql_s3_audit_role"` | no | +| [iam\_role\_path](#input\_iam\_role\_path) | The path to the role. For more information about paths, see IAM Identifiers in the IAM User Guide. Default is '/service-role/'. | `string` | `"/service-role/"` | no | +| [option\_group\_additional\_audit\_option\_settings](#input\_option\_group\_additional\_audit\_option\_settings) | A list of additional option settings to apply to the SQLSERVER\_AUDIT option group. |
list(object({
name = string
value = string
}))
| `[]` | no | +| [option\_group\_additional\_options](#input\_option\_group\_additional\_options) | A list of additional options to apply to this Option Group. |
list(object({
option_name = string
option_settings = list(object({
name = string
value = string
}))
}))
| `[]` | no | +| [option\_group\_description](#input\_option\_group\_description) | The description of the RDS option group. | `string` | `null` | no | +| [option\_group\_engine\_name](#input\_option\_group\_engine\_name) | Specifies the name of the engine that this option group should be associated with. Valid options: 'sqlserver-ee', 'sqlserver-ex', 'sqlserver-se', 'sqlserver-web'. | `string` | n/a | yes | +| [option\_group\_major\_engine\_version](#input\_option\_group\_major\_engine\_version) | Specifies the major version of the engine that this option group should be associated with. Supported options: '14.00', '15.00'. | `string` | n/a | yes | +| [option\_group\_name](#input\_option\_group\_name) | The name of the RDS option group. | `string` | n/a | yes | +| [option\_group\_tags](#input\_option\_group\_tags) | A map of tags to assign to the resource. | `map(string)` | `null` | no | +| [rds\_mssql\_allocated\_storage](#input\_rds\_mssql\_allocated\_storage) | The allocated storage in gibibytes. If max\_allocated\_storage is configured, this argument represents the initial storage allocation and differences from the configuration will be ignored automatically when Storage Autoscaling occurs. If replicate\_source\_db is set, the value is ignored during the creation of the instance. Default: 20. | `number` | `20` | no | +| [rds\_mssql\_apply\_immediately](#input\_rds\_mssql\_apply\_immediately) | Specifies whether any database modifications are applied immediately, or during the next maintenance window. Default is true. | `bool` | `true` | no | +| [rds\_mssql\_db\_name](#input\_rds\_mssql\_db\_name) | The name of the database to create when the DB instance is created. If this parameter is not specified, no database is created in the DB instance. | `string` | `null` | no | +| [rds\_mssql\_deletion\_protection](#input\_rds\_mssql\_deletion\_protection) | If the DB instance should have deletion protection enabled. The database can't be deleted when this value is set to true. Default is false. | `bool` | `false` | no | +| [rds\_mssql\_final\_snapshot\_identifier](#input\_rds\_mssql\_final\_snapshot\_identifier) | The name of your final DB snapshot when this DB instance is deleted. Must be provided if skip\_final\_snapshot is set to false. | `string` | `null` | no | +| [rds\_mssql\_identifier](#input\_rds\_mssql\_identifier) | The name of the RDS instance. | `string` | n/a | yes | +| [rds\_mssql\_instance\_class](#input\_rds\_mssql\_instance\_class) | The instance type of the RDS instance. For supported range of DB instance classes for RDS SQL Server, see the [AWS Docs](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_SQLServer.html#SQLServer.Concepts.General.InstanceClasses) or use the /`aws rds describe-orderable-db-instance-options/` CLI command. Default: db.t3.xlarge | `string` | `"db.t3.xlarge"` | no | +| [rds\_mssql\_max\_allocated\_storage](#input\_rds\_mssql\_max\_allocated\_storage) | When configured, the upper limit to which Amazon RDS can automatically scale the storage of the DB instance. Configuring this will automatically ignore differences to allocated\_storage. | `number` | `null` | no | +| [rds\_mssql\_option\_group\_name](#input\_rds\_mssql\_option\_group\_name) | Name of the option group to associate with the RDS instance. | `string` | `null` | no | +| [rds\_mssql\_password](#input\_rds\_mssql\_password) | Password for the master DB user. Note that this may show up in logs, and it will be stored in the state file. | `string` | n/a | yes | +| [rds\_mssql\_port](#input\_rds\_mssql\_port) | The port on which the DB accepts connections. Default: 1433 | `number` | `1433` | no | +| [rds\_mssql\_publicly\_accessible](#input\_rds\_mssql\_publicly\_accessible) | Bool to control if instance is publicly accessible. Default is true. | `bool` | `true` | no | +| [rds\_mssql\_skip\_final\_snapshot](#input\_rds\_mssql\_skip\_final\_snapshot) | Determines whether a final DB snapshot is created before the DB instance is deleted. If true is specified, no DBSnapshot is created. If false is specified, a DB snapshot is created before the DB instance is deleted, using the value from final\_snapshot\_identifier. Default is true. | `bool` | `true` | no | +| [rds\_mssql\_subnet\_group\_name](#input\_rds\_mssql\_subnet\_group\_name) | Name of DB subnet group. DB instance will be created in the VPC associated with the DB subnet group. If unspecified, will be created in the default VPC, or in EC2 Classic, if available. | `string` | `null` | no | +| [rds\_mssql\_tags](#input\_rds\_mssql\_tags) | A map of tags to assign to the RDS instance. | `map(string)` | `null` | no | +| [rds\_mssql\_username](#input\_rds\_mssql\_username) | Username for the master DB user. Default: 'admin'. | `string` | `"admin"` | no | +| [rds\_mssql\_vpc\_security\_group\_ids](#input\_rds\_mssql\_vpc\_security\_group\_ids) | List of VPC security groups to associate. | `list(string)` | `null` | no | +| [s3\_bucket](#input\_s3\_bucket) | The name of the bucket. Must be lowercase and less than or equal to 63 characters in length. | `string` | n/a | yes | +| [s3\_bucket\_prefix](#input\_s3\_bucket\_prefix) | The prefix to use for the S3 bucket. Required when auditing multiple RDS SQL Server instances sharing the same 'DB Identifier' across various regions or AWS accounts. Format: '/region/account\_id', e.g. '/us-east-1/123456789012'. | `string` | `""` | no | +| [s3\_force\_destroy](#input\_s3\_force\_destroy) | A boolean that indicates all objects should be deleted from the bucket when the bucket is destroyed so that the bucket can be destroyed without error. Default is false. See more details in the (AWS Terraform documentation)[https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket#force_destroy]. | `bool` | `false` | no | +| [s3\_object\_lock\_enabled](#input\_s3\_object\_lock\_enabled) | A boolean that indicates whether this bucket should have an Object Lock configuration enabled. Default is false. | `bool` | `false` | no | +| [s3\_tags](#input\_s3\_tags) | A map of tags to assign to the resource. | `map(string)` | `null` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [attach-rds-sql-server-iam-policy](#output\_attach-rds-sql-server-iam-policy) | Attaching the IAM policy to the IAM role | +| [rds-sql-server-instance](#output\_rds-sql-server-instance) | RDS SQL Server instance(s) | +| [rds-sql-server-instance-asset](#output\_rds-sql-server-instance-asset) | AWS RDS MS SQL SERVER asset(s) | +| [rds-sql-server-option-group](#output\_rds-sql-server-option-group) | RDS option group | +| [rds-sql-server-policy](#output\_rds-sql-server-policy) | IAM policy giving RDS permissions to write to S3 bucket | +| [rds-sql-server-role](#output\_rds-sql-server-role) | IAM role used in RDS option group | +| [s3-bucket](#output\_s3-bucket) | S3 Bucket | +| [s3-bucket-asset](#output\_s3-bucket-asset) | AWS S3 Bucket asset | + \ No newline at end of file diff --git a/modules/onboard-aws-rds-ms-sql-server/main.tf b/modules/onboard-aws-rds-ms-sql-server/main.tf new file mode 100644 index 0000000..a2774b6 --- /dev/null +++ b/modules/onboard-aws-rds-ms-sql-server/main.tf @@ -0,0 +1,188 @@ +module "s3-bucket" { + source = "../aws-s3-bucket" + + bucket = var.s3_bucket + force_destroy = var.s3_force_destroy + object_lock_enabled = var.s3_object_lock_enabled + tags = var.s3_tags +} + +data "aws_iam_policy_document" "rds-policy" { + statement { + effect = "Allow" + principals { + type = "Service" + identifiers = ["rds.amazonaws.com"] + } + actions = [ + "sts:AssumeRole" + ] + } + version = "2012-10-17" +} + +module "rds-sql-server-role" { + source = "../aws-iam-role" + + name = var.iam_role_name + path = var.iam_role_path + assume_role_policy = data.aws_iam_policy_document.rds-policy.json +} + +data "aws_iam_policy_document" "rds-sql-server-policy" { + statement { + effect = "Allow" + actions = [ + "s3:ListAllMyBuckets", + ] + resources = [ + "*" + ] + } + + statement { + effect = "Allow" + actions = [ + "s3:GetBucketLocation", + "s3:GetBucketACL", + "s3:ListBucket", + ] + resources = [ + "${module.s3-bucket.this.arn}${var.s3_bucket_prefix}", + ] + } + + statement { + effect = "Allow" + actions = [ + "s3:ListMultipartUploadParts", + "s3:AbortMultipartUpload", + "s3:PutObject", + ] + resources = [ + "${module.s3-bucket.this.arn}${var.s3_bucket_prefix}/*", + ] + } + + version = "2012-10-17" +} + +module "rds-sql-server-policy" { + source = "../aws-iam-policy" + + description = "RDS SQL Server IAM Policy" + name = var.iam_policy_name + path = "/service-role/" + policy = data.aws_iam_policy_document.rds-sql-server-policy.json +} + +module "attach-rds-sql-server-iam-policy" { + source = "../aws-iam-role-policy-attachment" + + role = module.rds-sql-server-role.this.name + policy_arn = module.rds-sql-server-policy.this.arn +} + + +locals { + option_group_audit_options = [ + { + name = "S3_BUCKET_ARN" + value = "${module.s3-bucket.this.arn}${var.s3_bucket_prefix}" + }, + { + name = "IAM_ROLE_ARN" + value = "${module.rds-sql-server-role.this.arn}" + }, + { + name = "ENABLE_COMPRESSION" + value = "false" + }, + { + name = "RETENTION_TIME" + value = "24" + }, + ] +} + +module "rds-sql-server-option-group" { + source = "../aws-rds-option-group" + + description = var.option_group_description + engine_name = var.option_group_engine_name + major_engine_version = var.option_group_major_engine_version + name = var.option_group_name + tags = var.option_group_tags + + options = concat( + [ + { + option_name = "SQLSERVER_AUDIT" + + option_settings = concat(local.option_group_audit_options, var.option_group_additional_audit_option_settings) + } + ], + var.option_group_additional_options) +} + +module "rds-sql-server-db" { + source = "../aws-rds-instance" + + count = var.db_instance_count + + allocated_storage = var.rds_mssql_allocated_storage + apply_immediately = var.rds_mssql_apply_immediately + + db_name = var.rds_mssql_db_name + deletion_protection = var.rds_mssql_deletion_protection + engine = module.rds-sql-server-option-group.this.engine_name + engine_version = module.rds-sql-server-option-group.this.major_engine_version + final_snapshot_identifier = var.rds_mssql_final_snapshot_identifier + identifier = "${var.rds_mssql_identifier}-${count.index}" + instance_class = var.rds_mssql_instance_class + license_model = "license-included" + max_allocated_storage = var.rds_mssql_max_allocated_storage + option_group_name = module.rds-sql-server-option-group.this.name + password = var.rds_mssql_password + port = var.rds_mssql_port + publicly_accessible = var.rds_mssql_publicly_accessible + skip_final_snapshot = var.rds_mssql_skip_final_snapshot + subnet_group_name = var.rds_mssql_subnet_group_name + tags = var.rds_mssql_tags + username = var.rds_mssql_username + vpc_security_group_ids = var.rds_mssql_vpc_security_group_ids +} + +module "aws-rds-ms-sql-server-asset" { + source = "../dsfhub-aws-rds-ms-sql-server" + + count = var.db_instance_count + + admin_email = var.aws_rds_mssql_admin_email + asset_display_name = module.rds-sql-server-db[count.index].this.identifier + asset_id = module.rds-sql-server-db[count.index].this.arn + audit_pull_enabled = var.aws_rds_mssql_audit_pull_enabled + db_engine_version = var.aws_rds_mssql_db_engine_version + gateway_id = var.aws_rds_mssql_gateway_id + logs_destination_asset_id = module.s3-bucket.this.arn + parent_asset_id = var.aws_rds_mssql_parent_asset_id + region = var.aws_rds_mssql_region + server_host_name = module.rds-sql-server-db[count.index].this.endpoint + server_port = module.rds-sql-server-db[count.index].this.port +} + +module "s3-bucket-asset" { + source = "../dsfhub-aws-s3-bucket-la" + + admin_email = var.aws_s3_admin_email + asset_display_name = module.s3-bucket.this.id + asset_id = module.s3-bucket.this.arn + audit_pull_enabled = var.aws_s3_audit_pull_enabled + gateway_id = var.aws_s3_gateway_id + parent_asset_id = var.aws_s3_parent_asset_id + region = var.aws_s3_region + server_host_name = module.s3-bucket.this.id + server_ip = module.s3-bucket.this.arn + server_port = var.aws_s3_server_port + s3_provider = "aws-rds-mssql" +} diff --git a/modules/onboard-aws-rds-ms-sql-server/outputs.tf b/modules/onboard-aws-rds-ms-sql-server/outputs.tf new file mode 100644 index 0000000..f7bc41c --- /dev/null +++ b/modules/onboard-aws-rds-ms-sql-server/outputs.tf @@ -0,0 +1,40 @@ +output "s3-bucket" { + description = "S3 Bucket" + value = module.s3-bucket.this +} + +output "rds-sql-server-role" { + description = "IAM role used in RDS option group" + value = module.rds-sql-server-role.this +} + +output "rds-sql-server-policy" { + description = "IAM policy giving RDS permissions to write to S3 bucket" + value = module.rds-sql-server-policy.this +} + +output "attach-rds-sql-server-iam-policy" { + description = "Attaching the IAM policy to the IAM role" + value = module.attach-rds-sql-server-iam-policy.this +} + +output "rds-sql-server-option-group" { + description = "RDS option group" + value = module.rds-sql-server-option-group.this +} + +output "rds-sql-server-instance" { + description = "RDS SQL Server instance(s)" + value = module.rds-sql-server-db.*.this + sensitive = true +} + +output "rds-sql-server-instance-asset" { + description = "AWS RDS MS SQL SERVER asset(s)" + value = module.aws-rds-ms-sql-server-asset.*.this +} + +output "s3-bucket-asset" { + description = "AWS S3 Bucket asset" + value = module.s3-bucket-asset.this +} diff --git a/modules/onboard-aws-rds-ms-sql-server/variables.tf b/modules/onboard-aws-rds-ms-sql-server/variables.tf new file mode 100644 index 0000000..6a38f58 --- /dev/null +++ b/modules/onboard-aws-rds-ms-sql-server/variables.tf @@ -0,0 +1,289 @@ +# AWS S3 Bucket variables +variable "s3_bucket" { + description = "The name of the bucket. Must be lowercase and less than or equal to 63 characters in length." + type = string +} + +variable "s3_force_destroy" { + description = "A boolean that indicates all objects should be deleted from the bucket when the bucket is destroyed so that the bucket can be destroyed without error. Default is false. See more details in the (AWS Terraform documentation)[https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket#force_destroy]." + type = bool + default = false +} + +variable "s3_object_lock_enabled" { + description = "A boolean that indicates whether this bucket should have an Object Lock configuration enabled. Default is false." + type = bool + default = false +} + +variable "s3_tags" { + description = "A map of tags to assign to the resource." + type = map(string) + default = null +} + +# AWS IAM Variables +variable "iam_role_name" { + description = "Friendly name of the IAM role that grants SQL Server access to write to an S3 bucket. Forces new resource." + type = string + default = "tf_rds_mssql_s3_audit_role" +} + +variable "iam_role_path" { + description = "The path to the role. For more information about paths, see IAM Identifiers in the IAM User Guide. Default is '/service-role/'." + type = string + default = "/service-role/" +} + +variable "iam_policy_name" { + description = "Friendly name of the IAM policy that grants SQL Server access to write to an S3 bucket. Forces new resource." + type = string + default = "tf_rds_mssql_s3_audit_policy" +} + +# Option Group variables +variable "option_group_description" { + description = "The description of the RDS option group." + type = string + default = null +} + +variable "option_group_engine_name" { + description = "Specifies the name of the engine that this option group should be associated with. Valid options: 'sqlserver-ee', 'sqlserver-ex', 'sqlserver-se', 'sqlserver-web'." + type = string + validation { + condition = contains(["sqlserver-ee", "sqlserver-ex", "sqlserver-se", "sqlserver-web"], var.option_group_engine_name) + error_message = "Invalid engine name. Valid options: 'sqlserver-ee', 'sqlserver-ex', 'sqlserver-se', 'sqlserver-web'." + } +} + +variable "option_group_major_engine_version" { + description = "Specifies the major version of the engine that this option group should be associated with. Supported options: '14.00', '15.00'." + type = string + validation { + condition = contains(["14.00", "15.00"], var.option_group_major_engine_version) + error_message = "Invalid major engine version. Supported options: '14.00', '15.00'." + } +} + +variable "option_group_name" { + description = "The name of the RDS option group." + type = string +} + +variable "option_group_additional_audit_option_settings" { + description = "A list of additional option settings to apply to the SQLSERVER_AUDIT option group." + type = list(object({ + name = string + value = string + })) + default = [] +} + +variable "option_group_additional_options" { + description = "A list of additional options to apply to this Option Group." + type = list(object({ + option_name = string + option_settings = list(object({ + name = string + value = string + })) + })) + default = [] +} + +variable "option_group_tags" { + description = "A map of tags to assign to the resource." + type = map(string) + default = null +} + +variable "s3_bucket_prefix" { + description = "The prefix to use for the S3 bucket. Required when auditing multiple RDS SQL Server instances sharing the same 'DB Identifier' across various regions or AWS accounts. Format: '/region/account_id', e.g. '/us-east-1/123456789012'." + type = string + default = "" + validation { + condition = var.s3_bucket_prefix != "" ? can(regex("^/[a-z]{2}(-gov)?-[a-z]+-[0-9]{1}/[0-9]{12}$", var.s3_bucket_prefix)) : true + error_message = "The S3 bucket prefix must be in the format '/region/account_id', e.g. '/us-east-1/123456789012'." + } +} + +# AWS RDS SQL Server instance variables +variable "db_instance_count" { + description = "The number of RDS instances to create. Default is 1." + type = number + default = 1 +} + +variable "rds_mssql_allocated_storage" { + description = "The allocated storage in gibibytes. If max_allocated_storage is configured, this argument represents the initial storage allocation and differences from the configuration will be ignored automatically when Storage Autoscaling occurs. If replicate_source_db is set, the value is ignored during the creation of the instance. Default: 20." + type = number + default = 20 +} + +variable "rds_mssql_apply_immediately" { + description = "Specifies whether any database modifications are applied immediately, or during the next maintenance window. Default is true." + type = bool + default = true +} + +variable "rds_mssql_db_name" { + description = "The name of the database to create when the DB instance is created. If this parameter is not specified, no database is created in the DB instance." + type = string + default = null +} + +variable "rds_mssql_deletion_protection" { + description = "If the DB instance should have deletion protection enabled. The database can't be deleted when this value is set to true. Default is false." + type = bool + default = false +} + +variable "rds_mssql_final_snapshot_identifier" { + description = "The name of your final DB snapshot when this DB instance is deleted. Must be provided if skip_final_snapshot is set to false." + type = string + default = null +} + +variable "rds_mssql_identifier" { + description = "The name of the RDS instance." + type = string +} + +variable "rds_mssql_instance_class" { + description = "The instance type of the RDS instance. For supported range of DB instance classes for RDS SQL Server, see the [AWS Docs](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_SQLServer.html#SQLServer.Concepts.General.InstanceClasses) or use the /`aws rds describe-orderable-db-instance-options/` CLI command. Default: db.t3.xlarge" + type = string + default = "db.t3.xlarge" +} + +variable "rds_mssql_max_allocated_storage" { + description = "When configured, the upper limit to which Amazon RDS can automatically scale the storage of the DB instance. Configuring this will automatically ignore differences to allocated_storage." + type = number + default = null +} + +variable "rds_mssql_option_group_name" { + description = "Name of the option group to associate with the RDS instance." + type = string + default = null +} + +variable "rds_mssql_password" { + description = "Password for the master DB user. Note that this may show up in logs, and it will be stored in the state file." + type = string +} + +variable "rds_mssql_port" { + description = "The port on which the DB accepts connections. Default: 1433" + type = number + default = 1433 +} + +variable "rds_mssql_publicly_accessible" { + description = "Bool to control if instance is publicly accessible. Default is true." + type = bool + default = true +} + +variable "rds_mssql_skip_final_snapshot" { + description = "Determines whether a final DB snapshot is created before the DB instance is deleted. If true is specified, no DBSnapshot is created. If false is specified, a DB snapshot is created before the DB instance is deleted, using the value from final_snapshot_identifier. Default is true." + type = bool + default = true +} + +variable "rds_mssql_subnet_group_name" { + description = "Name of DB subnet group. DB instance will be created in the VPC associated with the DB subnet group. If unspecified, will be created in the default VPC, or in EC2 Classic, if available." + type = string + default = null +} +variable "rds_mssql_tags" { + description = "A map of tags to assign to the RDS instance." + type = map(string) + default = null +} + +variable "rds_mssql_username" { + description = "Username for the master DB user. Default: 'admin'." + type = string + default = "admin" +} + +variable "rds_mssql_vpc_security_group_ids" { + description = "List of VPC security groups to associate." + type = list(string) + default = null +} + +# AWS RDS MS SQL Server asset variables +variable "aws_rds_mssql_admin_email" { + description = "The email address to notify about this asset." + type = string +} + +variable "aws_rds_mssql_audit_pull_enabled" { + description = "If true, sonargateway will collect the audit logs for this system if it can. Default is false." + type = bool + default = false +} + +variable "aws_rds_mssql_db_engine_version" { + description = "Denotes the major version of the asset, e.g. 2017 or 2019." + type = string + default = null +} + +variable "aws_rds_mssql_gateway_id" { + description = "Unique identifier (UID) attached to the jSonar machine controlling the asset" + type = string +} + +variable "aws_rds_mssql_parent_asset_id" { + description = "The asset_id of the AWS cloud account that contains this asset." + type = string + default = null +} + +variable "aws_rds_mssql_region" { + description = "AWS region containing the instance." + type = string + default = null +} + +# AWS S3 Asset variables +variable "aws_s3_admin_email" { + description = "The email address to notify about the S3 asset." + type = string +} + +variable "aws_s3_audit_pull_enabled" { + description = "A boolean that indicates whether the asset should be audited. Default is true." + type = bool + default = true +} + +variable "aws_s3_bucket_account_id" { + description = "The account_id of the bucket owner" + type = string + default = null +} + +variable "aws_s3_gateway_id" { + description = "Unique identifier (UID) attached to the jSonar machine controlling the S3 asset" + type = string +} + +variable "aws_s3_parent_asset_id" { + description = "The asset_id of AWS cloud account being used." + type = string +} + +variable "aws_s3_server_port" { + description = "Port used by the source server. Default: 443" + type = number + default = 443 +} + +variable "aws_s3_region" { + description = "AWS region containing the S3 bucket." + type = string +} diff --git a/modules/onboard-aws-redshift-odbc/output.tf b/modules/onboard-aws-redshift-odbc/outputs.tf similarity index 100% rename from modules/onboard-aws-redshift-odbc/output.tf rename to modules/onboard-aws-redshift-odbc/outputs.tf diff --git a/modules/onboard-aws-redshift-s3/README.md b/modules/onboard-aws-redshift-s3/README.md index 243885e..4efd2ae 100644 --- a/modules/onboard-aws-redshift-s3/README.md +++ b/modules/onboard-aws-redshift-s3/README.md @@ -45,7 +45,6 @@ No requirements. | [aws\_redshift\_parent\_asset\_id](#input\_aws\_redshift\_parent\_asset\_id) | The asset\_id of AWS cloud account being used. E.g. Key-pair, iam\_role, profile or default | `string` | `null` | no | | [aws\_redshift\_region](#input\_aws\_redshift\_region) | AWS region containing the Redshift cluster. | `string` | n/a | yes | | [aws\_s3\_admin\_email](#input\_aws\_s3\_admin\_email) | The email address to notify about the S3 asset | `string` | n/a | yes | -| [aws\_s3\_asset\_display\_name](#input\_aws\_s3\_asset\_display\_name) | User-friendly name of the asset, defined by the user | `string` | n/a | yes | | [aws\_s3\_audit\_pull\_enabled](#input\_aws\_s3\_audit\_pull\_enabled) | A boolean that indicates if the asset should be audited. | `bool` | `true` | no | | [aws\_s3\_bucket\_account\_id](#input\_aws\_s3\_bucket\_account\_id) | The account\_id of the bucket owner | `string` | `null` | no | | [aws\_s3\_gateway\_id](#input\_aws\_s3\_gateway\_id) | Unique identifier (UID) attached to the jSonar machine controlling the S3 asset | `string` | n/a | yes | @@ -89,12 +88,12 @@ No requirements. | Name | Description | |------|-------------| -| [redshift-asset](#output\_redshift-asset) | aws redshift asset | -| [redshift-cluster](#output\_redshift-cluster) | redshift cluster | -| [redshift-logging](#output\_redshift-logging) | redshift logging configuration | -| [redshift-parameter-group](#output\_redshift-parameter-group) | redshift parameter group | -| [s3-bucket](#output\_s3-bucket) | s3 bucket | -| [s3-bucket-asset](#output\_s3-bucket-asset) | aws s3 bucket asset | -| [s3-bucket-policy](#output\_s3-bucket-policy) | s3 bucket policy | -| [s3\_policy](#output\_s3\_policy) | s3 iam policy | +| [redshift-asset](#output\_redshift-asset) | AWS Redshift asset | +| [redshift-cluster](#output\_redshift-cluster) | Redshift Cluster | +| [redshift-logging](#output\_redshift-logging) | Redshift Logging Configuration | +| [redshift-parameter-group](#output\_redshift-parameter-group) | Redshift Parameter Group | +| [s3-bucket](#output\_s3-bucket) | S3 Bucket | +| [s3-bucket-asset](#output\_s3-bucket-asset) | AWS S3 bucket asset | +| [s3-bucket-policy](#output\_s3-bucket-policy) | S3 Bucket IAM Policy | +| [s3\_policy](#output\_s3\_policy) | S3 Bucket IAM Policy Document | \ No newline at end of file diff --git a/modules/onboard-aws-redshift-s3/main.tf b/modules/onboard-aws-redshift-s3/main.tf index e392276..af0ac0a 100644 --- a/modules/onboard-aws-redshift-s3/main.tf +++ b/modules/onboard-aws-redshift-s3/main.tf @@ -105,7 +105,7 @@ module "s3-bucket-asset" { source = "../dsfhub-aws-s3-bucket-la" admin_email = var.aws_s3_admin_email - asset_display_name = var.aws_s3_asset_display_name + asset_display_name = module.s3-bucket.this.id asset_id = module.s3-bucket.this.arn audit_pull_enabled = var.aws_s3_audit_pull_enabled audit_type = "REDSHIFT" diff --git a/modules/onboard-aws-redshift-s3/output.tf b/modules/onboard-aws-redshift-s3/outputs.tf similarity index 66% rename from modules/onboard-aws-redshift-s3/output.tf rename to modules/onboard-aws-redshift-s3/outputs.tf index c396e59..ef3a4d5 100644 --- a/modules/onboard-aws-redshift-s3/output.tf +++ b/modules/onboard-aws-redshift-s3/outputs.tf @@ -1,39 +1,39 @@ output "s3-bucket" { - description = "s3 bucket" + description = "S3 Bucket" value = module.redshift-cluster.this } output "s3_policy" { - description = "s3 iam policy" + description = "S3 Bucket IAM Policy Document" value = data.aws_iam_policy_document.s3_policy.json } output "s3-bucket-policy" { - description = "s3 bucket policy" + description = "S3 Bucket IAM Policy" value = module.s3-bucket-policy.this } output "redshift-parameter-group" { - description = "redshift parameter group" + description = "Redshift Parameter Group" value = module.redshift-parameter-group.this } output "redshift-logging" { - description = "redshift logging configuration" + description = "Redshift Logging Configuration" value = module.redshift-logging.this } output "redshift-cluster" { - description = "redshift cluster" + description = "Redshift Cluster" value = module.redshift-cluster.this } output "redshift-asset" { - description = "aws redshift asset" + description = "AWS Redshift asset" value = module.redshift-asset.this } output "s3-bucket-asset" { - description = "aws s3 bucket asset" + description = "AWS S3 bucket asset" value = module.s3-bucket-asset.this } diff --git a/modules/onboard-aws-redshift-s3/variables.tf b/modules/onboard-aws-redshift-s3/variables.tf index a2229f4..4b788d1 100644 --- a/modules/onboard-aws-redshift-s3/variables.tf +++ b/modules/onboard-aws-redshift-s3/variables.tf @@ -235,10 +235,6 @@ variable "aws_s3_admin_email" { description = "The email address to notify about the S3 asset" type = string } -variable "aws_s3_asset_display_name" { - description = "User-friendly name of the asset, defined by the user" - type = string -} variable "aws_s3_audit_pull_enabled" { description = "A boolean that indicates if the asset should be audited."