tech.guitarrapc.cóm

Technical updates

Ansibleでaquaツールをグローバルにインストールする

前回の記事でWSL Ubuntu環境のツールインストールをaquaにした経緯をメモしました。

Ubuntu環境のCLIツールをasdfからaquaに移行した話

今回はAnsibleでローカル環境を構成するときにaquaをどのように構成しているのかメモです。

Ansibleでaquaツールをグローバルにインストールする

私はWSLにUbuntu環境をAnsibleで構成しています。具体的には、aqua.yamlをグローバルコンフィグとして配置し、Ansibleでaquaグローバルツールをインストールします。

  1. dotfilesでaqua.yamlのグローバルツールを定義
  2. Ansibleでdotfilesを展開
  3. Ansibleでaquaツール定義に沿ってグローバルにインストール

具体的な構成を見ていきます。

dotfilesでaqua.yamlのグローバルツール定義

グローバルで使いたいツールをaqua.yamlに定義してdotifile/guitarrapcに保持しています。HOME/.config/aquaproj-aqua/aqua.yamlは次のように、グローバルで使いたいツールを定義しています。この定義は他のマシンでも同じように使えるので

ツールのアップグレードはこの定義を更新&git pushするのですが、dotfiles管理+Ansible展開しているので他マシンも同様に展開されます。

構成を抜き出すと次の流れになります。

---
# aqua - Declarative CLI Version Manager
# https://aquaproj.github.io/
# checksum:
#   enabled: true
#   require_checksum: true
#   supported_envs:
#   - all
registries:
  - type: standard
    ref: v4.219.0 # renovate: depName=aquaproj/aqua-registry
# see packages for https://github.com/aquaproj/aqua-registry or `aqua g`
# * Add package by `aqua g -i -o HOME/.config/aquaproj-aqua/aqua.yaml <pacakge>`
#   * Use `--ping` to install specific version
# * Update package by `pushd HOME/.config/aquaproj-aqua/ && aqua update && popd`
# * update all packlages via `aqua -c $AQUA_GLOBAL_CONFIG update --limit 10`
packages:
  - name: argoproj/argo-cd@v2.13.3
  - name: argoproj/argo-rollouts@v1.7.2
  - name: aws/aws-cli@2.22.29
  - name: 99designs/aws-vault@v7.2.0
  - name: biomejs/biome@cli/v1.9.4
  - name: codesenberg/bombardier@v1.2.6
  - name: fujiwara/cfft@v0.8.2
  - name: CircleCI-Public/circleci-cli@v0.1.31151
  - name: cli/cli@v2.65.0
  - name: open-policy-agent/conftest@v0.56.0
  - name: bcicen/ctop@v0.7.7
  - name: direnv/direnv@v2.35.0
  - name: homeport/dyff@v1.9.4
  - name: awslabs/eks-node-viewer@v0.7.1
  - name: eksctl-io/eksctl@v0.199.0
  - name: grpc-ecosystem/grpc-health-probe@v0.4.36
  - name: fullstorydev/grpcurl@v1.9.2
  - name: helm/helm@v3.16.4
  - name: ynqa/jnv@v0.5.0
  - name: zegl/kube-score@v1.19.0
  - name: kubernetes/kubectl
    version: v1.31.0
  - name: yannh/kubeconform@v0.6.7
  - name: kubernetes-sigs/kustomize@kustomize/v5.5.0
  - name: jesseduffield/lazygit@v0.44.1
  - name: nodejs/node@v23.5.0
  - name: peco/peco@v0.5.11
  - name: FairwindsOps/pluto@v5.21.1
  - name: pulumi/pulumi@v3.144.1
  - name: koalaman/shellcheck@v0.10.0
  - name: getsops/sops@v3.9.3
  - name: stern/stern@v1.31.0
  - name: tofuutils/tenv@v4.1.0
  - name: terraform-docs/terraform-docs@v0.19.0
  - name: GoogleCloudPlatform/terraformer@0.8.24
  - name: terraform-linters/tflint@v0.54.0
  - name: aquasecurity/trivy@v0.57.0
  - name: mikefarah/yq@v4.44.3
  - name: smallstep/cli@v0.28.0

Ansibleロールでdotfilesを展開

Ansibleのroleでdotfilesをインストールするタスクを定義しています。Ansibleを使ってdotfilesを展開することで、Ansibleを実行するだけでどのUbuntu環境でも同じ環境を再現できます。

Ansibleのdotfilesロールは次のように、dotfilesのinstall.shを実行しています。dotfilesインストールをトリガーすると、HOME/.config/aquaproj-aqua/aqua.yaml$HOME/.config/aquaproj-aqua/aqua.yamlにシンボリックリンクで展開されます。

