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.
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.
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"
}
}user_data is readable from the instance metadata service by anything running on the machine, so a literal token in it is not private. On a fleet of developer workstations, fetch the token at boot instead, as shown below.
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.
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.
Token handling and state
Declare the variable with
sensitive = trueso it is redacted from plan and apply output.Anything Terraform renders into
user_datais stored in state, including a token. Use an encrypted remote backend and restrict who can read state.Do not run applies with
TF_LOG=DEBUGwhen 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
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?