🌿

Ansible Night 2024.3 を振り返ってみた

2024/04/05に公開

3 行まとめ

  • 2024 年 3 月に実施された Ansible Night のえんでぃ氏の発表のデモ環境を作ってみました
  • 環境は Oracle VirtualBox + Vagrant 、OS は AlmaLinux 9 と VyOS です
  • ネットワーク部分も含まれるため、デモで扱ったすべての playbook を実行できます

https://www.youtube.com/watch?v=fD4ZwtCFzeM

ファイル

Vagrantfile

Vagrantfile
Vagrant.configure("2") do |config|
#
#   すべての仮想マシンに共通の設定
#
    config.vm.box = "almalinux/9"
    config.vm.synced_folder ".", "/vagrant", disabled: true
    config.vm.provider "virtualbox" do |vb|
        vb.memory = "2048"                                                                          # メモリサイズ
        vb.cpus = 1                                                                                 # CPU 数
        vb.gui = true                                                                               # コンソールウインドウを表示
        vb.customize [
            "modifyvm", :id,
            "--ioapic", "on",
            "--graphicscontroller", "vmsvga",
            "--nicpromisc2", "allow-all"
        ]
    end

    config.vm.define :ansible1 do |ansible1|
        ansible1.vm.network "public_network", mac: "00006c000010", ip: "192.168.0.10"
        ansible1.vm.hostname = "ansible1.example.jp"                                                # ホスト名
        ansible1.vm.provider "virtualbox" do |vb|
            vb.name = "ansible1"                                                                    # Oracle VirtualBox 上の仮想マシン名
        end
        ansible1.vm.provision "shell", path: "./account.sh"                                         # アカウントを作成
        ansible1.vm.provision "shell", path: "./ansible1.sh"                                        # Ansible をインストール
        ansible1.vm.provision "shell", path: "./ansible-night.sh"                                   # Ansible Night 2024.3 の playbook を配置
    end

    (1..2).each do |i|
        config.vm.define "linux#{i}" do |linux|
            linux.vm.network "public_network", mac: "00006c0000#{i+11}", ip: "192.168.0.#{i+11}"    # 1 枚目の NIC
            linux.vm.network "private_network", mac: "00006c0000#{i+21}", virtualbox__intnet: true  # 2 枚目の NIC
            linux.vm.hostname = "linux#{i}.example.jp"                                              # ホスト名
            linux.vm.provider "virtualbox" do |vb|
                vb.name = "linux#{i}"                                                               # Oracle VirtualBox 上の仮想マシン名
            end
            linux.vm.provision "shell", path: "./account.sh"                                        # アカウントを作成
        end
    end

    config.vm.define :vyos do |vyos|
        vyos.vm.box = "vyos/current"
        vyos.vm.network "public_network", mac: "00006c000011", ip: "192.168.0.11"                  # 1 枚目の NIC
        vyos.vm.network "private_network", mac: "00006c000021", virtualbox__intnet: true           # 2 枚目の NIC
        vyos.vm.network "private_network", mac: "00006c000031", virtualbox__intnet: true           # 3 枚目の NIC
        vyos.vm.hostname = "vyos1.example.jp"                                                      # ホスト名
        vyos.vm.provider "virtualbox" do |vb|
            vb.name = "vyos1"                                                                      # Oracle VirtualBox 上の仮想マシン名
            vb.memory = "1024"                                                                     # メモリサイズ
        end
        vyos.ssh.username = "vyos"
        vyos.ssh.password = "vyos"
        vyos.ssh.keys_only = false
        vyos.ssh.insert_key = false
        vyos.ssh.shell = "bash"
    end

end

account.sh

account.sh
#!/bin/sh -x
#
# アカウントを作成する
#
UNAME='y_mrok'
timedatectl set-timezone Asia/Tokyo
useradd ${UNAME}
echo 'pass+123' | passwd --stdin ${UNAME}
cat <<EOF > /etc/sudoers.d/${UNAME}
${UNAME} ALL=(ALL) NOPASSWD:ALL
EOF
unset UNAME
exit 0

ansible1.sh

ansible1.sh
#!/bin/sh -x
#
# Ansible をインストールする
#
UNAME="y_mrok"
dnf -y install python3-pip sshpass tar
su - ${UNAME} <<EOF
mkdir /home/${UNAME}/.ssh
chmod 0700 /home/${UNAME}/.ssh
cat <<OWARI > /home/${UNAME}/.ssh/config
Host *
  StrictHostKeyChecking no
  UserKnownHostsFile=/dev/null
OWARI
chmod 0600 /home/${UNAME}/.ssh/config
pip3 install --user ansible ansible-lint paramiko
EOF
unset UNAME
exit 0

ansible-night.sh

ansible-night.sh
#!/bin/sh -x
#
# Ansible Night 2024.3 のデモ用 playbook を配置する
#
UNAME="y_mrok"
DIR="home/${UNAME}/ansible-night-202403"
#
# 基本的な設定
#
su - ${UNAME} <<EOF
mkdir /${DIR}
mkdir /${DIR}/host_vars
mkdir /${DIR}/group_vars
mkdir /${DIR}/2_hello_world
mkdir /${DIR}/4_set_up_linux
mkdir /${DIR}/5_use_variables
mkdir /${DIR}/6_set_up_eos

cat <<OWARI > /${DIR}/ansible.cfg
[defaults]
inventory       = {{CWD}}/hosts
host_key_checking = False

bin_ansible_callbacks = True
stdout_callback = yaml
OWARI

cat <<OWARI > /${DIR}/hosts
[linux]
linux1
linux2

[vyos]
vyos1
OWARI

cat <<OWARI > /${DIR}/host_vars/linux1.yml
ansible_host: 192.168.0.12

# Used in 5_use_variables

eth2_ip4: 192.168.1.2/24
eth2_routes4:
  - 192.168.2.0/24 192.168.1.1
OWARI

cat <<OWARI > /${DIR}/host_vars/linux2.yml
ansible_host: 192.168.0.13

# Used in 5_use_variables

eth2_ip4: 192.168.2.2/24
eth2_routes4:
  - 192.168.1.0/24 192.168.2.1
OWARI

cat <<OWARI > /${DIR}/host_vars/vyos1.yml
ansible_host: 192.168.0.11
OWARI

cat <<OWARI > /${DIR}/group_vars/linux.yml
ansible_user: ${UNAME}
ansible_password: pass+123
OWARI

cat <<OWARI > /${DIR}/group_vars/vyos.yml
ansible_connection: ansible.netcommon.network_cli
ansible_network_os: vyos.vyos.vyos
ansible_user: vyos
ansible_password: vyos
ansible_become: true
ansible_network_cli_ssh_type: paramiko
OWARI

ln -s ../group_vars /${DIR}/4_set_up_linux/group_vars
ln -s ../host_vars /${DIR}/4_set_up_linux/host_vars
ln -s ../hosts /${DIR}/4_set_up_linux/hosts
ln -s ../group_vars /${DIR}/5_use_variables/group_vars
ln -s ../host_vars /${DIR}/5_use_variables/host_vars
ln -s ../hosts /${DIR}/5_use_variables/hosts
ln -s ../group_vars /${DIR}/6_set_up_eos
ln -s ../host_vars /${DIR}/6_set_up_eos
ln -s ../hosts /${DIR}/6_set_up_eos

#
# 2_hello_world
#
cat <<OWARI > /${DIR}/2_hello_world/playbook.yml
- name: Debug
  hosts: localhost
  gather_facts: false

  tasks:
    - name: Print hello world!
      ansible.builtin.debug:
        msg: Hello world!
OWARI

#
# 4_set_up_linux
#
cat <<OWARI > /${DIR}/4_set_up_linux/playbook_1_ping.yml
- name: Test with ping
  hosts: linux1
  gather_facts: false

  tasks:
    - name: Test with ping
      ansible.builtin.ping:
