# Ansible で Device Protection をデプロイする

SSH 経由でプッシュする Linux フリート全体に、Ansible を使って Device Protection をインストールします。以下のロールは各ホストに適したパッケージを選択し、ユーザーグループトークンを使ってインストールし、サービスを有効化された状態にします。

まず [Install Device Protection for Linux](https://help.aikidogov.us/docs/docs-ja/aikido-device-protection/deploying-aikido-endpoint/device-protection-mdm-guides/linux/install-device-protection-for-linux) を読んで、すべての方法で共通して使用するトークン、パッケージ、インストールオプションを確認してください。その他の内容（トークンの扱い、再起動、繰り返し実行、デバイス ID）は [Linux Rollout Reference](https://help.aikidogov.us/docs/docs-ja/aikido-device-protection/deploying-aikido-endpoint/device-protection-mdm-guides/linux/linux-rollout-reference) で説明しています。

## ロールの構成

```
roles/aikido_device_protection/
├── defaults/main.yml
├── handlers/main.yml
└── tasks/main.yml
group_vars/
└── developer_workstations.yml
site.yml
```

## ロールをセットアップする

{% stepper %}
{% step %}
**デフォルト値を追加する**

{% code title="roles/aikido_device_protection/defaults/main.yml" %}
```yaml
---
aikido_release_url: https://github.com/AikidoSec/safechain-internals/releases/latest/download

# Reboot after installing. Off by default, see step 3.
aikido_reboot: false
```
{% endcode %}
{% endstep %}

{% step %}
**タスクを追加する**

最初のタスクで実行すべき処理があるかどうかを判定するため、繰り返し実行しても負荷は小さく、トークンに触れることもありません。

{% code title="roles/aikido_device_protection/tasks/main.yml" %}
```yaml
---
- name: Check whether Device Protection is already installed
  ansible.builtin.command: aikidoctl --simple
  register: aikido_installed
  changed_when: false
  failed_when: false

- name: Install Device Protection
  when: aikido_installed.rc != 0
  block:
    - name: Work out the package architecture
      ansible.builtin.set_fact:
        aikido_arch: "{{ 'arm64' if ansible_facts['architecture'] == 'aarch64' else 'amd64' }}"

    - name: Work out the package name
      ansible.builtin.set_fact:
        aikido_package: >-
          {{
            'EndpointProtection-' ~ aikido_arch ~ '.deb'
            if ansible_facts['os_family'] == 'Debian'
            else 'EndpointProtection-' ~ aikido_arch ~ '.el'
                 ~ ansible_facts['distribution_major_version'] ~ '.rpm'
          }}

    - name: Download the package
      ansible.builtin.get_url:
        url: "{{ aikido_release_url }}/{{ aikido_package }}"
        dest: "/tmp/{{ aikido_package }}"
        mode: "0600"

    - name: Install the package on Debian and Ubuntu
      ansible.builtin.apt:
        deb: "/tmp/{{ aikido_package }}"
      environment:
        AIKIDO_TOKEN: "{{ aikido_token }}"
      no_log: true
      when: ansible_facts['os_family'] == 'Debian'
      notify: Reboot to activate Device Protection

    - name: Install the package on RHEL, Rocky Linux and CentOS
      ansible.builtin.dnf:
        name: "/tmp/{{ aikido_package }}"
        state: present
      environment:
        AIKIDO_TOKEN: "{{ aikido_token }}"
      no_log: true
      when: ansible_facts['os_family'] == 'RedHat'
      notify: Reboot to activate Device Protection

    - name: Remove the downloaded package
      ansible.builtin.file:
        path: "/tmp/{{ aikido_package }}"
        state: absent

- name: Make sure the service is enabled and running
  ansible.builtin.systemd_service:
    name: aikido-endpoint-protection
    state: started
    enabled: true
```
{% endcode %}

ロールで必要となるため、`gather_facts` は有効のままにしてください。`el9` と `el10` のどちらのビルドを使うかは `distribution_major_version` によって決まります。Amazon Linux 2023 は `2023` を返すため、使用している場合は `el9` にマッピングしてください。

`environment` キーワードによって[トークンがインストールに渡され](https://help.aikidogov.us/docs/docs-ja/aikido-device-protection/deploying-aikido-endpoint/device-protection-mdm-guides/linux/linux-rollout-reference#how-the-token-reaches-the-package)、`no_log: true` によってトークンがプレイの出力に表示されなくなります。
{% endstep %}

{% step %}
**再起動ハンドラーを追加する**

{% code title="roles/aikido_device_protection/handlers/main.yml" %}
```yaml
---
- name: Reboot to activate Device Protection
  ansible.builtin.reboot:
    reboot_timeout: 600
    msg: Rebooting to activate Aikido Device Protection
  when: aikido_reboot | bool
```
{% endcode %}

誰も作業していないホストでは `aikido_reboot: true` を設定してください。開発者のマシンでは無効のままにし、ユーザーに一度ログアウトして再ログインするよう依頼してください。[When protection becomes active](https://help.aikidogov.us/docs/docs-ja/aikido-device-protection/deploying-aikido-endpoint/device-protection-mdm-guides/linux/linux-rollout-reference#when-protection-becomes-active) を参照してください。
{% endstep %}

{% step %}
**トークンを Ansible Vault に保存する**

Aikido のユーザーグループに対応するインベントリグループ用にトークンを暗号化します:

{% code overflow="wrap" %}
```bash
ansible-vault encrypt_string --name aikido_token '<your-token>'
```
{% endcode %}

出力をグループの変数に貼り付けます:

{% code title="group_vars/developer_workstations.yml" %}
```yaml
---
aikido_token: !vault |
  $ANSIBLE_VAULT;1.1;AES256
  62313365396662343061393464336163383764373764613633653634306231386433626436623361
  ...
```
{% endcode %}

複数のユーザーグループを使用する場合は、グループごとに繰り返してください。各グループには専用のトークンと専用の `group_vars` ファイルを用意します。

{% hint style="info" %}
トークンがすでに CI シークレットに保存されている場合は、Vault で暗号化したコピーをコミットする代わりに、コントローラーの環境変数から読み込んでください: `aikido_token: "{{ lookup('env', 'AIKIDO_TOKEN') }}"`。
{% endhint %}
{% endstep %}

{% step %}
**Playbook を作成して実行する**

{% code title="site.yml" %}
```yaml
---
- name: Deploy Aikido Device Protection
  hosts: developer_workstations
  become: true
  serial: 20%
  roles:
    - aikido_device_protection
```
{% endcode %}

まず少数のマシンで実行し、その後対象を広げます:

{% code overflow="wrap" %}
```bash
ansible-playbook site.yml --ask-vault-pass --limit pilot
ansible-playbook site.yml --ask-vault-pass
```
{% endcode %}
{% endstep %}
{% endstepper %}

## ロールアウトを確認する

{% code overflow="wrap" %}
```bash
ansible developer_workstations -m command -a "aikidoctl --simple"
ansible developer_workstations -b -m command -a "systemctl is-active aikido-endpoint-protection"
```
{% endcode %}

その後、デバイスが [デバイス一覧](https://app.aikido.dev/endpoint-protection/devices) に **Active** ステータスで表示されます。

## トラブルシューティング


| 問題                                                                                  | 対処法                                                                                                                                                                                                                                             |
| ---------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| パッケージはインストールされるが、デバイスがダッシュボードに表示されない                       | インストールコマンドに `AIKIDO_TOKEN` が設定されていませんでした。構成管理ツールはローカル環境をホストに転送しないため、タスク自体に変数を設定してから、パッケージを再度インストールしてください                                    |
| `apt` または `dnf` がファイルをインストールせず、リポジトリ内でパッケージを探してしまう | 名前ではなくパスを指定してください: `apt install ./EndpointProtection-amd64.deb`。先頭の `./` によって、パッケージマネージャーはそれをローカルファイルとして扱います                                                                                              |
| Red Hat 系のホストでインストールが失敗する                                               | ビルドをメジャーバージョンに合わせてください。バージョン 9 では `el9` パッケージを、バージョン 10 では `el10` パッケージを使用します                                                                                                                                   |
| サービスが実行されていない                                                               | `systemctl status aikido-endpoint-protection` を実行し、次に `sudo aikidoctl diagnostics` を実行して詳細を送信してください                                                                                                                                 |
| Node.js または uv が依然として Aikido 証明書を拒否する                                        | インストール時に `NODE_EXTRA_CA_CERTS` と `UV_SYSTEM_CERTS` がシステム全体に設定されますが、実行中のシェルにはこれらが反映されません。新しいログインシェルを開くか、デバイスを再起動してください                                                                                    |
| トークンが実行出力やログに表示される                                                 | ツールのマスキング機能を使用してください: Ansible では `no_log`、Chef では `sensitive true`、Puppet では `Sensitive()`                                                                                                                                               |
| 複数のマシンがデバイス一覧で 1 つのエントリを共有している                                      | それらのマシンは同じ `/etc/machine-id` で起動しています。Linux のデバイス ID はこのファイルに基づくため、クローン元のイメージでこのファイルをクリアし、初回起動時に systemd に新しいものを書き込ませてください                                                                |
| トレイアイコンが表示されない                                                                     | Ubuntu 以外の GNOME では想定どおりの動作であり、見た目上の問題にすぎません。[Tray Icon Support on Linux](https://help.aikidogov.us/docs/docs-ja/aikido-device-protection/deploying-aikido-endpoint/device-protection-mdm-guides/linux/install-device-protection-for-linux/tray-icon-support-on-linux) を参照してください |
