😸

GitLab Generic Package Registryに配置したバイナリをAnsibleで取得してみた

に公開

はじめに

以前GitHub Releases に登録したバイナリ資材をAnsibleからを取得することを試した。

今回は、GitLabのGeneric Package Registryを使って同じことを実現してみた。


GitLab Generic Package Registryとは

GitLabのPackage Registryは、リポジトリごとに成果物(パッケージ)を管理できる機能だ。
npm・Maven・PyPIなど言語ごとのレジストリも用意されているが、
その中でも「Generic」タイプを使うと、拡張子に縛られず、ZIPなど任意のファイルを登録できる。

(Generic Package Registryに登録されたzipファイルの例)


実装構成

今回は以下の構成で、GitLabのPackage Registryに登録した(GitLab Saasを使用)
sample.zip をAnsibleから取得する。

project-root/
├── inventory/
│   └── hosts.yml              # インベントリ
├── playbook.yml               # 呼び出し元Playbook
└── roles/
    ├── sample/
    │   └── tasks/
    │       └── main.yml       # package_assetを呼び出すタスク
    └── package_asset/
        └── tasks/
            └── main.yml       # GitLabからアセットを取得する共通タスク

Ansibleタスク例

roles/package_asset/tasks/main.yml

- name: Validate vars
  ansible.builtin.assert:
    that:
      - gl_url is defined
      - gl_project_id is defined
      - gl_version is defined
      - gl_asset is defined
      - gl_package_name is defined
      - gl_dest is defined
      - gl_token is defined

- name: Check if asset already exists
  ansible.builtin.stat:
    path: "{{ gl_dest }}"
  register: gl_asset_file

- name: Download asset (binary)
  ansible.builtin.get_url:
    url: "{{ gl_url }}/api/v4/projects/{{ gl_project_id }}/packages/generic/{{ gl_package_name }}/{{ gl_version }}/{{ gl_asset }}"
    headers:
      PRIVATE-TOKEN: "{{ gl_token }}"
    dest: "{{ gl_dest }}"
    owner: "{{ gl_owner | default('root') }}"
    group: "{{ gl_group | default('root') }}"
    mode: "{{ gl_mode | default('0644') }}"
    force: false
    timeout: "{{ gl_timeout | default(120) }}"
    checksum: "{{ gl_checksum | default(omit) }}"  # 任意: "sha256:<HEX>"
  when: not gl_asset_file.stat.exists

呼び出し側 roles/sample/tasks/main.yml

- name: Fetch package asset (GitLab)
  import_role:
    name: package_asset
  vars:
    gl_url: https://gitlab.com
    gl_project_id: 12345678
    gl_version: 0.0.1
    gl_package_name: sample
    gl_asset: sample.zip
    gl_dest: /work/sample.zip
    gl_token: "{{ lookup('env', 'GITLAB_TOKEN') }}"   # PATまたはCI_JOB_TOKEN
  become: true

- name: List files in /work
  ansible.builtin.command: ls -la /work
  register: work_ls

- name: Show listing
  ansible.builtin.debug:
    var: work_ls.stdout_lines

実行例

ansible-playbook -i inventory/hosts.yml playbook.yml

出力結果の一部:

TASK [package_asset : Download asset (binary)] *******************************************
changed: [target_node]

TASK [common : List files in /work] ******************************************************
ok: [target_node] => {
    "work_ls.stdout_lines": [
        "total 20",
        "drwxr-xr-x 2 root root  4096 Oct 19 20:45 .",
        "drwxr-xr-x 1 root root  4096 Oct 15 23:58 ..",
        "-rw-r--r-- 1 root root 11228 Oct 19 20:45 sample.zip"
    ]
}

GitLab上のsample.zip/work/sample.zip に正常に配置されたことが確認できた。


まとめ

  • GitHub Releasesでも同様の管理は可能だが、GitLab Generic Package Registryは任意のバイナリに対応しているため、より柔軟。
  • 認証付きAPIが標準で用意されており、Ansibleのget_urlだけで完結するのが便利。

参考資料

Discussion