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 -e

# Configuration - passed as environment variables or hardcoded
ONEPAM_SERVER_URL="${ONEPAM_SERVER_URL:-https://onepam.com}"
ONEPAM_TENANT_ID="${ONEPAM_TENANT_ID:-00000000-0000-0000-0000-000000000000}"

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

# Download agent
curl -sL https://updates.onepam.com/agent/latest/onepam-agent-linux-amd64 \
  -o /opt/onepam/bin/onepam-agent
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_LOG_LEVEL=info
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}
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
# variables.tf
variable "onepam_server_url" {
  description = "OnePAM server URL"
  type        = string
  default     = "https://onepam.example.com"
}

variable "onepam_tenant_id" {
  description = "OnePAM tenant ID"
  type        = string
  sensitive   = true
}

# main.tf
resource "aws_instance" "web" {
  ami           = data.aws_ami.amazon_linux_2.id
  instance_type = "t3.micro"
  
  user_data = templatefile("${path.module}/scripts/install-onepam.sh", {
    ONEPAM_SERVER_URL = var.onepam_server_url
    ONEPAM_TENANT_ID  = var.onepam_tenant_id
  })

  tags = {
    Name = "web-server"
  }
}

data "aws_ami" "amazon_linux_2" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}
Auto Scaling Group with Launch Template
resource "aws_launch_template" "web" {
  name_prefix   = "web-"
  image_id      = data.aws_ami.amazon_linux_2.id
  instance_type = "t3.micro"

  user_data = base64encode(templatefile("${path.module}/scripts/install-onepam.sh", {
    ONEPAM_SERVER_URL = var.onepam_server_url
    ONEPAM_TENANT_ID  = var.onepam_tenant_id
  }))

  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
# variables.tf
variable "onepam_server_url" {
  description = "OnePAM server URL"
  type        = string
}

variable "onepam_tenant_id" {
  description = "OnePAM tenant ID"
  type        = string
  sensitive   = true
}

variable "project_id" {
  description = "GCP project ID"
  type        = string
}

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-11"
    }
  }

  network_interface {
    network = "default"
    access_config {}
  }

  metadata_startup_script = templatefile("${path.module}/scripts/install-onepam.sh", {
    ONEPAM_SERVER_URL = var.onepam_server_url
    ONEPAM_TENANT_ID  = var.onepam_tenant_id
  })

  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-11"
    auto_delete  = true
    boot         = true
  }

  network_interface {
    network = "default"
  }

  metadata = {
    startup-script = templatefile("${path.module}/scripts/install-onepam.sh", {
      ONEPAM_SERVER_URL = var.onepam_server_url
      ONEPAM_TENANT_ID  = var.onepam_tenant_id
    })
  }

  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
# variables.tf
variable "onepam_server_url" {
  description = "OnePAM server URL"
  type        = string
}

variable "onepam_tenant_id" {
  description = "OnePAM tenant ID"
  type        = string
  sensitive   = true
}

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(templatefile("${path.module}/scripts/install-onepam.sh", {
    ONEPAM_SERVER_URL = var.onepam_server_url
    ONEPAM_TENANT_ID  = var.onepam_tenant_id
  }))

  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(templatefile("${path.module}/scripts/install-onepam.sh", {
    ONEPAM_SERVER_URL = var.onepam_server_url
    ONEPAM_TENANT_ID  = var.onepam_tenant_id
  }))
}

Terraform Module

Use the official OnePAM Terraform modules from the Terraform Registry or from source. The agent module produces a cloud-init user-data script you can attach to any cloud instance.

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
resource "aws_instance" "web" {
  ami           = data.aws_ami.amazon_linux_2.id
  instance_type = "t3.micro"
  user_data     = module.onepam_agent.user_data

  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 = "your-gateway-id"
  api_url    = "https://onepam.example.com"
  api_token  = var.onepam_api_token
  vpc_id     = var.vpc_id
  subnet_id  = var.subnet_id
}
Module Variables
VariableDefaultDescription
server_urlhttps://onepam.comOnePAM server URL
tenant_id-Organisation UUID (required)
agent_versionlatestAgent version to install
log_levelinfoLogging verbosity
group_uuid""Optional group assignment
Module Outputs
output "user_data" {
  description = "User data script for cloud-init"
  value       = module.onepam_agent.user_data
}

output "user_data_base64" {
  description = "Base64 encoded user data script"
  value       = module.onepam_agent.user_data_base64
}
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.