# Automated Deployment

Deploying LinuxGuard at scale requires automation — scripts or configuration management tools that install and enroll agents without manual intervention on each host. Two cross-cutting concerns apply regardless of which tool you use: **idempotency** (the deployment is safe to run multiple times without side effects) and **secrets management** (API keys and tenant IDs are never hardcoded in scripts or version control).

## Choosing a Deployment Method

Select the deployment method that fits your existing infrastructure and tooling:

| Tool                   | Best for                                                  | Secrets pattern                        | Idempotency mechanism                                            |
| ---------------------- | --------------------------------------------------------- | -------------------------------------- | ---------------------------------------------------------------- |
| Ansible                | Existing Ansible inventory, mixed environments            | Ansible Vault (`encrypt_string`)       | `args: creates:` file guard on enroll task                       |
| AWS EC2 User-Data      | EC2 instances launched via Auto Scaling or CloudFormation | IAM instance profile + Secrets Manager | Agent built-in guard (user-data runs once on launch)             |
| GCP Startup Script     | Compute Engine VMs in GCP projects                        | Service account + Secret Manager       | Explicit file guard required (startup scripts run on every boot) |
| Azure cloud-init / CSE | Azure VMs, including VMSS and ARM template deployments    | Managed Identity + Key Vault           | Agent built-in guard                                             |
| Chef                   | Existing Chef infrastructure with Chef Infra Server       | chef-vault                             | `not_if` file guard on enroll resource                           |
| Puppet                 | Existing Puppet infrastructure with PuppetDB              | Hiera with eyaml encryption            | `unless` file guard on enroll exec                               |

> **Where to start:** Already using a configuration management platform? Start with [Ansible](/how-to-guides/how-to/automated-deployment/deploy-with-ansible.md), [Chef](/how-to-guides/how-to/automated-deployment/deploy-with-chef.md), or [Puppet](/how-to-guides/how-to/automated-deployment/deploy-with-puppet.md). Deploying new cloud VMs? Use your cloud provider's native script method: [AWS](/how-to-guides/how-to/automated-deployment/deploy-with-aws-userdata.md), [GCP](/how-to-guides/how-to/automated-deployment/deploy-with-gcp-startup.md), or [Azure](/how-to-guides/how-to/automated-deployment/deploy-with-azure.md).

## Enrollment Idempotency

The `linuxguard-agent enroll` command is safe to call on an already-enrolled server. On startup, the agent checks its own configuration: if `/var/lib/linuxguard/config` exists and contains a valid server ID, it prints "Server is already enrolled" and exits with code 0. No duplicate enrollment occurs.

```
/var/lib/linuxguard/config
```

This file is written on successful enrollment. Its existence is the reliable enrollment indicator used by configuration management tool guards.

> **Note:** Cloud scripts (AWS, GCP, Azure) rely on the agent's built-in guard as the primary protection. CM tools (Ansible, Chef, Puppet) additionally use a file existence check on `/var/lib/linuxguard/config` as the `when`/`not_if`/`unless` condition — this produces a clean convergence run with no spurious "changed" output when the agent is already enrolled.

## Prerequisites

* A LinuxGuard API key and tenant ID (from the LinuxGuard console)
* Network access from target hosts to `packages.linuxguard.io` for installation
* Tool-specific prerequisites are documented in each individual guide

***

**Related**: [Installation](/how-to-guides/how-to/installation.md) | [Deploy with Ansible](/how-to-guides/how-to/automated-deployment/deploy-with-ansible.md) | [Deploy with AWS EC2 User-Data](/how-to-guides/how-to/automated-deployment/deploy-with-aws-userdata.md) | [Deploy with GCP Startup Script](/how-to-guides/how-to/automated-deployment/deploy-with-gcp-startup.md) | [Deploy with Azure](/how-to-guides/how-to/automated-deployment/deploy-with-azure.md) | [Deploy with Chef](/how-to-guides/how-to/automated-deployment/deploy-with-chef.md) | [Deploy with Puppet](/how-to-guides/how-to/automated-deployment/deploy-with-puppet.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.linuxguard.io/how-to-guides/how-to/automated-deployment.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
