tech.guitarrapc.cóm

Technical updates

Ansibleで任意の.NET SDKをUbuntuにインストールする

Ubuntuへの.NET SDKのインストール方法はいろいろあります。ただ数年WSLにAnsibleでインストールしてきた結果、やり方が落ち着いたのでメモ。

Linuxへの.NET SDKインストール

Linuxへのインストールはドキュメントが用意されています。私はWSL2でUbuntu 24.04を使っているのですが、Ubuntuに関しては以下の手段が提供されています。

方法 対応バージョン
apt (Ubuntuビルトインフィード) LTSのみ
apt (.NETバックポートフィード) STS含む1津前のLTSまで
スクリプト プレビュー含む任意のバージョン

aptは見ての通り適当に使っていると.NETリリースでインストールされるバージョンが変わります。これはこれで便利ですが、プレビューを試したり、フィードに出るまでタイミングを待つことになったり、いつも通りインストールしたら思ったのと違うバージョンが入るなど扱いにくさがあります。

結局のところ、この環境でどの.NET SDKを使うかをパッケージ配布都合に合わせるのは使い勝手が悪すぎるため、スクリプトを使って任意のバージョンをインストールする方法を使うことにしました。

Ansibleで.NET SDKをインストール

Ansibleで.NET SDKをインストールするためのプレイブックです。

- name: "dotnet - check if SDK version is already installed"
  ansible.builtin.shell: "set -o pipefail && which dotnet && dotnet --list-sdks | grep '{{ args.version }}'"
  register: dotnet_check
  changed_when: false
  ignore_errors: true
  failed_when: false

- name: "dotnet - check if script file exists"
  ansible.builtin.stat:
    path: "/tmp/dotnet-install.sh"
  register: script_file
  when: dotnet_check.rc != 0

- name: "dotnet - download script"
  become: true
  ansible.builtin.get_url:
    url: "https://dot.net/v1/dotnet-install.sh"
    dest: "/tmp/dotnet-install.sh"
    mode: "a+x"
    timeout: 20
  retries: 10
  changed_when: false
  when: dotnet_check.rc != 0 and (script_file.skipped is defined or not script_file.stat.exists)

- name: "dotnet - install ({{ args.version }})"
  ansible.builtin.shell: "DOTNET_ROOT={{ ansible_home }}/.dotnet && /tmp/dotnet-install.sh --channel {{ args.version }}"
  changed_when: false
  when: dotnet_check.rc != 0

インストールしたいバージョンを変数定義しておきます。

dotnet:
  - version: "8.0"
  - version: "9.0"

呼び出す時はこれで。

- name: ".NET - Install dotnet"
  ansible.builtin.include_tasks: ../include_role/ubuntu/install_dotnet.yaml
  with_items: "{{ dotnet }}"
  loop_control:
    loop_var: args

実行してみる

$ ansible-playbook

初回はインストールされます。

TASK [tools : .NET - Install dotnet] ***************************************************************
included: /mnt/d/github/guitarrapc/local-provisioner/envs/include_role/ubuntu/install_dotnet.yaml for localhost => (item={'version': '8.0'})
included: /mnt/d/github/guitarrapc/local-provisioner/envs/include_role/ubuntu/install_dotnet.yaml for localhost => (item={'version': '9.0'})

TASK [tools : dotnet - check if SDK version is already installed] **********************************
ok: [localhost]

TASK [tools : dotnet - check if script file exists] ************************************************
ok: [localhost]

TASK [tools : dotnet - download script] ************************************************************
FAILED - RETRYING: [localhost]: dotnet - download script (10 retries left).
ok: [localhost]

TASK [tools : dotnet - install (8.0)] **************************************************************
ok: [localhost]

TASK [tools : dotnet - check if SDK version is already installed] **********************************
ok: [localhost]

TASK [tools : dotnet - check if script file exists] ************************************************
ok: [localhost]

TASK [tools : dotnet - download script] ************************************************************
skipping: [localhost]

TASK [tools : dotnet - install (9.0)] **************************************************************
ok: [localhost]

2回目はすでにインストールされていればスキップされます。

TASK [tools : .NET - Install dotnet] ***************************************************************
included: /mnt/d/github/guitarrapc/local-provisioner/envs/include_role/ubuntu/install_dotnet.yaml for localhost => (item={'version': '8.0'})
included: /mnt/d/github/guitarrapc/local-provisioner/envs/include_role/ubuntu/install_dotnet.yaml for localhost => (item={'version': '9.0'})

TASK [tools : dotnet - check if SDK version is already installed] **********************************
ok: [localhost]

TASK [tools : dotnet - check if script file exists] ************************************************
ok: [localhost]

TASK [tools : dotnet - download script] ************************************************************
skipping: [localhost]

TASK [tools : dotnet - install (8.0)] **************************************************************
ok: [localhost]

TASK [tools : dotnet - check if SDK version is already installed] **********************************
ok: [localhost]

TASK [tools : dotnet - check if script file exists] ************************************************
ok: [localhost]

TASK [tools : dotnet - download script] ************************************************************
skipping: [localhost]

TASK [tools : dotnet - install (9.0)] **************************************************************
ok: [localhost]

インストールされていますね。

$ dotnet --list-sdks
8.0.407 [/home/guitarrapc/.dotnet/sdk]
9.0.202 [/home/guitarrapc/.dotnet/sdk]

まとめ

割と真面目にインストールスクリプトが便利です。 インストールスクリプトの問題があるとしたら、スクリプト自体のダウンロードCDNがかなり不安定です。ありえないぐらい不安定でしょっちゅうダウンロードに失敗するので、AzureのCDN品質を疑わざるを得ない状況なのでいい加減にしてほしいですね。

参考