グローバルナビゲーションへ

本文へ

フッターへ

お役立ち情報Blog



WSL2のUbuntu 22.04をAnsible playbookを使って環境構築してみる

寒い季節から段々と暖かくなり、目や鼻がむずむずする季節性の風邪が起こりやすい季節になってきました。

つまり環境構築のいい季節ですね。

今回はWSL2のUbuntu 22.04をAnsible playbookを使って環境構築してみたいと思います。

Ansibleの紹介

Ansible について

Ansible は IT 自動化ツールです。 このツールを使用すると、システムの構成、ソフトウェアの展開、より高度なITタスク (継続的なデプロイメントやダウンタイムなしのローリング更新など) のオーケストレーションが可能になります。Ansible ドキュメント

ざっくり要約するとステージングやプロダクション環境の環境構築作業をコード化し、再利用可能な形で配布できる環境構築自動化ツールです。

環境構築作業をコード化することによって、システムの構成の追加・変更手続きをレビュー可能にしたり、ヒューマンエラーの排除などに貢献できそうです。Ansibleが当てはまるかは不明ですが、一般的にこういった環境構築作業をコード化することを IaC(Infrastructure as Code)と呼んだりします。

今回はAnsible playbookで環境構築自動化は気になるけど、いきなりステージング、プロダクション環境をAnsibleで作成するのは怖いなといった方向けに、それ、WSL2のローカル環境でもできるでといった趣向になります。

WSL2のUbuntu 22.04のセットアップ

2022-03-03時点でのインストール可能なディストリビューションの確認です。 Ubuntu-22.04  が含まれていることを確認しましょう。

PS> wsl --list --online
インストールできる有効なディストリビューションの一覧を次に示します。
'wsl.exe --install <Distro>' を使用してインストールします。

NAME                                   FRIENDLY NAME
Ubuntu                                 Ubuntu
Debian                                 Debian GNU/Linux
kali-linux                             Kali Linux Rolling
Ubuntu-18.04                           Ubuntu 18.04 LTS
Ubuntu-20.04                           Ubuntu 20.04 LTS
Ubuntu-22.04                           Ubuntu 22.04 LTS
OracleLinux_8_5                        Oracle Linux 8.5
OracleLinux_7_9                        Oracle Linux 7.9
SUSE-Linux-Enterprise-Server-15-SP4    SUSE Linux Enterprise Server 15 SP4
openSUSE-Leap-15.4                     openSUSE Leap 15.4
openSUSE-Tumbleweed                    openSUSE Tumbleweed

以下のコマンドをPowerShell上で実行し、Ubuntu-22.04をインストールします。

PS> wsl --install -d Ubuntu-22.04

Ubuntu 22.04 LTS はインストールされました。
Ubuntu 22.04 LTS を開始しています...
Installing, this may take a few minutes...
Please create a default UNIX user account. The username does not need to match your Windows username.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username: r1cep
New password:
Retype new password:
passwd: password updated successfully
Installation successful!
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

