fivetran / terraform-provider-fivetran

Terraform Provider for Fivetran
https://fivetran.com
Apache License 2.0
41 stars 22 forks source link

Provider produced inconsistent result after apply #312

Closed sergeyrudenko111 closed 5 days ago

sergeyrudenko111 commented 1 month ago

Describe the bug We have changed secrets for host, DB, user etc... and not able to successfully complete modification of connector.

To Reproduce

resource "fivetran_connector" "wallets" {
  group_id = data.fivetran_group.group.id
  service  = "postgres_rds"

  destination_schema {
    prefix = "wallets_${local.project_name}"
  }

  config {
    host             = data.vault_kv_secret_v2.wallets.data.hostname
    port             = data.vault_kv_secret_v2.wallets.data.port
    database         = data.vault_kv_secret_v2.wallets.data.database
    user             = data.vault_kv_secret_v2.wallets.data.username
    password         = data.vault_kv_secret_v2.wallets.data.password
    update_method    = "WAL_PGOUTPUT"
    replication_slot = data.vault_kv_secret_v2.wallets.data.replication_slot_name
    publication_name = data.vault_kv_secret_v2.wallets.data.publication_name
    tunnel_host      = var.tunnel_host
    tunnel_port      = var.tunnel_port
    tunnel_user      = var.tunnel_user
  }
}

Expected behavior No error, successful modification

Logs & Output When applying changes to fivetran_connector.wallets, provider "provider[\"registry.terraform.io/fivetran/fivetran\"]" produced an unexpected new value: .config.update_method: was cty.StringVal("WAL_PGOUTPUT"), but now null.

This is a bug in the provider, which should be reported in the provider's own issue tracker.

Plugin version: 1.1.23

Additional context

beevital commented 1 month ago

@sergeyrudenko111 I have tried to reproduce this behavior, but without success. I can suggest you to pause connection, comment out line update_method = "WAL_PGOUTPUT" - apply changes, and then uncomment, and apply one more time. It seems like connector has some intenral logic that "defaults" value for update_method field. So you have to re-apply it after host change.

NOTE: I'm just guessing, and I'll investigate what's happening.

could you please share conenction_id so I'll be able to check logs?

sergeyrudenko111 commented 1 month ago

@beevital i tried your suggestion but unfortunately this doesn't help, i received the same error with paused connector

When applying changes to fivetran_connector.wallets, provider "provider[\"registry.terraform.io/fivetran/fivetran\"]" produced an unexpected new value: .config.update_method: was cty.StringVal("WAL_PGOUTPUT"), but now null.
This is a bug in the provider, which should be reported in the provider's own issue tracker.

connector_id: interminable_officiating

beevital commented 1 month ago

Thank you, will take a look at logs.

beevital commented 1 month ago

@sergeyrudenko111 unfortunately I can't reproduce the issue on my side. I've checked logs for your connector and didn't find any issues with payloads etc.

Could you please make GET https://api.fivetran.com/v1/connectors/interminable_officiating request with your API key you're using with Terraform via curl or postman and share response - I'm interested in the fact if API doesn't returns update_method value under config in response?

sergeyrudenko111 commented 1 month ago

@beevital API returned update method - "incremental_update_method": "WAL_PGOUTPUT",

"config": {
  "public_key": "key",
  "database": "db",
  "password": "",
  "tunnel_port": "port",
  "publication_name": "name",
  "port": "port",
  "host": "host",
  "tunnel_host": "host",
  "incremental_update_method": "WAL_PGOUTPUT",
  "replication_slot": "slot",
  "user": "user",
  "tunnel_user": "user"
}
beevital commented 1 month ago

aha, now things more clear.

beevital commented 1 month ago

You connector signed up at:

image

So it uses legacy config format, and API returns incremental_update_method in response by default. I know what to do with that, but there are two possible options:

Anyway - now I know what to do! It was super helpful =)

sergeyrudenko111 commented 1 month ago

@beevital Hi, thanks for the update on this issue. May i ask you to help me with providing instructions of how to make an additional value update_method on fivetran API?

i tried something like