OWARI
cat <<OWARI > /${DIR}/4_set_up_linux/playbook_2_set_up_httpd.yml
- name: Set up Linux
  hosts: linux1
  become: true
  gather_facts: false

  tasks:
    - name: Install httpd
      ansible.builtin.dnf:
        name:
          - httpd
        state: present

    - name: Start and enable httpd.service
      ansible.builtin.systemd_service:
        name: httpd.service
        state: started
        enabled: true

    - name: Start and enable firewalld.service
      ansible.builtin.systemd_service:
        name: firewalld.service
        state: started
        enabled: true
OWARI
cat <<OWARI > /${DIR}/4_set_up_linux/playbook_3_permit_httpd_at_firewalld.yml
- name: Set up Linux
  hosts: linux1
  become: true
  gather_facts: false

  tasks:
    - name: Install httpd
      ansible.builtin.dnf:
        name:
          - httpd
        state: present

    - name: Start and enable httpd.service
      ansible.builtin.systemd_service:
        name: httpd.service
        state: started
        enabled: true

    - name: Start and enable firewalld.service
      ansible.builtin.systemd_service:
        name: firewalld.service
        state: started
        enabled: true

    - name: Permit TCP 80 at firewalld
      ansible.posix.firewalld:
        zone: public
        port: 80/tcp
        permanent: true
        immediate: true
        state: enabled
OWARI
cat <<OWARI > /${DIR}/4_set_up_linux/playbook_4_nmcli.yml
- name: Set up Linux
  hosts: linux1
  become: true
  gather_facts: false

  tasks:
    - name: Install httpd
      ansible.builtin.dnf:
        name:
          - httpd
        state: present

    - name: Start and enable httpd.service
      ansible.builtin.systemd_service:
        name: httpd.service
        state: started
        enabled: true

    - name: Start and enable firewalld.service
      ansible.builtin.systemd_service:
        name: firewalld.service
        state: started
        enabled: true

    - name: Permit TCP 80 at firewalld
      ansible.posix.firewalld:
        zone: public
        port: 80/tcp
        permanent: true
        immediate: true
        state: enabled

    - name: Configure IP address
      community.general.nmcli:
        conn_name: eth2
        type: ethernet
        method4: manual
        ip4: 192.168.1.2/24
        routes4:
          - 192.168.2.0/24 192.168.1.1
        autoconnect: true
        state: present

    - name: Bring up eth2 to for configuration change to take effect
      ansible.builtin.command: nmcli connection up eth2
OWARI
#
# 5_use_variables
#
cat <<OWARI > /${DIR}/5_use_variables/playbook_1_use_variables.yml
- name: Set up Linux
  hosts: linux
  become: true
  gather_facts: false

  tasks:
    - name: Install httpd
      ansible.builtin.dnf:
        name:
          - httpd
        state: present

    - name: Start and enable httpd.service
      ansible.builtin.systemd_service:
        name: httpd.service
        state: started
        enabled: true

    - name: Start and enable firewalld.service
      ansible.builtin.systemd_service:
        name: firewalld.service
        state: started
        enabled: true

    - name: Permit TCP 80 at firewalld
      ansible.posix.firewalld:
        zone: public
        port: 80/tcp
        permanent: true
        immediate: true
        state: enabled

    - name: Configure IP address
      community.general.nmcli:
        conn_name: eth2
        type: ethernet
        method4: manual
        ip4: '{{ eth2_ip4 }}'
        routes4: '{{ eth2_routes4 }}'
        autoconnect: true
        state: present

    - name: Bring up eth2 to for configuration change to take effect
      ansible.builtin.command: nmcli connection up eth2
OWARI
cat <<OWARI > /${DIR}/5_use_variables/playbook_2_add_index_html.yml
- name: Set up Linux
  hosts: linux
  become: true
  gather_facts: false

  tasks:
    - name: Install httpd
      ansible.builtin.dnf:
        name:
          - httpd
        state: present

    - name: Start and enable httpd.service
      ansible.builtin.systemd_service:
        name: httpd.service
        state: started
        enabled: true

    - name: Start and enable firewalld.service
      ansible.builtin.systemd_service:
        name: firewalld.service
        state: started
        enabled: true

    - name: Permit TCP 80 at firewalld
      ansible.posix.firewalld:
        zone: public
        port: 80/tcp
        permanent: true
        immediate: true
        state: enabled

    - name: Configure IP address
      community.general.nmcli:
        conn_name: eth2
        type: ethernet
        method4: manual
        ip4: '{{ eth2_ip4 }}'
        routes4: '{{ eth2_routes4 }}'
        autoconnect: true
        state: present

    - name: Bring up eth2 to for configuration change to take effect
      ansible.builtin.command: nmcli connection up eth2

    - name: Put index.html
      ansible.builtin.copy:
        content: |
          {{ inventory_hostname }}
        dest: /var/www/html/index.html
OWARI
#
# 6_set_up_eos
#
cat <<OWARI > /${DIR}/6_set_up_eos/playbook_1_set_up_eos.yml
- name: Set up VyOS
  hosts: vyos1
  gather_facts: false

  tasks:
   - name: Set IP addresses on L3 interfaces
     vyos.vyos.vyos_l3_interfaces:
       config:
       - name: eth2
         ipv4:
         - address: 192.168.1.1/24
       - name: eth3
         ipv4:
         - address: 192.168.2.1/24
OWARI
cat <<OWARI > /${DIR}/6_set_up_eos/playbook_2_linux_and_veos.yml
- name: Set up Linux
  hosts: linux
  become: true
  gather_facts: false

  tasks:
    - name: Install httpd
      ansible.builtin.dnf:
        name:
          - httpd
        state: present

    - name: Start and enable httpd.service
      ansible.builtin.systemd_service:
        name: httpd.service
        state: started
        enabled: true

    - name: Start and enable firewalld.service
      ansible.builtin.systemd_service:
        name: firewalld.service
        state: started
        enabled: true

    - name: Permit TCP 80 at firewalld
      ansible.posix.firewalld:
        zone: public
        port: 80/tcp
        permanent: true
        immediate: true
        state: enabled

    - name: Configure IP address
      community.general.nmcli:
        conn_name: eth2
        type: ethernet
        method4: manual
        ip4: '{{ eth2_ip4 }}'
        routes4: '{{ eth2_routes4 }}'
        autoconnect: true
        state: present

    - name: Bring up eth2 to for configuration change to take effect
      ansible.builtin.command: nmcli connection up eth2

    - name: Put index.html
      ansible.builtin.copy:
        content: |
          {{ inventory_hostname }}
        dest: /var/www/html/index.html

- name: Set up VyOS
  hosts: vyos1
  gather_facts: false

  tasks:
   - name: Set IP addresses on L3 interfaces
     vyos.vyos.vyos_l3_interfaces:
       config:
       - name: eth2
         ipv4:
         - address: 192.168.1.1/24
       - name: eth3
         ipv4:
         - address: 192.168.2.1/24
OWARI
EOF
unset UNAME
unset DIR
exit 0

環境構築

構築方法

上述の「ファイル」であげたすべてのファイルを同じフォルダーにいれて、以下のコマンドを実行します。あとは、環境ができあがるのを待つだけです。

コマンド
vagrant plugin install vagrant-vyos
vagrant up

構築ログ

構築ログ
C:\home\ansible>vagrant plugin install vagrant-vyos
Installing the 'vagrant-vyos' plugin. This can take a few minutes...
Fetching vagrant-vyos-1.1.10.gem
Installed the plugin 'vagrant-vyos (1.1.10)'!

C:\home\ansible>
C:\home\ansible>vagrant up
Bringing machine 'ansible1' up with 'virtualbox' provider...
Bringing machine 'linux1' up with 'virtualbox' provider...
Bringing machine 'linux2' up with 'virtualbox' provider...
Bringing machine 'vyos' up with 'virtualbox' provider...
==> ansible1: Box 'almalinux/9' could not be found. Attempting to find and install...
    ansible1: Box Provider: virtualbox
    ansible1: Box Version: >= 0
==> ansible1: Loading metadata for box 'almalinux/9'
    ansible1: URL: https://vagrantcloud.com/api/v2/vagrant/almalinux/9
==> ansible1: Adding box 'almalinux/9' (v9.3.20231118) for provider: virtualbox (amd64)
    ansible1: Downloading: https://vagrantcloud.com/almalinux/boxes/9/versions/9.3.20231118/providers/virtualbox/amd64/vagrant.box
    ansible1:
    ansible1: Calculating and comparing box checksum...
