AnsibleでGoをインストールするのにansible.builtin.apt_repository
を使ってppaをインストールしていたのですが、Ubuntu 24.04からはエラーが出るようになりました。
ということで対処メモ。
Ansible処理変更前
当初はansible.builtin.apt_repository
を使っていましたが、ここでエラーが出ます。
- name: "go - Add ppa:longsleep/golang-backports ppa repository" become: true ansible.builtin.apt_repository: repo: ppa:longsleep/golang-backports state: present - name: "go - Install go" become: true ansible.builtin.apt: name: "golang-{{ go.version }}" state: latest update_cache: true register: apt until: "apt is not failed" retries: 2
エラーメッセージ
fatal: [localhost]: FAILED! => {"changed": false, "cmd": "/usr/bin/apt-key adv --recv-keys --no-tty --keyserver hkp://keyserver.ubuntu.com:80 876B22BA887CA91614B5323FC631127F87FA12D1", "msg": "Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).\ngpg: key C631127F87FA12D1: public key \"Launchpad PPA for Simon Eisenmann\" imported\ngpg: can't connect to the gpg-agent: IPC connect call failed\ngpg: Total number processed: 1\ngpg: imported: 1", "rc": 2, "stderr": "Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).\ngpg: key C631127F87FA12D1: public key \"Launchpad PPA for Simon Eisenmann\" imported\ngpg: can't connect to the gpg-agent: IPC connect call failed\ngpg: Total number processed: 1\ngpg: imported: 1\n", "stderr_lines": ["Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).", "gpg: key C631127F87FA12D1: public key \"Launchpad PPA for Simon Eisenmann\" imported", "gpg: can't connect to the gpg-agent: IPC connect call failed", "gpg: Total number processed: 1", "gpg: imported: 1"], "stdout": "Executing: /tmp/apt-key-gpghome.swW3tIZwgo/gpg.1.sh --recv-keys --no-tty --keyserver hkp://keyserver.ubuntu.com:80 876B22BA887CA91614B5323FC631127F87FA12D1\n", "stdout_lines": ["Executing: /tmp/apt-key-gpghome.swW3tIZwgo/gpg.1.sh --recv-keys --no-tty --keyserver hkp://keyserver.ubuntu.com:80 876B22BA887CA91614B5323FC631127F87FA12D1"]}
Ansible処理変更後
ansible.builtin.apt_key
を使ってキーを管理して、リポジトリ定義をdeb形式に変更すれば解決です。なるほど、apt-keyが非推奨確定。
- name: "go - Add Golang PPA GPG key" become: true ansible.builtin.apt_key: id: "C631127F87FA12D1" keyserver: "keyserver.ubuntu.com" keyring: /etc/apt/trusted.gpg.d/longsleep.gpg state: present - name: "go - Add Golang PPA repository with keyring" become: true ansible.builtin.apt_repository: repo: "deb [signed-by=/etc/apt/trusted.gpg.d/longsleep.gpg] http://ppa.launchpad.net/longsleep/golang-backports/ubuntu {{ ansible_distribution_release }} main" filename: "longsleep-golang-backports" state: present - name: "go - Install go" become: true ansible.builtin.apt: name: "golang-{{ go.version }}" state: latest update_cache: true register: apt until: "apt is not failed" retries: 2
aptではなくバイナリインストールに切り替える
公式サイトでgoのインストールを見ると、aptからバイナリインストールに変わっています。 ということでAnsibleもそれに合わせましょう。
- name: "go - Create temporary directory for download" ansible.builtin.tempfile: state: directory prefix: golang_install register: temp_dir - name: "go - Download Go tarball" ansible.builtin.get_url: url: "https://go.dev/dl/go{{ go.version }}.linux-amd64.tar.gz" dest: "{{ temp_dir.path }}/go.tar.gz" mode: "0644" register: download_result until: download_result is not failed retries: 3 delay: 2 - name: "go - Remove previous Go installation if exists" become: true ansible.builtin.file: path: "/usr/local/go" state: absent when: default(false) # trueにすれば入れかえ - name: "go - Extract Go tarball to /usr/local" become: true ansible.builtin.unarchive: src: "{{ temp_dir.path }}/go.tar.gz" dest: "/usr/local" remote_src: true creates: "/usr/local/go/bin/go" - name: "go - Add Go to system PATH in /etc/profile.d" become: true ansible.builtin.copy: dest: "/etc/profile.d/profile_andible_init_go.sh" content: | export PATH=$PATH:/usr/local/go/bin export GOPATH=$HOME/go export PATH=$PATH:$GOPATH/bin mode: "0644" register: go_path - name: "go - Clean up temporary directory" ansible.builtin.file: path: "{{ temp_dir.path }}" state: absent
あるいは、次のように指定したgoがすでにインストールされているかで判定してもいいでしょう。
- name: "go - Check if Go is already installed" ansible.builtin.command: /usr/local/go/bin/go version register: go_version_result ignore_errors: true changed_when: false check_mode: false - name: "go - Check if specified Go version is installed" ansible.builtin.shell: set -o pipefail && /usr/local/go/bin/go version | grep -q "go{{ go.version }}" register: go_version_check ignore_errors: true changed_when: false check_mode: false - name: "go - Install Go tasks" when: go_version_check is failed block: - name: "go - Create temporary directory for download" ansible.builtin.tempfile: state: directory prefix: golang_install register: temp_dir - name: "go - Download Go tarball" ansible.builtin.get_url: url: "https://go.dev/dl/go{{ go.version }}.linux-amd64.tar.gz" dest: "{{ temp_dir.path }}/go.tar.gz" mode: "0644" register: download_result until: download_result is not failed retries: 3 delay: 2 - name: "go - Remove previous Go installation if exists" become: true ansible.builtin.file: path: "/usr/local/go" state: absent - name: "go - Extract Go tarball to /usr/local" become: true ansible.builtin.unarchive: src: "{{ temp_dir.path }}/go.tar.gz" dest: "/usr/local" remote_src: true - name: "go - Add Go to system PATH in /etc/profile.d" become: true ansible.builtin.copy: dest: "/etc/profile.d/profile_andible_init_go.sh" content: | export PATH=$PATH:/usr/local/go/bin export GOPATH=$HOME/go export PATH=$PATH:$GOPATH/bin mode: "0644" register: go_path - name: "go - Clean up temporary directory" ansible.builtin.file: path: "{{ temp_dir.path }}" state: absent
実行するときは変数だけ設定しておきます。
go: version: "1.24.1"
実行してみる
$ ansible-playbook
実行例です。
TASK [tools : Go - Install go] ********************************************************************* included: /mnt/d/github/guitarrapc/local-provisioner/envs/include_role/ubuntu/install_go.yaml for localhost => (item=version) TASK [tools : go - Check if Go is already installed] *********************************************** fatal: [localhost]: FAILED! => {"changed": false, "cmd": "/usr/local/go/bin/go version", "msg": "[Errno 2] No such file or directory: b'/usr/local/go/bin/go'", "rc": 2, "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []} ...ignoring TASK [tools : go - Parse installed Go version] ***************************************************** skipping: [localhost] TASK [tools : go - Check if specified Go version is installed] ************************************* fatal: [localhost]: FAILED! => {"changed": false, "cmd": "set -o pipefail && /usr/local/go/bin/go version | grep -q \"go1.24.1\"", "delta": "0:00:00.003985", "end": "2025-03-27 02:48:04.628278", "msg": "non-zero return code", "rc": 1, "start": "2025-03-27 02:48:04.624293", "stderr": "/bin/bash: line 1: /usr/local/go/bin/go: No such file or directory", "stderr_lines": ["/bin/bash: line 1: /usr/local/go/bin/go: No such file or directory"], "stdout": "", "stdout_lines": []} ...ignoring TASK [tools : go - Create temporary directory for download] **************************************** changed: [localhost] TASK [tools : go - Download Go tarball] ************************************************************ changed: [localhost] TASK [tools : go - Remove previous Go installation if exists] ************************************** ok: [localhost] TASK [tools : go - Extract Go tarball to /usr/local] *********************************************** changed: [localhost] TASK [tools : go - Add Go to system PATH in /etc/profile.d] **************************************** changed: [localhost] TASK [tools : go - Clean up temporary directory] *************************************************** changed: [localhost]
うまく入っていますね。
$ go version go version go1.24.1 linux/amd64
まとめ
原型が残らなくなったんですが、aptを使いたくない理由の1つだったりします。 Ansible飽きたので、そろそろ別の仕組みに乗せ換えてもいい気がしてきました。