curl --request PATCH --url https://api.fivetran.com/v1/connectors/$connector_id --header "Accept: application/json;version=2" --header "content-type: application/json" --header "Authorization: Basic $auth_data" --data '{"config": {"update_method": "WAL_PGOUTPUT"}}' | jq

as an output i received that connector update was successful, also i'm seeing next config output where update_method value is present, but this doesn't work and nothing changed on fivetran side and i still only able to see incremental_update_method value from API.

"config": {
      "host": "host",
      "port":port,
      "database": "db",
      "user": "user",
      "password": "",
      "tunnel_host": "host",
      "tunnel_port": port,
      "tunnel_user": "user",
      "public_key": "key",
      "always_encrypted": true,
      "connection_type": "type",
      "update_method": "WAL_PGOUTPUT",
      "replication_slot": "slot",
      "publication_name": "name"
    }

Thanks in advance.

beevital commented 3 weeks ago

Hey @sergeyrudenko111 , what did you mean by how to make an additional value update_method on fivetran API? You've already done exactly what should be done - passed application/json;version=2 accept header. And you've received correct response.

sergeyrudenko111 commented 3 weeks ago

@beevital yep, all is looking fine from what i sent you in previous comment, except terraform apply, it has the same error as it was before, that's why i asked about some additional help. Thanks in advance.

When applying changes to fivetran_connector.wallets, provider
"provider["registry.terraform.io/fivetran/fivetran"]" produced an
unexpected new value: .config.update_method: was
cty.StringVal("WAL_PGOUTPUT"), but now null.
MaxymVlasov commented 2 weeks ago

A similar happens for me too

Provider version: 1.1.26

module.fivetran_connector[0].fivetran_connector.connector: Modifying... [id=unzip_mutation]
╷
│ Error: Provider produced inconsistent result after apply
│ 
│ When applying changes to
│ module.fivetran_connector[0].fivetran_connector.connector, provider
│ "provider[\"registry.terraform.io/fivetran/fivetran\"]" produced an
│ unexpected new value: .networking_method: was cty.StringVal("Directly"),
│ but now cty.StringVal("SshTunnel").
│ 
│ This is a bug in the provider, which should be reported in the provider's
│ own issue tracker.

It happens for the next (or similar) plan for 10 different stacks:

It destroys entities and then fails to recreate them, because it stuck in mutation