# envs/ubuntu/roles/dotfiles/tasks/main.yml
# https://github.com/guitarrapc/local-provisioner/blob/f1462e9f36be10815ca101c791ab1a7d3098a6fa/envs/ubuntu/roles/dotfiles/tasks/main.yml
- name: "Install dotfiles"
  ansible.builtin.include_tasks: ../include_role/all/install_dotfiles.yaml
  with_items: "{{ dotfiles }}"
  loop_control:
    loop_var: args

# envs/ubuntu/roles/dotfiles/vars/main.yml
# https://github.com/guitarrapc/local-provisioner/blob/f1462e9f36be10815ca101c791ab1a7d3098a6fa/envs/ubuntu/roles/dotfiles/vars/main.yml
dotfiles:
  - repository: "https://github.com/guitarrapc/dotfiles-linux.git"
    clone_destination: "{{ ansible_home }}/github/guitarrapc/dotfiles-linux"
    run_command: "bash ./install.sh --force y"

# envs/include_role/all/install_dotfiles.yaml
# https://github.com/guitarrapc/local-provisioner/blob/f1462e9f36be10815ca101c791ab1a7d3098a6fa/envs/include_role/all/install_dotfiles.yaml
- name: "dotfiles - create github directory"
  ansible.builtin.file:
    path: "{{ args.clone_destination }}"
    state: directory
    mode: "0755"

- name: "dotfiles - clone & Fetch"
  ansible.builtin.git:
    repo: "{{ args.repository }}"
    dest: "{{ args.clone_destination }}"

- name: "dotfiles - create symlinks"
  become: true
  become_user: "{{ ansible_user_id }}"
  ansible.builtin.command: "{{ args.run_command }}"
  args:
    chdir: "{{ args.clone_destination }}"
  register: install_dotfiles
  changed_when: install_dotfiles.rc != 0
  when: not ansible_check_mode

Ansibleでaquaツール定義に沿ってグローバルにインストール

Ansibleのroleでaquaをインストールするタスクを定義しています。dotfilesで展開されたaqua定義をグローバルにインストールします。これでdotfileseに更新があっても、Ansibleを再実行すると最新の環境に更新されます。

AnsibleのaquaロールはInstall tools globally | aquaに沿って、AQUA_GLOBAL_CONFIG環境変数を定義してからaqua i -aを利用しています。

# envs/ubuntu/roles/tools/tasks/main.yml
# https://github.com/guitarrapc/local-provisioner/blob/f1462e9f36be10815ca101c791ab1a7d3098a6fa/envs/ubuntu/roles/tools/tasks/main.yml#L49-L51
- name: "aqua - Install aqua global tools"
  ansible.builtin.include_tasks: ../include_role/ubuntu/install_aqua.yaml
  when: feature_enabed.aqua == "true"

# envs/ubuntu/roles/tools/vars/main.yml
# https://github.com/guitarrapc/local-provisioner/blob/f1462e9f36be10815ca101c791ab1a7d3098a6fa/envs/ubuntu/roles/tools/vars/main.yml#L1C1-L14C20
feature_enabed:
  aqua: "true"
  # 他の値は省略

# envs/include_role/ubuntu/install_aqua.yaml
# https://github.com/guitarrapc/local-provisioner/blob/f1462e9f36be10815ca101c791ab1a7d3098a6fa/envs/include_role/ubuntu/install_aqua.yaml
- name: "aqua - install tools (global)"
  ansible.builtin.command: aqua i -a
  args:
    chdir: "{{ ansible_home }}/"
  environment:
    AQUA_GLOBAL_CONFIG: "{{ aqua.global_path }}"
  register: install_aqua_globaltools
  changed_when: install_aqua_globaltools.rc != 0

- name: "aqua - list global tools"
  ansible.builtin.command: aqua list -a -installed
  register: list_aqua_globaltools
  changed_when: false

まとめ

ツール定義をdotfilesに分離しているのはdotfilesを使っている人ならあるあるかじゃないでしょうか。aqua定義をローカルではなくdotfilesで管理すると「異なるマシンでも同じ定義を簡単に展開」できます。ローカル環境をクリーンアップしやすいWSLを前提にすると、Git管理されていないローカルのaqua.yamlはやりたいことと管理でコンセプトが一致しないんですよね。

Ansible+dotfilesを使ったツールの管理は、aquaに限らず多くのツール導入で有効なので、ここ数年使っている限りでは結構おすすめです。 いいやり方があれば教えてください。