For the complete documentation index, see llms.txt. This page is also available as Markdown.

Deploy Device Protection with Terraform

Terraform creates machines, it does not keep software converged on machines that already exist. So Terraform's job here is to make sure every Linux instance it creates comes up with Device Protection already installed.

Read Deploying on Linux first for the token, the package list, and the reboot behaviour that applies to every method.

This is not the Aikido Terraform provider. That provider manages Aikido workspace configuration, such as repository activation and AutoFix settings. It has nothing to do with installing the agent on a machine.

Install on new instances

Pass a cloud-init document as user_data. Keep the document in its own file so it stays readable and can be reused outside Terraform. See cloud-init for the document itself and its options.

main.tf
variable "aikido_token" {
  type      = string
  sensitive = true
}

resource "aws_instance" "workstation" {
  ami           = var.workstation_ami
  instance_type = "m7i.large"

  user_data = templatefile("${path.module}/aikido-user-data.yaml.tftpl", {
    package      = "EndpointProtection-amd64.deb"
    aikido_token = var.aikido_token
  })

  tags = {
    Name = "workstation"
  }
}

Fetch the token at boot instead

Store the token in your cloud's secret store, give the instance a role that can read it, and let the boot script pull it. The token then stays out of user_data, out of instance metadata, and out of Terraform state.

Terraform then passes the parameter name rather than the token, and grants the instance profile ssm:GetParameter on it:

The aikido_token variable drops out entirely, so nothing sensitive reaches Terraform state.

Changing user_data does not reinstall anything on instances that are already running, because cloud-init's runcmd only fires on first boot. A change only affects instances created after it.

Install on instances Terraform already manages

For a one-off push at create time, use a remote-exec provisioner:

Provisioners come with real limits, which is why HashiCorp calls them a last resort:

  • They run once, at create time. They never run again, so drift is never corrected.

  • A failed provisioner marks the resource tainted, and the next apply destroys and recreates the instance.

  • Terraform needs SSH reachability from wherever you run it, including from CI.

For a fleet that already exists, use Ansible, Chef, or Puppet. On AWS, SSM Run Command and State Manager also fit better than Terraform, because they are built to act on running instances.

Token handling and state

  • Declare the variable with sensitive = true so it is redacted from plan and apply output.

  • Anything Terraform renders into user_data is stored in state, including a token. Use an encrypted remote backend and restrict who can read state.

  • Do not run applies with TF_LOG=DEBUG when a token is in play. Debug logs are not redacted.

  • One token per Aikido user group. If different machine groups belong to different user groups, pass a different token or parameter name per module instance.

Verify the rollout

On a new instance:

The device then appears in your device list with an Active status.

Troubleshooting

Problem
Fix

The package installs but the device never appears in the dashboard

AIKIDO_TOKEN was not set for the install command. Configuration management tools do not forward your local environment to the host, so set the variable on the task itself, then install the package again

apt or dnf looks for the package in your repositories instead of installing the file

Pass a path, not a name: apt install ./EndpointProtection-amd64.deb. The leading ./ is what makes the package manager treat it as a local file

The install fails on a Red Hat-family host

Match the build to the major version: use the el9 package on version 9 and the el10 package on version 10

The service is not running

Run systemctl status aikido-endpoint-protection, then sudo aikido-doctor diagnostics to send us the details

Node.js or uv still reject the Aikido certificate

Installing sets NODE_EXTRA_CA_CERTS and UV_SYSTEM_CERTS system-wide, and running shells do not pick them up. Open a new login shell or reboot the device

The token shows up in run output or logs

Use your tool's redaction: no_log in Ansible, sensitive true in Chef, Sensitive() in Puppet

Several machines share one entry in the device list

They booted with the same /etc/machine-id. Device identity on Linux follows that file, so clear it in the image you clone from and let systemd write a fresh one on first boot

No tray icon appears

Expected on GNOME outside Ubuntu, and cosmetic. See Tray Icon Support on Linux

Last updated

Was this helpful?