Retrieving APM Secret from Elastic EC Provider

Hi folks!

Key Value
Kibana version 8.3.3
Elasticsearch version 8.3.3
APM version 8.3.3
APM Agent language and version N/A
Browser version N/A
Original install method and version Terraform Integrations Server Block
Fresh install or upgraded from other version? Fresh
Is there anything special in your setup? N/A

Description of the problem including expected versus actual behavior. Please include screenshots (if relevant):

I can create an Integrations Server using the Elastic EC Terraform Provider by creating an integrations_server within the ec_deployment block, as below:

resource "ec_deployment" "ec_configuration" {
  name                   = local.deployment_name
  region                 = var.aws_region
  version                = var.elastic_version
  deployment_template_id = "aws-storage-optimized-v3"

  elasticsearch { [...] }

  lifecycle { [...] }

  kibana { [...] }

  dynamic "integrations_server" {
    for_each = var.globals.stage == "dev" ? [1] : []

    content {
      topology {
        size = "1g"
      }
    }
  }
}

But I need to save the APM Secret Token in secure cloud storage, so that this can be picked up by the agents when they are installed (via automation). The elastic documentation states that:

apm DEPRECATED (Optional) APM instance definition, can only be specified once. It should only be used with deployments with a version prior to 8.0.0.

And that the integrations_server should instead be used:

integrations_server (Optional) Integrations Server instance definition, can only be specified once. It has replaced apm in stack version 8.0.0.

But in the Attributes Reference section there is no ability to grab the APM secret token when using the integrations_server block

  • apm_secret_token - Auto-generated APM secret_token, empty unless an apm resource is specified.
  • integrations_server.#.resource_id - Integrations Server resource unique identifier.
  • integrations_server.#.region - Integrations Server region.
  • integrations_server.#.http_endpoint - Integrations Server resource HTTP endpoint.
  • integrations_server.#.https_endpoint - Integrations Server resource HTTPs endpoint.
  • integrations_server.#.fleet_https_endpoint - HTTPs endpoint for Fleet Server.
  • integrations_server.#.apm_https_endpoint - HTTPs endpoint for APM Server.

Is there a way of retrieving the secret token using integrations_server, or should I instead opt for a workaround: a post-deploy script that interacts with the API to retrieve the secret?

Steps to reproduce:

  1. Create an Integrations Server using Elastic EC Terraform Provider

Provide logs and/or server output (if relevant):

Terraform error from CI/CD output:

╷
│ Error: Missing required argument
│ 
│   on main.tf line 38, in module "operations_infrastructure":
│   38: module "operations_infrastructure" {
│ 
│ The argument "apm_secret_token" is required, but no definition was found.
╵

Thanks ever so much in advance!

There's no way to fetch the secret token from the Elastic Cloud API for integrations_server - it must instead be fetched from the Fleet integration policy via Kibana. Here's an example of how we're doing that in our testing setup:

Alternatively, you can create an API Key via Elasticsearch or Kibana (APM agent Key API | Kibana Guide [8.5] | Elastic), and configure the agents to use API Key auth.

2 Likes

Hi Andrew!

Thanks for your reply - I've actually made some headway in the last day or so, though I'm not entirely sure what changed. I'll share my working:

My ec_deployment block is unchanged:

resource "ec_deployment" "ec_configuration" {
  name                   = local.deployment_name
  region                 = var.aws_region
  version                = var.elastic_version
  deployment_template_id = "aws-storage-optimized-v3"

  elasticsearch { [...] }

  lifecycle { [...] }

  kibana { [...] }

  dynamic "integrations_server" {
    for_each = var.globals.stage == "dev" ? [1] : []

    content {
      topology {
        size = "1g"
      }
    }
  }
}

But I am now seeing a value returning for apm_secret_token when using integrations_server in the ec_deployment block. So the following output block works.

output "integration_resource_id" {
  value = ec_deployment.ec_configuration.integrations_server[0].resource_id
}

Looks like you can grab the apm_secret_token when not using the apm block.

I was having issues with this before, so will run some additional tests in a clean environment to see if I get the token every time.

@Hyaden_WB resource_id and secret token are different things. The resource ID uniquely identifies the integrations server, and (AFAIK) isn't used for authentication. If it can be used for authentication, that would be surprising and probably a bug.

Thanks Andrew - actually, this was a mistake on my part. I copied the wrong block of code over. It should have been as below:

output "apm_secret_token" {
  value     = ec_deployment.ec_configuration.apm_secret_token
  sensitive = true
}

Thanks for your help!