2023年3月1日
Ansibleでgpg公開鍵とaptのサードパーティリポジトリを追加する ~Terraformをインストールしたい~
apt を使って docker や terraform をインストールする時など、提供元のサードパーティ apt リポジトリを追加する場合が結構ありますよね。その際に、今までは apt-key
を使って OpenPGP 公開鍵をインポートしていたのですが、apt-key
は Debian 11 と Ubuntu 22.04 を最後に使えなくなる ので、今後は gnupg
を使った方法が主流になっていきます。
Ansible にも ansible.builtin.apt_key module がありますが、これは後方互換性のために残されるものの、今後新たに使うのは避けたほうが良いでしょう。
幸い、これからの公開鍵と apt リポジトリの紐づけの方法はとてもシンプルです。
- 公開鍵はどこにおいても OK
/usr/share/keyrings/
に置くことが多そう
deb [signed-by=/path/to/key] ...
と書いたファイルを/etc/apt/sources.list.d
に追加するadd-apt-repository
でも同様
- 公開鍵の形式は
.asc
でも.gpg
でも OK- apt-key が非推奨になったので の記事が参考になります
3点目の公開鍵の形式については、私はそもそも2種類あることを今回初めて知りました。
- バイナリ形式
.gpg
拡張子
- ASCII 形式(armored)
.asc
拡張子
まぁバイナリかテキストエンコードされているかという違いだけですね。インターネットからダウンロードしてくるときは asc になっていて、そのあと dearmor して格納するという手順を Docker および Hashicorp のドキュメントで見つけることができました(いつも意味を理解せずにコマンドを流し込んでいたことを反省)。
成果物
前段が長くなりましたが、今回作っていく Ansible の task は以下の流れになります。
apt update
&& 依存ライブラリのインストール- 公開鍵(
.asc
形式)をダウンロード - 公開鍵のフィンガープリントを検証
- サードパーティ apt リポジトリの追加 &&
apt update
- サードパーティ apt リポジトリからパッケージをインストール
Hashicorp の公開鍵と apt リポジトリを追加して、terraform パッケージをインストールするためのサンプルが下記になります。他のサードパーティ apt リポジトリを追加する場合にも応用が利くかもしれません。
- name: apt cache is updated apt: update_cache: yes cache_valid_time: 3600 when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu' - name: prerequisites are installed package: name: "{{ item }}" state: present with_items: - gnupg - software-properties-common - name: hashicorp gpg key is installed ansible.builtin.get_url: url: https://apt.releases.hashicorp.com/gpg dest: /usr/share/keyrings/hashicorp-archive-keyring.asc - name: hashicorp gpg key is verified command: gpg --dry-run -q --import --import-options import-show /usr/share/keyrings/hashicorp-archive-keyring.asc register: hashicorp_gpg_show_result changed_when: no # MEMO: Check the URL below for the latest fingerprint. # https://www.hashicorp.com/official-packaging-guide failed_when: "'798AEC654E5C15428C8E42EEAA16FCBCA621E701' not in hashicorp_gpg_show_result.stdout" - name: hashicorp repository is added ansible.builtin.apt_repository: repo: deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.asc] https://apt.releases.hashicorp.com {{ ansible_distribution_release }} main filename: hashicorp state: present - name: terraform is installed package: name: terraform state: present
すこし解説
hashicorp gpg key is verified
ではダウンロードした公開鍵が公式のものかどうかをフィンガープリントを比較して検証しています。フィンガープリントは執筆時点(2023/3/1)のものです。
若干気持ち悪い実装な気もするので(とはいえ目視でやっていることと同じだけども)、もっと良い実装を知っている人はぜひ教えてください。。
参考までに gpg --dry-run -q --import --import-options import-show /usr/share/keyrings/hashicorp-archive-keyring.asc
の出力は下記のようになります。
pub rsa4096 2023-01-10 [SC] [expires: 2028-01-09] 798AEC654E5C15428C8E42EEAA16FCBCA621E701 uid HashiCorp Security (HashiCorp Package Signing) <security+packaging@hashicorp.com> sub rsa4096 2023-01-10 [S] [expires: 2028-01-09]
hashicorp repository is added
では signed-by=
でダウンロードした公開鍵のパスを指定することで公開鍵と apt リポジトリを紐づけています。Ansible の ansible_distribution_release
変数を使うことで、コードネーム(jammy とか focal とか bionic とか)を取得することができます(lsb_release -cs
と同等)。
ansible.builtin.apt_repository module
がデフォルトで changed の時に自動で apt update
もしてくれるので明示的に書く必要はありません。
実行結果
PLAY [localhost] ********************************************************************************************************** TASK [Gathering Facts] **************************************************************************************************** ok: [localhost] TASK [apt cache is updated] *********************************************************************************************** ok: [localhost] TASK [prerequisites are installed] **************************************************************************************** ok: [localhost] => (item=gnupg) ok: [localhost] => (item=software-properties-common) TASK [hashicorp gpg key is installed] ************************************************************************************* changed: [localhost] TASK [hashicorp gpg key is verified] ************************************************************************************** ok: [localhost] TASK [hashicorp repository is added] ************************************************************************************** changed: [localhost] TASK [terraform is installed] ********************************************************************************************* changed: [localhost] PLAY RECAP **************************************************************************************************************** localhost : ok=7 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
参考文献
- APT-KEY(8)
- ansible.builtin.apt_key module – Add or remove an apt key
- ansible.builtin.apt_repository module – Add and remove APT repositories
- Official Packaging Guide
- Install Terraform
- Install Docker Engine on Ubuntu
- apt-key が非推奨になったので
- 非推奨となったapt-keyの代わりにsigned-byとgnupgを使う方法
- GnuPG の使用法
- How do I verify an asc key fingerprint?