==> ansible1: Successfully added box 'almalinux/9' (v9.3.20231118) for 'virtualbox (amd64)'!
==> ansible1: Importing base box 'almalinux/9'...
==> ansible1: Matching MAC address for NAT networking...
==> ansible1: Checking if box 'almalinux/9' version '9.3.20231118' is up to date...
==> ansible1: Setting the name of the VM: ansible1
==> ansible1: Clearing any previously set network interfaces...
==> ansible1: Preparing network interfaces based on configuration...
    ansible1: Adapter 1: nat
    ansible1: Adapter 2: bridged
==> ansible1: Forwarding ports...
    ansible1: 22 (guest) => 2222 (host) (adapter 1)
==> ansible1: Running 'pre-boot' VM customizations...
==> ansible1: Booting VM...
==> ansible1: Waiting for machine to boot. This may take a few minutes...
    ansible1: SSH address: 127.0.0.1:2222
    ansible1: SSH username: vagrant
    ansible1: SSH auth method: private key
    ansible1: Warning: Connection reset. Retrying...
    ansible1: Warning: Connection aborted. Retrying...
    ansible1: Warning: Remote connection disconnect. Retrying...
    ansible1:
    ansible1: Vagrant insecure key detected. Vagrant will automatically replace
    ansible1: this with a newly generated keypair for better security.
    ansible1:
    ansible1: Inserting generated public key within guest...
    ansible1: Removing insecure key from the guest if it's present...
    ansible1: Key inserted! Disconnecting and reconnecting using new SSH key...
==> ansible1: Machine booted and ready!
==> ansible1: Checking for guest additions in VM...
==> ansible1: Setting hostname...
==> ansible1: Configuring and enabling network interfaces...
==> ansible1: Running provisioner: shell...
    ansible1: Running: C:/Users/y_mrok/AppData/Local/Temp/vagrant-shell20240407-11880-19sr40.sh
    ansible1: + UNAME=y_mrok
    ansible1: + timedatectl set-timezone Asia/Tokyo
    ansible1: + useradd y_mrok
    ansible1: + passwd --stdin y_mrok
    ansible1: + echo pass+123
    ansible1: Changing password for user y_mrok.
    ansible1: passwd: all authentication tokens updated successfully.
    ansible1: + cat
    ansible1: + unset UNAME
    ansible1: + exit 0
==> ansible1: Running provisioner: shell...
    ansible1: Running: C:/Users/y_mrok/AppData/Local/Temp/vagrant-shell20240407-11880-agihag.sh
    ansible1: + UNAME=y_mrok
    ansible1: + dnf -y install python3-pip sshpass tar
    ansible1: AlmaLinux 9 - AppStream                         1.7 MB/s |  10 MB     00:06
    ansible1: AlmaLinux 9 - BaseOS                            3.8 MB/s | 6.9 MB     00:01
    ansible1: AlmaLinux 9 - Extras                            7.5 kB/s |  17 kB     00:02
    ansible1: Package tar-2:1.34-6.el9_1.x86_64 is already installed.
    ansible1: Dependencies resolved.
    ansible1: ================================================================================
    ansible1:  Package                 Arch        Version               Repository      Size
    ansible1: ================================================================================
    ansible1: Installing:
    ansible1:  python3-pip             noarch      21.2.3-7.el9_3.1      appstream      1.7 M
    ansible1:  sshpass                 x86_64      1.09-4.el9            appstream       27 k
    ansible1: Installing weak dependencies:
    ansible1:  python3-setuptools      noarch      53.0.0-12.el9         baseos         839 k
    ansible1:
    ansible1: Transaction Summary
    ansible1: ================================================================================
    ansible1: Install  3 Packages
    ansible1:
    ansible1: Total download size: 2.6 M
    ansible1: Installed size: 13 M
    ansible1: Downloading Packages:
    ansible1: (1/3): python3-setuptools-53.0.0-12.el9.noarch. 1.1 MB/s | 839 kB     00:00
    ansible1: (2/3): python3-pip-21.2.3-7.el9_3.1.noarch.rpm  1.4 MB/s | 1.7 MB     00:01
    ansible1: (3/3): sshpass-1.09-4.el9.x86_64.rpm             10 kB/s |  27 kB     00:02
    ansible1: --------------------------------------------------------------------------------
    ansible1: Total                                           557 kB/s | 2.6 MB     00:04
    ansible1: Running transaction check
    ansible1: Transaction check succeeded.
    ansible1: Running transaction test
    ansible1: Transaction test succeeded.
    ansible1: Running transaction
    ansible1:   Preparing        :                                                        1/1
    ansible1:   Installing       : python3-setuptools-53.0.0-12.el9.noarch                1/3
    ansible1:   Installing       : python3-pip-21.2.3-7.el9_3.1.noarch                    2/3
    ansible1:   Installing       : sshpass-1.09-4.el9.x86_64                              3/3
    ansible1:   Running scriptlet: sshpass-1.09-4.el9.x86_64                              3/3
    ansible1:   Verifying        : python3-pip-21.2.3-7.el9_3.1.noarch                    1/3
    ansible1:   Verifying        : sshpass-1.09-4.el9.x86_64                              2/3
    ansible1:   Verifying        : python3-setuptools-53.0.0-12.el9.noarch                3/3
    ansible1:
    ansible1: Installed:
    ansible1:   python3-pip-21.2.3-7.el9_3.1.noarch  python3-setuptools-53.0.0-12.el9.noarch
    ansible1:   sshpass-1.09-4.el9.x86_64
    ansible1:
    ansible1: Complete!
    ansible1: + su - y_mrok
    ansible1: Collecting ansible
    ansible1:   Downloading ansible-8.7.0-py3-none-any.whl (48.4 MB)
    ansible1: Collecting ansible-lint
    ansible1:   Downloading ansible_lint-6.22.2-py3-none-any.whl (297 kB)
    ansible1: Collecting paramiko
    ansible1:   Downloading paramiko-3.4.0-py3-none-any.whl (225 kB)
    ansible1: Collecting ansible-core~=2.15.7
    ansible1:   Downloading ansible_core-2.15.10-py3-none-any.whl (2.3 MB)
    ansible1: Collecting filelock>=3.3.0
    ansible1:   Downloading filelock-3.13.3-py3-none-any.whl (11 kB)
    ansible1: Collecting pathspec>=0.10.3
    ansible1:   Downloading pathspec-0.12.1-py3-none-any.whl (31 kB)
    ansible1: Collecting subprocess-tee>=0.4.1
    ansible1:   Downloading subprocess_tee-0.4.1-py3-none-any.whl (5.1 kB)
    ansible1: Collecting wcmatch>=8.1.2
    ansible1:   Downloading wcmatch-8.5.1-py3-none-any.whl (39 kB)
    ansible1: Collecting ruamel.yaml>=0.18.5
    ansible1:   Downloading ruamel.yaml-0.18.6-py3-none-any.whl (117 kB)
    ansible1: Collecting ansible-compat>=4.1.11
    ansible1:   Downloading ansible_compat-4.1.11-py3-none-any.whl (23 kB)
    ansible1: Collecting yamllint>=1.30.0
    ansible1:   Downloading yamllint-1.35.1-py3-none-any.whl (66 kB)
    ansible1: Collecting black>=22.8.0
    ansible1:   Downloading black-24.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.7 MB)
    ansible1: Collecting packaging>=21.3
    ansible1:   Downloading packaging-24.0-py3-none-any.whl (53 kB)
    ansible1: Requirement already satisfied: pyyaml>=5.4.1 in /usr/lib64/python3.9/site-packages (from ansible-lint) (5.4.1)
    ansible1: Collecting jsonschema>=4.10.0
    ansible1:   Downloading jsonschema-4.21.1-py3-none-any.whl (85 kB)
    ansible1: Collecting rich>=12.0.0
    ansible1:   Downloading rich-13.7.1-py3-none-any.whl (240 kB)
    ansible1: Collecting pynacl>=1.5
    ansible1:   Downloading PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (856 kB)
    ansible1: Collecting cryptography>=3.3
    ansible1:   Downloading cryptography-42.0.5-cp39-abi3-manylinux_2_28_x86_64.whl (4.6 MB)
    ansible1: Collecting bcrypt>=3.2
    ansible1:   Downloading bcrypt-4.1.2-cp39-abi3-manylinux_2_28_x86_64.whl (698 kB)
    ansible1: Collecting typing-extensions>=4.5.0
    ansible1:   Downloading typing_extensions-4.11.0-py3-none-any.whl (34 kB)
    ansible1: Collecting importlib-resources<5.1,>=5.0
    ansible1:   Downloading importlib_resources-5.0.7-py3-none-any.whl (24 kB)
    ansible1: Collecting resolvelib<1.1.0,>=0.5.3
    ansible1:   Downloading resolvelib-1.0.1-py2.py3-none-any.whl (17 kB)
    ansible1: Collecting jinja2>=3.0.0
    ansible1:   Downloading Jinja2-3.1.3-py3-none-any.whl (133 kB)
    ansible1: Collecting click>=8.0.0
    ansible1:   Downloading click-8.1.7-py3-none-any.whl (97 kB)
    ansible1: Collecting mypy-extensions>=0.4.3
    ansible1:   Downloading mypy_extensions-1.0.0-py3-none-any.whl (4.7 kB)
    ansible1: Collecting tomli>=1.1.0
    ansible1:   Downloading tomli-2.0.1-py3-none-any.whl (12 kB)
    ansible1: Collecting platformdirs>=2
    ansible1:   Downloading platformdirs-4.2.0-py3-none-any.whl (17 kB)
    ansible1: Collecting cffi>=1.12
    ansible1:   Downloading cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (443 kB)
    ansible1: Collecting pycparser
    ansible1:   Downloading pycparser-2.22-py3-none-any.whl (117 kB)
    ansible1: Collecting MarkupSafe>=2.0
    ansible1:   Downloading MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25 kB)
    ansible1: Collecting referencing>=0.28.4
    ansible1:   Downloading referencing-0.34.0-py3-none-any.whl (26 kB)
    ansible1: Collecting rpds-py>=0.7.1
    ansible1:   Downloading rpds_py-0.18.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.1 MB)
    ansible1: Collecting jsonschema-specifications>=2023.03.6
    ansible1:   Downloading jsonschema_specifications-2023.12.1-py3-none-any.whl (18 kB)
    ansible1: Collecting attrs>=22.2.0
    ansible1:   Downloading attrs-23.2.0-py3-none-any.whl (60 kB)
    ansible1: Collecting pygments<3.0.0,>=2.13.0
    ansible1:   Downloading pygments-2.17.2-py3-none-any.whl (1.2 MB)
    ansible1: Collecting markdown-it-py>=2.2.0
    ansible1:   Downloading markdown_it_py-3.0.0-py3-none-any.whl (87 kB)
    ansible1: Collecting mdurl~=0.1
    ansible1:   Downloading mdurl-0.1.2-py3-none-any.whl (10.0 kB)
    ansible1: Collecting ruamel.yaml.clib>=0.2.7
    ansible1:   Downloading ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl (562 kB)
    ansible1: Collecting bracex>=2.1.1
    ansible1:   Downloading bracex-2.4-py3-none-any.whl (11 kB)
    ansible1: Installing collected packages: rpds-py, pycparser, attrs, referencing, MarkupSafe, cffi, resolvelib, packaging, mdurl, jsonschema-specifications, jinja2, importlib-resources, cryptography, typing-extensions, tomli, subprocess-tee, ruamel.yaml.clib, pygments, platformdirs, pathspec, mypy-extensions, markdown-it-py, jsonschema, click, bracex, ansible-core, yamllint, wcmatch, ruamel.yaml, rich, pynacl, filelock, black, bcrypt, ansible-compat, paramiko, ansible-lint, ansible
    ansible1:   WARNING: Value for scheme.platlib does not match. Please report this to <https://github.com/pypa/pip/issues/10151>
    ansible1:   distutils: /home/y_mrok/.local/lib/python3.9/site-packages
    ansible1:   sysconfig: /home/y_mrok/.local/lib64/python3.9/site-packages
    ansible1:   WARNING: Additional context:
    ansible1:   user = True
    ansible1:   home = None
    ansible1:   root = None
    ansible1:   prefix = None
    ansible1: Successfully installed MarkupSafe-2.1.5 ansible-8.7.0 ansible-compat-4.1.11 ansible-core-2.15.10 ansible-lint-6.22.2 attrs-23.2.0 bcrypt-4.1.2 black-24.3.0 bracex-2.4 cffi-1.16.0 click-8.1.7 cryptography-42.0.5 filelock-3.13.3 importlib-resources-5.0.7 jinja2-3.1.3 jsonschema-4.21.1 jsonschema-specifications-2023.12.1 markdown-it-py-3.0.0 mdurl-0.1.2 mypy-extensions-1.0.0 packaging-24.0 paramiko-3.4.0 pathspec-0.12.1 platformdirs-4.2.0 pycparser-2.22 pygments-2.17.2 pynacl-1.5.0 referencing-0.34.0 resolvelib-1.0.1 rich-13.7.1 rpds-py-0.18.0 ruamel.yaml-0.18.6 ruamel.yaml.clib-0.2.8 subprocess-tee-0.4.1 tomli-2.0.1 typing-extensions-4.11.0 wcmatch-8.5.1 yamllint-1.35.1
    ansible1: + unset UNAME
    ansible1: + exit 0