image

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  ~ update in-place
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # module.fivetran_connector[0].fivetran_connector.connector will be updated in-place
  ~ resource "fivetran_connector" "connector" {
      ~ connected_by       = "grader_regard" -> (known after apply)
      ~ created_at         = "2023-10-13 15:33:07.830635 +0000 UTC" -> (known after apply)
      ~ id                 = "unzip_mutation" -> (known after apply)
      ~ name               = "campaign_delivery_service" -> (known after apply)
      ~ networking_method  = "SshTunnel" -> "Directly"
        # (5 unchanged attributes hidden)

      ~ config {
          + abs_connection_string                               = (sensitive value)
          + abs_container_name                                  = (known after apply)
          + access_key                                          = (sensitive value)
          + access_key_id                                       = (sensitive value)
          + access_token                                        = (sensitive value)
          + account                                             = (known after apply)
          + account_id                                          = (known after apply)
          + account_key                                         = (sensitive value)
          + account_region                                      = (known after apply)
          + account_type                                        = (known after apply)
          + action_report_time                                  = (known after apply)
          + agent_config_method                                 = (known after apply)
          + agent_host                                          = (known after apply)
          + agent_ora_home                                      = (known after apply)
          + agent_password                                      = (sensitive value)
          + agent_port                                          = (known after apply)
          + agent_public_cert                                   = (known after apply)
          + agent_user                                          = (known after apply)
          + aggregation                                         = (known after apply)
          ~ always_encrypted                                    = true -> (known after apply)
          + api_access_token                                    = (sensitive value)
          + api_environment                                     = (known after apply)
          + api_key                                             = (sensitive value)
          + api_quota                                           = (known after apply)
          + api_requests_per_minute                             = (known after apply)
          + api_secret                                          = (sensitive value)
          + api_token                                           = (sensitive value)
          + api_type                                            = (known after apply)
          + api_url                                             = (known after apply)
          + api_usage                                           = (known after apply)
          + api_utilization_percentage                          = (known after apply)
          + api_version                                         = (known after apply)
          + app_sync_mode                                       = (known after apply)
          + append_file_option                                  = (known after apply)
          + archive_pattern                                     = (known after apply)
          + are_soap_credentials_provided                       = (known after apply)
          + asm_option                                          = (known after apply)
          + asm_oracle_home                                     = (known after apply)
          + asm_password                                        = (sensitive value)
          + asm_tns                                             = (known after apply)
          + asm_user                                            = (known after apply)
          + auth                                                = (known after apply)
          + auth_environment                                    = (known after apply)
          + auth_mode                                           = (known after apply)
          + auth_type                                           = (known after apply)
          + authentication_method                               = (known after apply)
          + authorization_method                                = (known after apply)
          + aws_region_code                                     = (known after apply)
          + base_url                                            = (known after apply)
          + blockchain                                          = (known after apply)
          + bucket                                              = (known after apply)
          + bucket_name                                         = (known after apply)
          + bucket_service                                      = (known after apply)
          + certificate                                         = (sensitive value)
          + click_attribution_window                            = (known after apply)
          + client_id                                           = (sensitive value)
          + client_name                                         = (sensitive value)
          + client_secret                                       = (sensitive value)
          + cloud_storage_type                                  = (known after apply)
          + company_id                                          = (known after apply)
          + compression                                         = (known after apply)
          + config_method                                       = (known after apply)
          + config_type                                         = (known after apply)
          + connection_method                                   = (known after apply)
          + connection_string                                   = (sensitive value)
          + consumer_group                                      = (known after apply)
          + consumer_key                                        = (sensitive value)
          + consumer_secret                                     = (sensitive value)
          + container_name                                      = (known after apply)
          + conversion_report_time                              = (known after apply)
          + conversion_window_size                              = (known after apply)
          + convert_dats_type_to_date                           = (known after apply)
          + csv_definition                                      = (known after apply)
          + customer_id                                         = (known after apply)
          + customer_list_id                                    = (known after apply)
          + daily_api_call_limit                                = (known after apply)
          + data_access_method                                  = (known after apply)
          + data_center                                         = (known after apply)
          + dataset_id                                          = (known after apply)
          + datasource                                          = (known after apply)
          + date_granularity                                    = (known after apply)
          + delimiter                                           = (known after apply)
          + direct_capture_method                               = (known after apply)
          + distributed_connector_cluster_size                  = (known after apply)
          + domain                                              = (known after apply)
          + domain_host_name                                    = (known after apply)
          + domain_name                                         = (known after apply)
          + domain_type                                         = (known after apply)
          + email                                               = (known after apply)
          + empty_header                                        = (known after apply)
          + enable_all_dimension_combinations                   = (known after apply)
          + enable_archive_log_only                             = (known after apply)
          + enable_data_extensions_syncing                      = (known after apply)
          + enable_distributed_connector_mode                   = (known after apply)
          + enable_enrichments                                  = (known after apply)
          + enable_exports                                      = (known after apply)
          + enable_tde                                          = (known after apply)
          + encryption_key                                      = (sensitive value)
          + endpoint                                            = (known after apply)
          + engagement_attribution_window                       = (known after apply)
          + entity_id                                           = (known after apply)
          + environment                                         = (known after apply)
          + escape_char                                         = (known after apply)
          + escape_char_options                                 = (known after apply)
          + eu_region                                           = (known after apply)
          + export_storage_type                                 = (known after apply)
          + external_id                                         = (known after apply)
          + file_type                                           = (known after apply)
          + finance_account_sync_mode                           = (known after apply)
          + folder_id                                           = (known after apply)
          + ftp_host                                            = (known after apply)
          + ftp_password                                        = (sensitive value)
          + ftp_port                                            = (known after apply)
          + ftp_user                                            = (known after apply)
          + function                                            = (known after apply)
          + function_app                                        = (known after apply)
          + function_key                                        = (sensitive value)
          + function_name                                       = (known after apply)
          + function_trigger                                    = (sensitive value)
          + gcs_bucket                                          = (known after apply)
          + gcs_folder                                          = (known after apply)
          + group_name                                          = (known after apply)
          + hana_mode                                           = (known after apply)
          + has_manage_permissions                              = (known after apply)
          + home_folder                                         = (known after apply)
          + identity                                            = (known after apply)
          + include_ocapi_endpoints                             = (known after apply)
          + instance                                            = (known after apply)
          + integration_key                                     = (sensitive value)
          + is_account_level_connector                          = (known after apply)
          + is_auth2_enabled                                    = (known after apply)
          + is_custom_api_credentials                           = (known after apply)
          + is_external_activities_endpoint_selected            = (known after apply)
          + is_ftps                                             = (known after apply)
          + is_keypair                                          = (known after apply)
          + is_multi_entity_feature_enabled                     = (known after apply)
          + is_new_package                                      = (known after apply)
          + is_private_key_encrypted                            = (known after apply)
          + is_private_link_required                            = (known after apply)
          + is_public                                           = (known after apply)
          + is_sailthru_connect_enabled                         = (known after apply)
          + is_secure                                           = (known after apply)
          + is_sftp_creds_available                             = (known after apply)
          + is_single_table_mode                                = (known after apply)
          + is_vendor                                           = (known after apply)
          + key                                                 = (known after apply)
          + last_synced_changes__utc_                           = (known after apply)
          + latest_version                                      = (known after apply)
          + limit_for_api_calls_to_external_activities_endpoint = (known after apply)
          + list_strategy                                       = (known after apply)
          + login_password                                      = (sensitive value)
          + merchant_id                                         = (known after apply)
          + message_type                                        = (known after apply)
          + named_range                                         = (known after apply)
          + network_code                                        = (known after apply)
          + non_standard_escape_char                            = (known after apply)
          + null_sequence                                       = (known after apply)
          + oauth_token                                         = (sensitive value)
          + oauth_token_secret                                  = (sensitive value)
          + on_error                                            = (known after apply)
          + on_premise                                          = (known after apply)
          + organization                                        = (known after apply)
          + organization_id                                     = (known after apply)
          + passphrase                                          = (sensitive value)
          + pat                                                 = (sensitive value)
          + path                                                = (known after apply)
          + pattern                                             = (known after apply)
          + pdb_name                                            = (known after apply)
          + pem_certificate                                     = (sensitive value)
          + post_click_attribution_window_size                  = (known after apply)
          + prebuilt_report                                     = (known after apply)
          + prefix                                              = (known after apply)
          + private_key                                         = (sensitive value)
          + product                                             = (known after apply)
          + project_id                                          = (known after apply)
          ~ public_key                                          = <<-EOT
                ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCsIBE7MKX8MXiYU24W5SoImDAIe1qaP+nE5Wfj+wcUhlGGhj5l9Vvr/aQD/MOUzvzFmryo+cYIjlBzrMI8Is4E8lbw53ClMrSCI4hKq7MIfLV6XepSTugA3GFn0rWoEy6mS8G1zBerzjZ+QFirq4hSZcFkQJBhfF2iMDhi3+vJ687HBQ2X2hYfWa6cSDJVArpQCaTaz1TOIUCygvBMa5UarrtsL8eNYXshbj233aN+Oby7msjX13HVbwCYqrmK0qPSapmW9QjJCs7mGB1Exp+ZSSOPEjDAB6Oib7OoLEuy7PNaP0r5vxNbZZ7eFcOb/c49VnAJyGxNGPWqg9B3/2l7V29HwF1OWa0mmkLNh5hgHPCUwvcY8E5bpnsJoCzdesURUlGa7aZQ5cp7+GjdNFNvdHJ7m56Gl6uZCGOz/5UdhREPnpzYQ9epbB2UlmThAaraXJfMlcE5VSr0lljYvccEMmZ2hqysZVNJ2OnOo+UofSZimrBg3SIIy4eF8yxDfX8GVGS4a23bqEYUJMm+a3vmmt2lXhJewNQfHAuHm/QhoVSgRc5L45D14Fc9UaZx3+nH0FqMc19NOckBEPM/+SJ7DUFNKwwtnd+K3col71iPtUR/gBgQymWW70v1plfI6s4B2b/sjNpKgLg20y3Ic3YaVO3CNPCLnsuBq/e06Agc1w== fivetran user key
            EOT -> (known after apply)
          + publication_name                                    = (known after apply)
          + pull_archived_campaigns                             = (known after apply)
          + query_id                                            = (known after apply)
          + region                                              = (known after apply)
          + region_api_url                                      = (known after apply)
          + region_auth_url                                     = (known after apply)
          + region_token_url                                    = (known after apply)
          + replica_id                                          = (known after apply)
          + replication_slot                                    = (known after apply)
          + report_type                                         = (known after apply)
          + report_url                                          = (known after apply)
          + resource_url                                        = (known after apply)
          + rest_api_limit                                      = (known after apply)
          + role                                                = (known after apply)
          + role_arn                                            = (sensitive value)
          + rollback_window_size                                = (known after apply)
          + s3bucket                                            = (known after apply)
          + s3external_id                                       = (known after apply)
          + s3folder                                            = (known after apply)
          + s3role_arn                                          = (sensitive value)
          + sales_account_sync_mode                             = (known after apply)
          + sap_user                                            = (known after apply)
          + secret                                              = (sensitive value)
          + secret_key                                          = (sensitive value)
          + secrets                                             = (sensitive value)
          + security_protocol                                   = (known after apply)
          + server                                              = (known after apply)
          + server_url                                          = (known after apply)
          + service_version                                     = (known after apply)
          + sftp_host                                           = (known after apply)
          + sftp_is_key_pair                                    = (known after apply)
          + sftp_password                                       = (sensitive value)
          + sftp_port                                           = (known after apply)
          + sftp_user                                           = (known after apply)
          + share_url                                           = (known after apply)
          + sheet_id                                            = (known after apply)
          + shop                                                = (known after apply)
          + short_code                                          = (sensitive value)
          + should_sync_events_with_deleted_profiles            = (known after apply)
          + show_records_with_no_metrics                        = (known after apply)
          + sid                                                 = (known after apply)
          + site_id                                             = (known after apply)
          + skip_after                                          = (known after apply)
          + skip_before                                         = (known after apply)
          + snc_mode                                            = (known after apply)
          + soap_uri                                            = (known after apply)
          + source                                              = (known after apply)
          + sub_domain                                          = (known after apply)
          + subdomain                                           = (known after apply)
          + subscriber_name                                     = (known after apply)
          + support_connected_accounts_sync                     = (known after apply)
          + support_nested_columns                              = (known after apply)
          + swipe_attribution_window                            = (known after apply)
          + sync_data_locker                                    = (known after apply)
          + sync_format                                         = (known after apply)
          + sync_formula_fields                                 = (known after apply)
          + sync_metadata                                       = (known after apply)
          + sync_method                                         = (known after apply)
          + sync_mode                                           = (known after apply)
          + sync_mode_advertiser                                = (known after apply)
          + sync_mode_seat                                      = (known after apply)
          + sync_multiple_accounts                              = (known after apply)
          + sync_pack_mode                                      = (known after apply)
          + sync_pull_api                                       = (known after apply)
          + sync_type                                           = (known after apply)
          + target_entity_id                                    = (known after apply)
          + technical_account_id                                = (known after apply)
          + test_table_name                                     = (known after apply)
          + time_zone                                           = (known after apply)
          + timeframe_months                                    = (known after apply)
          + tns                                                 = (known after apply)
          + token_key                                           = (sensitive value)
          + token_secret                                        = (sensitive value)
          + unique_id                                           = (known after apply)
          + update_config_on_each_sync                          = (known after apply)
          + uri                                                 = (known after apply)
          + url_format                                          = (known after apply)
          + use_api_keys                                        = (known after apply)
          + use_customer_bucket                                 = (known after apply)
          + use_oracle_rac                                      = (known after apply)
          + use_pgp_encryption_options                          = (known after apply)
          + use_service_account                                 = (known after apply)
          + use_template_labels                                 = (known after apply)
          + use_webhooks                                        = (known after apply)
          + use_workspace                                       = (known after apply)
          + user_id                                             = (known after apply)
          + user_key                                            = (sensitive value)
          + user_name                                           = (known after apply)
          + username                                            = (known after apply)
          + view_attribution_window                             = (known after apply)
          + view_through_attribution_window_size                = (known after apply)
          + workspace_same_as_source                            = (known after apply)
            # (10 unchanged attributes hidden)
        }

        # (1 unchanged block hidden)
    }

  # module.fivetran_connector[0].fivetran_connector_schedule.schedule must be replaced
