🚀
GitHub Releaseに置いたインストーラをAnsibleで取得する方法
はじめに
AnsibleのPlaybookを運用している中で、インストーラやZIPファイルなどのバイナリをどう管理するかが課題になった。
当初は リポジトリ内のfiles/ に直接置いて管理していたが、気づけばリポジトリが数GBを超えるほど肥大化していた。
履歴を含めると clone に時間がかかる。
そこで「バイナリはGitの履歴に含めず、外部に保存・取得する方法」を検討し、GitHub Releasesを使ったバイナリ管理とAnsible連携の方法を試してみた。
GitHub Releasesを用いたバイナリ管理
GitHubには、リリースに紐づけて任意のファイル(最大2GB)をアップロードできる「Releases」機能がある。
GUIから簡単にZIPやインストーラを添付できる。
実装構成
以下のような構成で、GitHubのReleaseに登録したアセット(例: sample.zip)をAnsibleで取得する。
ディレクトリ構成
project-root/
├── inventory/
│ └── hosts.yml # インベントリ
├── playbook.yml # 呼び出し元Playbook
└── roles/
├── sample/
│ └── tasks/
│ └── main.yml # package_assetを呼び出すタスク
└── package_asset/
└── tasks/
└── main.yml # GitHub Releaseからアセットを取得するタスク
Ansibleタスク例
roles/package_asset/tasks/main.yml
- name: Validate vars
ansible.builtin.assert:
that:
- gh_repo is defined
- gh_tag is defined
- gh_asset is defined
- gh_dest is defined
- gh_token is defined
- name: Get release by tag (GitHub API)
ansible.builtin.uri:
url: "https://api.github.com/repos/{{ gh_repo }}/releases/tags/{{ gh_tag }}"
headers:
Authorization: "Bearer {{ gh_token }}"
Accept: "application/vnd.github+json"
return_content: true
register: _rel
- name: Resolve asset id
ansible.builtin.set_fact:
gh_asset_id: "{{ (_rel.json.assets | selectattr('name','equalto', gh_asset) | first).id }}"
failed_when: gh_asset_id is not defined
- name: Download asset (binary)
ansible.builtin.get_url:
url: "https://api.github.com/repos/{{ gh_repo }}/releases/assets/{{ gh_asset_id }}"
headers:
Authorization: "Bearer {{ gh_token }}"
Accept: "application/octet-stream"
dest: "{{ gh_dest }}"
owner: "{{ gh_owner | default('root') }}"
group: "{{ gh_group | default('root') }}"
mode: "{{ gh_mode | default('0644') }}"
force: false
timeout: "{{ gh_timeout | default(120) }}"
checksum: "{{ gh_checksum | default(omit) }}"
呼び出し側 roles/sample/tasks/main.yml
- name: Fetch package asset (GitHub private)
import_role:
name: gh_release_asset
vars:
gh_repo: your-org/your-repo
gh_tag: v1.0.0
gh_asset: sample.zip
gh_dest: /work/sample.zip
gh_token: "{{ lookup('env', 'GITHUB_TOKEN') }}"
become: true
この構成により、GitHub APIを通じて指定のリリースからアセットをダウンロードできる。
Ansibleの copy モジュールを使う感覚で、外部バイナリを任意のディレクトリに配置できるのがポイントだ。
動作確認
ansible-playbook -i inventory/hosts.yml playbook.yml
出力結果の一部:
TASK [gh_release_asset : Download asset (binary)] ******************************
changed: [target_node]
TASK [sample : List files in /work] ********************************************
changed: [target_node]
TASK [sample : Show listing] ********************************************
ok: [target_node] => {
"work_ls.stdout_lines": [
"total 20",
"-rw-r--r-- 1 root root 11228 Oct 16 00:00 sample.zip"
]
}
GitHub Release上のアセットが /work 配下に正常に配置されていることが確認できた。
まとめ
- バイナリをGitリポジトリに直接コミットすると、履歴が膨らんで管理しづらくなる
- GitHub Releaseを使えば、バージョン単位でインストーラを管理しつつ、Ansible内で取得できる
- 完全に万能ではないが、GitHub内で完結する点はシンプルで、用途によっては“使える”構成だと感じた。
もしGitLabを使っている場合は、同様の機能としてGeneric Package Registryも検討できる。
リリース管理+アクセス制御まで一貫して行えるため、より使いやすい印象だ。
📚 参考

Discussion