Skip to content

Commit d2f1fee

Browse files
authored
BI Fixes (#128)
* Fix: schema name in fivetran does not allow some characters * fix: must define ROLE ARN for Snowflake Source * Adds SQL Script to generate read-only user for RDS * Bug: Snowflake Network Policy doesn't work, remove for now * Adjust readmes and variable names * must pass role arn in analytics module to fivetran
1 parent b0d7a1a commit d2f1fee

File tree

10 files changed

+89
-29
lines changed

10 files changed

+89
-29
lines changed

analytics/fivetran.tf

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ module "fivetran" {
1515
destination_user_name = var.destination_user_name
1616
destination_password = var.destination_password
1717
destination_connection_type = var.destination_connection_type
18+
destination_role_arn = var.destination_role_arn
1819

1920
environment = local.environment
2021
project = local.project

analytics/variables.tf

+7-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,13 @@ variable "time_zone_offset" {
3030
}
3131

3232
variable "destination_user_name" {
33-
type = string
33+
type = string
34+
default = "FIVETRAN_USER"
35+
}
36+
37+
variable "destination_role_arn" {
38+
type = string
39+
default = "FIVETRAN_ROLE"
3440
}
3541

3642
variable "destination_host" {

fivetran/README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ module "fivetran" {
2222
project = "my-project"
2323
environment = "production"
2424
25-
destination_user_name = "${project}-${environment}-bot"
25+
destination_user_name = "FIVETRAN_USER"
26+
destination_role_arn = "FIVETRAN_ROLE"
2627
destination_host = "${SNOWFLAKE_ACCOUNT_LOCATOR}.eu-central-1.snowflakecomputing.com" # `eu-central-1` if you run on AWS in EU region
2728
destination_connection_type = "Directly"
2829
destination_password = "XXX"

fivetran/connectors.tf

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ resource "fivetran_connector" "github" {
4242
run_setup_tests = true
4343

4444
destination_schema {
45-
name = "github_${each.value.organisation}" # name shown on Fivetran UI
45+
name = "github_${replace(each.value.organisation, "/[^0-9A-Za-z_]/", "_")}" # name shown on Fivetran UI
4646
}
4747

4848
config {

fivetran/main.tf

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ resource "fivetran_destination" "main" {
1818
port = var.destination_port
1919
database = var.destination_database_name
2020
user = var.destination_user_name
21+
role_arn = var.destination_role_arn
2122
password = var.destination_password
2223
auth = "PASSWORD"
2324
connection_type = var.destination_connection_type

fivetran/rds-readonly-role.sql

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-- creates a read-only role for fivetran to connect to RDS
2+
3+
CREATE ROLE {project}_{environment}_fivetran;
4+
ALTER ROLE {project}_{environment}_fivetran WITH LOGIN ENCRYPTED PASSWORD 'generate-a-secure-password';
5+
6+
GRANT CONNECT ON DATABASE {project}_{environment} TO {project}_{environment}_fivetran;
7+
GRANT USAGE ON SCHEMA public TO {project}_{environment}_fivetran;
8+
9+
GRANT SELECT ON ALL TABLES IN SCHEMA public TO {project}_{environment}_fivetran;
10+
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO {project}_{environment}_fivetran;

fivetran/variables.tf

+4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ variable "destination_user_name" {
2929
type = string
3030
}
3131

32+
variable "destination_role_arn" {
33+
type = string
34+
}
35+
3236
variable "destination_host" {
3337
description = "e.g. 'your-account.snowflakecomputing.com'"
3438
type = string

snowflake/cloud/README.md

+13-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ Note: Since this module consist of the snowflake network policy, the Snowflake u
77
```terraform
88
# main.tf
99
module "snowflake_cloud" {
10-
source = "github.com/dbl-works/terraform//awesome-module?ref=v2022.08.05"
10+
source = "github.com/dbl-works/terraform//snowflake/cloud?ref=v2022.08.05"
11+
12+
providers = {
13+
snowflake = snowflake
14+
snowflake.security_admin = snowflake.security_admin
15+
}
1116
1217
warehouse_name = "WH_FIVETRAN" # Snowflake mostly uses upcase by their convention
1318
@@ -27,9 +32,11 @@ module "snowflake_cloud" {
2732
]
2833
2934
# optional
30-
suspend_compute_after_seconds = 57 # on AWS, the minimum charge is 60 seconds
31-
warehouse_size = "large" # 8 credits/hour/cluster for "large"
32-
warehouse_cluster_count = 1
35+
suspend_compute_after_seconds = 57 # on AWS, the minimum charge is 60 seconds
36+
warehouse_size = "large" # 8 credits/hour/cluster for "large"
37+
warehouse_cluster_count = 1
38+
multi_cluster_warehouses_enabled = false # must be enabled in the Snowflake account (via UI)
39+
3340
# Default value of this variable is the fivetrans IP address in the EU region + using GCP as cloud provider
3441
# If you are using fivetrans, check the list of IP addresses here: https://fivetran.com/docs/getting-started/ips#euregions
3542
allowed_ip_list = ["35.235.32.144/29"]
@@ -75,7 +82,7 @@ provider "snowflake" {
7582
region = var.snowflake_region
7683
7784
# For auth exactly one option must be set.
78-
private_key_passphrase = var.snowflake_private_key_path
85+
private_key_path = var.snowflake_private_key_path
7986
}
8087
8188
provider "snowflake" {
@@ -87,7 +94,7 @@ provider "snowflake" {
8794
region = var.snowflake_region
8895
8996
# For auth exactly one option must be set.
90-
private_key_passphrase = var.snowflake_private_key_path
97+
private_key_path = var.snowflake_private_key_path
9198
}
9299
```
93100

snowflake/cloud/main.tf

+43-20
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,56 @@ resource "snowflake_warehouse" "main" {
1414
auto_suspend = var.suspend_compute_after_seconds
1515
auto_resume = true
1616

17-
max_cluster_count = var.warehouse_cluster_count
18-
min_cluster_count = 1 # if set to less than max count, auto-scaling is enabled
19-
scaling_policy = "ECONOMY" # Conserves credits by favoring keeping running clusters fully-loaded
17+
max_cluster_count = var.multi_cluster_warehouses_enabled ? var.warehouse_cluster_count : null
18+
min_cluster_count = var.multi_cluster_warehouses_enabled ? 1 : null # if set to less than max count, auto-scaling is enabled
19+
scaling_policy = var.multi_cluster_warehouses_enabled ? "ECONOMY" : null # Conserves credits by favoring keeping running clusters fully-loaded
2020
}
2121

2222
locals {
2323
network_policy_name = "IpNetworkPolicy"
2424
}
2525

26+
27+
#
28+
# when using "SECURITYADMIN" + "SYSADMIN" roles, which should be suffcient, see https://docs.snowflake.com/en/sql-reference/sql/create-network-policy.html
29+
#
30+
# │ Error: error creating network policy IpNetworkPolicy: 003001 (42501): SQL access control error:
31+
# │ Insufficient privileges to operate on account 'IL49394'
32+
#
33+
# │ with module.snowflake_cloud.snowflake_network_policy.policy,
34+
# │ on .terraform/modules/snowflake_cloud/main.tf line 27, in resource "snowflake_network_policy" "policy":
35+
# │ 27: resource "snowflake_network_policy" "policy" {
36+
#
37+
#
38+
#
39+
# │ Error: error creating attachment for network policy IpNetworkPolicy: error setting network policy IpNetworkPolicy on account: 003001 (42501): SQL access control error:
40+
# │ Insufficient privileges to operate on account 'IL49394'
41+
#
42+
# │ with module.snowflake_cloud.snowflake_network_policy_attachment.attach,
43+
# │ on .terraform/modules/snowflake_cloud/main.tf line 39, in resource "snowflake_network_policy_attachment" "attach":
44+
# │ 39: resource "snowflake_network_policy_attachment" "attach" {
45+
46+
47+
2648
# https://docs.snowflake.com/en/user-guide/network-policies.html
27-
resource "snowflake_network_policy" "policy" {
28-
# The identifier must start with an alphabetic character
29-
# and cannot contain spaces or special characters unless the
30-
# entire identifier string is enclosed in double quotes (e.g. "My object").
49+
# resource "snowflake_network_policy" "policy" {
50+
# # The identifier must start with an alphabetic character
51+
# # and cannot contain spaces or special characters unless the
52+
# # entire identifier string is enclosed in double quotes (e.g. "My object").
3153

32-
name = local.network_policy_name
33-
comment = "Network policy to allow or deny access to a single IP address or a list of addresses."
54+
# name = local.network_policy_name
55+
# comment = "Network policy to allow or deny access to a single IP address or a list of addresses."
3456

35-
allowed_ip_list = var.allowed_ip_list
36-
blocked_ip_list = var.blocked_ip_list
37-
}
57+
# allowed_ip_list = var.allowed_ip_list
58+
# blocked_ip_list = var.blocked_ip_list
59+
# }
3860

39-
resource "snowflake_network_policy_attachment" "attach" {
40-
network_policy_name = local.network_policy_name
41-
# A Snowflake account can only have one network policy set globally at any given time.
42-
# This resource does not enforce one-policy-per-account, it is the user's responsibility to enforce this. If multiple network policy resources have set_for_account: true,
43-
# the final policy set on the account will be non-deterministic.
44-
set_for_account = true
45-
users = var.snowflake_users
46-
}
61+
# resource "snowflake_network_policy_attachment" "attach" {
62+
# network_policy_name = local.network_policy_name
63+
# # A Snowflake account can only have one network policy set globally at any given time.
64+
# # This resource does not enforce one-policy-per-account, it is the user's responsibility to enforce this.
65+
# # If multiple network policy resources have set_for_account: true,
66+
# # the final policy set on the account will be non-deterministic.
67+
# set_for_account = true
68+
# users = var.snowflake_users
69+
# }

snowflake/cloud/variables.tf

+7
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ variable "warehouse_cluster_count" {
2222
default = 1
2323
}
2424

25+
# has to be enabled in the Snowflake account. Disabled by default.
26+
variable "multi_cluster_warehouses_enabled" {
27+
description = "https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/warehouse#max_cluster_count"
28+
type = bool
29+
default = false
30+
}
31+
2532
#
2633
# A retention period of 0 days for an object effectively disables Time Travel for the object.
2734
#

0 commit comments

Comments
 (0)