==> ansible1: Running provisioner: shell...
    ansible1: Running: C:/Users/y_mrok/AppData/Local/Temp/vagrant-shell20240407-11880-xgnv0g.sh
    ansible1: + UNAME=y_mrok
    ansible1: + DIR=home/y_mrok/ansible-night-202403
    ansible1: + su - y_mrok
    ansible1: Last login: Sun Apr  7 20:31:19 JST 2024
    ansible1: + unset UNAME
    ansible1: + unset DIR
    ansible1: + exit 0
==> linux1: Box 'almalinux/9' could not be found. Attempting to find and install...
    linux1: Box Provider: virtualbox
    linux1: Box Version: >= 0
==> linux1: Loading metadata for box 'almalinux/9'
    linux1: URL: https://vagrantcloud.com/api/v2/vagrant/almalinux/9
==> linux1: Adding box 'almalinux/9' (v9.3.20231118) for provider: virtualbox (amd64)
==> linux1: Importing base box 'almalinux/9'...
==> linux1: Matching MAC address for NAT networking...
==> linux1: Checking if box 'almalinux/9' version '9.3.20231118' is up to date...
==> linux1: Setting the name of the VM: linux1
==> linux1: Fixed port collision for 22 => 2222. Now on port 2200.
==> linux1: Clearing any previously set network interfaces...
==> linux1: Preparing network interfaces based on configuration...
    linux1: Adapter 1: nat
    linux1: Adapter 2: bridged
    linux1: Adapter 3: intnet
==> linux1: Forwarding ports...
    linux1: 22 (guest) => 2200 (host) (adapter 1)
==> linux1: Running 'pre-boot' VM customizations...
==> linux1: Booting VM...
==> linux1: Waiting for machine to boot. This may take a few minutes...
    linux1: SSH address: 127.0.0.1:2200
    linux1: SSH username: vagrant
    linux1: SSH auth method: private key
    linux1:
    linux1: Vagrant insecure key detected. Vagrant will automatically replace
    linux1: this with a newly generated keypair for better security.
    linux1:
    linux1: Inserting generated public key within guest...
    linux1: Removing insecure key from the guest if it's present...
    linux1: Key inserted! Disconnecting and reconnecting using new SSH key...
==> linux1: Machine booted and ready!
==> linux1: Checking for guest additions in VM...
==> linux1: Setting hostname...
==> linux1: Configuring and enabling network interfaces...
==> linux1: Running provisioner: shell...
    linux1: Running: C:/Users/y_mrok/AppData/Local/Temp/vagrant-shell20240407-11880-nq8pkg.sh
    linux1: + UNAME=y_mrok
    linux1: + timedatectl set-timezone Asia/Tokyo
    linux1: + useradd y_mrok
    linux1: + passwd --stdin y_mrok
    linux1: + echo pass+123
    linux1: Changing password for user y_mrok.
    linux1: passwd: all authentication tokens updated successfully.
    linux1: + cat
    linux1: + unset UNAME
    linux1: + exit 0
