site24x7 / terraform-provider-site24x7

Terraform provider for Site24x7
MIT License
23 stars 35 forks source link

[site24x7_amazon_monitor] Cannot import existing monitors #319

Open bryanhorstmann opened 5 days ago

bryanhorstmann commented 5 days ago

I have an existing Site24x7 estate I'm trying to import into Terraform. I've hit a blocker on my first resource type.

When trying to import existing AWS Monitors (using the monitor id as guess) I get the following error:

* Failed to execute "terraform import site24x7_amazon_monitor.this["<REDACTED>"] <REDACTED" in .
  ╷
  │ Error: resource site24x7_amazon_monitor doesn't support import
  │ 
  │ 
  ╵

  exit status 1

This is unfortunate, but I decide to create new site24x7_amazon_monitor resources instead and I'll remove my existing ones. I follow the example on https://registry.terraform.io/providers/site24x7/site24x7/latest/docs/resources/amazon_monitor but have another issue. The output for site24x7_aws_external_id data source updates on each plan. Its not static.

10:08:39.637 STDOUT terraform: Terraform used the selected providers to generate the following execution
10:08:39.637 STDOUT terraform: plan. Resource actions are indicated with the following symbols:
10:08:39.637 STDOUT terraform:   ~ update in-place
10:08:39.637 STDOUT terraform: Terraform will perform the following actions:
10:08:39.637 STDOUT terraform:   # site24x7_amazon_monitor.this["<REDACTED>"] will be updated in-place
10:08:39.637 STDOUT terraform:   ~ resource "site24x7_amazon_monitor" "this" {
10:08:39.637 STDOUT terraform:       ~ external_id             = "S247.............................229" -> "S247.............................75d"
10:08:39.637 STDOUT terraform:         id                      = "<REDACTED>"
10:08:39.637 STDOUT terraform:         # (8 unchanged attributes hidden)
10:08:39.637 STDOUT terraform:     }
10:08:39.637 STDOUT terraform: Plan: 0 to add, 1 to change, 0 to destroy.
10:08:39.637 STDOUT terraform: 
10:08:39.637 STDOUT terraform: Changes to Outputs:
10:08:39.637 STDOUT terraform:   ~ site24x7_aws_external_id = {
10:08:39.637 STDOUT terraform:       ~ <REDACTED> = "S247.............................229" -> "S247.............................75d"
10:08:39.637 STDOUT terraform:     }
10:08:39.637 STDOUT terraform: 
10:08:39.637 STDOUT terraform: ─────────────────────────────────────────────────────────────────────────────

This is blocker for me, as all our AWS IAM roles are created separately. I need to retrieve the external ID here and then update my IAM role in another repo.

Here is my terraform code to reproduce this:

variable "amazon_monitors" {
  description = "A list of AWS Accounts to monitor with Site24x7"
  type = list(object({
    name                    = string
    role_arn                = string
    aws_discover_services   = optional(list(string), []) # A list of AWS services to discover
    aws_discovery_frequency = optional(number, 5)        # AWS discover frequency
  }))
}

locals {
  # Constants are documented here: https://www.site24x7.com/help/api/#constants
  site24x7_constants = {
    aws_discover_services = {
      "Amazon DocumentDB"                = 68
      "Amazon FSx"                       = 65
      "Amazon MQ"                        = 48
      ...
      "WorkSpace"                        = 42
    }
  }
}

data "site24x7_aws_external_id" "this" {
  for_each = { for monitor in var.amazon_monitors : monitor.name => monitor }
}

resource "site24x7_amazon_monitor" "this" {
  for_each = { for monitor in var.amazon_monitors : monitor.name => monitor }

  display_name            = "${each.value.name} (terraform)"
  external_id             = data.site24x7_aws_external_id.this[each.key].id
  role_arn                = each.value.role_arn
  aws_discovery_frequency = each.value.aws_discovery_frequency

  # Convert each service name in aws_discover_services to its corresponding ID
  # using the local map. If a service name is not found in the map, this will
  # cause the plan to fail, ensuring only valid services are provided.
  aws_discover_services = [
    for service in each.value.aws_discover_services : local.site24x7_constants.aws_discover_services[service]
  ]
}

output "site24x7_aws_external_id" {
  description = "A map of AWS Account names to their corresponding Site24x7 External ID"
  value       = { for monitor in var.amazon_monitors : monitor.name => data.site24x7_aws_external_id.this[monitor.name].id }
}

Is it possible to retrieve a static value for the external id?

VinothDarwin-ZC commented 4 days ago

@bryanhorstmann The External ID can remain static for a while when fetching the data source. However, please note that a single External ID can only be used for one AWS monitor when creating monitors in Site24x7.

If you need to create multiple AWS monitors in bulk, please ensure that you fetch a unique External ID for each respective monitor.

Thanks, Vinoth K.

bryanhorstmann commented 4 days ago

Hi @VinothDarwin-ZC ,

It does not appear to remain static though. Running two plans directly after each other generates a new external id which means the external id associated with the monitor updates on each plan/apply.

I am retrieving one per account using the for_each here:

data "site24x7_aws_external_id" "this" {
  for_each = { for monitor in var.amazon_monitors : monitor.name => monitor }
}
VinothDarwin-ZC commented 3 days ago

@bryanhorstmann
I received an update from the AWS product team that the External ID is no longer static. Here’s what we can suggest for your use case:

You can create multiple External IDs using the data sources, create the Role ARN separately, and then proceed to apply or create the AWS monitor in Site24x7.

Please note that the External ID cannot be static across multiple AWS monitors. The purpose of the External ID is to enhance security for the Role ARN in AWS. Each Role ARN should have a unique External ID associated with it to maintain security integrity.

Thanks,
Vinoth K.

bryanhorstmann commented 3 days ago

Hi @VinothDarwin-ZC ,

I appreciate that feedback and while in theory that works, it goes against the basic idea of Terraform. If I ever run another plan / apply in the module where the monitor is created, then it will create a new External ID and update my monitor and stop the IAM role from working.

Once the value is retrieved and set it needs to remain static.