Skip to content

Latest commit

 

History

History
107 lines (76 loc) · 4.92 KB

README.md

File metadata and controls

107 lines (76 loc) · 4.92 KB

Terraform

snowalert-tf

158665186-36fa7acf-fecc-452c-ae4f-482eddf79b72

SnowAlert is an alerting and violations platform that allows you to write SQL queries to run on a schedule and handlers that dispatch them to Slack, Jira, or other RPC endpoints. It is collection of Snowflake objects that enable you to write what we call rules as Snowflake views that query tables for security-relevant events, suppress the ones that are expected, and dispatch the rest for human review. We manage these objects in a Terraform module.

Details of the implementation are at docs.snowalert.com.

This is a partial re-implementation of the original SnowAlert project using Snowflake-native resources like Tasks, User Defined Functions, Procedures, and External Functions.

It communicates with remote RPC's using Snowflake External Functions with a GEFF API backend.

snowalert.auto.tfvars Inputs File

A couple of instructions to provide the right set of input variables:

  1. Conditional resources: warehouse, database, user, role, schemas are conditional resources and hence existing resources can be re-used and provided as input variables. This can be done by setting the snowalert_*_name variables to the existing resource names and setting create_* variables to false(which is the default).
  2. Handlers: The handlers list is an optional list for those handlers you want created. For each handler provider the corresponding *_secrets_arn must be passed and should be created with the specific format required by GEFF with hostname pinned into the secret for added security. Other variables may be conditionally required depending on the handler.

For example, if handlers = ["jira"], you'll additionally have to pass:

  • jira_secrets_arn
  • jira_url
  • default_jira_project
  • default_jira_issue_type

which are the variables that come into play due to using the JIRA handler. The same follows for serviceNow, slack or SMTP.

A sample tfvars file is provided in the examples. You can copy it and rename it to anything with an extension of .auto.tfvars e.g. snowalert.auto.tfvars

Install

git clone [email protected]:Snowflake-Labs/terraform-snowflake-api-integration-with-geff.git
cd examples/complete

# copy the tfvars file and rename to remove the '.sample' suffix

terraform init

# Import any external resources you want controlled in this module.
# NOTE: The import HAS to be done before plan and apply otherwise the downstream resources will error out at creation.
terraform import snowflake_database.snowalert[0] 'SNOWALERT'
terraform import snowflake_warehouse.snowalert[0] 'SNOWALERT_WAREHOUSE'
# ...

terraform plan -out=snowalert.plan # Use the .auto.tfvars file in the same dir
terraform apply snowalert.plan

Importing Existing Snowflake Resources

This module is designed to work with the following existing resources:

  1. Warehouse
  2. Database
  3. User
  4. Role
  5. Schemas

There are two ways to use existing resources:

  1. Provide them as inputs: In this case, they're managed elsewhere and the names of the resources are input as strings through the tfvars file.
  2. Import them into the module: In this case, they were managed elsewhere and with the import you can manage them within this module. The first step is to import these conditional resources and then run the terraform plan and apply.

zsh function to set environment variables

zsh function to set appropriate env variables based on which snowflake you want to target with terraform:

sfc_env()
{
    case $1 in
        "sfc_dev")
            export SNOWFLAKE_USER=$1_tf_user
            export SNOWFLAKE_PRIVATE_KEY_PATH=
            export SNOWFLAKE_PRIVATE_KEY=`cat ~/.ssh/$1_tf_key.p8`
            export SNOWFLAKE_PRIVATE_KEY_PASSPHRASE='<my private key passphrase>'
            ;;
        "sfc_prod")
            export SNOWFLAKE_USER=$1_tf_user
            export SNOWFLAKE_PRIVATE_KEY_PATH="~/.ssh/$1_tf_key.p8"
            export SNOWFLAKE_PRIVATE_KEY=
            export SNOWFLAKE_PRIVATE_KEY_PASSPHRASE='<my private key passphrase>'
            ;;
        *)
            export SNOWFLAKE_USER=<username>
            export SNOWFLAKE_PRIVATE_KEY_PATH="~/.ssh/$1_tf_key.p8"
            export SNOWFLAKE_PRIVATE_KEY=
            export SNOWFLAKE_PRIVATE_KEY_PASSPHRASE='<my private key passphrase>'
            ;;
    esac
}

You can then set the appropriate env vars using:

sfc_env sfc_dev
# or
sfc_env sfc_prod

For this function to work, you'll have to place ~/.ssh/sfc_dev_tf_key.p8 and ~/.ssh/sfc_prod_tf_key.p8 keys in your ~/.ssh/ folder.