diff --git a/.gitleaksignore b/.gitleaksignore index 374d0269..70ce96c8 100644 --- a/.gitleaksignore +++ b/.gitleaksignore @@ -1,6 +1,8 @@ # SEE: https://github.com/gitleaks/gitleaks/blob/master/README.md#gitleaksignore -9469a5a10e20b5c3275ba055e65ba98e7d11e9d2:infrastructure/terraform/components/reporting/README.md:ipv4:16 -9469a5a10e20b5c3275ba055e65ba98e7d11e9d2:infrastructure/terraform/components/reporting/variables.tf:ipv4:109 +39565cc5ab1245e4e6a6368c19fd0aa9a187733a:infrastructure/terraform/components/reporting/README.md:ipv4:16 +39565cc5ab1245e4e6a6368c19fd0aa9a187733a:infrastructure/terraform/components/reporting/variables.tf:ipv4:109 ca243cb73d3804a14f3eeefa8073c96802420c52:infrastructure/terraform/etc/env_eu-west-2_int.tfvars:generic-api-key:29 ca243cb73d3804a14f3eeefa8073c96802420c52:infrastructure/terraform/etc/env_eu-west-2_prod.tfvars:generic-api-key:43 +d38af4e4f6c36ca9c3d843193b434386a9bad5ee:infrastructure/terraform/etc/env_eu-west-2_int.tfvars:generic-api-key:29 +d38af4e4f6c36ca9c3d843193b434386a9bad5ee:infrastructure/terraform/etc/env_eu-west-2_prod.tfvars:generic-api-key:43 diff --git a/docs/diagrams/reporting.drawio b/docs/diagrams/reporting.drawio index 49c1c5ed..c62e304d 100644 --- a/docs/diagrams/reporting.drawio +++ b/docs/diagrams/reporting.drawio @@ -157,4 +157,4 @@ - \ No newline at end of file + diff --git a/infrastructure/terraform/bin/test_mandatory_tfvars.sh b/infrastructure/terraform/bin/test_mandatory_tfvars.sh index fc8c4845..db1c9dc0 100755 --- a/infrastructure/terraform/bin/test_mandatory_tfvars.sh +++ b/infrastructure/terraform/bin/test_mandatory_tfvars.sh @@ -81,6 +81,3 @@ for tfvars_file in ./etc/env_eu-west-2_*; do fi done done - - - diff --git a/infrastructure/terraform/components/powerbi-gateway/.tool-versions b/infrastructure/terraform/components/powerbi-gateway/.tool-versions new file mode 100644 index 00000000..3dd74c72 --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/.tool-versions @@ -0,0 +1 @@ +terraform 1.10.1 diff --git a/infrastructure/terraform/components/powerbi-gateway/README.md b/infrastructure/terraform/components/powerbi-gateway/README.md new file mode 100644 index 00000000..a0afbf57 --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/README.md @@ -0,0 +1,44 @@ + + + + +## Requirements + +No requirements. +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [account\_ids](#input\_account\_ids) | All AWS Account IDs for this project | `map(string)` | `{}` | no | +| [account\_name](#input\_account\_name) | The name of the AWS Account to deploy into (see globals.tfvars) | `string` | n/a | yes | +| [athena\_driver\_url](#input\_athena\_driver\_url) | Amazon Athena ODBC MSI download URL for PowerBI gateway bootstrap | `string` | `"https://downloads.athena.us-east-1.amazonaws.com/drivers/ODBC/v2.1.0.0/Windows/AmazonAthenaODBC-2.1.0.0.msi"` | no | +| [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes | +| [component](#input\_component) | The name of the component | `string` | `"powerbi-gateway"` | no | +| [core\_account\_id](#input\_core\_account\_id) | The core account that contains the corresponding Glue Catalog | `string` | `1234567890` | no | +| [core\_account\_ids](#input\_core\_account\_ids) | List of all corresponding core account id's that exist in the Non-Prod domain | `list(string)` | `[]` | no | +| [default\_kms\_deletion\_window\_in\_days](#input\_default\_kms\_deletion\_window\_in\_days) | Default number of days to set KMS key deletion window | `number` | `14` | no | +| [default\_tags](#input\_default\_tags) | A map of default tags to apply to all taggable resources within the component | `map(string)` | `{}` | no | +| [enable\_powerbi\_gateway](#input\_enable\_powerbi\_gateway) | Deploy EC2 instance for PowerBI On-Premises Gateway | `bool` | `true` | no | +| [enable\_spot](#input\_enable\_spot) | run Power BI On-Premises Gateway as spot instances | `bool` | `false` | no | +| [environment](#input\_environment) | The name of the environment | `string` | n/a | yes | +| [group](#input\_group) | The group variables are being inherited from (often synonmous with account short-name) | `string` | `"n/a"` | no | +| [instance\_type](#input\_instance\_type) | The EC2 instance type. | `string` | `"t3.medium"` | no | +| [module](#input\_module) | The variable encapsulating the name of this module | `string` | `"n/a"` | no | +| [powerbi\_gateway\_instance\_count](#input\_powerbi\_gateway\_instance\_count) | Number of standalone Power BI On-Premises Gateway instances created directly from the launch template. | `number` | `2` | no | +| [private\_subnet\_cidrs](#input\_private\_subnet\_cidrs) | List of CIDR blocks for private subnets. | `list(string)` | `[]` | no | +| [project](#input\_project) | The name of the Project we are bootstrapping tfscaffold for | `string` | n/a | yes | +| [public\_subnet\_cidrs](#input\_public\_subnet\_cidrs) | List of CIDR blocks for public subnets. | `list(string)` | `[]` | no | +| [region](#input\_region) | The AWS Region | `string` | n/a | yes | +| [root\_volume\_size](#input\_root\_volume\_size) | Size of root volume for the Power BI On-Premises Gateway instances - 30GB minimum for Windows Server | `number` | `80` | no | +| [spot\_max\_price](#input\_spot\_max\_price) | max spot price for Power BI On-Premises Gateway instances | `string` | `"0.3"` | no | +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [powerbi\_gateway\_vpc](#module\_powerbi\_gateway\_vpc) | terraform-aws-modules/vpc/aws | 5.5.1 | +## Outputs + +No outputs. + + + diff --git a/infrastructure/terraform/components/powerbi-gateway/cloudwatch_metric_alarm_patch_task_failed.tf b/infrastructure/terraform/components/powerbi-gateway/cloudwatch_metric_alarm_patch_task_failed.tf new file mode 100644 index 00000000..bf230769 --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/cloudwatch_metric_alarm_patch_task_failed.tf @@ -0,0 +1,18 @@ +resource "aws_cloudwatch_metric_alarm" "patch_task_failed" { + count = var.enable_powerbi_gateway ? 1 : 0 + + alarm_name = "${local.csi}-patch-task-failed" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = 1 + metric_name = "FailedCommands" + namespace = "AWS/SSM-RunCommand" + period = 300 + statistic = "Sum" + threshold = 1 + alarm_description = "Alarm when the AWS-RunPatchBaseline maintenance window task reports a failed run" + treat_missing_data = "notBreaching" + + dimensions = { + DocumentName = "AWS-RunPatchBaseline" + } +} diff --git a/infrastructure/terraform/components/powerbi-gateway/cloudwatch_metric_alarm_powerbi_gateway_standalone_status.tf b/infrastructure/terraform/components/powerbi-gateway/cloudwatch_metric_alarm_powerbi_gateway_standalone_status.tf new file mode 100644 index 00000000..91d4e855 --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/cloudwatch_metric_alarm_powerbi_gateway_standalone_status.tf @@ -0,0 +1,25 @@ +resource "aws_cloudwatch_metric_alarm" "powerbi_gateway_standalone_status_check_failed" { + for_each = var.enable_powerbi_gateway ? { + for idx, instance in aws_instance.powerbi_gateway_standalone : + idx => { + id = instance.id + name = format("%s-standalone-%02d-status-check-failed", local.csi, idx + 1) + } + } : {} + + alarm_name = each.value.name + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = 2 + datapoints_to_alarm = 2 + metric_name = "StatusCheckFailed" + namespace = "AWS/EC2" + period = 300 + statistic = "Maximum" + threshold = 1 + alarm_description = "Instance or system status check failed for a standalone Power BI gateway host" + treat_missing_data = "breaching" + + dimensions = { + InstanceId = each.value.id + } +} diff --git a/infrastructure/terraform/components/powerbi-gateway/data_cloudinit_config_powerbi_gateway.tf b/infrastructure/terraform/components/powerbi-gateway/data_cloudinit_config_powerbi_gateway.tf new file mode 100644 index 00000000..0d36a054 --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/data_cloudinit_config_powerbi_gateway.tf @@ -0,0 +1,11 @@ +data "cloudinit_config" "powerbi_gateway" { + count = var.enable_powerbi_gateway ? 1 : 0 + + gzip = false + base64_encode = true + + part { + content_type = "text/cloud-config" + content = local.powerbi_gateway_script + } +} diff --git a/infrastructure/terraform/components/powerbi-gateway/ec2_instances_powerbi_gateway.tf b/infrastructure/terraform/components/powerbi-gateway/ec2_instances_powerbi_gateway.tf new file mode 100644 index 00000000..aff7991f --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/ec2_instances_powerbi_gateway.tf @@ -0,0 +1,14 @@ +resource "aws_instance" "powerbi_gateway_standalone" { + count = var.enable_powerbi_gateway ? var.powerbi_gateway_instance_count : 0 + + associate_public_ip_address = false + launch_template { + id = aws_launch_template.powerbi_gateway_standalone[0].id + version = "$Latest" + } + + tags = { + "Name" = format("%s-standalone-%02d", local.csi, count.index + 1) + "Patch Group" = aws_ssm_patch_group.windows_patch_group[0].patch_group + } +} diff --git a/infrastructure/terraform/components/powerbi-gateway/iam_instance_profile_powerbi_gateway.tf b/infrastructure/terraform/components/powerbi-gateway/iam_instance_profile_powerbi_gateway.tf new file mode 100644 index 00000000..4d340697 --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/iam_instance_profile_powerbi_gateway.tf @@ -0,0 +1,226 @@ +resource "aws_iam_instance_profile" "powerbi_gateway" { + count = var.enable_powerbi_gateway ? 1 : 0 + + name = local.csi + role = aws_iam_role.powerbi_gateway_role[0].name +} + +data "aws_iam_policy_document" "powerbi_gateway_assume_role_policy" { + count = var.enable_powerbi_gateway ? 1 : 0 + + statement { + effect = "Allow" + + principals { + type = "Service" + identifiers = ["ec2.amazonaws.com"] + } + + actions = ["sts:AssumeRole"] + } +} + +resource "aws_iam_role" "powerbi_gateway_role" { + count = var.enable_powerbi_gateway ? 1 : 0 + + name = local.csi + description = "PowerBI Gateway Instance Role" + path = "/" + assume_role_policy = data.aws_iam_policy_document.powerbi_gateway_assume_role_policy[0].json +} + + +resource "aws_iam_policy" "powerbi_gateway_permissions_policy" { + count = var.enable_powerbi_gateway ? 1 : 0 + + name = local.csi + description = "PowerBI Gateway Instance Permissions" + path = "/" + policy = data.aws_iam_policy_document.powerbi_gateway_permissions_policy[0].json +} + +resource "aws_iam_role_policy_attachment" "powerbi_gateway_permissions_policy_attachment" { + count = var.enable_powerbi_gateway ? 1 : 0 + + role = aws_iam_role.powerbi_gateway_role[0].name + policy_arn = aws_iam_policy.powerbi_gateway_permissions_policy[0].arn +} + +resource "aws_iam_role_policy_attachment" "powerbi_gateway_ssm_policy_attachment" { + count = var.enable_powerbi_gateway ? 1 : 0 + + role = aws_iam_role.powerbi_gateway_role[0].name + policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" +} + +data "aws_iam_policy_document" "powerbi_gateway_permissions_policy" { + count = var.enable_powerbi_gateway ? 1 : 0 + + statement { + sid = "AllowLogs" + effect = "Allow" + + actions = [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents", + ] + + resources = [ + "arn:aws:logs:${local.parameter_bundle.region}:${local.this_account}:log-group:*", + ] + } + + statement { + sid = "AllowS3DataBucket" + effect = "Allow" + + actions = [ + "s3:GetBucketLocation", + "s3:GetObject", + "s3:ListBucket" + ] + + resources = [ + local.reporting.powerbi_data_bucket_arn, + "${local.reporting.powerbi_data_bucket_arn}/*" + ] + } + + statement { + sid = "AllowS3ResultsBucket" + effect = "Allow" + + actions = [ + "s3:GetBucketLocation", + "s3:GetObject", + "s3:ListBucket", + "s3:PutObject" + ] + + resources = [ + local.reporting.powerbi_results_bucket_arn, + "${local.reporting.powerbi_results_bucket_arn}/*" + ] + } + + statement { + sid = "AllowAthenaAccess1" + effect = "Allow" + + actions = [ + "athena:GetQueryResults", + "athena:GetQueryResultsStream", + "athena:GetQueryExecution", + "athena:StartQueryExecution", + "athena:GetWorkGroup", + "athena:GetNamedQuery" + ] + + resources = [ + local.reporting.powerbi_user_workgroup_arn + ] + } + + statement { + sid = "AllowAthenaAccess2" + effect = "Allow" + + actions = [ + "athena:GetDatabase", + "athena:GetTableMetadata", + "athena:GetDataCatalog", + "athena:GetTable" + ] + + resources = [ + "arn:aws:athena:${var.region}:${local.this_account}:datacatalog/AWSDataCatalog" + ] + } + + statement { + sid = "AllowAthenaAccess3" + effect = "Allow" + + actions = [ + "athena:ListDataCatalogs", + "athena:ListDatabases", + "athena:ListTableMetadata", + "athena:ListWorkGroups" + ] + + resources = ["*"] # Access to List all above is required. Condition keys not supported for these resources. + } + + statement { + sid = "AllowGlueAccess" + effect = "Allow" + + actions = [ + "glue:GetTable", + "glue:GetTables", + "glue:BatchGetTable", + "glue:GetDatabase", + "glue:GetDatabases", + "glue:GetPartition", + "glue:GetPartitions" + ] + + resources = concat( + local.core_glue_catalog_resources, # Access to all core account catalogs is required as they are all accessible via the default catalog in the environment's account + [ + local.reporting.powerbi_reporting_database_arn, + "arn:aws:glue:${var.region}:${var.core_account_id}:catalog", + "arn:aws:glue:${var.region}:${local.this_account}:catalog", + # Tables + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/request_item_plan_completed_summary", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/request_item_plan_completed_summary_batch", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/request_item_plan_status", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/request_item_status", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/request_item_status_summary", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/request_item_status_summary_batch", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/client_latest_name", + # Views + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/request_item_plan_completed_summary_all", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/request_item_status_summary_all", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/request_item_status_summary_all_email_filter", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/request_item_status_smsnudge_staging", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/request_item_plan_status_smsnudge", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/request_item_plan_read_status_smsnudge", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/request_item_status_smsnudge", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/dates", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/letters_invoice_units_monthly", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/letters_invoice_units_weekly", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/latency_percentiles", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/daily_recipient_count", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/daily_recipient_distribution", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/raw_latency_3m", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/delivered_messages", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/monthly_app_recipients_distribution", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/monthly_app_recipients_multiple_clients", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/monthly_messages_per_recipient", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/monthly_recipient_with_more_than_five_messages", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/monthly_recipients_distribution", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/monthly_recipients_distribution_by_integrator", + "arn:aws:glue:${var.region}:${local.this_account}:table/${local.reporting.powerbi_reporting_database_name}/billing_transactions", + ] + ) + } + + statement { + sid = "AllowS3KMSAccess" + effect = "Allow" + + actions = [ + "kms:Decrypt", + "kms:Encrypt", + "kms:GenerateDataKey", + "kms:GenerateDataKeyWithoutPlaintext", + "kms:DescribeKey" + ] + + resources = [ + local.reporting.powerbi_s3_kms_key_arn + ] + } +} diff --git a/infrastructure/terraform/components/powerbi-gateway/kms_key_ebs.tf b/infrastructure/terraform/components/powerbi-gateway/kms_key_ebs.tf new file mode 100644 index 00000000..1e72bb7c --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/kms_key_ebs.tf @@ -0,0 +1,107 @@ +resource "aws_kms_key" "ebs" { + count = var.enable_powerbi_gateway ? 1 : 0 + + description = "CMK for encrypting EBS volumes" + deletion_window_in_days = local.parameter_bundle.default_kms_deletion_window_in_days + enable_key_rotation = true + policy = data.aws_iam_policy_document.ebs[0].json +} + +resource "aws_kms_alias" "ebs" { + count = var.enable_powerbi_gateway ? 1 : 0 + + name = "alias/${local.csi}-ebs" + target_key_id = aws_kms_key.ebs[0].key_id +} + + +data "aws_iam_policy_document" "ebs" { + count = var.enable_powerbi_gateway ? 1 : 0 + + statement { + sid = "AllowLocalIAMAdministration" + effect = "Allow" + + actions = [ + "kms:Create*", + "kms:Describe*", + "kms:Enable*", + "kms:List*", + "kms:Put*", + "kms:Update*", + "kms:Revoke*", + "kms:Disable*", + "kms:Get*", + "kms:Delete*", + "kms:ScheduleKeyDeletion", + "kms:CancelKeyDeletion", + "kms:Decrypt", + "kms:Encrypt", + "kms:GenerateDataKey", + "kms:TagResource" + ] + + resources = [ + "*", + ] + + principals { + type = "AWS" + identifiers = [ + local.parameter_bundle.iam_resource_arns.any_authorised_user_in_this_account, + + ] + } + } + + statement { + sid = "AllowUsageAccess" + effect = "Allow" + + actions = [ + "kms:Decrypt", + "kms:DescribeKey", + "kms:Encrypt", + "kms:GenerateDataKey*", + "kms:ReEncrypt*", + ] + + resources = [ + "*", + ] + + principals { + type = "AWS" + identifiers = [ + local.parameter_bundle.iam_resource_arns.any_authorised_user_in_this_account, + "arn:aws:iam::${local.this_account}:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling" + + ] + } + } + statement { + sid = "AllowAutoscalingToUse" + effect = "Allow" + + actions = [ + "kms:CreateGrant", + ] + + resources = [ + "*", + ] + + principals { + type = "AWS" + identifiers = [ + "arn:aws:iam::${local.this_account}:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling", + ] + } + + condition { + test = "Bool" + variable = "kms:GrantIsForAWSResource" + values = ["true"] + } + } +} diff --git a/infrastructure/terraform/components/reporting/launch_template_powerbi_gateway_asg.tf b/infrastructure/terraform/components/powerbi-gateway/launch_template_powerbi_gateway_standalone.tf similarity index 84% rename from infrastructure/terraform/components/reporting/launch_template_powerbi_gateway_asg.tf rename to infrastructure/terraform/components/powerbi-gateway/launch_template_powerbi_gateway_standalone.tf index 00c0a657..8a5946e2 100644 --- a/infrastructure/terraform/components/reporting/launch_template_powerbi_gateway_asg.tf +++ b/infrastructure/terraform/components/powerbi-gateway/launch_template_powerbi_gateway_standalone.tf @@ -1,10 +1,10 @@ -resource "aws_launch_template" "powerbi_gateway" { +resource "aws_launch_template" "powerbi_gateway_standalone" { count = var.enable_powerbi_gateway ? 1 : 0 - name = local.csi - description = "Template for the Power BI On-Premises Gateway" + name = "${local.csi}-standalone" + description = "Template for the Power BI On-Premises Gateway (standalone instances)" update_default_version = true - image_id = "resolve:ssm:/aws/service/ami-windows-latest/Windows_Server-2022-English-Full-Base" + image_id = "resolve:ssm:/aws/service/ami-windows-latest/Windows_Server-2025-English-Full-Base" instance_type = var.instance_type user_data = data.cloudinit_config.powerbi_gateway[0].rendered instance_initiated_shutdown_behavior = var.enable_spot ? "terminate" : "stop" @@ -57,11 +57,7 @@ resource "aws_launch_template" "powerbi_gateway" { tag_specifications { resource_type = "instance" - tags = merge(local.deployment_default_tags, - { - "Patch Group" = "${local.csi}-windows-group" - } - ) + tags = local.deployment_default_tags } tag_specifications { diff --git a/infrastructure/terraform/components/powerbi-gateway/locals.tf b/infrastructure/terraform/components/powerbi-gateway/locals.tf new file mode 100644 index 00000000..8289c8b4 --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/locals.tf @@ -0,0 +1,68 @@ +locals { + # Compound Scope Identifier + csi = replace( + format( + "%s-%s-%s", + var.project, + var.environment, + var.component, + ), + "_", + "" + ) + + base_parameter_bundle = { + project = var.project + environment = var.environment + component = var.component + group = var.group + region = var.region + account_ids = var.account_ids + account_name = var.account_name + default_kms_deletion_window_in_days = var.default_kms_deletion_window_in_days + default_tags = local.deployment_default_tags + } + + parameter_bundle = merge( + local.base_parameter_bundle, { + iam_resource_arns = { + any_authorised_user_in_this_account = "arn:aws:iam::${local.this_account}:root" + }, + } + ) + + deployment_default_tags = { + AccountId = var.account_ids[var.account_name] + AccountName = var.account_name + Project = var.project + Environment = var.environment + Component = var.component + Group = var.group + Module = var.module + } + + this_account = local.base_parameter_bundle.account_ids[local.base_parameter_bundle.account_name] + + # Create the powerbi_gateway_script only if var.enable_powerbi_gateway is true + powerbi_gateway_script = var.enable_powerbi_gateway ? templatefile("${path.module}/templates/cloudinit_config.tmpl", { + odbc_dsn_name = "${local.csi}-dsn" + odbc_description = "AWS Simba Athena ODBC Connection for ${local.csi}" + athena_driver_url = var.athena_driver_url + region = var.region + catalog = "AWSDataCatalog" + database = data.terraform_remote_state.reporting.outputs.powerbi_reporting_database_name + workgroup = data.terraform_remote_state.reporting.outputs.powerbi_user_workgroup_name + authentication_type = "Instance Profile" + gateway_name = "${local.csi}-gateway" + }) : null + + use_core_glue_catalog_resources = length(var.core_account_ids) > 0 ? true : false + + core_glue_catalog_resources = local.use_core_glue_catalog_resources ? flatten([ + for account_id in var.core_account_ids : [ + "arn:aws:glue:${var.region}:${account_id}:catalog", + ] + ]) : [] + + reporting = data.terraform_remote_state.reporting.outputs +} diff --git a/infrastructure/terraform/components/powerbi-gateway/locals_reporting_remote_state.tf b/infrastructure/terraform/components/powerbi-gateway/locals_reporting_remote_state.tf new file mode 100644 index 00000000..44710645 --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/locals_reporting_remote_state.tf @@ -0,0 +1,16 @@ +data "terraform_remote_state" "reporting" { + backend = "s3" + + config = { + bucket = local.terraform_state_bucket + key = format( + "%s/%s/%s/%s/%s.tfstate", + var.project, + var.aws_account_id, + var.region, + var.environment, + "reporting" + ) + region = var.region + } +} diff --git a/infrastructure/terraform/components/powerbi-gateway/locals_tfscaffold.tf b/infrastructure/terraform/components/powerbi-gateway/locals_tfscaffold.tf new file mode 100644 index 00000000..bf93f3a6 --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/locals_tfscaffold.tf @@ -0,0 +1,27 @@ +locals { + terraform_state_bucket = format( + "%s-tfscaffold-%s-%s", + var.project, + var.aws_account_id, + var.region, + ) + + # Central account component deployed with "nhs" project name, not "nhs-notify" for legacy reasons. + terraform_state_bucket_acct = format( + "%s-tfscaffold-%s-%s", + "nhs", + var.aws_account_id, + var.region, + ) + + default_tags = merge( + var.default_tags, + { + Project = var.project + Environment = var.environment + Component = var.component + Group = var.group + Name = local.csi + }, + ) +} diff --git a/infrastructure/terraform/components/powerbi-gateway/module_powerbi_gateway_vpc.tf b/infrastructure/terraform/components/powerbi-gateway/module_powerbi_gateway_vpc.tf new file mode 100644 index 00000000..55939f92 --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/module_powerbi_gateway_vpc.tf @@ -0,0 +1,67 @@ +module "powerbi_gateway_vpc" { + count = var.enable_powerbi_gateway ? 1 : 0 + + source = "terraform-aws-modules/vpc/aws" + version = "5.5.1" # Adjust to the latest version + + create_vpc = var.enable_powerbi_gateway + + name = "${local.csi}-vpc" + cidr = "10.0.0.0/16" + + azs = data.aws_availability_zones.available[0].names + public_subnets = var.public_subnet_cidrs + private_subnets = var.private_subnet_cidrs + + enable_nat_gateway = true + single_nat_gateway = false + enable_dns_support = true + enable_dns_hostnames = true + create_igw = true +} + +data "aws_availability_zones" "available" { + count = var.enable_powerbi_gateway ? 1 : 0 + + state = "available" +} + +#trivy:ignore:aws-ec2-no-public-egress-sgr +resource "aws_security_group" "powerbi_gateway" { + count = var.enable_powerbi_gateway ? 1 : 0 + + name = "${local.csi}-security-group" + vpc_id = module.powerbi_gateway_vpc[0].vpc_id + + egress { + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 443 + to_port = 443 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 5671 + to_port = 5672 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 9350 + to_port = 9354 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + tags = { + Name = "${local.csi}-sg" + } +} diff --git a/infrastructure/terraform/components/powerbi-gateway/provider.tf b/infrastructure/terraform/components/powerbi-gateway/provider.tf new file mode 100644 index 00000000..e5b9a49e --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/provider.tf @@ -0,0 +1,23 @@ +### +# Default provider, used for all deployments to eu-west-2 +# If no provider name is supplied for a resource then it uses this one +### +provider "aws" { + region = var.region + + default_tags { + tags = local.deployment_default_tags + } +} + +### +# Provider specifically for deploying to us-east-1, e.g. for cloudfront, ACM, etc. +### +provider "aws" { + alias = "us-east-1" + region = "us-east-1" + + default_tags { + tags = local.deployment_default_tags + } +} diff --git a/infrastructure/terraform/components/powerbi-gateway/ssm_maintenance_window_patch_window.tf b/infrastructure/terraform/components/powerbi-gateway/ssm_maintenance_window_patch_window.tf new file mode 100644 index 00000000..e5f35a5e --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/ssm_maintenance_window_patch_window.tf @@ -0,0 +1,21 @@ +resource "aws_ssm_maintenance_window" "patch_window_sunday" { + count = var.enable_powerbi_gateway ? 1 : 0 + + name = "${local.csi}-windows-patch-window-sun" + description = "Windows Server 2025 Sunday Patch Window" + schedule = "cron(0 3 ? * SUN *)" # Every Sunday at 3 AM + duration = 4 + cutoff = 1 + allow_unassociated_targets = true +} + +resource "aws_ssm_maintenance_window" "patch_window_wednesday" { + count = var.enable_powerbi_gateway ? 1 : 0 + + name = "${local.csi}-windows-patch-window-wed" + description = "Windows Server 2025 Wednesday Patch Window" + schedule = "cron(0 3 ? * WED *)" # Every Wednesday at 3 AM + duration = 4 + cutoff = 1 + allow_unassociated_targets = true +} diff --git a/infrastructure/terraform/components/powerbi-gateway/ssm_maintenance_window_target_windows_instances.tf b/infrastructure/terraform/components/powerbi-gateway/ssm_maintenance_window_target_windows_instances.tf new file mode 100644 index 00000000..d4193bc1 --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/ssm_maintenance_window_target_windows_instances.tf @@ -0,0 +1,27 @@ +resource "aws_ssm_maintenance_window_target" "windows_instances_sunday" { + count = var.enable_powerbi_gateway && var.powerbi_gateway_instance_count >= 1 ? 1 : 0 + + description = "Windows Server 2025 Sunday Maintenance Window Target " + window_id = aws_ssm_maintenance_window.patch_window_sunday[0].id + resource_type = "INSTANCE" + name = "${local.csi}-maintenance-window-target-sun" + + targets { + key = "InstanceIds" + values = [aws_instance.powerbi_gateway_standalone[0].id] + } +} + +resource "aws_ssm_maintenance_window_target" "windows_instances_wednesday" { + count = var.enable_powerbi_gateway && var.powerbi_gateway_instance_count >= 2 ? 1 : 0 + + description = "Windows Server 2025 Wednesday Maintenance Window Target" + window_id = aws_ssm_maintenance_window.patch_window_wednesday[0].id + resource_type = "INSTANCE" + name = "${local.csi}-maintenance-window-target-wed" + + targets { + key = "InstanceIds" + values = [aws_instance.powerbi_gateway_standalone[1].id] + } +} diff --git a/infrastructure/terraform/components/powerbi-gateway/ssm_maintenance_window_task_patch_task.tf b/infrastructure/terraform/components/powerbi-gateway/ssm_maintenance_window_task_patch_task.tf new file mode 100644 index 00000000..3e0e5aa5 --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/ssm_maintenance_window_task_patch_task.tf @@ -0,0 +1,63 @@ +resource "aws_ssm_maintenance_window_task" "patch_task_sunday" { + count = var.enable_powerbi_gateway ? 1 : 0 + + description = "Windows Server 2025 Sunday Patch Task" + window_id = aws_ssm_maintenance_window.patch_window_sunday[0].id + task_arn = "AWS-RunPatchBaseline" + task_type = "RUN_COMMAND" + + targets { + key = "WindowTargetIds" + values = [aws_ssm_maintenance_window_target.windows_instances_sunday[0].id] + } + + task_invocation_parameters { + run_command_parameters { + comment = "Patching Sunday instances" + parameter { + name = "Operation" + values = ["Install"] + } + parameter { + name = "RebootOption" + values = ["RebootIfNeeded"] + } + } + } + + priority = 1 + max_concurrency = "1" + max_errors = "1" +} + +resource "aws_ssm_maintenance_window_task" "patch_task_wednesday" { + count = var.enable_powerbi_gateway && var.powerbi_gateway_instance_count >= 2 ? 1 : 0 + + description = "Windows Server 2025 Wednesday Patch Task" + window_id = aws_ssm_maintenance_window.patch_window_wednesday[0].id + task_arn = "AWS-RunPatchBaseline" + task_type = "RUN_COMMAND" + + targets { + key = "WindowTargetIds" + values = [aws_ssm_maintenance_window_target.windows_instances_wednesday[0].id] + } + + task_invocation_parameters { + run_command_parameters { + comment = "Patching Wednesday instance" + parameter { + name = "Operation" + values = ["Install"] + } + parameter { + name = "RebootOption" + values = ["RebootIfNeeded"] + } + } + } + + priority = 1 + max_concurrency = "1" + max_errors = "1" +} diff --git a/infrastructure/terraform/components/powerbi-gateway/ssm_parameter_powerbi_gateway_recovery_key.tf b/infrastructure/terraform/components/powerbi-gateway/ssm_parameter_powerbi_gateway_recovery_key.tf new file mode 100644 index 00000000..3a01dc64 --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/ssm_parameter_powerbi_gateway_recovery_key.tf @@ -0,0 +1,14 @@ +resource "aws_ssm_parameter" "powerbi_gateway_recovery_key" { + count = var.enable_powerbi_gateway ? 1 : 0 + + name = "/${local.csi}/gateway-recovery-key" + description = "The Recovery Key for the On-Premises Gateway - Updated manually with the actual key value after deployment" + type = "SecureString" + value = "RECOVERY_KEY_PLACEHOLDER" + + lifecycle { + ignore_changes = [ + value, + ] + } +} diff --git a/infrastructure/terraform/components/powerbi-gateway/ssm_patch_baseline_windows_patch_baseline.tf b/infrastructure/terraform/components/powerbi-gateway/ssm_patch_baseline_windows_patch_baseline.tf new file mode 100644 index 00000000..59a8fd1c --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/ssm_patch_baseline_windows_patch_baseline.tf @@ -0,0 +1,24 @@ +resource "aws_ssm_patch_baseline" "windows_patch_baseline" { + count = var.enable_powerbi_gateway ? 1 : 0 + + name = "${local.csi}-windows-patch-baseline" + description = "Windows Server 2025 Patch Baseline" + operating_system = "WINDOWS" + approval_rule { + patch_filter { + key = "PRODUCT" + values = ["WindowsServer2025"] + } + patch_filter { + key = "CLASSIFICATION" + values = ["SecurityUpdates", "CriticalUpdates"] + } + patch_filter { + key = "MSRC_SEVERITY" + values = [ + "Critical", + "Important", + ] + } + } +} diff --git a/infrastructure/terraform/components/powerbi-gateway/ssm_patch_group_windows_patch_group.tf b/infrastructure/terraform/components/powerbi-gateway/ssm_patch_group_windows_patch_group.tf new file mode 100644 index 00000000..d316a3cf --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/ssm_patch_group_windows_patch_group.tf @@ -0,0 +1,6 @@ +resource "aws_ssm_patch_group" "windows_patch_group" { + count = var.enable_powerbi_gateway ? 1 : 0 + + baseline_id = aws_ssm_patch_baseline.windows_patch_baseline[0].id + patch_group = "${local.csi}-windows-group" +} diff --git a/infrastructure/terraform/components/powerbi-gateway/templates/cloudinit_config.tmpl b/infrastructure/terraform/components/powerbi-gateway/templates/cloudinit_config.tmpl new file mode 100644 index 00000000..399b8d98 --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/templates/cloudinit_config.tmpl @@ -0,0 +1,117 @@ + + +# Create scripts directory if it doesn't exist +if (!(Test-Path -Path "C:\scripts")) { + New-Item -ItemType Directory -Path "C:\scripts" +} + +# Create the install_powerbi_gateway.ps1 script +$installPowerBiGatewayScript = @" +# Set execution policy to bypass +Set-ExecutionPolicy Bypass -Scope Process -Force + +# Enable TLS 1.2 +[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072 + +# Download and install Chocolatey (if not already installed) +if (-not (Get-Command choco -ErrorAction SilentlyContinue)) { + iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) +} + +# Install Powershell 7 +choco install -y powershell-core + +# Install Amazon Athena ODBC 2.x Driver +`$athenaDriverUrl = "${athena_driver_url}" +`$athenaDriverInstaller = "C:\scripts\AmazonAthenaODBC.msi" +Invoke-WebRequest -Uri `$athenaDriverUrl -OutFile `$athenaDriverInstaller + +# Silent installation of Amazon Athena ODBC driver +Start-Process -FilePath `$athenaDriverInstaller -ArgumentList "/quiet" -Wait + +# Configure the ODBC Connection: +`$odbcDsnName = "${odbc_dsn_name}" +`$odbcDescription = "${odbc_description}" +`$region = "${region}" +`$catalog = "${catalog}" +`$database = "${database}" +`$workgroup = "${workgroup}" +`$authenticationType = "${authentication_type}" + +# Path to the ODBC DSN registry key +`$odbcDsnPath = "HKLM:HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI\`$odbcDsnName" +`$odbcDsnListPath = "HKLM:\HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI\ODBC Data Sources" + +# Create the DSN key and set values +New-Item -Path `$odbcDsnPath -Force +Set-ItemProperty -Path `$odbcDsnPath -Name "Description" -Value `$odbcDescription +Set-ItemProperty -Path `$odbcDsnPath -Name "AwsRegion" -Value `$region +Set-ItemProperty -Path `$odbcDsnPath -Name "Catalog" -Value `$catalog +Set-ItemProperty -Path `$odbcDsnPath -Name "Schema" -Value `$database +Set-ItemProperty -Path `$odbcDsnPath -Name "Workgroup" -Value `$workgroup +Set-ItemProperty -Path `$odbcDsnPath -Name "AuthenticationType" -Value `$authenticationType + +# Add the DSN to the list of ODBC Data Sources +Set-ItemProperty -Path `$odbcDsnListPath -Name `$odbcDsnName -Value "Amazon Athena ODBC (x64)" + +Write-Output "ODBC DSN '`$odbcDsnName' created successfully." + +Write-Output "Power BI on-premises data gateway and Amazon Athena ODBC driver installation completed." + +# Check if PowerShell 7 (pwsh) is installed and available +`$pwshPath = "C:\Program Files\PowerShell\7\pwsh.exe" +if (Test-Path `$pwshPath) { + # Invoke PowerShell 7 to run the remaining commands + & `$pwshPath -ExecutionPolicy Bypass -Command { + # Set execution policy to bypass + Set-ExecutionPolicy Bypass -Scope Process -Force + + # Install DataGateway CMDLets + Install-Module -Name DataGateway -Force -AllowClobber -Scope AllUsers + + # Install AWSCLI + choco install -y awscli + `$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + + # Verify AWS CLI installation + if (!(Get-Command aws -ErrorAction SilentlyContinue)) { + Write-Output "AWS CLI installation failed or not found in PATH." + exit 1 + } + } +} +else { + Write-Output "AWSCLI & PowerShell 7 installation failed or path not found." +} + +# Function to disable Internet Explorer Enhanced Security Configuration (ESC) +# Required due to ESC rejecting Microsoft's own SSO endpoints - https://login.microsoftonline.com, https://aadcdn.msftauth.net, https://fs.nhs.net +function Disable-InternetExplorerESC { + `$AdminKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}" + `$UserKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}" + Set-ItemProperty -Path `$AdminKey -Name "IsInstalled" -Value 0 -Force + Set-ItemProperty -Path `$UserKey -Name "IsInstalled" -Value 0 -Force + Stop-Process -Name Explorer -Force + Write-Host "IE Enhanced Security Configuration (ESC) has been disabled." -ForegroundColor Green +} + +# Function to enable Internet Explorer Enhanced Security Configuration (ESC) +function Enable-InternetExplorerESC { + `$AdminKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}" + `$UserKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}" + Set-ItemProperty -Path `$AdminKey -Name "IsInstalled" -Value 1 -Force + Set-ItemProperty -Path `$UserKey -Name "IsInstalled" -Value 1 -Force + Stop-Process -Name Explorer -Force + Write-Host "IE Enhanced Security Configuration (ESC) has been enabled." -ForegroundColor Green +} + +# Disable IE ESC +Disable-InternetExplorerESC + +"@ +Set-Content -Path "C:\scripts\install_powerbi_gateway.ps1" -Value $installPowerBiGatewayScript + +# Execute the script +powershell.exe -ExecutionPolicy Bypass -File "C:\scripts\install_powerbi_gateway.ps1" > "C:\scripts\install_powerbi_gateway.log" 2>&1 + + diff --git a/infrastructure/terraform/components/powerbi-gateway/variables.tf b/infrastructure/terraform/components/powerbi-gateway/variables.tf new file mode 100644 index 00000000..edbffdbe --- /dev/null +++ b/infrastructure/terraform/components/powerbi-gateway/variables.tf @@ -0,0 +1,126 @@ +variable "project" { + type = string + description = "The name of the Project we are bootstrapping tfscaffold for" +} + +variable "account_ids" { + type = map(string) + description = "All AWS Account IDs for this project" + default = {} +} + +variable "aws_account_id" { + type = string + description = "The AWS Account ID (numeric)" +} + +variable "account_name" { + type = string + description = "The name of the AWS Account to deploy into (see globals.tfvars)" +} + +variable "default_tags" { + type = map(string) + description = "A map of default tags to apply to all taggable resources within the component" + default = {} +} + +variable "region" { + type = string + description = "The AWS Region" +} + +variable "environment" { + type = string + description = "The name of the environment" +} + +variable "component" { + type = string + description = "The name of the component" + default = "powerbi-gateway" +} + +variable "group" { + type = string + description = "The group variables are being inherited from (often synonmous with account short-name)" + default = "n/a" +} + +variable "module" { + type = string + description = "The variable encapsulating the name of this module" + default = "n/a" +} + +variable "default_kms_deletion_window_in_days" { + type = number + description = "Default number of days to set KMS key deletion window" + default = 14 +} + +variable "core_account_id" { + type = string + description = "The core account that contains the corresponding Glue Catalog" + default = 1234567890 +} + +variable "enable_powerbi_gateway" { + type = bool + description = "Deploy EC2 instance for PowerBI On-Premises Gateway" + default = true +} + +variable "athena_driver_url" { + type = string + description = "Amazon Athena ODBC MSI download URL for PowerBI gateway bootstrap" + default = "https://downloads.athena.us-east-1.amazonaws.com/drivers/ODBC/v2.1.0.0/Windows/AmazonAthenaODBC-2.1.0.0.msi" +} + +variable "powerbi_gateway_instance_count" { + description = "Number of standalone Power BI On-Premises Gateway instances created directly from the launch template." + type = number + default = 2 +} + +variable "public_subnet_cidrs" { + description = "List of CIDR blocks for public subnets." + type = list(string) + default = [] +} + +variable "private_subnet_cidrs" { + description = "List of CIDR blocks for private subnets." + type = list(string) + default = [] +} + +variable "instance_type" { + description = "The EC2 instance type." + type = string + default = "t3.medium" +} + +variable "enable_spot" { + type = bool + description = "run Power BI On-Premises Gateway as spot instances" + default = false +} + +variable "spot_max_price" { + type = string + description = "max spot price for Power BI On-Premises Gateway instances" + default = "0.3" +} + +variable "root_volume_size" { + type = number + description = "Size of root volume for the Power BI On-Premises Gateway instances - 30GB minimum for Windows Server" + default = 80 +} + +variable "core_account_ids" { + description = "List of all corresponding core account id's that exist in the Non-Prod domain" + type = list(string) + default = [] +} diff --git a/infrastructure/terraform/components/reporting/README.md b/infrastructure/terraform/components/reporting/README.md index 82985d40..8db61524 100644 --- a/infrastructure/terraform/components/reporting/README.md +++ b/infrastructure/terraform/components/reporting/README.md @@ -13,6 +13,7 @@ No requirements. | [account\_name](#input\_account\_name) | The name of the AWS Account to deploy into (see globals.tfvars) | `string` | n/a | yes | | [app\_deployer\_role\_name](#input\_app\_deployer\_role\_name) | Name of the app deployer role that is allowed to deploy Comms Mgr applications but not create other IAM roles | `string` | n/a | yes | | [app\_deployer\_role\_permission\_account\_ids](#input\_app\_deployer\_role\_permission\_account\_ids) | All AWS Account IDs for this project that have the AppDeployer role created | `map(string)` | `{}` | no | +| [athena\_driver\_url](#input\_athena\_driver\_url) | Amazon Athena ODBC MSI download URL for PowerBI gateway bootstrap | `string` | `"https://downloads.athena.us-east-1.amazonaws.com/drivers/ODBC/v2.1.0.0/Windows/AmazonAthenaODBC-2.1.0.0.msi"` | no | | [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes | | [batch\_client\_ids](#input\_batch\_client\_ids) | List of client ids that require additional batch identifier dimensions when aggregating data | `list(string)` |
[
"NULL"
]
| no | | [cloudtrail\_log\_group\_name](#input\_cloudtrail\_log\_group\_name) | The name of the Cloudtrail log group name on the account (see globals.tfvars) | `string` | n/a | yes | @@ -23,10 +24,9 @@ No requirements. | [core\_env](#input\_core\_env) | The core environment that contains the corresponding Glue table/S3 buckets etc. | `string` | `"internal-dev"` | no | | [default\_kms\_deletion\_window\_in\_days](#input\_default\_kms\_deletion\_window\_in\_days) | Default number of days to set KMS key deletion window | `number` | `14` | no | | [default\_tags](#input\_default\_tags) | A map of default tags to apply to all taggable resources within the component | `map(string)` | `{}` | no | -| [desired\_capacity](#input\_desired\_capacity) | The desired number of instances in the Power BI On-Premises Gateway Auto Scaling group. | `number` | `1` | no | | [destination\_backup\_vault\_arn](#input\_destination\_backup\_vault\_arn) | ARN of the destination backup vault to copy periodic backups to | `string` | `""` | no | | [email\_filter\_client\_ids](#input\_email\_filter\_client\_ids) | List of client ids that need email-only sending groups to be hidden in certain views | `list(string)` |
[
"NULL"
]
| no | -| [enable\_powerbi\_gateway](#input\_enable\_powerbi\_gateway) | Deploy EC2 instance for PowerBI On-Premises Gateway | `bool` | `true` | no | +| [enable\_powerbi\_gateway](#input\_enable\_powerbi\_gateway) | Deploy supporting resources for the legacy PowerBI On-Premises Gateway | `bool` | `true` | no | | [enable\_s3\_backup](#input\_enable\_s3\_backup) | Enable AWS S3 Backup of the data bucket | `bool` | `true` | no | | [enable\_spot](#input\_enable\_spot) | run Power BI On-Premises Gateway as spot instances | `bool` | `false` | no | | [enable\_vault\_lock\_configuration](#input\_enable\_vault\_lock\_configuration) | Enable vault lock, preventing the deletion of a vault that contains 1 or more Recovery Points | `bool` | `false` | no | @@ -34,8 +34,6 @@ No requirements. | [group](#input\_group) | The group variables are being inherited from (often synonmous with account short-name) | `string` | `"n/a"` | no | | [instance\_type](#input\_instance\_type) | The EC2 instance type. | `string` | `"t3.medium"` | no | | [log\_retention\_days](#input\_log\_retention\_days) | How many days to retain the logs generated by the step function | `number` | `30` | no | -| [max\_size](#input\_max\_size) | The maximum number of instances in the Power BI On-Premises Gateway Auto Scaling group. | `number` | `1` | no | -| [min\_size](#input\_min\_size) | The minimum number of instances in the Power BI On-Premises Gateway Auto Scaling group. | `number` | `1` | no | | [module](#input\_module) | The variable encapsulating the name of this module | `string` | `"n/a"` | no | | [parent\_acct\_environment](#input\_parent\_acct\_environment) | Name of the environment responsible for the acct resources used, affects things like DNS zone. Useful for named dev environments | `string` | `"main"` | no | | [periodic\_s3backup\_copy\_retention\_days](#input\_periodic\_s3backup\_copy\_retention\_days) | number of days to retain weekly s3 backups in the destination vault | `number` | `31` | no | @@ -47,8 +45,6 @@ No requirements. | [public\_subnet\_cidrs](#input\_public\_subnet\_cidrs) | List of CIDR blocks for public subnets. | `list(string)` | `[]` | no | | [region](#input\_region) | The AWS Region | `string` | n/a | yes | | [root\_volume\_size](#input\_root\_volume\_size) | Size of root volume for the Power BI On-Premises Gateway instances - 30GB minimum for Windows Server | `number` | `80` | no | -| [scale\_in\_recurrence\_schedule](#input\_scale\_in\_recurrence\_schedule) | The cron expression for the scale in schedule. Set to null if no recurrence is needed. | `string` | `null` | no | -| [scale\_out\_recurrence\_schedule](#input\_scale\_out\_recurrence\_schedule) | The cron expression for the scale out schedule. Set to null if no recurrence is needed. | `string` | `null` | no | | [shared\_infra\_account\_id](#input\_shared\_infra\_account\_id) | The AWS Account ID of the shared infrastructure account | `string` | `"000000000000"` | no | | [sms\_nudge\_client\_id](#input\_sms\_nudge\_client\_id) | Client id for the SMS Nudge umbrella client used to filter smsnudge views | `string` | `"NULL"` | no | | [spot\_max\_price](#input\_spot\_max\_price) | max spot price for Power BI On-Premises Gateway instances | `string` | `"0.3"` | no | @@ -60,7 +56,15 @@ No requirements. | [powerbi\_gateway\_vpc](#module\_powerbi\_gateway\_vpc) | terraform-aws-modules/vpc/aws | 5.5.1 | ## Outputs -No outputs. +| Name | Description | +|------|-------------| +| [powerbi\_data\_bucket\_arn](#output\_powerbi\_data\_bucket\_arn) | Data bucket ARN used by the Power BI gateway component | +| [powerbi\_reporting\_database\_arn](#output\_powerbi\_reporting\_database\_arn) | Glue reporting database ARN for Power BI gateway access policy | +| [powerbi\_reporting\_database\_name](#output\_powerbi\_reporting\_database\_name) | Glue reporting database name for Power BI gateway access policy | +| [powerbi\_results\_bucket\_arn](#output\_powerbi\_results\_bucket\_arn) | Results bucket ARN used by the Power BI gateway component | +| [powerbi\_s3\_kms\_key\_arn](#output\_powerbi\_s3\_kms\_key\_arn) | KMS key ARN for S3 data encryption used by Power BI gateway access policy | +| [powerbi\_user\_workgroup\_arn](#output\_powerbi\_user\_workgroup\_arn) | Athena user workgroup ARN used by the Power BI gateway access policy | +| [powerbi\_user\_workgroup\_name](#output\_powerbi\_user\_workgroup\_name) | Athena user workgroup name used by the Power BI gateway bootstrap | diff --git a/infrastructure/terraform/components/reporting/autoscaling_group_powerbi_gateway.tf b/infrastructure/terraform/components/reporting/autoscaling_group_powerbi_gateway.tf deleted file mode 100644 index 5e7c6872..00000000 --- a/infrastructure/terraform/components/reporting/autoscaling_group_powerbi_gateway.tf +++ /dev/null @@ -1,25 +0,0 @@ -resource "aws_autoscaling_group" "powerbi_gateway" { - count = var.enable_powerbi_gateway ? 1 : 0 - - name = local.csi - - launch_template { - id = aws_launch_template.powerbi_gateway[0].id - version = "$Latest" - } - - vpc_zone_identifier = module.powerbi_gateway_vpc[0].private_subnets - desired_capacity = var.desired_capacity - min_size = var.min_size - max_size = var.max_size - - tag { - key = "Name" - value = "${local.csi}-powerbi-gateway-instance" - propagate_at_launch = true - } - - health_check_type = "EC2" - health_check_grace_period = 300 - wait_for_capacity_timeout = "0" -} diff --git a/infrastructure/terraform/components/reporting/autoscaling_schedule_scale_in.tf b/infrastructure/terraform/components/reporting/autoscaling_schedule_scale_in.tf deleted file mode 100644 index 57d330a2..00000000 --- a/infrastructure/terraform/components/reporting/autoscaling_schedule_scale_in.tf +++ /dev/null @@ -1,11 +0,0 @@ -resource "aws_autoscaling_schedule" "scale_in" { - count = var.enable_powerbi_gateway && var.scale_in_recurrence_schedule != null ? 1 : 0 - - scheduled_action_name = "${local.csi}-scale-in" - desired_capacity = 0 - min_size = 0 - max_size = -1 - autoscaling_group_name = aws_autoscaling_group.powerbi_gateway[0].name - - recurrence = coalesce(var.scale_in_recurrence_schedule, null) -} diff --git a/infrastructure/terraform/components/reporting/autoscaling_schedule_scale_out.tf b/infrastructure/terraform/components/reporting/autoscaling_schedule_scale_out.tf deleted file mode 100644 index 50c71f55..00000000 --- a/infrastructure/terraform/components/reporting/autoscaling_schedule_scale_out.tf +++ /dev/null @@ -1,11 +0,0 @@ -resource "aws_autoscaling_schedule" "scale_out" { - count = var.enable_powerbi_gateway && var.scale_out_recurrence_schedule != null ? 1 : 0 - - scheduled_action_name = "${local.csi}-scale-out" - desired_capacity = var.desired_capacity - min_size = var.min_size - max_size = var.max_size - autoscaling_group_name = aws_autoscaling_group.powerbi_gateway[0].name - - recurrence = coalesce(var.scale_in_recurrence_schedule, null) -} diff --git a/infrastructure/terraform/components/reporting/iam_instance_profile_powerbi_gateway.tf b/infrastructure/terraform/components/reporting/iam_instance_profile_powerbi_gateway.tf index 53b16b72..e2a1efee 100644 --- a/infrastructure/terraform/components/reporting/iam_instance_profile_powerbi_gateway.tf +++ b/infrastructure/terraform/components/reporting/iam_instance_profile_powerbi_gateway.tf @@ -223,22 +223,4 @@ data "aws_iam_policy_document" "powerbi_gateway_permissions_policy" { aws_kms_key.s3.arn ] } - - statement { - sid = "AllowSSMAccess" - effect = "Allow" - - actions = [ - "ssm:GetParameter", - "ssm:GetParameters", - "ssm:GetParameterHistory", - ] - - resources = [ - aws_ssm_parameter.powerbi_gateway_recovery_key[0].arn, - aws_ssm_parameter.powerbi_gateway_client_id[0].arn, - aws_ssm_parameter.powerbi_gateway_client_secret[0].arn, - aws_ssm_parameter.powerbi_gateway_tenant_id[0].arn - ] - } } diff --git a/infrastructure/terraform/components/reporting/locals.tf b/infrastructure/terraform/components/reporting/locals.tf index 3d4c48ab..761faa69 100644 --- a/infrastructure/terraform/components/reporting/locals.tf +++ b/infrastructure/terraform/components/reporting/locals.tf @@ -54,26 +54,17 @@ locals { this_account = local.base_parameter_bundle.account_ids[local.base_parameter_bundle.account_name] - # Check if each required SSM parameter exists individually - recovery_key = length(aws_ssm_parameter.powerbi_gateway_recovery_key) > 0 ? aws_ssm_parameter.powerbi_gateway_recovery_key[0].name : null - client_secret = length(aws_ssm_parameter.powerbi_gateway_client_secret) > 0 ? aws_ssm_parameter.powerbi_gateway_client_secret[0].name : null - client_id = length(aws_ssm_parameter.powerbi_gateway_client_id) > 0 ? aws_ssm_parameter.powerbi_gateway_client_id[0].name : null - tenant_id = length(aws_ssm_parameter.powerbi_gateway_tenant_id) > 0 ? aws_ssm_parameter.powerbi_gateway_tenant_id[0].name : null - # Create the powerbi_gateway_script only if var.enable_powerbi_gateway is true powerbi_gateway_script = var.enable_powerbi_gateway ? templatefile("${path.module}/templates/cloudinit_config.tmpl", { odbc_dsn_name = "${local.csi}-dsn" odbc_description = "AWS Simba Athena ODBC Connection for ${local.csi}" + athena_driver_url = var.athena_driver_url region = var.region catalog = "AWSDataCatalog" database = aws_glue_catalog_database.reporting.name workgroup = aws_athena_workgroup.user.name authentication_type = "Instance Profile" gateway_name = "${local.csi}-gateway" - recovery_key = local.recovery_key - client_secret = local.client_secret - client_id = local.client_id - tenant_id = local.tenant_id }) : null use_core_glue_catalog_resources = length(var.core_account_ids) > 0 ? true : false diff --git a/infrastructure/terraform/components/reporting/outputs.tf b/infrastructure/terraform/components/reporting/outputs.tf index 9dcc2f39..7dfcbf14 100644 --- a/infrastructure/terraform/components/reporting/outputs.tf +++ b/infrastructure/terraform/components/reporting/outputs.tf @@ -1 +1,36 @@ # Define the outputs for the component. The outputs may well be referenced by other component in the same or different environments using terraform_remote_state data sources... + +output "powerbi_data_bucket_arn" { + description = "Data bucket ARN used by the Power BI gateway component" + value = aws_s3_bucket.data.arn +} + +output "powerbi_results_bucket_arn" { + description = "Results bucket ARN used by the Power BI gateway component" + value = aws_s3_bucket.results.arn +} + +output "powerbi_reporting_database_name" { + description = "Glue reporting database name for Power BI gateway access policy" + value = aws_glue_catalog_database.reporting.name +} + +output "powerbi_reporting_database_arn" { + description = "Glue reporting database ARN for Power BI gateway access policy" + value = aws_glue_catalog_database.reporting.arn +} + +output "powerbi_user_workgroup_name" { + description = "Athena user workgroup name used by the Power BI gateway bootstrap" + value = aws_athena_workgroup.user.name +} + +output "powerbi_user_workgroup_arn" { + description = "Athena user workgroup ARN used by the Power BI gateway access policy" + value = aws_athena_workgroup.user.arn +} + +output "powerbi_s3_kms_key_arn" { + description = "KMS key ARN for S3 data encryption used by Power BI gateway access policy" + value = aws_kms_key.s3.arn +} diff --git a/infrastructure/terraform/components/reporting/s3_bucket_access_logs.tf b/infrastructure/terraform/components/reporting/s3_bucket_access_logs.tf index 631f7c24..764c76f6 100644 --- a/infrastructure/terraform/components/reporting/s3_bucket_access_logs.tf +++ b/infrastructure/terraform/components/reporting/s3_bucket_access_logs.tf @@ -146,5 +146,3 @@ resource "aws_s3_bucket_lifecycle_configuration" "access_logs" { } } } - - diff --git a/infrastructure/terraform/components/reporting/scripts/sql/views/monthly_recipient_with_more_than_five_messages.sql b/infrastructure/terraform/components/reporting/scripts/sql/views/monthly_recipient_with_more_than_five_messages.sql index 5b08ffa4..0ade1c36 100644 --- a/infrastructure/terraform/components/reporting/scripts/sql/views/monthly_recipient_with_more_than_five_messages.sql +++ b/infrastructure/terraform/components/reporting/scripts/sql/views/monthly_recipient_with_more_than_five_messages.sql @@ -21,4 +21,3 @@ FROM ( ) WHERE monthlytotalmessages >= 5 GROUP BY 1, 2, 3, 4 - diff --git a/infrastructure/terraform/components/reporting/ssm_parameter_completed_batch_report_client_ids.tf b/infrastructure/terraform/components/reporting/ssm_parameter_completed_batch_report_client_ids.tf index 3e0d80cb..9ddbfdbe 100644 --- a/infrastructure/terraform/components/reporting/ssm_parameter_completed_batch_report_client_ids.tf +++ b/infrastructure/terraform/components/reporting/ssm_parameter_completed_batch_report_client_ids.tf @@ -8,4 +8,3 @@ resource "aws_ssm_parameter" "completed_batch_report_client_ids" { ignore_changes = [value] } } - diff --git a/infrastructure/terraform/components/reporting/ssm_parameter_completed_comms_report_client_ids.tf b/infrastructure/terraform/components/reporting/ssm_parameter_completed_comms_report_client_ids.tf index 633c5dd0..984e3682 100644 --- a/infrastructure/terraform/components/reporting/ssm_parameter_completed_comms_report_client_ids.tf +++ b/infrastructure/terraform/components/reporting/ssm_parameter_completed_comms_report_client_ids.tf @@ -8,4 +8,3 @@ resource "aws_ssm_parameter" "completed_comms_report_client_ids" { ignore_changes = [value] } } - diff --git a/infrastructure/terraform/components/reporting/ssm_parameter_powerbi_gateway_client_id.tf b/infrastructure/terraform/components/reporting/ssm_parameter_powerbi_gateway_client_id.tf deleted file mode 100644 index 581498a8..00000000 --- a/infrastructure/terraform/components/reporting/ssm_parameter_powerbi_gateway_client_id.tf +++ /dev/null @@ -1,14 +0,0 @@ -resource "aws_ssm_parameter" "powerbi_gateway_client_id" { - count = var.enable_powerbi_gateway ? 1 : 0 - - name = "/${local.csi}/powerbi-gateway-client-id" - description = "The Client (Application) ID for the Service Principal" - type = "SecureString" - value = "CLIENT_ID_PLACEHOLDER" - - lifecycle { - ignore_changes = [ - value, - ] - } -} diff --git a/infrastructure/terraform/components/reporting/ssm_parameter_powerbi_gateway_client_secret.tf b/infrastructure/terraform/components/reporting/ssm_parameter_powerbi_gateway_client_secret.tf deleted file mode 100644 index abff954e..00000000 --- a/infrastructure/terraform/components/reporting/ssm_parameter_powerbi_gateway_client_secret.tf +++ /dev/null @@ -1,14 +0,0 @@ -resource "aws_ssm_parameter" "powerbi_gateway_client_secret" { - count = var.enable_powerbi_gateway ? 1 : 0 - - name = "/${local.csi}/powerbi-gateway-client-secret" - description = "The Client Secret for the Service Principal" - type = "SecureString" - value = "CLIENT_SECRET_PLACEHOLDER" - - lifecycle { - ignore_changes = [ - value, - ] - } -} diff --git a/infrastructure/terraform/components/reporting/ssm_parameter_powerbi_gateway_tenant_id.tf b/infrastructure/terraform/components/reporting/ssm_parameter_powerbi_gateway_tenant_id.tf deleted file mode 100644 index eac5550c..00000000 --- a/infrastructure/terraform/components/reporting/ssm_parameter_powerbi_gateway_tenant_id.tf +++ /dev/null @@ -1,14 +0,0 @@ -resource "aws_ssm_parameter" "powerbi_gateway_tenant_id" { - count = var.enable_powerbi_gateway ? 1 : 0 - - name = "/${local.csi}/powerbi-gateway-tenant-id" - description = "The Tenant ID for the Service Principal" - type = "SecureString" - value = "TENANT_ID_PLACEHOLDER" - - lifecycle { - ignore_changes = [ - value, - ] - } -} diff --git a/infrastructure/terraform/components/reporting/templates/cloudinit_config.tmpl b/infrastructure/terraform/components/reporting/templates/cloudinit_config.tmpl index 5555c9f1..399b8d98 100644 --- a/infrastructure/terraform/components/reporting/templates/cloudinit_config.tmpl +++ b/infrastructure/terraform/components/reporting/templates/cloudinit_config.tmpl @@ -18,19 +18,12 @@ if (-not (Get-Command choco -ErrorAction SilentlyContinue)) { iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) } -# Install PowerBI On-Premises Gateway and Desktop -choco install -y powerbigateway --version=3000.298.8 --ignore-checksums -choco install -y powerbi --ignore-checksums - -# Install vim -choco install -y vim - # Install Powershell 7 choco install -y powershell-core # Install Amazon Athena ODBC 2.x Driver -`$athenaDriverUrl = "https://downloads.athena.us-east-1.amazonaws.com/drivers/ODBC/v2.0.6.0/Windows/AmazonAthenaODBC-2.0.6.0.msi" -`$athenaDriverInstaller = "C:\scripts\SimbaAthenaODBC.msi" +`$athenaDriverUrl = "${athena_driver_url}" +`$athenaDriverInstaller = "C:\scripts\AmazonAthenaODBC.msi" Invoke-WebRequest -Uri `$athenaDriverUrl -OutFile `$athenaDriverInstaller # Silent installation of Amazon Athena ODBC driver @@ -85,23 +78,6 @@ if (Test-Path `$pwshPath) { Write-Output "AWS CLI installation failed or not found in PATH." exit 1 } - - # Get the client (application) and tenant id's - `$clientId = aws ssm get-parameter --name ${client_id} --with-decryption --query Parameter.Value --output text - `$tenantId = aws ssm get-parameter --name ${tenant_id} --with-decryption --query Parameter.Value --output text - - # Get and convert the client secret and recovery key to SecureStrings - `$clientSecretPlainText = aws ssm get-parameter --name ${client_secret} --with-decryption --query Parameter.Value --output text - `$clientSecret = `$clientSecretPlainText | ConvertTo-SecureString -AsPlainText -Force - `$recoveryKeyPlainText = aws ssm get-parameter --name ${recovery_key} --with-decryption --query Parameter.Value --output text - `$recoveryKey = `$recoveryKeyPlainText | ConvertTo-SecureString -AsPlainText -Force - - # Login to the PowerBI Service using the Service Principal (proposed, untested) https://learn.microsoft.com/en-us/powershell/module/datagateway.profile/connect-datagatewayserviceaccount?view=datagateway-ps - # Connect-DataGatewayServiceAccount -ApplicationId `$clientId -ClientSecret `$clientSecret -Tenant `$tenantId - # Install the gateway - # Install-DataGateway -AcceptConditions - # Register the Gateway (proposed, untested) https://learn.microsoft.com/en-us/powershell/module/datagateway/add-datagatewaycluster?view=datagateway-ps - # Add-DataGatewayCluster -RecoveryKey `$recoveryKey -Name ${gateway_name} -RegionKey uksouth } } else { diff --git a/infrastructure/terraform/components/reporting/variables.tf b/infrastructure/terraform/components/reporting/variables.tf index 3a1c983a..2d8130c3 100644 --- a/infrastructure/terraform/components/reporting/variables.tf +++ b/infrastructure/terraform/components/reporting/variables.tf @@ -99,10 +99,16 @@ variable "log_retention_days" { variable "enable_powerbi_gateway" { type = bool - description = "Deploy EC2 instance for PowerBI On-Premises Gateway" + description = "Deploy supporting resources for the legacy PowerBI On-Premises Gateway" default = true } +variable "athena_driver_url" { + type = string + description = "Amazon Athena ODBC MSI download URL for PowerBI gateway bootstrap" + default = "https://downloads.athena.us-east-1.amazonaws.com/drivers/ODBC/v2.1.0.0/Windows/AmazonAthenaODBC-2.1.0.0.msi" +} + variable "powerbi_gateway_instance_count" { description = "Number of standalone Power BI On-Premises Gateway instances created directly from the launch template." type = number @@ -127,24 +133,6 @@ variable "instance_type" { default = "t3.medium" } -variable "desired_capacity" { - description = "The desired number of instances in the Power BI On-Premises Gateway Auto Scaling group." - type = number - default = 1 -} - -variable "min_size" { - description = "The minimum number of instances in the Power BI On-Premises Gateway Auto Scaling group." - type = number - default = 1 -} - -variable "max_size" { - description = "The maximum number of instances in the Power BI On-Premises Gateway Auto Scaling group." - type = number - default = 1 -} - variable "enable_spot" { type = bool description = "run Power BI On-Premises Gateway as spot instances" @@ -163,18 +151,6 @@ variable "root_volume_size" { default = 80 } -variable "scale_out_recurrence_schedule" { - description = "The cron expression for the scale out schedule. Set to null if no recurrence is needed." - type = string - default = null -} - -variable "scale_in_recurrence_schedule" { - description = "The cron expression for the scale in schedule. Set to null if no recurrence is needed." - type = string - default = null -} - variable "core_account_ids" { description = "List of all corresponding core account id's that exist in the Non-Prod domain" type = list(string) diff --git a/infrastructure/terraform/deploy.sh b/infrastructure/terraform/deploy.sh index dcf64c44..66354c92 100755 --- a/infrastructure/terraform/deploy.sh +++ b/infrastructure/terraform/deploy.sh @@ -31,11 +31,17 @@ cd "${basedir}" || exit 1; terraform_environment="${DEPLOY_ENVIRONMENT}"; # determine the order of components to process +if [[ -n "${TERRAFORM_COMPONENTS:-}" ]]; then + component_list="${TERRAFORM_COMPONENTS}"; +elif [[ "${TERRAFORM_ACTION}" == "destroy" ]]; then + component_list="powerbi-gateway reporting"; +else + component_list="reporting powerbi-gateway"; +fi; + if [[ "${TERRAFORM_ACTION}" == "destroy" ]]; then - component_list="reporting"; plan_action="plan-destroy"; else - component_list="reporting"; plan_action="plan"; fi; diff --git a/infrastructure/terraform/etc/env_eu-west-2_main.tfvars b/infrastructure/terraform/etc/env_eu-west-2_main.tfvars index d3662737..150c6057 100644 --- a/infrastructure/terraform/etc/env_eu-west-2_main.tfvars +++ b/infrastructure/terraform/etc/env_eu-west-2_main.tfvars @@ -15,6 +15,8 @@ core_account_ids = [ # PowerBI On-Premises Gateway variables: enable_powerbi_gateway = true +instance_type = "t3.xlarge" +root_volume_size = 200 public_subnet_cidrs = [ "10.0.1.0/24", diff --git a/scripts/config/gitleaks.toml b/scripts/config/gitleaks.toml index 3f748294..106544af 100644 --- a/scripts/config/gitleaks.toml +++ b/scripts/config/gitleaks.toml @@ -22,7 +22,9 @@ paths = [ '''poetry.lock''', '''yarn.lock''', '''Gemfile.lock''', - '''infrastructure/terraform/components/reporting/templates/cloudinit_config.tmpl''' + '''infrastructure/terraform/components/reporting/templates/cloudinit_config.tmpl''', + '''infrastructure/terraform/components/powerbi-gateway/variables.tf''', + '''infrastructure/terraform/components/powerbi-gateway/README.md''' ] # Exclude Chrome version in user agent