Skip to content

Commit 4086e1c

Browse files
Merge pull request #486 from cagov/tf-5-auth-policies
Merging the code for password and 5 authentication policies into main
2 parents 4cb9f93 + 4644575 commit 4086e1c

File tree

3 files changed

+106
-0
lines changed

3 files changed

+106
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,4 @@ cython_debug/
161161
# and can be added to the global gitignore or merged into this file. For a more nuclear
162162
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
163163
#.idea/
164+
.DS_Store

terraform/snowflake/environments/prd/main.tf

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ variable "organization_name" {
1717
type = string
1818
}
1919

20+
variable "okta_integration_name" {
21+
description = "The name of the Okta security integration. If null, the odi_okta_only authentication policy will not be created."
22+
type = string
23+
default = null
24+
}
25+
2026
############################
2127
# Providers #
2228
############################
@@ -50,6 +56,7 @@ provider "snowflake" {
5056
role = "ACCOUNTADMIN"
5157
account_name = var.account_name
5258
organization_name = var.organization_name
59+
preview_features_enabled = ["snowflake_authentication_policy_resource", "snowflake_password_policy_resource"]
5360
}
5461

5562
# Snowflake provider for creating databases, warehouses, etc.
@@ -66,6 +73,7 @@ provider "snowflake" {
6673
role = "SECURITYADMIN"
6774
account_name = var.account_name
6875
organization_name = var.organization_name
76+
preview_features_enabled = ["snowflake_authentication_policy_resource", "snowflake_password_policy_resource"]
6977
}
7078

7179
# Snowflake provider for managing user accounts and roles.
@@ -104,3 +112,99 @@ resource "snowflake_grant_account_role" "logger_to_transformer" {
104112
role_name = "LOGGER_${var.environment}"
105113
parent_role_name = "TRANSFORMER_${var.environment}"
106114
}
115+
// Create the POLICIES database to store the password policy
116+
resource "snowflake_database" "policies" {
117+
name = "POLICIES"
118+
}
119+
120+
# Default user password policy
121+
resource "snowflake_password_policy" "user_password_policy" {
122+
provider = snowflake.accountadmin
123+
database = snowflake_database.policies.name # Database name
124+
schema = "PUBLIC" # Schema name
125+
name = "user_password_policy"
126+
min_length = 14
127+
min_upper_case_chars = 1
128+
min_lower_case_chars = 1
129+
min_numeric_chars = 1
130+
min_special_chars = 1
131+
max_retries = 5
132+
lockout_time_mins = 30
133+
history = 5
134+
or_replace = true # Ensures the policy can be updated without errors
135+
}
136+
137+
# Set the default password policy for the account
138+
resource "snowflake_account_password_policy_attachment" "attachment" {
139+
provider = snowflake.accountadmin
140+
password_policy = snowflake_password_policy.user_password_policy.fully_qualified_name
141+
}
142+
143+
// Defines an authentication policy for ODI human users that enforces Okta-only authentication via SAML.
144+
resource "snowflake_authentication_policy" "odi_okta_only" {
145+
count = var.okta_integration_name == null ? 0 : 1 // meta-argument to conditionally create the resource
146+
provider = snowflake.accountadmin
147+
database = snowflake_database.policies.name # Database name
148+
schema = "PUBLIC" # Schema name
149+
name = "odi_okta_only"
150+
authentication_methods = ["SAML"]
151+
security_integrations = [var.okta_integration_name] # Okta security integration name
152+
comment = "Okta-only authentication policy for ODI human users"
153+
}
154+
155+
// Defines an authentication policy for external human users that enforces password-based authentication with Duo MFA.
156+
resource "snowflake_authentication_policy" "external_duo_mfa" {
157+
provider = snowflake.accountadmin
158+
database = snowflake_database.policies.name # Database name
159+
schema = "PUBLIC" # Schema name
160+
name = "external_duo_mfa"
161+
authentication_methods = ["PASSWORD"]
162+
mfa_authentication_methods = ["PASSWORD"]
163+
mfa_enrollment = "REQUIRED"
164+
client_types = ["SNOWFLAKE_UI", "DRIVERS", "SNOWSQL"] # MFA enrollment requires SNOWFLAKE_UI
165+
comment = "Duo-MFA-only authentication policy for external human users"
166+
}
167+
168+
// Defines an authentication policy for admin human users that allows both Okta SAML and password-based authentication with Duo MFA.
169+
resource "snowflake_authentication_policy" "admin_okta_duo" {
170+
count = var.okta_integration_name == null ? 0 : 1 // meta-argument to conditionally create the resource
171+
provider = snowflake.accountadmin
172+
database = snowflake_database.policies.name # Database name
173+
schema = "PUBLIC" # Schema name
174+
name = "admin_okta_duo"
175+
authentication_methods = ["SAML", "PASSWORD"]
176+
mfa_authentication_methods = ["PASSWORD"]
177+
mfa_enrollment = "REQUIRED"
178+
client_types = ["SNOWFLAKE_UI", "DRIVERS", "SNOWSQL"]
179+
security_integrations = [var.okta_integration_name] # Okta security integration name
180+
comment = "Okta and Duo-MFA authentication policy for admin human users"
181+
}
182+
183+
// Defines an authentication policy for most service accounts that enforces key-pair authentication.
184+
resource "snowflake_authentication_policy" "service_account_keypair" {
185+
provider = snowflake.accountadmin
186+
database = snowflake_database.policies.name # Database name
187+
schema = "PUBLIC" # Schema name
188+
name = "service_account_keypair"
189+
authentication_methods = ["KEYPAIR"]
190+
client_types = ["DRIVERS", "SNOWSQL"]
191+
comment = "Key-pair only authentication policy for most service accounts"
192+
}
193+
194+
// Defines an authentication policy for legacy service accounts that enforces password-based authentication.
195+
resource "snowflake_authentication_policy" "legacy_service_password" {
196+
provider = snowflake.accountadmin
197+
database = snowflake_database.policies.name # Database name
198+
schema = "PUBLIC" # Schema name
199+
name = "legacy_service_password"
200+
authentication_methods = ["PASSWORD"]
201+
client_types = ["DRIVERS", "SNOWSQL"]
202+
comment = "Password-only authentication policy for legacy service accounts"
203+
}
204+
205+
# Set odi_okta_only as the default authentication policy for the account
206+
resource "snowflake_account_authentication_policy_attachment" "default_policy" {
207+
count = var.okta_integration_name == null ? 0 : 1
208+
provider = snowflake.accountadmin
209+
authentication_policy = snowflake_authentication_policy.odi_okta_only[0].fully_qualified_name // using the first and only instance that gets created
210+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
account_name = "HJB86910"
22
environment = "PRD"
33
organization_name= "VSB79059"
4+
okta_integration_name= "OKTAINTEGRATION"

0 commit comments

Comments
 (0)