👨‍💻

AnsibleでTurtlebot3 simulationsのインストールを自動化する

2023/07/10に公開

海洋ロボコンをやってた人です。

今回は構成管理ツールの一種で、サーバーやクラウド環境などを設定・管理できる自動化ツールAnsibleを触ってROSのパッケージインストールを自動化してみたので、その備忘録として記載していきます。

Ansibleは冪統制(べきとうせい)があるため、何度同じ処理を実行しても、同じ結果になるという点や、yaml形式でシンプルに記述できるなどの利点がありますね。

記事を書いた理由は以下です。

  • Ansibleを触りながら学びたいため
  • 後から使い方を自分で見直せるようにするため


記事の最終ゴールは以下のようにAnsibleを書けるようになることです。

https://github.com/tasada038/turtlebot3_simulations_ansible

また、本記事に対するコメントも積極的に募集しますので、よろしくお願いいたします。


使用機器と環境は以下です。

  • Ansible サーバー Laptop PC Ubuntu 22.04
    • ansible: core 2.15.1
  • 管理対象ホスト Jetson Nano Ubuntu 20.04 (ROS インストール済み)

Ansibleのインストール

まずはAnsibleサーバー側に、Ansibleをインストールします。

Laptop PC Shell
sudo apt update
sudo apt install sshpass
sudo apt install ansible
ansible --version

sshpassがないと以下のエラーが生じることもあります。

Ansible playbookの構造を作る

ここから実際にturtlebot3_simulations_ansibleを例にAnsibleの作成例をいくつか紹介していきます。

ディレクトリ構成は以下のとおりです。

directory-tree
turtlebot3_simulations_ansible/
  ├ site.yml
  ├ ansible.cfg
  ├ inventory/
      ├ inventory.ini
  ├ roles/
      ├ apt/tasks
          ├ apt.yml
	  ├ main.yml
      ├ clone/tasks
          ├ clone.yml
	  ├ main.yml
      ├ lineinfile/tasks
          ├ lineinfile.yml
	  ├ main.yml
      ├ shell/tasks
          ├ shell.yml
	  ├ main.yml

まずは構成管理対象で実行したい処理の流れを作るファイルを作成します。

site.yml
---
- name: Run apt update on Jetson Nano
  vars:
    ansible_user: jetson
    ansible_password: jetson
    destination_directory: tb3_noetic_ws
    ros_distribution: noetic

  hosts: target
  gather_facts: false
  become: true

  roles:
    - role: apt
    - role: clone
      tags: git
    - role: lineinfile
    - role: shell

Playbookの構成は基本的にTargetsVarsTasksHandlersの4セクションから構成されます。(最低2つ)

上記では

Section yml
Targets hosts: target
Vars vars:
Tasks roles:
Handlers ---

という対応で構成しています。

以降、こちらの詳細を備忘録も兼ねて記載していきます。

Targets セクションの構成

hosts: targetの箇所はTargetsセクションを表しており、管理対象ホストに接続するための情報を定義しています。

hostsディレクティブ(以下略)では、ホスト名を宣言、gather_factsではsetupモジュールで管理対象の情報を取得するかを決めれます。今回は管理対象から情報を取得しないのでfalseを指定しています。

becomeはログイン後、ユーザーを切り替えて処理実行するかで、trueにすることでrootユーザー権限で操作できるようになります。


上記ではhostsでIPアドレスを直接指定しておらず、複数の管理対象をグループ化できるインベントリーファイルにて管理対象ホストのIPアドレスをしていしています。

inventory/inventory.ini
[target]
192.168.11.7

管理対象が増える場合は、上記のようにインベントリーファイルを作成し、IPアドレスを追加していけば良さそうです。

またinventory.iniですが、特に何も設定しない場合は

Laptop PC Shell
ansible-playbook -i inventory/inventory.ini -e "ansible_user=jetson ansible_password=jetson" site.yml

のような形でコマンドライン側でインベントリーファイルを指定する必要があります。

そのためansible.cfgファイルでdefaultsとしてインベントリーファイル指定することで、ansible-playbookでの宣言を

Laptop PC Shell
ansible-playbook site.yml

のように省略できます。

ansible.cfg
[defaults]
inventory = inventory/inventory.ini
retry_files_enabled = False
log_path=ansible.log

[privilege_escalation]
become = True