==> linux2: Box 'almalinux/9' could not be found. Attempting to find and install...
    linux2: Box Provider: virtualbox
    linux2: Box Version: >= 0
==> linux2: Loading metadata for box 'almalinux/9'
    linux2: URL: https://vagrantcloud.com/api/v2/vagrant/almalinux/9
==> linux2: Adding box 'almalinux/9' (v9.3.20231118) for provider: virtualbox (amd64)
==> linux2: Importing base box 'almalinux/9'...
==> linux2: Matching MAC address for NAT networking...
==> linux2: Checking if box 'almalinux/9' version '9.3.20231118' is up to date...
==> linux2: Setting the name of the VM: linux2
==> linux2: Fixed port collision for 22 => 2222. Now on port 2201.
==> linux2: Clearing any previously set network interfaces...
==> linux2: Preparing network interfaces based on configuration...
    linux2: Adapter 1: nat
    linux2: Adapter 2: bridged
    linux2: Adapter 3: intnet
==> linux2: Forwarding ports...
    linux2: 22 (guest) => 2201 (host) (adapter 1)
==> linux2: Running 'pre-boot' VM customizations...
==> linux2: Booting VM...
==> linux2: Waiting for machine to boot. This may take a few minutes...
    linux2: SSH address: 127.0.0.1:2201
    linux2: SSH username: vagrant
    linux2: SSH auth method: private key
    linux2:
    linux2: Vagrant insecure key detected. Vagrant will automatically replace
    linux2: this with a newly generated keypair for better security.
    linux2:
    linux2: Inserting generated public key within guest...
    linux2: Removing insecure key from the guest if it's present...
    linux2: Key inserted! Disconnecting and reconnecting using new SSH key...
==> linux2: Machine booted and ready!
==> linux2: Checking for guest additions in VM...
==> linux2: Setting hostname...
==> linux2: Configuring and enabling network interfaces...
==> linux2: Running provisioner: shell...
    linux2: Running: C:/Users/y_mrok/AppData/Local/Temp/vagrant-shell20240407-11880-2aku8h.sh
    linux2: + UNAME=y_mrok
    linux2: + timedatectl set-timezone Asia/Tokyo
    linux2: + useradd y_mrok
    linux2: + passwd --stdin y_mrok
    linux2: + echo pass+123
    linux2: Changing password for user y_mrok.
    linux2: passwd: all authentication tokens updated successfully.
    linux2: + cat
    linux2: + unset UNAME
    linux2: + exit 0
==> vyos: Box 'vyos/current' could not be found. Attempting to find and install...
    vyos: Box Provider: virtualbox
    vyos: Box Version: >= 0
==> vyos: Loading metadata for box 'vyos/current'
    vyos: URL: https://vagrantcloud.com/api/v2/vagrant/vyos/current
==> vyos: Adding box 'vyos/current' (v20240404.00.19) for provider: virtualbox
    vyos: Downloading: https://vagrantcloud.com/vyos/boxes/current/versions/20240404.00.19/providers/virtualbox/unknown/vagrant.box
    vyos:
==> vyos: Successfully added box 'vyos/current' (v20240404.00.19) for 'virtualbox'!
==> vyos: Importing base box 'vyos/current'...
==> vyos: Matching MAC address for NAT networking...
==> vyos: Checking if box 'vyos/current' version '20240404.00.19' is up to date...
==> vyos: Setting the name of the VM: vyos1
==> vyos: Fixed port collision for 22 => 2222. Now on port 2202.
==> vyos: Clearing any previously set network interfaces...
==> vyos: Preparing network interfaces based on configuration...
    vyos: Adapter 1: nat
    vyos: Adapter 2: bridged
    vyos: Adapter 3: intnet
    vyos: Adapter 4: intnet
==> vyos: Forwarding ports...
    vyos: 22 (guest) => 2202 (host) (adapter 1)
==> vyos: Running 'pre-boot' VM customizations...
==> vyos: Booting VM...
==> vyos: Waiting for machine to boot. This may take a few minutes...
    vyos: SSH address: 127.0.0.1:2202
    vyos: SSH username: vyos
    vyos: SSH auth method: password
    vyos: Warning: Connection reset. Retrying...
    vyos: Warning: Remote connection disconnect. Retrying...
    vyos: Warning: Connection aborted. Retrying...
==> vyos: Machine booted and ready!
==> vyos: Checking for guest additions in VM...
    vyos: No guest additions were detected on the base box for this VM! Guest
    vyos: additions are required for forwarded ports, shared folders, host only
    vyos: networking, and more. If SSH fails on this machine, please install
    vyos: the guest additions and repackage the box to continue.
    vyos:
    vyos: This is not an error message; everything may continue to work properly,
    vyos: in which case you may ignore this message.
==> vyos: Setting hostname...
==> vyos: Configuring and enabling network interfaces...

==> vyos: Machine 'vyos' has a post `vagrant up` message. This is a message
==> vyos: from the creator of the Vagrantfile, and not from Vagrant itself:
==> vyos:
==> vyos: VyOS box. See https://app.vagrantup.com/vyos for help and bug reports

C:\home\ansible>

説明

構成図(イメージ)

ログインアカウント

Linux サーバー

ansible1 / linux1 / linux2 の 3 台の Linux サーバーはすべて同じアカウントでログインできます。必要に応じて変更ください。

ユーザー名 パスワード
y_mrok pass+123

ルーター

ルーター vyos1 のアカウントです。

ユーザー名 パスワード
vyos vyos

違い

えんでぃ氏のデモ環境と Vagrant で構築した環境の違いです。えんでぃ氏のデモ環境は CentOS Stream 9 & Arista vEOS ですが、Vagrant で構築した環境は AlmaLinux/9 & VyOS です。ログインするときのアカウント ( ユーザー名 / パスワード ) も異なります。それらの差異の関係で playbook の内容などは多少異なりますが、ファイル名は同一にしています。結果、playbook を実行するときのコマンドは同一になっています。環境による違いは各ファイルで吸収しているので、ansible-playbook コマンドはデモどおりに実行できます。

実行確認

ログイン

ansible1

アカウント y_mrok/pass+123 で ansible1 にログインした状態です。この状態から playbook を実行します。

