Snowflake-Labs / terraform-provider-snowflake

Terraform provider for managing Snowflake accounts
https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest
MIT License
554 stars 422 forks source link

Unintended modification in allowed_accounts for snowflake_failover_group #2332

Open joaocepaa opened 10 months ago

joaocepaa commented 10 months ago

Terraform CLI and Provider Versions

Terraform version: 1.4.2 Snowflake provider version: 0.73.0 (Snowflake-Labs/snowflake)

Terraform Configuration

terraform {
  required_version = "1.4.2"
  required_providers {
    snowflake = {
      source  = "Snowflake-Labs/snowflake"
      version = "0.73.0"
    }
  }
}

provider "snowflake" {
  alias            = "source_account"
  username         = var.snowflake_user
  private_key_path = var.source_account_private_key_path
  account          = var.snowflake_source_account_locator
  region           = var.snowflake_source_account_region
  role             = "my_role"
}

provider "snowflake" {
  alias            = "target_account"
  username         = var.snowflake_user
  private_key_path = var.target_account_private_key_path
  account          = var.snowflake_target_account_locator
  region           = var.snowflake_target_account_region
  role             = "my_role"
}

locals {
  primary_failover_group_identifier   = upper("${var.snowflake_source_account_name}_FG")
  secondary_failover_group_identifier = upper("FROM_${var.snowflake_target_account_name}_FG")
  allowed_accounts                    = [upper("${var.snowflake_organization_name}.${var.snowflake_target_account_name}")]
}

resource "snowflake_failover_group" "source_failover_group" {
  provider          = snowflake.source_account
  name              = var.primary_failover_group_identifier != null ? var.primary_failover_group_identifier : local.primary_failover_group_identifier
  object_types      = ["DATABASES"]
  allowed_accounts  = local.allowed_accounts
  allowed_databases = [for db in data.snowflake_database.allowed_databases : db.name]

  dynamic "replication_schedule" {
    for_each = var.replication_schedule != null && var.replication_schedule.type == "interval" ? [1] : []
    content {
      interval = var.replication_schedule.interval
    }
  }

  dynamic "replication_schedule" {
    for_each = var.replication_schedule != null && var.replication_schedule.type == "cron" ? [1] : []
    content {
      cron {
        expression = var.replication_schedule.cron.expression
        time_zone  = var.replication_schedule.cron.time_zone
      }
    }
  }
}

resource "snowflake_failover_group" "target_failover_group" {
  provider = snowflake.target_account
  name     = var.secondary_failover_group_identifier != null ? var.secondary_failover_group_identifier : local.secondary_failover_group_identifier
  from_replica {
    organization_name   = var.snowflake_organization_name
    source_account_name = var.snowflake_source_account_name
    name                = snowflake_failover_group.source_failover_group.name
  }
}

Expected Behavior

The provider should natively handle the fact that Snowflake adds the account where the source failover group is located to allowed_accounts, so that on a run after the first one it doesn't detect changes.

Actual Behavior

After the first creation of the source_failover_group resource, Snowflake internally adds the source account to the allowed_accounts list without indication. This leads to Terraform detecting a change in the allowed_accounts during subsequent terraform apply executions, even when no changes are made to the configuration.

Change that it detects by running a second time without me changing anything:

Screenshot 2024-01-09 at 21 57 22

Steps to Reproduce

  1. Run terraform apply to create the initial setup.
  2. Run terraform apply again without making any changes to the configuration.

How much impact is this issue causing?

High

Logs

No response

Additional Information

This behaviour seems to be an unintended side effect of the Snowflake provider's interaction with the Snowflake platform, particularly in a cross-region, multi-account setup. There has been no recent change in the environment or workflow that might be relevant to this issue. No workaround has been found at this moment.

sfc-gh-asawicki commented 10 months ago

Hey @joaocepaa. Thanks for reporting the issue.

I am not convinced that this should be natively handled. I will consult with the team and get back to you.

Does declaring the source account as one of the allowed_accounts (either in the first or subsequent run) work as a workaround for now?

joaocepaa commented 10 months ago

@sfc-gh-asawicki thank you very much for your reply.

I personally think that the provider should handle this natively because then changes to the source primary failover group can have an impact, and the final tf state should be 100% aligned with the resource created and seen in Snowsight. Also, the official snowflake documentation is clear that allowed_accounts should only contain information about target accounts (the target account or list of target accounts) but again just my opinion.

Yes, adding the source account to the allowed_accounts list as a workaround works.

sfc-gh-asawicki commented 10 months ago

@joaocepaa I'm glad the workaround works; please use it for the time being.

We will take your opinion into consideration during our talks. After all, we want to follow our users' suggestions if they are consistent with our bigger assumptions.