上記のdefaultsセッションも説明しておくと

  • inventory: インベントリファイルを設定
  • retry_files_enabled: 失敗タスクのリトライをFalse:なしの設定
  • log_path: ansible-playbook後にターミナル上のログを記録
  • privilege_escalation: sudo権限の有効を意味します。

privilege_escalationでbecome=Trueを指定する場合は、他のymlでの宣言は重複するので不要になります。

Vars セクションの構成

varsセクションでは、管理対象ホストのユーザ名:ansible_user, パスワード:ansible_passwordや各ファイルで使用する共通の変数を定義することができます。

site.yml
---
- name: Run apt update on Jetson Nano
  vars:
    ansible_user: jetson
    ansible_password: jetson
    destination_directory: tb3_noetic_ws
    ros_distribution: noetic

上記では、管理対象のユーザー名やROSパッケージのインストール先ディレクトリ、ディストリビューションなどを指定しています。

Tasks セクションの構成

Tasksセクションは、実行したい処理を指定する箇所になります。

モジュールとしてはservicefirewalldcommandなど多数ありますが、ここではturtlebot3_simulations_ansibleで使用するモジュールに限り一部紹介します。

全文のプログラムが見たい方は、本記事TOPのGitを参照ください。

Ansibleで利用できるモジュール一覧は Ansible Documentation Module Index を参照するのが良いと思います。

aptモジュール

aptモジュールではUbuntuやDevian系でパッケージ管理を行うためのモジュールです。

apt.yml
---
- name: apt update cache
  apt:
    update_cache: yes

# - name: Remove ros-noetic-dynamixel-sdk package
#   apt:
#     name: ros-noetic-dynamixel-sdk
#     state: absent # remove

# --- 略 ---

- name: apt install ros-noetic-gmapping package
  apt:
    name: ros-noetic-gmapping
    state: present # install

以下aptモジュールとshellの対応でイメージしてもらうのが良いと思います。

aptモジュール shell
update_cache: yes apt-get update
state: absent apt-get remove
state: present apt-get install

apt dictionally下のnameはpackage-nameの名称です。

gitモジュール

こちらはGitからクローンするモジュールを使用しています。

clone.yml
---
# Install Turtlebot3 Packages
- name: Create directory for tb3_noetic_ws
  file:
    path: "/home/{{ ansible_user }}/{{ destination_directory }}/src/"
    state: directory
    owner: "{{ ansible_user }}"
    group: "{{ ansible_user }}"
    mode: '0755'

# --- 略 ---

- name: Clone DynamixelSDK repository
  git:
    repo: "https://github.com/ROBOTIS-GIT/DynamixelSDK.git"
    dest: "{{ destination_directory }}/src/DynamixelSDK"
    version: noetic-devel

repoはリポジトリ名、destはクローンするディレクトリ、versionはブランチ名を記載します。

また、ROSパッケージをインストールするため、事前にfileモジュールでディレクトリを作成しています。

Ansibleでファイルを作製する場合、アクセス権限を与えないと後からcatkin_makeでエラーが生じるので、パーミッションを0755としています。

lineinfileモジュール

lineinfileモジュールは、テキストファイルの特定の行に対して操作を行うために使用します。

Turtlebot3のGazeboシミュレーションでは、MODELの定義があるので、こちらを.bashrcに書き込む必要があります。

lineinfile.yml
- name: Append TURTLEBOT3_MODEL to .bashrc
  lineinfile:
    dest: .bashrc
    state: present
    line: "export TURTLEBOT3_MODEL=big_wheel_3rs"
    insertafter: EOF
    
    # --- 略 ---

destはディレクトリを、state指定したファイルが存在しなければ作成します。
lineは追加したいコマンドを、insertafterはどこの行に追加するかを指定します。
今回は最終行なのでEOFを指定します。

shellモジュール

shellモジュールはshellscriptを実行するコマンドで、特定のスクリプトを実行するときに使用します。

shell.yml
- name: Build lightsfm
  shell: make
  args:
    chdir: "{{ destination_directory }}/src/lightsfm"

argsのchdirでディレクトリの指定も可能です。


自分なりのAnsible Playbookが完成したら

Laptop PC Shell
ansible-playbook site.yml

などとコマンドを実行して確認してみましょうね。

以上です。

Reference

Zenn:Ansible の使い方

Engineer Tutorials:Ansible入門講座

Github:turtlebot3_setup

Github:raspberry-ansible

Github:ansible-role-ros

Discussion