ansible1
[y_mrok@ansible1 ~]$ id
uid=1001(y_mrok) gid=1001(y_mrok) groups=1001(y_mrok) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[y_mrok@ansible1 ~]$
[y_mrok@ansible1 ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:92:30:cb brd ff:ff:ff:ff:ff:ff
    altname enp0s3
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute eth0
       valid_lft 86133sec preferred_lft 86133sec
    inet6 fe80::a00:27ff:fe92:30cb/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:00:6c:00:00:10 brd ff:ff:ff:ff:ff:ff
    altname enp0s8
    inet 192.168.0.10/24 brd 192.168.0.255 scope global noprefixroute eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::200:6cff:fe00:10/64 scope link
       valid_lft forever preferred_lft forever
[y_mrok@ansible1 ~]$
[y_mrok@ansible1 ~]$ cd ansible-night-202403/
[y_mrok@ansible1 ansible-night-202403]$
[y_mrok@ansible1 ansible-night-202403]$ pwd
/home/y_mrok/ansible-night-202403
[y_mrok@ansible1 ansible-night-202403]$

linux1

アカウント y_mrok/pass+123 で linux1 にログインした状態です。この状態から linux1 の状態を確認します。今は eth2 に IP アドレスが未設定ですが、playbook を実行して設定します。

linux1
[y_mrok@linux1 ~]$ id
uid=1001(y_mrok) gid=1001(y_mrok) groups=1001(y_mrok) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[y_mrok@linux1 ~]$
[y_mrok@linux1 ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:92:30:cb brd ff:ff:ff:ff:ff:ff
    altname enp0s3
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute eth0
       valid_lft 86283sec preferred_lft 86283sec
    inet6 fe80::a00:27ff:fe92:30cb/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:00:6c:00:00:12 brd ff:ff:ff:ff:ff:ff
    altname enp0s8
    inet 192.168.0.12/24 brd 192.168.0.255 scope global noprefixroute eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::200:6cff:fe00:12/64 scope link
       valid_lft forever preferred_lft forever
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:00:6c:00:00:22 brd ff:ff:ff:ff:ff:ff
    altname enp0s9
    inet6 fe80::f9e4:ba76:a3e4:fcf4/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
[y_mrok@linux1 ~]$
[y_mrok@linux1 ~]$ pwd
/home/y_mrok
[y_mrok@linux1 ~]$

linux2

アカウント y_mrok/pass+123 で linux2 にログインした状態です。この状態から linux2 の状態を確認します。今は eth2 に IP アドレスが未設定ですが、playbook を実行して設定します。

linux2
[y_mrok@linux2 ~]$ id
uid=1001(y_mrok) gid=1001(y_mrok) groups=1001(y_mrok) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[y_mrok@linux2 ~]$
[y_mrok@linux2 ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:92:30:cb brd ff:ff:ff:ff:ff:ff
    altname enp0s3
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute eth0
       valid_lft 86335sec preferred_lft 86335sec
    inet6 fe80::a00:27ff:fe92:30cb/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:00:6c:00:00:13 brd ff:ff:ff:ff:ff:ff
    altname enp0s8
    inet 192.168.0.13/24 brd 192.168.0.255 scope global noprefixroute eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::200:6cff:fe00:13/64 scope link
       valid_lft forever preferred_lft forever
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:00:6c:00:00:23 brd ff:ff:ff:ff:ff:ff
    altname enp0s9
    inet6 fe80::6229:f08b:c1c4:b8c6/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
[y_mrok@linux2 ~]$
[y_mrok@linux2 ~]$ pwd
/home/y_mrok
[y_mrok@linux2 ~]$

vyos1

アカウント vyos/vyos で vyos1 にログインした状態です。この状態から vyos1 の状態を確認します。今は eth2 と eth3 に IP アドレスが未設定ですが、playbook を実行して設定します。

vyos1
vyos@vyos1.example.jp:~$ id
uid=1002(vyos) gid=100(users) groups=100(users),4(adm),6(disk),27(sudo),30(dip),102(vyattacfg),114(_kea),116(frrvty),117(frr)
vyos@vyos1.example.jp:~$
vyos@vyos1.example.jp:~$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 fe80::200:ff:fe00:0/64 scope link
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:8d:c0:4d brd ff:ff:ff:ff:ff:ff
    altname enp0s3
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic eth0
       valid_lft 85643sec preferred_lft 85643sec
    inet6 fe80::a00:27ff:fe8d:c04d/64 scope link
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:00:6c:00:00:11 brd ff:ff:ff:ff:ff:ff
    altname enp0s8
    inet 192.168.0.11/24 brd 192.168.0.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::200:6cff:fe00:11/64 scope link
       valid_lft forever preferred_lft forever
4: eth2: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
    link/ether 00:00:6c:00:00:21 brd ff:ff:ff:ff:ff:ff
    altname enp0s9
5: eth3: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
    link/ether 00:00:6c:00:00:31 brd ff:ff:ff:ff:ff:ff
    altname enp0s10
6: pim6reg@NONE: <NOARP,UP,LOWER_UP> mtu 1452 qdisc noqueue state UNKNOWN group default qlen 1000
    link/pimreg
vyos@vyos1.example.jp:~$
vyos@vyos1.example.jp:~$ pwd
/home/vyos
vyos@vyos1.example.jp:~$

1_install_ansible

Ansible のインストールなので、ここではスキップします。

2_hello_world

画面に "Hello World!" の文字列を表示します。

command
ansible-playbook 2_hello_world/playbook.yml
2_hello_world/playbook.yml
[y_mrok@ansible1 ansible-night-202403]$ ansible-playbook 2_hello_world/playbook.yml

PLAY [Debug] ***********************************************************************************************************

TASK [Print hello world!] **********************************************************************************************
ok: [localhost] =>
  msg: Hello world!

PLAY RECAP *************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[y_mrok@ansible1 ansible-night-202403]$

3_use_vs_code

VS Code のセットアップなので、ここではスキップします。

4_set_up_linux

まずは疎通確認から

linux1 への疎通確認です。

command
ansible-playbook -i hosts 4_set_up_linux/playbook_1_ping.yml
4_set_up_linux/playbook_1_ping.yml
[y_mrok@ansible1 ansible-night-202403]$ ansible-playbook -i hosts 4_set_up_linux/playbook_1_ping.yml

PLAY [Test with ping] **************************************************************************************************

TASK [Test with ping] **************************************************************************************************
ok: [linux1]

PLAY RECAP *************************************************************************************************************
linux1                     : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[y_mrok@ansible1 ansible-night-202403]$

Apache httpd のインストール

linux1 に Apache httpd をインストールします。

実行前
[y_mrok@linux1 ~]$ rpm -q httpd
package httpd is not installed
[y_mrok@linux1 ~]$
[y_mrok@linux1 ~]$ systemctl status httpd.service
Unit httpd.service could not be found.
[y_mrok@linux1 ~]$
command
ansible-playbook -i hosts 4_set_up_linux/playbook_2_set_up_httpd.yml
4_set_up_linux/playbook_2_set_up_httpd.yml
[y_mrok@ansible1 ansible-night-202403]$ ansible-playbook -i hosts 4_set_up_linux/playbook_2_set_up_httpd.yml

PLAY [Set up Linux] ****************************************************************************************************

TASK [Install httpd] ***************************************************************************************************
changed: [linux1]

TASK [Start and enable httpd.service] **********************************************************************************
changed: [linux1]

TASK [Start and enable firewalld.service] ******************************************************************************
changed: [linux1]

PLAY RECAP *************************************************************************************************************
linux1                     : ok=3    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[y_mrok@ansible1 ansible-night-202403]$
実行後
[y_mrok@linux1 ~]$ rpm -q httpd
httpd-2.4.57-5.el9.x86_64
[y_mrok@linux1 ~]$
[y_mrok@linux1 ~]$ systemctl status httpd.service
● httpd.service - The Apache HTTP Server
     Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; preset: disabled)
     Active: active (running) since Sun 2024-04-07 22:23:47 JST; 54s ago
       Docs: man:httpd.service(8)
   Main PID: 4684 (httpd)
     Status: "Total requests: 0; Idle/Busy workers 100/0;Requests/sec: 0; Bytes served/sec:   0 B/sec"
      Tasks: 213 (limit: 11928)
     Memory: 25.4M
        CPU: 162ms
     CGroup: /system.slice/httpd.service
             tq4684 /usr/sbin/httpd -DFOREGROUND
             tq4685 /usr/sbin/httpd -DFOREGROUND
             tq4686 /usr/sbin/httpd -DFOREGROUND
             tq4687 /usr/sbin/httpd -DFOREGROUND
             mq4688 /usr/sbin/httpd -DFOREGROUND
[y_mrok@linux1 ~]$

firewalldの通信許可設定追加

linux1 のファイアウォールに 80/tcp の通信許可を追加します。

実行前
[y_mrok@linux1 ~]$ sudo firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0 eth1 eth2
  sources:
  services: cockpit dhcpv6-client ssh
  ports:
  protocols:
  forward: yes
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
[y_mrok@linux1 ~]$
command
ansible-playbook -i hosts 4_set_up_linux/playbook_3_permit_httpd_at_firewalld.yml --start-at-task 'Permit TCP 80 at firewalld'
4_set_up_linux/playbook_3_permit_httpd_at_firewalld.yml
[y_mrok@ansible1 ansible-night-202403]$ ansible-playbook -i hosts 4_set_up_linux/playbook_3_permit_httpd_at_firewalld.yml --start-at-task 'Permit TCP 80 at firewalld'

PLAY [Set up Linux] ****************************************************************************************************

TASK [Permit TCP 80 at firewalld] **************************************************************************************
changed: [linux1]

PLAY RECAP *************************************************************************************************************
linux1                     : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[y_mrok@ansible1 ansible-night-202403]$
実行後
[y_mrok@linux1 ~]$ sudo firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0 eth1 eth2
  sources:
  services: cockpit dhcpv6-client ssh
  ports: 80/tcp
  protocols:
  forward: yes
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
[y_mrok@linux1 ~]$

IPアドレスの設定

linux1 の eth2 に IP アドレスを設定します。

実行前
[y_mrok@linux1 ~]$ nmcli device
DEVICE  TYPE      STATE                   CONNECTION
eth0    ethernet  connected               eth0
eth1    ethernet  connected               System eth1
lo      loopback  connected (externally)  lo
eth2    ethernet  disconnected            --
[y_mrok@linux1 ~]$
[y_mrok@linux1 ~]$ nmcli
eth0: connected to eth0
        "Intel 82540EM"
        ethernet (e1000), 08:00:27:92:30:CB, hw, mtu 1500
        ip4 default
        inet4 10.0.2.15/24
        route4 default via 10.0.2.2 metric 100
        route4 10.0.2.0/24 metric 100
        inet6 fe80::a00:27ff:fe92:30cb/64
        route6 fe80::/64 metric 1024

eth1: connected to System eth1
        "Intel 82540EM"
        ethernet (e1000), 00:00:6C:00:00:12, hw, mtu 1500
        inet4 192.168.0.12/24
        route4 192.168.0.0/24 metric 101
        inet6 fe80::200:6cff:fe00:12/64
        route6 fe80::/64 metric 256

lo: connected (externally) to lo
        "lo"
        loopback (unknown), 00:00:00:00:00:00, sw, mtu 65536
        inet4 127.0.0.1/8
        inet6 ::1/128
        route6 ::1/128 metric 256

eth2: disconnected
        "Intel 82540EM"
        1 connection available
        ethernet (e1000), 00:00:6C:00:00:22, hw, mtu 1500

DNS configuration:
        servers: 10.0.2.3
        domains: localdomain
        interface: eth0

Use "nmcli device show" to get complete information about known devices and
"nmcli connection show" to get an overview on active connection profiles.

Consult nmcli(1) and nmcli-examples(7) manual pages for complete usage details.
[y_mrok@linux1 ~]$
[y_mrok@linux1 ~]$ ip -br address show
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             10.0.2.15/24 fe80::a00:27ff:fe92:30cb/64
eth1             UP             192.168.0.12/24 fe80::200:6cff:fe00:12/64
eth2             UP
[y_mrok@linux1 ~]$
command
ansible-playbook -i hosts 4_set_up_linux/playbook_4_nmcli.yml --start-at-task 'Configure IP address'
4_set_up_linux/playbook_4_nmcli.yml
[y_mrok@ansible1 ansible-night-202403]$ ansible-playbook -i hosts 4_set_up_linux/playbook_4_nmcli.yml --start-at-task 'Configure IP address'

PLAY [Set up Linux] ****************************************************************************************************

TASK [Configure IP address] ********************************************************************************************
changed: [linux1]

TASK [Bring up eth2 to for configuration change to take effect] ********************************************************
changed: [linux1]

PLAY RECAP *************************************************************************************************************
linux1                     : ok=2    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[y_mrok@ansible1 ansible-night-202403]$
実行後
[y_mrok@linux1 ~]$ nmcli
eth0: connected to eth0
        "Intel 82540EM"
        ethernet (e1000), 08:00:27:92:30:CB, hw, mtu 1500
        ip4 default
        inet4 10.0.2.15/24
        route4 default via 10.0.2.2 metric 100
        route4 10.0.2.0/24 metric 100
        inet6 fe80::a00:27ff:fe92:30cb/64
        route6 fe80::/64 metric 1024

eth1: connected to System eth1
        "Intel 82540EM"
        ethernet (e1000), 00:00:6C:00:00:12, hw, mtu 1500
        inet4 192.168.0.12/24
        route4 192.168.0.0/24 metric 101
        inet6 fe80::200:6cff:fe00:12/64
        route6 fe80::/64 metric 256

eth2: connected to eth2
        "Intel 82540EM"
        ethernet (e1000), 00:00:6C:00:00:22, hw, mtu 1500
        inet4 192.168.1.2/24
        route4 192.168.1.0/24 metric 102
        route4 192.168.2.0/24 via 192.168.1.1 metric 102
        inet6 fe80::8a72:4698:7eef:212/64
        route6 fe80::/64 metric 1024

lo: connected (externally) to lo
        "lo"
        loopback (unknown), 00:00:00:00:00:00, sw, mtu 65536
        inet4 127.0.0.1/8
        inet6 ::1/128
        route6 ::1/128 metric 256

DNS configuration:
        servers: 10.0.2.3
        domains: localdomain
        interface: eth0

Use "nmcli device show" to get complete information about known devices and
"nmcli connection show" to get an overview on active connection profiles.

Consult nmcli(1) and nmcli-examples(7) manual pages for complete usage details.
[y_mrok@linux1 ~]$
[y_mrok@linux1 ~]$ nmcli device
DEVICE  TYPE      STATE                   CONNECTION
eth0    ethernet  connected               eth0
eth1    ethernet  connected               System eth1
eth2    ethernet  connected               eth2
lo      loopback  connected (externally)  lo
[y_mrok@linux1 ~]$
[y_mrok@linux1 ~]$ ip -br address show
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             10.0.2.15/24 fe80::a00:27ff:fe92:30cb/64
eth1             UP             192.168.0.12/24 fe80::200:6cff:fe00:12/64
eth2             UP             192.168.1.2/24 fe80::8a72:4698:7eef:212/64
[y_mrok@linux1 ~]$

5_use_variables

linux2を自動設定する

linux1 と同様に linux2 を設定します。

実行前 / Linux1
[y_mrok@linux1 ~]$ ip -br address show
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             10.0.2.15/24 fe80::a00:27ff:fe92:30cb/64
eth1             UP             192.168.0.12/24 fe80::200:6cff:fe00:12/64
eth2             UP             192.168.1.2/24 fe80::8a72:4698:7eef:212/64
[y_mrok@linux1 ~]$
[y_mrok@linux1 ~]$ ip route show proto static
192.168.2.0/24 via 192.168.1.1 dev eth2 metric 102
[y_mrok@linux1 ~]$
実行前 / Linux2
[y_mrok@linux2 ~]$ ip -br address show
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             10.0.2.15/24 fe80::a00:27ff:fe92:30cb/64
eth1             UP             192.168.0.13/24 fe80::200:6cff:fe00:13/64
eth2             UP             fe80::feb9:fc53:20f6:a1ae/64
[y_mrok@linux2 ~]$
[y_mrok@linux2 ~]$ ip route show proto static
[y_mrok@linux2 ~]$
command
ansible-playbook -i hosts 5_use_variables/playbook_1_use_variables.yml
5_use_variables/playbook_1_use_variables.yml
[y_mrok@ansible1 ansible-night-202403]$ ansible-playbook -i hosts 5_use_variables/playbook_1_use_variables.yml

PLAY [Set up Linux] ****************************************************************************************************

TASK [Install httpd] ***************************************************************************************************
ok: [linux1]
changed: [linux2]

TASK [Start and enable httpd.service] **********************************************************************************
ok: [linux1]
changed: [linux2]

TASK [Start and enable firewalld.service] ******************************************************************************
ok: [linux1]
changed: [linux2]

TASK [Permit TCP 80 at firewalld] **************************************************************************************
ok: [linux1]
changed: [linux2]

TASK [Configure IP address] ********************************************************************************************
ok: [linux1]
changed: [linux2]

TASK [Bring up eth2 to for configuration change to take effect] ********************************************************
changed: [linux1]
changed: [linux2]

PLAY RECAP *************************************************************************************************************
linux1                     : ok=6    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
linux2                     : ok=6    changed=6    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[y_mrok@ansible1 ansible-night-202403]$
実行後 / Linux1
[y_mrok@linux1 ~]$ ip -br address show
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             10.0.2.15/24 fe80::a00:27ff:fe92:30cb/64
eth1             UP             192.168.0.12/24 fe80::200:6cff:fe00:12/64
eth2             UP             192.168.1.2/24 fe80::8a72:4698:7eef:212/64
[y_mrok@linux1 ~]$
[y_mrok@linux1 ~]$ ip route show proto static
192.168.2.0/24 via 192.168.1.1 dev eth2 metric 102
[y_mrok@linux1 ~]$
実行後 / Linux2
[y_mrok@linux2 ~]$ ip -br address show
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             10.0.2.15/24 fe80::a00:27ff:fe92:30cb/64
eth1             UP             192.168.0.13/24 fe80::200:6cff:fe00:13/64
eth2             UP             192.168.2.2/24 fe80::3ba3:3130:d5d8:6368/64
[y_mrok@linux2 ~]$
[y_mrok@linux2 ~]$ ip route show proto static
192.168.1.0/24 via 192.168.2.1 dev eth2 metric 102
[y_mrok@linux2 ~]$

index.html

linux1 と linux2 に index.html を配置します。

実行前 / Linux1
[y_mrok@linux1 ~]$ ls -l /var/www/html/
total 0
[y_mrok@linux1 ~]$
実行前 / Linux2
[y_mrok@linux2 ~]$ ls -l /var/www/html/
total 0
[y_mrok@linux2 ~]$
command
ansible-playbook -i hosts 5_use_variables/playbook_2_add_index_html.yml --start-at-task 'Put index.html'
5_use_variables/playbook_2_add_index_html.yml
実行後 / Linux1
[y_mrok@ansible1 ansible-night-202403]$ ansible-playbook -i hosts 5_use_variables/playbook_2_add_index_html.yml --start-at-task 'Put index.html'

PLAY [Set up Linux] ****************************************************************************************************

TASK [Put index.html] **************************************************************************************************
changed: [linux2]
changed: [linux1]

PLAY RECAP *************************************************************************************************************
linux1                     : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
linux2                     : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[y_mrok@ansible1 ansible-night-202403]$
実行後 / Linux1
[y_mrok@linux1 ~]$ ls -l /var/www/html/
total 4
-rw-r--r--. 1 root root 7 Apr  8 20:00 index.html
[y_mrok@linux1 ~]$
[y_mrok@linux1 ~]$ cat /var/www/html/index.html
linux1
[y_mrok@linux1 ~]$
実行後 / Linux2
[y_mrok@linux2 ~]$ ls -l /var/www/html/
total 4
-rw-r--r--. 1 root root 7 Apr  8 20:00 index.html
[y_mrok@linux2 ~]$
[y_mrok@linux2 ~]$ cat /var/www/html/index.html
linux2
[y_mrok@linux2 ~]$

6_set_up_eos

VyOS の自動化

ルーター vyos1 の eth2 と eht3 に IP アドレスを設定し、linux1(192.168.1.0/24) と linux2(192.168.2.0/24) 間でルーティングできるようにします。

実行前
vyos@vyos1.example.jp:~$ ip -br address show
lo               UNKNOWN        127.0.0.1/8 fe80::200:ff:fe00:0/64 ::1/128
eth0             UP             10.0.2.15/24 fe80::a00:27ff:fe8d:c04d/64
eth1             UP             192.168.0.11/24 fe80::200:6cff:fe00:11/64
eth2             DOWN
eth3             DOWN
pim6reg@NONE     UNKNOWN
vyos@vyos1.example.jp:~$
vyos@vyos1.example.jp:~$ show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
       f - OpenFabric,
       > - selected route, * - FIB route, q - queued, r - rejected, b - backup
       t - trapped, o - offload failure

S>* 0.0.0.0/0 [210/0] via 10.0.2.2, eth0, weight 1, 00:29:18
C>* 10.0.2.0/24 is directly connected, eth0, 00:29:19
C>* 192.168.0.0/24 is directly connected, eth1, 00:29:23
vyos@vyos1.example.jp:~$
command
ansible-playbook -i hosts 6_set_up_eos/playbook_1_set_up_eos.yml
6_set_up_eos/playbook_1_set_up_eos.yml
[y_mrok@ansible1 ansible-night-202403]$ ansible-playbook -i hosts 6_set_up_eos/playbook_1_set_up_eos.yml

PLAY [Set up VyOS] *****************************************************************************************************

TASK [Set IP addresses on L3 interfaces] *******************************************************************************
changed: [vyos1]

PLAY RECAP *************************************************************************************************************
vyos1                      : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[y_mrok@ansible1 ansible-night-202403]$
実行後
vyos@vyos1.example.jp:~$ ip -br address show
lo               UNKNOWN        127.0.0.1/8 fe80::200:ff:fe00:0/64 ::1/128
eth0             UP             10.0.2.15/24 fe80::a00:27ff:fe8d:c04d/64
eth1             UP             192.168.0.11/24 fe80::200:6cff:fe00:11/64
eth2             UP             192.168.1.1/24 fe80::200:6cff:fe00:21/64
eth3             UP             192.168.2.1/24 fe80::200:6cff:fe00:31/64
pim6reg@NONE     UNKNOWN
vyos@vyos1.example.jp:~$
vyos@vyos1.example.jp:~$ show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
       f - OpenFabric,
       > - selected route, * - FIB route, q - queued, r - rejected, b - backup
       t - trapped, o - offload failure

S>* 0.0.0.0/0 [210/0] via 10.0.2.2, eth0, weight 1, 00:32:59
C>* 10.0.2.0/24 is directly connected, eth0, 00:33:00
C>* 192.168.0.0/24 is directly connected, eth1, 00:33:04
C>* 192.168.1.0/24 is directly connected, eth2, 00:00:24
C>* 192.168.2.0/24 is directly connected, eth3, 00:00:22
vyos@vyos1.example.jp:~$

linux1 から linux2 に対し、ping / curl / tracepath を実行します。

実行結果 / Linux1
[y_mrok@linux1 ~]$ ping -c2 192.168.2.2
PING 192.168.2.2 (192.168.2.2) 56(84) bytes of data.
64 bytes from 192.168.2.2: icmp_seq=1 ttl=63 time=5.50 ms
64 bytes from 192.168.2.2: icmp_seq=2 ttl=63 time=2.76 ms

--- 192.168.2.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1006ms
rtt min/avg/max/mdev = 2.755/4.129/5.504/1.374 ms
[y_mrok@linux1 ~]$
[y_mrok@linux1 ~]$ curl 192.168.2.2
linux2
[y_mrok@linux1 ~]$
[y_mrok@linux1 ~]$ tracepath -l 1500 -n 192.168.2.2
 1:  192.168.1.1                                           1.435ms
 2:  192.168.2.2                                           2.941ms !H
     Resume: pmtu 1500
[y_mrok@linux1 ~]$

linux2 から linux1 に対し、ping / curl / tracepath を実行します。

実行結果 / Linux2
[y_mrok@linux2 ~]$ ping -c2 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=63 time=2.42 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=63 time=2.22 ms

--- 192.168.1.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1015ms
rtt min/avg/max/mdev = 2.218/2.318/2.418/0.100 ms
[y_mrok@linux2 ~]$
[y_mrok@linux2 ~]$ curl 192.168.1.2
linux1
[y_mrok@linux2 ~]$
[y_mrok@linux2 ~]$ tracepath -l 1500 -n 192.168.1.2
 1:  192.168.2.1                                           1.359ms
 2:  192.168.1.2                                           2.204ms !H
     Resume: pmtu 1500
[y_mrok@linux2 ~]$

その他

ネットワーク

えんでぃ氏のデモ環境と同じ 192.168.0.0/24 を想定しています。ご自身の環境にあわせて変更ください。

ターミナルソフト

ansible1 に接続するターミナルソフトは別途ご用意ください。デモ環境と同じように VS Code + Remote SSH や TeraTerm / PuTTY などのターミナルソフトなど、お好みにあわせてご用意ください。

参考資料

https://speakerdeck.com/stopendy/how-to-start-ansible-small
https://github.com/stopendy/ansible-night-202403
https://ansible-users.connpass.com/event/310794/
https://www.virtualbox.org/
https://www.vagrantup.com/
https://zenn.dev/y_mrok/books/vagrant-no-tsukaikata

Discussion