4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AnsibleAdvent Calendar 2021

Day 17

GitLab の private repository を ansible-galaxy collection install する

Last updated at Posted at 2021-12-16

こんにちは。
初めまして Ansible アドベントカレンダー :a: :sparkles:

TL;DR

  1. roles のあるリポジトリ(たとえば https://gitlab.com/hogehoge/hoge.git)、に galaxy.yml を作成する

    galaxy.yml
    namespace: "hello"
    name: "world"
    version: "1.0.0"
    readme: "README.md"
    <略>
    
  2. read_apiとread_repository権限のついた、gitlab Personal Access Tokenを作る

  3. ~/.netrc を作る

    .netrc
    machine gitlab.com
      login yourname@gitlab.com
      password yourpersonalaccesstoken
    
  4. playbook があるリポジトリで requirements.yml を書く

    requirements.yml
    ---
    collections:
    - name: https://gitlab.com/hogehoge/hoge.git
      type: git
      version: 1.0.0 # あるいは branch 名などでもOK
    
  5. ansible-galaxy collection install -r ./requirements.yml する

  6. playbook の中で collection の roles を参照する

    playbook.yaml
    ---
    - hosts:
        - some_host
      become: true
      collections:
        - hello.world
      roles:
        - japanese/konnichiwa_sekai
    
  7. ansible playbook ... すると実行できます :tada:

はじめに

我々のチームでは、ansible スクリプトをチーム内で細々と運用管理してきました。
これまでは、ansible で設定が必要な VM も少なく、公式ベストプラクティスで示される Playbooks のディレクトリ構成の1つのリポジトリに全て突っ込んでいて、特に不自由はありませんでした。

ところが、今年に入ってから ansible で設定(もしくはコンテナをデプロイするなど)したい VM 群が急増し、モノリポでの運用が難しくなってきました。これまでの VM とは用途が異なるものが追加され、inventories はきちんと分けたいけど、これまで作ってきた roles は共有したいというシチュエーションがありました。
また、 ansible-playbook --check によるいわゆるドライランや、場合によってはデプロイも CICD パイプラインから実施しており、VM 数が増えたことで、パイプラインのコントロールが難しくなったことも、リポジトリを分割したい要因でした。

やりたいこと

roles内もさまざまなカテゴリーのものが入り乱れていたため、下記の方針を立てました。

  • roles 側のリポジトリ
    • roles は再利用性を高め、専用のリポジトリに分ける
      • アプリ開発におけるライブラリ的な位置付け
    • コンテナを操作したりアプリケーションをデプロイするものと、マシンをセットアップする系はリポジトリを分ける
      • メンテナンス頻度や、メンテナそのものが異なる可能性も考慮して
  • playbook 側のリポジトリ
    • roles を参照する playbook は、マシンの用途に応じてリポジトリを分ける
    • playbook リポジトリからは、roles リポジトリを git tag で参照できると良い
    • もちろん、CICD パイプラインからも roles リポジトリを参照できないといけない

やったこと

お待たせしました。本題です。
我々は、開発にGitLabのプライベートリポジトリを使用しているので、GitLab上の Ansible Playbook リポジトリから、別プライベートリポジトリにある、roles を参照しなくてはなりません。
以前、「gitlab の private repository を go get する」という記事を書きましたが、やらなければいけないことはほとんど同じでした。

roles collection リポジトリ設定

まず、既存のモノリポから roles を引き離し、分類して、それぞれ collection として公式のドキュメントに従って、構成し直しました。

hoge.git/
├── docs/
├── galaxy.yml
├── README.md
├── roles/
│   ├── role1/
│   ├── role2/
│   └── .../
└── tests/

この時、 galaxy.yml にはここにあるパラメータを含めることができます。
例えば、下記のような collection だと、 インストール後に ansible-galaxy collection list を実行した際に、 hello.world 1.0.0 という表示になります。

namespace: "hello"
name: "world"
version: "1.0.0"
readme: "README.md"
<略>

collection 側の設定はこれで全てです。

playbook リポジトリ設定

この collection をローカル環境にインストールすることで、playbook 側で参照できるようになります。
プライベートリポジトリにある collection をローカルにインストールするには、認証を行う必要があるのですが、それは ~/.netrc ファイルを作成することで可能になります。GitLab リポジトリの場合、gitlab Personal Access Tokenを使用して、下記のようなファイルを作成します。

.netrc
machine gitlab.com
  login yourname@gitlab.com
  password yourpersonalaccesstoken

実際にインストールできるか確かめてみましょう。
例えば下記のコマンドの場合、git+ で明示的に git リポジトリからのインストールであることを指し、, 以降はブランチ名やタグ名が指定できます。他にもさまざまな形式がサポートされています。
この例の場合、https://gitlab.com/hogehoge/hoge.git という git リポジトリの dev ブランチをインストールしています。

ansible-galaxy collection install git+https://gitlab.com/hogehoge/hoge.git,dev

hello.world:1.0.0 was installed successfully というように出力されれば OK です。インストールした collection は ~/.ansible/collections/ansible_collections に配置されていました。

複数の roles collection をインストールする場合、コマンドを羅列する必要はありません。
playbook 側のリポジトリに、requirements.yml という yaml ファイルを作成し、下記のコマンドを実行することで、一括インストールすることができます。

ansible-galaxy collection install -r ./requirements.yml

このとき、 requirements.yml には下記のような内容を記述します。先ほどコマンドで指定した内容が記載されます。

requirements.yml
---
collections:
- name: https://gitlab.com/hogehoge/hoge.git
  type: git
  version: 1.0.0 # あるいは branch 名などでもOK

こちらも先ほどと同様に hello.world:1.0.0 was installed successfully というように出力されれば OK です。

最後に、playbook の中で、インストールした roles を使う宣言を書きます。
たとえば下記のように collections に先ほどインストールした collection 名を指定し、roles では、collection 側リポジトリの rols/ ディレクトリ配下のパスを記述します。

playbook.yaml
---
- hosts:
    - some_host
  become: true
  collections:
    - hello.world
  roles:
    - japanese/konnichiwa_sekai

これで、晴れて collections リポジトリの roles を参照して、playbook が実行できるようになりました :tada:

おまけ - CICD パイプラインでの collection インストール

GitLab CICDする際に、動的に collection をインストールするには、下記のように、.gitlab-ci.yml 内で、.netrc ファイルを作成します。
このときの認証情報には、${CI_JOB_TOKEN} という runner によって事前に定義された環境変数が使用できます。

.gitlab-ci.yml
ansible-play:
  stage: deploy
  image: your.registry/ansible:4.9.0
  script:
    - |
      cat <<EOL >> $HOME/.netrc
      machine gitlab.com
        login gitlab-ci-token
        password ${CI_JOB_TOKEN}
      EOL
    - ansible-galaxy collection install -r ./requirements.yml
    - ansible-playbook playbook.yml -i inventories/inventory.yml -u user -D

まとめ

これまで、いわゆる Go や Python などのアプリケーションでは、ライブラリの配布方法や、その形態などを考えることが多かったのですが、ansible でもいい感じに再利用可能な package 配布の仕組みを構築することができました :sparkles:
学び :relaxed:

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?