# Deploy with Chef

This guide provides a complete Chef cookbook for installing and enrolling LinuxGuard. Credentials are managed with chef-vault, which encrypts data bag items using each node's public key so only authorised nodes can decrypt them. The recipe is idempotent — safe to run on already-enrolled nodes because the enroll resource includes a `not_if` guard on `/var/lib/linuxguard/config`.

## Prerequisites

* Chef Workstation installed on your workstation
* Chef Infra Server with nodes registered and their public keys uploaded
* The `chef-vault` gem available on your workstation (`chef gem install chef-vault` if not already installed)
* A LinuxGuard API key and tenant ID (from the LinuxGuard console)

> **Important:** chef-vault requires Chef Infra Server with public/private key pairs per node. It is not compatible with chef-solo or knife-solo. If you are using chef-solo or chef-zero, use the Chef `secret()` helper (available in Chef Infra Client 17.5+) to integrate with AWS Secrets Manager or Azure Key Vault instead.

## Cookbook Structure

Create the following structure in your Chef repository's `cookbooks/` directory:

```
cookbooks/
└── linuxguard/
    ├── metadata.rb          # Cookbook name, version, description
    ├── attributes/
    │   └── default.rb       # Default attribute values
    └── recipes/
        └── default.rb       # Install, enable, enroll
```

## Step 1: Create the chef-vault Item

Store LinuxGuard credentials in a chef-vault item. The vault encrypts the data bag item using the public keys of the nodes you specify — only those nodes can decrypt it during a Chef run.

Run the following command from your workstation:

```bash
knife vault create linuxguard credentials \
  '{"api_key":"<API_KEY>","tenant_id":"<TENANT_ID>"}' \
  --search "role:linuxguard-node" \
  --admins "admin"
```

* **`--search`** — specifies which nodes should have decryption access. Adjust the search query to match the nodes in your environment (for example, `role:linuxguard-node` or `name:*`).
* **`--admins`** — specifies Chef Server users who can administer the vault item (read, update, delete).

To verify the vault item was created:

```bash
knife vault show linuxguard credentials
```

## Step 2: Create the Cookbook Files

### metadata.rb

```ruby
name             'linuxguard'
maintainer       'Your Organization'
maintainer_email 'ops@example.com'
license          'All Rights Reserved'
description      'Installs and enrolls LinuxGuard agent'
version          '1.0.0'

chef_version '>= 16.0'
```

### attributes/default.rb

```ruby
# Default attributes — override in roles or environments as needed
default['linuxguard']['installer_url'] = 'https://packages.linuxguard.io/install-linuxguard.sh'
```

### recipes/default.rb

```ruby
# Install LinuxGuard agent
execute 'install_linuxguard' do
  command "curl -fsSL #{node['linuxguard']['installer_url']} | bash -s -- --yes"
  not_if { ::File.exist?('/usr/bin/linuxguard-agent') }
end

# Enable and start LinuxGuard service
service 'linuxguard-agent' do
  action [:enable, :start]
end

# Retrieve credentials from chef-vault
linuxguard_creds = chef_vault_item('linuxguard', 'credentials')

# Enroll LinuxGuard agent (idempotent via not_if guard)
execute 'enroll_linuxguard' do
  command lazy {
    "linuxguard-agent enroll " \
    "--api-key=#{linuxguard_creds['api_key']} " \
    "--tenant-id=#{linuxguard_creds['tenant_id']}"
  }
  not_if { ::File.exist?('/var/lib/linuxguard/config') }
  sensitive true
end
```

> **Note:** The `not_if { ::File.exist?('/var/lib/linuxguard/config') }` guard skips enrollment if the agent is already enrolled. The `sensitive true` attribute prevents credentials from appearing in Chef run logs. See [Automated Deployment Overview](/how-to-guides/how-to/automated-deployment.md) for details on the agent's built-in idempotency behavior.

## Step 3: Add the Cookbook to a Run List

Add the cookbook to a node's run list:

```bash
knife node run_list add <NODE_NAME> recipe[linuxguard]
```

Or add `recipe[linuxguard]` to a role's run list so all nodes in that role receive the cookbook automatically:

```bash
knife role edit linuxguard-node
```

Then run the Chef client on the target node to apply the cookbook:

```bash
chef-client
```

## Verifying the Deployment

After the Chef run completes, you can add a verification step to your recipe to confirm the agent is running:

```ruby
# Verify LinuxGuard agent service is running
ruby_block 'verify_linuxguard_running' do
  block do
    status = `systemctl is-active linuxguard-agent`.strip
    raise "LinuxGuard agent is not running (status: #{status})" unless status == 'active'
  end
  only_if { ::File.exist?('/var/lib/linuxguard/config') }
end
```

Enrolled nodes also appear in the **Infrastructure** view of the LinuxGuard console within a few minutes of successful enrollment.

***

**Related**: [Automated Deployment Overview](/how-to-guides/how-to/automated-deployment.md) | [Installation](/how-to-guides/how-to/installation.md) | [Configuration](/how-to-guides/how-to/configuration.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/deploy-with-chef.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.