-/+ resource "fivetran_connector_schedule" "schedule" {
      ~ connector_id      = "unzip_mutation" # forces replacement -> (known after apply) # forces replacement
      ~ id                = "unzip_mutation" -> (known after apply)
        # (5 unchanged attributes hidden)
    }

  # module.fivetran_connector[0].fivetran_connector_schema_config.schema must be replaced
-/+ resource "fivetran_connector_schema_config" "schema" {
      ~ connector_id           = "unzip_mutation" # forces replacement -> (known after apply) # forces replacement
      ~ id                     = "unzip_mutation" -> (known after apply)
        # (1 unchanged attribute hidden)

      - schema {
          - enabled = true -> null
          - name    = "public" -> null

          - table {
              - enabled = true -> null
              - name    = "ltv_customerregister" -> null
            }
          - table {
              - enabled = true -> null
              - name    = "ltv_marketingtransaction" -> null
            }
          - table {
              - enabled = true -> null
              - name    = "ltv_merchantaverageordervalue" -> null
            }
          - table {
              - enabled = true -> null
              - name    = "ltv_merchantindirectltvvalue" -> null
            }
          - table {
              - enabled = true -> null
              - name    = "unsubscribed_customers" -> null
            }
        }
      + schema {
          + enabled = true
          + name    = "public"

          + table {
              + enabled   = true
              + name      = "ltv_customerregister"
              + sync_mode = (known after apply)
            }
          + table {
              + enabled   = true
              + name      = "ltv_marketingtransaction"
              + sync_mode = (known after apply)
            }
          + table {
              + enabled   = true
              + name      = "ltv_merchantaverageordervalue"
              + sync_mode = (known after apply)
            }
          + table {
              + enabled   = true
              + name      = "ltv_merchantindirectltvvalue"
              + sync_mode = (known after apply)
            }
          + table {
              + enabled   = true
              + name      = "unsubscribed_customers"
              + sync_mode = (known after apply)
            }
        }
    }

Plan: 2 to add, 1 to change, 2 to destroy.
beevital commented 2 weeks ago

@MaxymVlasov it's not related issue. Original issue caused by the API response version and now it's fixed on API side.

Your issue caused by another problem on API side. It's not related to Terraform provider itself. We will roll out fix on API soon.

beevital commented 2 weeks ago

@sergeyrudenko111 your problem should be already fixed, please make the same API request I've asked you to do last time - API should return both fields in response: update_method and incremental_update_method with the same value. So Terraform should be able to recover from error.

sergeyrudenko111 commented 2 weeks ago

@beevital hi, unfortunately that doesn't help. I still see only one field from API response it's update_method and as well for terraform i see the same error

beevital commented 2 weeks ago

looks like the solution wasn't deployed yet. sorry - false alarm. Will trigger you when everything will be on prod.

beevital commented 5 days ago

@sergeyrudenko111 we have deployed fix on API side, so now API should return both update_method and incremental_update_method in response for you. PLease check and report the results.

sergeyrudenko111 commented 5 days ago

@beevital Hi, thanks for the update, it worked for us and now i see both fields from API, also connectors were successfully modified by terraform. Going to close the issue.