Terraform Deployment

Bootstrap OnePAM agents on cloud instances using Terraform.

Install from Terraform Registry

Use the official OnePAM Terraform modules directly from the Terraform Registry. Available modules for agent deployment and gateway deployment on AWS, GCP, and Azure.


Agent Module (recommended)
module "onepam_agent" {
  source    = "onepamcom/agent/aws"
  tenant_id = "YOUR-TENANT-UUID"
}
From Source
git clone https://github.com/onepamcom/onepam-terraform.git
cd onepam-terraform

Overview

Deploy OnePAM agents automatically when provisioning cloud infrastructure with Terraform. This guide covers cloud-init user data scripts and Terraform modules for AWS, GCP, and Azure.

AWS EC2
Google Cloud
Azure VMs

User Data Script

This cloud-init script works across all major cloud providers. Use it as user data (AWS), startup script (GCP), or custom data (Azure):

scripts/install-onepam.sh
#!/bin/bash
set -euo pipefail

# Configuration
ONEPAM_SERVER_URL="${ONEPAM_SERVER_URL:-https://onepam.com}"
ONEPAM_TENANT_ID="${ONEPAM_TENANT_ID:-00000000-0000-0000-0000-000000000000}"
ONEPAM_RELEASE_URL="${ONEPAM_RELEASE_URL:-https://updates.onepam.com}"
ONEPAM_AGENT_VERSION="${ONEPAM_AGENT_VERSION:-latest}"
ONEPAM_LOG_LEVEL="${ONEPAM_LOG_LEVEL:-info}"

# Generate unique agent ID
AGENT_ID=$(cat /proc/sys/kernel/random/uuid)

# Create directories
mkdir -p /opt/onepam/bin /opt/onepam/data/queue /opt/onepam/etc

# Download agent binary and checksum
curl -sL "${ONEPAM_RELEASE_URL}/agent/${ONEPAM_AGENT_VERSION}/onepam-agent-linux-amd64" \
  -o /opt/onepam/bin/onepam-agent
curl -sL "${ONEPAM_RELEASE_URL}/agent/${ONEPAM_AGENT_VERSION}/onepam-agent-linux-amd64.sha256" \
  -o /tmp/onepam-agent.sha256

# Verify SHA256 checksum
cd /opt/onepam/bin
echo "$(cat /tmp/onepam-agent.sha256)  onepam-agent" | sha256sum -c -
chmod +x /opt/onepam/bin/onepam-agent

# Create configuration
cat > /opt/onepam/etc/agent.env <<EOF
AGENT_API_URL="${ONEPAM_SERVER_URL}"
AGENT_TENANT_ID="${ONEPAM_TENANT_ID}"
AGENT_ID="${AGENT_ID}"
AGENT_LOG_LEVEL="${ONEPAM_LOG_LEVEL}"
AGENT_DATA_DIR="/opt/onepam/data"
EOF

# Create systemd service
cat > /etc/systemd/system/onepam-agent.service <<'EOF'
[Unit]
Description=OnePAM Agent
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
EnvironmentFile=/opt/onepam/etc/agent.env
ExecStart=/opt/onepam/bin/onepam-agent \
    --server=${AGENT_API_URL} \
    --tenant-id=${AGENT_TENANT_ID} \
    --agent-id=${AGENT_ID}
Restart=always
RestartSec=10
LimitNOFILE=65536
LimitMEMLOCK=infinity

[Install]
WantedBy=multi-user.target
EOF

# Enable and start service
systemctl daemon-reload
systemctl enable onepam-agent
systemctl start onepam-agent

echo "OnePAM agent installed successfully"

AWS Examples

EC2 Instance with User Data
module "onepam_agent" {
  source    = "onepamcom/agent/onepam"
  version   = "~> 1.0"
  tenant_id = var.onepam_tenant_id
}

data "aws_ssm_parameter" "ami" {
  name = "/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64"
}

resource "aws_instance" "example" {
  ami           = data.aws_ssm_parameter.ami.value
  instance_type = "t3.micro"
  user_data     = module.onepam_agent.install_script

  tags = {
    Name = "web-server"
  }
}
Auto Scaling Group with Launch Template
resource "aws_launch_template" "web" {
  name_prefix   = "web-"
  image_id      = data.aws_ssm_parameter.ami.value
  instance_type = "t3.micro"
  user_data     = base64encode(module.onepam_agent.install_script)

  tag_specifications {
    resource_type = "instance"
    tags = {
      Name = "web-asg"
    }
  }
}

resource "aws_autoscaling_group" "web" {
  name                = "web-asg"
  vpc_zone_identifier = var.subnet_ids
  desired_capacity    = 2
  max_size            = 10
  min_size            = 1

  launch_template {
    id      = aws_launch_template.web.id
    version = "$Latest"
  }
}

GCP Examples

Compute Instance with Startup Script
module "onepam_agent" {
  source    = "onepamcom/agent/onepam"
  version   = "~> 1.0"
  tenant_id = var.onepam_tenant_id
}

variable "zone" {
  description = "GCP zone"
  type        = string
  default     = "us-central1-a"
}

