Ansible Deployment
Deploy OnePAM agents at scale using Ansible playbooks and roles.
OnePAM Ansible Module
Clone the official OnePAM Ansible module from GitHub. Includes tasks, templates, handlers, default variables, and example playbooks.
Clone from GitHub
git clone https://github.com/onepamcom/onepam-ansible.git
cd onepam-ansible
Requirements
Control Node
- Ansible 2.9 or later
- Python 3.8+
- SSH access to managed hosts
Managed Nodes
- Linux with systemd (Ubuntu 20.04+, Debian 11+, RHEL/CentOS 8+, Amazon Linux 2/2023)
- Python 3 on managed hosts
- Root or sudo access
For deprecated or non-systemd distributions, use the Gateway SSH Proxy instead — no agent installation required.
Quick Start
Run the OnePAM role against your inventory in a single command:
# Clone the module
git clone https://github.com/onepamcom/onepam-ansible.git
cd onepam-ansible
# Run the playbook
ansible-playbook -i inventory/hosts site.yml
Minimal playbook (site.yml):
---
- name: Deploy OnePAM agent
hosts: all
become: true
roles:
- role: agent
vars:
onepam_server_url: "https://onepam.com"
onepam_tenant_id: "00000000-0000-0000-0000-000000000000"
Role Structure
roles/agent/
├── defaults/
│ └── main.yml # Default variables
├── handlers/
│ └── main.yml # Service handlers
├── meta/
│ └── main.yml # Role metadata
├── tasks/
│ ├── main.yml # Entrypoint (validate, route to install/uninstall)
│ ├── install.yml # Download binary with SHA256 verification
│ ├── config.yml # Generate agent ID, render agent.env
│ ├── service.yml # Deploy systemd unit, enable and start
│ └── uninstall.yml # Stop service, remove files
└── templates/
├── agent.env.j2 # Environment file
└── onepam-agent.service.j2 # Systemd unit
defaults/main.yml
---
onepam_state: "present"
onepam_server_url: "https://onepam.com"
onepam_tenant_id: ""
onepam_group_uuid: ""
onepam_agent_version: "latest"
onepam_log_level: "info"
onepam_release_url: "https://updates.onepam.com"
onepam_install_dir: "/opt/onepam"
tasks/main.yml
---
# Validate requirements
- name: Validate systemd is present
ansible.builtin.command: systemctl --version
changed_when: false
- name: Validate tenant_id is a valid UUID
ansible.builtin.assert:
that:
- onepam_tenant_id | length > 0
- onepam_tenant_id is match('^[0-9a-f]{8}-...')
fail_msg: "onepam_tenant_id must be a valid UUID"
- name: Validate log_level
ansible.builtin.assert:
that:
- onepam_log_level in ['debug', 'info', 'warn', 'error']
- name: Validate group_uuid when provided
ansible.builtin.assert:
that:
- onepam_group_uuid is match('^[0-9a-f]{8}-...')
fail_msg: "onepam_group_uuid must be a valid UUID"
when: onepam_group_uuid | length > 0
# Detect architecture
- name: Detect system architecture
ansible.builtin.set_fact:
onepam_arch: "{{ 'amd64' if ansible_architecture == 'x86_64' else 'arm64' }}"
# Create directories
- name: Create OnePAM directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: root
group: root
mode: "0755"
loop:
- "{{ onepam_install_dir }}"
- "{{ onepam_install_dir }}/bin"
- "{{ onepam_install_dir }}/data"
- "{{ onepam_install_dir }}/etc"
# Download binary with SHA256 checksum verification
- name: Download OnePAM agent binary
ansible.builtin.get_url:
url: "{{ onepam_release_url }}/agent/{{ onepam_agent_version }}/onepam-agent-linux-{{ onepam_arch }}"
checksum: "sha256:{{ onepam_release_url }}/agent/{{ onepam_agent_version }}/onepam-agent-linux-{{ onepam_arch }}.sha256"
dest: "{{ onepam_install_dir }}/bin/onepam-agent"
owner: root
group: root
mode: "0755"
notify: Restart onepam-agent
# Manage agent ID
- name: Check for existing agent ID
ansible.builtin.stat:
path: "{{ onepam_install_dir }}/etc/agent-id"
register: agent_id_file
- name: Read existing agent ID
ansible.builtin.slurp:
src: "{{ onepam_install_dir }}/etc/agent-id"
register: existing_agent_id
when: agent_id_file.stat.exists
- name: Generate new agent ID
ansible.builtin.set_fact:
onepam_agent_id: "{{ lookup('file', '/proc/sys/kernel/random/uuid') }}"
when: not agent_id_file.stat.exists
- name: Use existing agent ID
ansible.builtin.set_fact:
onepam_agent_id: "{{ existing_agent_id.content | b64decode | trim }}"
when: agent_id_file.stat.exists
- name: Save agent ID
ansible.builtin.copy:
content: "{{ onepam_agent_id }}"
dest: "{{ onepam_install_dir }}/etc/agent-id"
owner: root
group: root
mode: "0644"
# Deploy configuration and service
- name: Deploy agent configuration
ansible.builtin.template:
src: agent.env.j2
dest: "{{ onepam_install_dir }}/etc/agent.env"
owner: root
group: root
mode: "0600"
notify: Restart onepam-agent
- name: Deploy systemd service unit
ansible.builtin.template:
src: onepam-agent.service.j2
dest: /etc/systemd/system/onepam-agent.service
owner: root
group: root
mode: "0644"
notify:
- Reload systemd
- Restart onepam-agent
- name: Enable and start OnePAM agent
ansible.builtin.systemd:
name: onepam-agent
enabled: true
state: started
daemon_reload: true
handlers/main.yml
---
- name: Reload systemd
ansible.builtin.systemd:
daemon_reload: true
- name: Restart onepam-agent
ansible.builtin.systemd:
name: onepam-agent
state: restarted
templates/agent.env.j2
# OnePAM Agent Configuration
# Managed by Ansible — do not edit manually
AGENT_API_URL="{{ onepam_server_url }}"
AGENT_TENANT_ID="{{ onepam_tenant_id }}"
AGENT_ID="{{ onepam_agent_id }}"
AGENT_LOG_LEVEL="{{ onepam_log_level }}"
{{% if onepam_group_uuid | length > 0 %}}
AGENT_GROUP_UUID="{{ onepam_group_uuid }}"
{{% endif %}}
templates/onepam-agent.service.j2
[Unit]
Description=OnePAM Agent
Documentation=https://onepam.com/docs
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=0
[Service]
Type=notify
User=root
Group=root
EnvironmentFile=-{{ onepam_install_dir }}/etc/agent.env
ExecStart={{ onepam_install_dir }}/bin/onepam-agent \
--server=${AGENT_API_URL} \
--tenant-id=${AGENT_TENANT_ID} \
--agent-id=${AGENT_ID} \
--data-dir={{ onepam_install_dir }}/data \
--log-level=${AGENT_LOG_LEVEL}
Restart=always
RestartSec=10
TimeoutStartSec=60
TimeoutStopSec=360
WatchdogSec=120
LimitNOFILE=65536
LimitMEMLOCK=infinity
StandardOutput=journal
StandardError=journal
SyslogIdentifier=onepam-agent
[Install]
WantedBy=multi-user.target
Variables Reference
| Variable | Default | Description |
|---|---|---|
onepam_server_url |
https://onepam.com |
OnePAM server URL to connect to |
onepam_tenant_id |
"" (required) |
Organisation UUID (tenant ID) |
onepam_group_uuid |
"" |
Optional group UUID to assign the agent to |
onepam_agent_version |
latest |
Agent version to install |
onepam_log_level |
info |
Logging verbosity (debug, info, warn, error) |
onepam_release_url |
https://updates.onepam.com |
Base URL for agent binary downloads |
onepam_install_dir |
/opt/onepam |
Base installation directory |
Inventory Setup
Organise hosts into groups with group-specific variables:
inventory/hosts
[webservers]
web01.example.com
web02.example.com
[databases]
db01.example.com
db02.example.com
[all:vars]
ansible_user=deploy
ansible_become=true
inventory/group_vars/all.yml
---
onepam_server_url: "https://onepam.example.com"
onepam_tenant_id: "00000000-0000-0000-0000-000000000000"
inventory/group_vars/databases.yml
---
onepam_log_level: "debug"
Playbook Examples
---
- name: Deploy OnePAM agent to all hosts
hosts: all
become: true
roles:
- role: agent
vars:
onepam_server_url: "https://onepam.example.com"
onepam_tenant_id: "00000000-0000-0000-0000-000000000000"
---
- name: Deploy OnePAM to production
hosts: production
become: true
roles:
- role: agent
vars:
onepam_server_url: "https://prod.onepam.example.com"
onepam_tenant_id: "{{ vault_prod_tenant_id }}"
onepam_log_level: "warn"
- name: Deploy OnePAM to staging
hosts: staging
become: true
roles:
- role: agent
vars:
onepam_server_url: "https://staging.onepam.example.com"
onepam_tenant_id: "{{ vault_staging_tenant_id }}"
onepam_log_level: "debug"
Encrypt sensitive values with Ansible Vault:
# Create encrypted vars file
ansible-vault create inventory/group_vars/all/vault.yml
# Contents of vault.yml
vault_onepam_tenant_id: "your-real-tenant-id"
# Reference in playbook
- name: Deploy OnePAM agent
hosts: all
become: true
roles:
- role: agent
vars:
onepam_tenant_id: "{{ vault_onepam_tenant_id }}"
# Run with vault password
# ansible-playbook -i inventory/hosts site.yml --ask-vault-pass
---
- name: Rolling update of OnePAM agent
hosts: all
become: true
serial: "25%"
max_fail_percentage: 10
pre_tasks:
- name: Verify connectivity
ansible.builtin.ping:
roles:
- role: agent
post_tasks:
- name: Verify agent is running
ansible.builtin.systemd:
name: onepam-agent
state: started
register: agent_status
- name: Fail if agent not running
ansible.builtin.assert:
that: agent_status.status.ActiveState == "active"
fail_msg: "OnePAM agent failed to start"
Security Note: Always use Ansible Vault to encrypt sensitive values like
onepam_tenant_id.
Never commit unencrypted secrets to version control.