この記事はエーピーコミュニケーションズAdvent Calendar 2023 17日目の投稿です。
はじめに
Ansible Automation Platform(以下AAPという)環境ではよくGitも併せて利用して様々なデータの保管場所にすることが多いかと思います。
AAPで利用するProjectやInventoryなどはAAPの機能でGUIから参照することができますが、Playbook実行時の作業証跡などを参照したい場合やデータ追加したい場合はPlaybook内で個別操作する必要があります。
Playbook内でGitを操作する方法として、Ansible Tower時代はTowerサーバ内のLinuxユーザがGit権限を持っていればそれを利用することができました。
しかし、AAPになってからはEEを使用するため、Git権限を持つ環境を事前準備する必要が出てきました。
AAPからGit操作する方法としては以下やり方が考えられます。
- AAPでGit接続情報を持ったうえでEEに事前準備してGit操作を行う
- AAPからGit利用できるサーバに接続してそこからgit操作を行う
- EE作成時にGit接続情報を含めてビルドして利用する(EE内に機密情報があるので非推奨)
この中で1つ目のAAPでGit接続情報を持ったうえでEEに事前準備してGit操作を行う
方法を紹介します。
※Gitサーバとの認証方法は大別してHTTPS方式
とSSH方式
がありますがここでは、SSH方式
で説明します。Git操作自体は同じなので認証情報を変えてあげればHTTPS方式
でも対応可能です。
事前準備
SSH認証鍵の作成とGitサーバへの公開鍵登録
事前にTerratermなどでSSH認証鍵ペア(id_rsa.pub
, id_rsa
)を作成して、Gitサーバ側にid_rsa.pub
を登録します。
AAPに秘密鍵登録
次に先ほど作成したSSH秘密鍵(id_rsa
)をAAPの認証情報として利用できるようにします。
秘密鍵用カスタム認証タイプ作成
AAPでは、ソースコントロール
という認証タイプがすでに存在しますが、こちらはAAPシステムがProjectなどを取得するためのもののため、今回は利用できません。
代わりに、カスタム認証タイプを作成します。
カスタム認証タイプで以下内容のものを作成します。
これにより、AAPはJob Template実行時にEEのランダムな場所にSSH秘密鍵情報が記載されたファイルを作成したうえでファイル名をgit_ssh_private_key
変数に格納します。
fields:
- id: ssh_private_key
type: string
label: SSH秘密鍵
secret: true
multiline: true
required:
- ssh_private_key
file:
template.ssh_private_key: '{{ ssh_private_key }}'
extra_vars:
git_ssh_private_key: '{{ tower.filename.ssh_private_key }}'
SSH認証情報オブジェクトを作成
先ほど作成したカスタム認証タイプをもとに認証情報オブジェクトを作成します。
注意点として、秘密鍵フォーマットは最後に空白行が必要なのでコピペする際は最終行までコピーしてください。
私は、ここでうまくいかず苦戦しました。
実行
Playbook
以下作業を行うPlaybookを作成しました。
- Gitアクセス環境の準備
- Git clone
- 適当なファイルを作成
- Git push
Gitアクセス環境の準備では、SSH Configの設定とGitホストのフィンガープリント登録を行っています。
もろもろファイル操作をしていますが、EEが対象だと毎回変更フラグがついてしますのでfailed_when: false
をつけています。
フィンガープリントの追加は、SSH ConfigのところでStrictHostKeyChecking
をつけてもよさそうです。
Git用のモジュールは参照関連のものしかないため、Git commit & Git pushはコマンドモジュールを使っています。
ファイルの内容は以下のとおり。
- name: Git access playbook
hosts: localhost
gather_facts: false
vars:
git_host: <Gitサーバホスト>
git_repo: <レポジトリ名>
git_branch: main
git_dir: ./ansible-test
git_username: Test User
git_email: testuser@local
git_commit_comment: Test Commit
tasks:
- name: Set ssh_config
ansible.builtin.blockinfile:
path: ~/.ssh/config
mode: "0644"
create: true
block: |
Host {{ git_host }}
IdentityFile {{ git_ssh_private_key }}
- name: Get git host fingerprints
ansible.builtin.command: "ssh-keyscan -H {{ git_host }}"
register: ssh_keyscan_result
changed_when: false
- name: Set known_hosts
ansible.builtin.lineinfile:
path: ~/.ssh/known_hosts
mode: "0644"
create: true
line: "{{ item }}"
loop: "{{ ssh_keyscan_result.stdout_lines }}"
changed_when: false
- name: Clone git repository
ansible.builtin.git:
repo: "git@{{ git_host }}:{{ git_repo }}"
dest: "{{ git_dir }}"
version: "{{ git_branch }}"
- name: Set git_config
community.general.git_config:
repo: "{{ git_dir }}"
scope: local
name: "{{ item.name }}"
value: "{{ item.value }}"
loop:
- name: user.name
value: "{{ git_username }}"
- name: user.email
value: "{{ git_email }}"
changed_when: false
- name: Create test file
ansible.builtin.copy:
content: "{{ now() }}"
dest: "{{ git_dir }}/test"
mode: "0644"
- name: Execute git add all files
ansible.builtin.command: "git add -A -v"
args:
chdir: "{{ git_dir }}"
register: git_add_result
changed_when: git_add_result.stdout | length > 0
- name: Check respository is changed
ansible.builtin.command: "git diff --staged --name-only"
args:
chdir: "{{ git_dir }}"
register: git_diff_result
changed_when: false
- name: Set is_changed
ansible.builtin.set_fact:
is_changed: "{{ git_diff_result.stdout | length > 0 }}"
- name: Execute git commit
ansible.builtin.command: "git commit -m '{{ git_commit_comment }}'"
args:
chdir: "{{ git_dir }}"
changed_when: true
when:
- is_changed
- name: Execute git push
ansible.builtin.command: "git push"
args:
chdir: "{{ git_dir }}"
changed_when: true
when:
- is_changed
Job Template
Job Templateには、前述のPlaybookと認証情報をいれます。
これを実行することでPlaybook内でGit認証情報を受け取ってGit操作をすることができます。
まとめ
今更なネタではあるのですが、なかなか例が見当たらなかったため投稿しました。
認証情報をAAP側で制御することができるので検証・本番でSSH鍵を使い分けることができ置き換えも楽にすることができます。
案件で使う場合はGit push、Git pull用のRoleを作っておくことでメンテナンスしやすく再利用性が高くなるためおすすめです。
参考リンク