# main.tf
resource "google_compute_instance" "web" {
  name         = "web-server"
  machine_type = "e2-micro"
  zone         = var.zone

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-12"
    }
  }

  network_interface {
    network = "default"
    access_config {}
  }

  metadata_startup_script = module.onepam_agent.install_script

  labels = {
    environment = "production"
  }
}
Instance Template for Managed Instance Groups
resource "google_compute_instance_template" "web" {
  name_prefix  = "web-"
  machine_type = "e2-small"

  disk {
    source_image = "debian-cloud/debian-12"
    auto_delete  = true
    boot         = true
  }

  network_interface {
    network = "default"
  }

  metadata = {
    startup-script = module.onepam_agent.install_script
  }

  lifecycle {
    create_before_destroy = true
  }
}

resource "google_compute_instance_group_manager" "web" {
  name               = "web-mig"
  base_instance_name = "web"
  zone               = var.zone
  target_size        = 2

  version {
    instance_template = google_compute_instance_template.web.id
  }
}

Azure Examples

Linux Virtual Machine with Custom Data
module "onepam_agent" {
  source    = "onepamcom/agent/onepam"
  version   = "~> 1.0"
  tenant_id = var.onepam_tenant_id
}

variable "resource_group_name" {
  description = "Azure resource group name"
  type        = string
}

variable "location" {
  description = "Azure region"
  type        = string
  default     = "East US"
}

# main.tf
resource "azurerm_linux_virtual_machine" "web" {
  name                = "web-server"
  resource_group_name = var.resource_group_name
  location            = var.location
  size                = "Standard_B1s"
  admin_username      = "adminuser"

  network_interface_ids = [
    azurerm_network_interface.web.id,
  ]

  admin_ssh_key {
    username   = "adminuser"
    public_key = file("~/.ssh/id_rsa.pub")
  }

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "0001-com-ubuntu-server-jammy"
    sku       = "22_04-lts"
    version   = "latest"
  }

  custom_data = base64encode(module.onepam_agent.install_script)

  tags = {
    environment = "production"
  }
}
Virtual Machine Scale Set
resource "azurerm_linux_virtual_machine_scale_set" "web" {
  name                = "web-vmss"
  resource_group_name = var.resource_group_name
  location            = var.location
  sku                 = "Standard_B1s"
  instances           = 2
  admin_username      = "adminuser"

  admin_ssh_key {
    username   = "adminuser"
    public_key = file("~/.ssh/id_rsa.pub")
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "0001-com-ubuntu-server-jammy"
    sku       = "22_04-lts"
    version   = "latest"
  }

  os_disk {
    storage_account_type = "Standard_LRS"
    caching              = "ReadWrite"
  }

  network_interface {
    name    = "web-nic"
    primary = true

    ip_configuration {
      name      = "internal"
      primary   = true
      subnet_id = azurerm_subnet.web.id
    }
  }

  custom_data = base64encode(module.onepam_agent.install_script)
}

Terraform Module

Use the official OnePAM Terraform modules from the Terraform Registry or from source. The agent module produces an install script (marked sensitive) you can attach to any cloud instance as user data.

From Terraform Registry (recommended)
module "onepam_agent" {
  source  = "onepamcom/agent/onepam"
  version = "~> 1.0"

  server_url = "https://onepam.example.com"
  tenant_id  = var.onepam_tenant_id
}

# Use in EC2 instance
data "aws_ssm_parameter" "ami" {
  name = "/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64"
}

resource "aws_instance" "web" {
  ami           = data.aws_ssm_parameter.ami.value
  instance_type = "t3.micro"
  user_data     = module.onepam_agent.install_script

  tags = {
    Name = "web-server"
  }
}
From GitHub Source
module "onepam_agent" {
  source = "github.com/onepamcom/onepam-terraform//modules/agent"

  server_url = "https://onepam.example.com"
  tenant_id  = var.onepam_tenant_id
}
Gateway Module (AWS)
module "onepam_gateway" {
  source  = "onepamcom/gateway-aws/onepam"
  version = "~> 1.0"

  gateway_id    = var.gateway_id
  api_url       = "https://onepam.example.com"
  api_token     = var.onepam_api_token
  vpc_id        = var.vpc_id
  subnet_id     = var.subnet_id
  instance_type = "t4g.small"
  architecture  = "arm64"
  public_domain = "gateway.example.com"
  s3_bucket     = var.s3_bucket
  s3_access_key = var.s3_access_key
  s3_secret_key = var.s3_secret_key
  s3_region     = var.s3_region
}
Module Variables
VariableDefaultDescription
server_urlhttps://onepam.comOnePAM server URL
tenant_id-Organisation UUID (required, validated)
group_uuid""Optional group UUID (validated when non-empty)
agent_versionlatestAgent version to install
log_levelinfoLogging verbosity (debug, info, warn, error)
release_urlhttps://updates.onepam.comAgent release download URL
Module Outputs
output "install_script" {
  description = "Install script for cloud-init (sensitive)"
  value       = module.onepam_agent.install_script
  sensitive   = true
}
Security Note: Store sensitive values like tenant_id in Terraform variables files that are not committed to version control, or use a secrets manager like HashiCorp Vault.