Welcome to Ubuntu 22.04.1 LTS (GNU/Linux 5.15.90.1-microsoft-standard-WSL2 x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

This message is shown once a day. To disable it please create the
/home/<USERNAME>/.hushlogin file

Ansibleのインストール

Ansible playbook を実行するためにまずはAnsibleをインストールします。
WSL2 Ubuntu-22.04にログインし、以下のコマンドを実行します。

sudo apt-get update
sudo apt-get install ansible

ディレクトリ構成

ディレクトリ構成は公式ドキュメントのベストプラクティスを参考にしました。
参照:ベストプラクティス — Ansible Documentation

./
├── group_vars/
├── host_vars/
├── inventories/
├── roles/
├── ansible.cfg
└── playbook.yaml

各種ディレクトリとファイルの内容は以下の通りです。

ansible.cfg

参照:Ansible の設定 — Ansible Documentation

Ansibleの設定ファイルです。
root権限または別のユーザーのパーミッションでタスクを実行可能にする設定等、Ansibleの基本的な設定をこのファイルで設定します。

inventories

参照:インベントリーの構築方法 — Ansible Documentation

インベントリーと呼ばれる複数の管理ノードまたは「ホスト」のリストとグループを設定します。

mail.example.com

[webservers]
foo.example.com
bar.example.com

[dbservers]
one.example.com
two.example.com
three.example.com

公式ドキュメントより引用

上記の例で言うと、 webservers  dbservers がグループ名、それ以外が「ホスト」です。
グループ名の下にホストを設定することで、グループ毎に一括で何かを実行するといったようなことができます。

group_vars

グループ変数を配置するディレクトリです。
グループ単位で設定したい変数をここで定義していきます。

host_vars

ホスト変数を配置するディレクトリです。
ホスト単位で設定したい変数をここで定義していきます。

roles

参照:ロール — Ansible Documentation

このディレクトリの中で、再利用可能な形で実際にAnsibleで実行したいタスクやハンドラーを定義していきます。このまとまりをAnsible playbookではロールと呼びます。
Ansible playbookではロールの各種タスクやハンドラは暗黙的に特定のディレクトリ名の中に配置されていることを想定されています。

各種ロールのディレクトリ名を公式ドキュメントより引用します。

  • tasks – このロールによって実行される主なタスクの一覧が含まれます。
  • handlers – このロールによって使用される可能性のあるハンドラーや、このロールの外でも使用できるハンドラーが含まれます。
  • defaults – ロールのデフォルト変数です (詳細は 変数の使用 を参照)。
  • vars – ロールの他の変数です (詳細は 変数の使用 を参照)。
  • files – このロールでデプロイできるファイルが含まれます。
  • templates – このロールでデプロイできるテンプレートが含まれます。
  • meta – このロールのメタデータを定義します。詳細は、以下を参照してください。
ロール — Ansible Documentation

playbook.yaml

Ansible playbookのエントリーポイントとなるファイルです。
rolesで定義するようなタスクを直接このファイルで定義することも可能です。 このファイルで、直接定義するタスクや、事前定義したロールのマッピングしたものをAnsible playbook では、「プレイ」と呼びます。

ansible.cfg

まずはAnsibleの設定ファイルを作成します。

; offical example
; ref. https://github.com/ansible/ansible/blob/devel/examples/ansible.cfg
; ref. https://docs.ansible.com/ansible/latest/reference_appendices/config.html#ansible-configuration-settings
[defaults]
host_key_checking = true
gathering = smart

[privilege_escalation]
become = true

[defaults]

デフォルトの設定値をこのセクション内で設定します。
ほぼすべての設定値はplaybookで上書きできます。

host_key_checking

ホストキーチェックを有効にする設定です。
接続方法および詳細 — Ansible Documentation

gathering

Ansibleではシステムから検出される変数、リモートシステムに関するデータを取得する方法を「ファクト」と呼びます。 このファクトをキャッシュして再利用する可否の設定値です。設定値には3種類の値が設定可能です。

  • smart – デフォルトは収集する、キャッシュ済みの場合は変数を再取得しない
  • implicit – デフォルトは収集する、 gather_facts: false で無効化可能
  • explicit – デフォルトは収集しない、  gather_facts: true で有効化

[privilege_escalation]

権限昇格についての設定をこのセクション内で設定します。

become

trueでroot権限昇格を有効化します。

その他の設定値についても、Ansible公式のExampleがあるのでその他の設定値が気になる方はご参照ください。
参照:ansible/examples/ansible.cfg

inventories

[localhost]
jammy

今回はローカルのWSL2で確認していくのでグループのセクションには   [localhost]   を指定します。
ホスト名はUbuntu 22.04 LTSのコードネーム Jammy Jellyfish から  jammy  とホストを定義しました。

group_vars

グループ毎の上書きしたい設定値や変数を指定していきます。

---

ansible_host: localhost
ansible_connection: local
ansible_python_interpreter: "/usr/bin/env python3"

ansible_host

接続するホストの名前を指定します。
運用フェーズではステージングやプロダクション環境のホスト名を指定します。
今回はWSL2なのでlocalhostを指定します。

ansible_connection

ホストへの接続の種類です。SSHのプロトコルタイプは以下の二種類です

  • smart(デフォルト)
  • ssh

その他にも paramiko という SSHv2のPhython実装などもあるようです。
今回はWSL2のローカルで実行しますので、  local  を指定します。

暗黙的な ‘localhost’ — Ansible Documentation

ansible_python_interpreter

pythonインタープリターを指定します。
指定せずにいると  /usr/bin/python  を参照してしまい、エラーになってしまうので python3のパスを指定します。
参照:インタープリターの検出 — Ansible Documentation

その他の設定値について興味がある方はこちらのドキュメントをご参照ください。
参照:インベントリーの構築方法 — Ansible Documentation

host_vars

ホスト毎の上書きしたい設定値や変数を指定していきます。

---

common:
  packages:
    - make
    - git
    - vim
    - tree
    - jq
    - nkf
    - zip
    - unzip

ここで定義しているのはユーザ定義変数です。後述のroles内のタスクでここで定義した変数を参照します。
ここではUbuntu-22.04にインストールしたいパッケージをリスト形式で指定しています。

roles

実際にAnsibleで実行したいタスクを定義していきます。
パッケージのアップデート、インストールに必要なroot権限昇格のためのsudoersの設定と、事前に定義した  host_vars  の変数を使って、パッケージのインストールを行う共通のロール common を作成します。

ユーザの設定ロール(user)

パッケージのアップデートやインストールの際にroot権限が必要なので、まずはsudoersの設定を行います。
Ansibleのtemplateモジュールを使用して /etc/sudoers.d/<USERNAME> にsudoersの設定ファイルを配置するサブタスクを定義します。
参照:template – Template a file out to a remote server — Ansible Documentation

---

- name: Configure sudo for working users.
  template:
    src: sudoers.j2
    dest: "/etc/sudoers.d/{{ ansible_env.SUDO_USER }}"
    owner: root
    group: root
    mode: 0440

作成したサブタスクを呼び出すタスクを定義します。

---

- import_tasks: 001_configure-sudo-for-working-users.yaml
  tags: user-sudo

templatesにはAnsibleで使用可能なPhytyonのテンプレートエンジン、Jinja2のフォーマットのファイルを配置します。

{{ ansible_env.SUDO_USER }} ALL=(ALL) NOPASSWD: ALL
Defaults:%{{ ansible_env.SUDO_USER }} !requiretty
Defaults:%{{ ansible_env.SUDO_USER }} env_keep += SSH_AUTH_SOCK
 ansible_env.SUDO_USER でUbuntu-22.04のログインユーザを参照しています。

ディレクトリツリー

roles/
└── user/
    ├── tasks/    
    │   ├── 001_configure-sudo-for-working-users.yaml
    │   └── main.yaml
    └── templates/
        └── sudoers.j2

共通ロール

共通ロールではパッケージのアップデートや、事前変数定義していたパッケージのインストールタスクを定義していきます。
まずは日本のミラーリポジトリに変更するサブタスクを定義します。

---

- name: Change package archive repository to japanese server.
  replace:
    path: /etc/apt/sources.list
    backup: yes
    regexp: '\/archive\.ubuntu'
    replace: '/jp.archive.ubuntu'

全てのパッケージをアップデートするサブタスクを定義します。

---

- name: Update all packages.
  apt:
    name: '*'
    state: latest
    update_cache: yes
    cache_valid_time: 3600

事前定義していたパッケージをインストールするサブタスクを定義します。

---

- name: Install various utility packages.
  apt:
    name: "{{ common.packages }}"
    state: present

最後に定義したサブタスクを呼び出すcommonロールのタスクファイルを定義します。

---

- import_tasks: 001_change-package-repository-to-japanese.yaml
  tags: common-repo

- import_tasks: 002_update-all-packages.yaml
  tags: common-update-packages

- import_tasks: 003_install-utility-packages.yaml
  tags: common-install-packages

ディレクトリツリー

roles/
└── common/
    └── tasks/
        ├── 001_change-package-repository-to-japanese.yaml
        ├── 002_update-all-packages.yaml
        ├── 003_install-utility-packages.yaml
        └── main.yaml

Ansible playbook

最後にAnsible playbookのエントリーポイントとなるplaybookを作成していきます。
プロジェクトルートディレクトリ直下に playbook.yaml を作成します。

---

- name: Configure Ubuntu-22.04 LTS (Jammy Jellyfish) settings for Windows Subsystem for Linux 2.
  hosts: jammy
  tasks:
    - import_role:
        name: user
      tags: user

    - import_role:
        name: common
      tags: common
 import_role  で rolesディレクトリ配下のロールを指定し、tagsを指定しておくことで後のplaybookの実行時の引数オプションで特定のタグだけ実行するといったことが可能になります。

この tags を指定しておくと、特定のタスクだけの動作検証が楽になりますので指定しておくことをお勧めします。

Ansible playbookの実行

ここまで来たら後はAnsible playbookを実際にコマンドラインから実行するだけです。
実行コマンドは以下のようなオプションを指定します。

# Dry run
ansible-playbook -i inventories/hosts.ini -l jammy playbook.yaml --diff --check

# 実際に実行
ansible-playbook -i inventories/hosts.ini -l jammy playbook.yaml --diff
  •  -i  インベントリファイルのパス
  •  -l  インベントリのホスト
  •  –diff  差分表示
  •  –check  ドライラン

ただし、初回実行時にはまだsudoersの設定がされていないのでroot権限昇格にログインユーザのパスワードが必要です。 初回実行時のみ  –ask-become-pass  オプションを指定して、ログインユーザのパスワードを入力してください。

ansible-playbook -i inventories/hosts.ini -l jammy playbook.yaml --diff --ask-become-pass

まとめ

初歩的な部分までですが、WSL2のUbuntu-22.04をAnsible playbookを使って環境構築してみる手順は以上です。

ステージング環境、プロダクション環境をAnsibleで構築したいけど気軽に試せる環境がないなという方は、WSL2であればローカルで気軽に試せます。
localhostから一歩進むのであれば、Dockerを使ってリモートホストをエミュレートするのもよいのではないでしょうか。

最終的なディレクトリ、ファイルツリーは以下の通りです。

./
├── group_vars/
│   └── localhost.yaml
├── host_vars/
│   └── jammy.yaml
├── inventories/
│   └── hosts.ini
├── roles/
│   ├── common/
│   │   └── tasks/
│   │       ├── 001_change-package-repository-to-japanese.yaml
│   │       ├── 002_update-all-packages.yaml
│   │       ├── 003_install-utility-packages.yaml
│   │       └── main.yaml
│   └── user/
│       ├── tasks/
│       │   ├── 001_configure-sudo-for-working-users.yaml
│       │   └── main.yaml
│       └── templates/
│           └── sudoers.j2
├── ansible.cfg
└── playbook.yaml

Ansible playbook を使ってIaC(Infrastructure as Code)を推し進めていく手助けになると嬉しいですね。

この記事を書いた人

美髭公
美髭公事業開発部 web application engineer
2013年にアーティスに入社。システムエンジニアとしてアーティスCMSを使用したWebサイトや受託システムの構築・保守に携わる。環境構築が好き。
この記事のカテゴリ

FOLLOW US

最新の情報をお届けします