3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AnsibleからOpenStackを操作する

Last updated at Posted at 2024-03-23

はじめに

本記事は、下記の続きです。

KVMホストに Ansible をインストールし、上記で構築した OpenStack を操作することが目標です。

Ansible のインストール

KVMホストに Ansible をインストールします。

python -m venv venv_ansible
source venv_ansible/bin/activate
vi requirements.txt
requirements.txt
openstacksdk
ansible
ansible-core
pip install -r requirements.txt

今回はバージョンを指定しませんでしたが、以下のバージョンがインストールされました。

実行結果例
$ pip freeze | egrep "openstack|ansible"
ansible==8.7.0
ansible-core==2.15.9
openstackclient==4.0.0
openstacksdk==3.0.0

Ansible から OpenStack を操作するには、 openstack.cloud という collection が必要なのですが、すでにインストールされています。

実行結果例
$ ansible-galaxy collection list | grep openstack
openstack.cloud               2.2.0 

認証情報の設定

前回の記事で構築した OpenStack 環境では、 openstackclient という pod から OpenStack を操作することができます。
openstackclient に接続し、認証情報を ~/.config/openstack/ にコピーします。

mkdir ~/.config
oc cp openstackclient:.config/openstack ~/.config

clouds.yamlsecure.yaml がコピーされました。

clouds.yaml の中を見ると、 auth_url が以下のようになっています。

            auth_url: https://keystone-public-openstack.apps-crc.testing

プロトコルが https なので、rootCA もコピーする必要があります。
openssl コマンドで確認すると、 rootca-public という rootCA が必要のようです。

実行結果例
$ openssl s_client -connect keystone-public-openstack.apps-crc.testing:443
CONNECTED(00000003)
depth=1 CN = rootca-public
verify return:1
depth=0 
verify return:1
---
Certificate chain
 0 s:
   i:CN = rootca-public
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: ecdsa-with-SHA256
   v:NotBefore: Mar 16 08:36:24 2024 GMT; NotAfter: Mar 16 08:36:24 2025 GMT
 1 s:CN = rootca-public
   i:CN = rootca-public
   a:PKEY: id-ecPublicKey, 256 (bit); sigalg: ecdsa-with-SHA256
   v:NotBefore: Mar 16 08:34:29 2024 GMT; NotAfter: Mar 15 08:34:29 2029 GMT
---
Server certificate
(以下略)

rootca-public のインストール

rootCA は /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem にありますので、確認します。

実行結果例
$ oc rsh openstackclient cat /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem 
# rootca-public
-----BEGIN CERTIFICATE-----
(中略)
-----END CERTIFICATE-----
# rootca-internal
-----BEGIN CERTIFICATE-----
(中略)
-----END CERTIFICATE-----
# rootca-ovn
-----BEGIN CERTIFICATE-----
(中略)
-----END CERTIFICATE-----
# ACCVRAIZ1
(以下略)

今回必要なのは rootca-public だけですが、念のため rootca-public, rootca-internal, rootca-ovn のCA認証情報を /etc/pki/ca-trust/source/anchors/rootca.pem にコピーし、以下を実行します。

sudo update-ca-trust

次に、Python のCA認証情報は別ファイルで管理されているので、そちらにも反映します。
反映の手順は下記記事を参考にしました。

local_ca_install.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import certifi

cabundle = certifi.where()
local_rootCA = '/etc/pki/ca-trust/source/anchors/rootca.pem'

print( 'read from {}'.format( local_rootCA ) )
with open( local_rootCA, 'rb' ) as infile:
    myrootca = infile.read()

print( 'append to {}'.format( cabundle ) )
with open( cabundle, 'ab' ) as outfile:
    outfile.write( myrootca )

print( '{} has been imported.'.format( local_rootCA ) )
python local_ca_install.py

cirrosイメージ入手

リソースを作成する前に cirrosイメージを入手しておきます。

wget https://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img

これで準備ができました。

Ansibleによる OpenStack の各種リソース作成

以下のリソースを作成します。

項目 リソース名 備考
project demo-project
user demo-user
network demo-net
subnet demo-subnet allocation_pool: 10.0.0.100-10.0.0.250
router demo-router public に接続する
security group demo-sg ssh, icmp を許可
flavor demo-flavor
keypair demo-key 秘密鍵は demo-key-private.pem として保存
image demo-cirros
volume demo-volume demo-cirros の bootable volume
server demo-instance
all-in-one.yml
---
- hosts: localhost
  tasks:
    - name: admin - create project
      openstack.cloud.project:
        cloud: overcloud
        state: present
        name: demo-project
        description: demo-project
        domain_id: Default
        enabled: True
 
    - name: admin - create user
      openstack.cloud.identity_user:
        cloud: overcloud
        state: present
        name: demo-user
        password: secret
        domain: Default

    - name: admin - grant demo role on the user demo in the project demo-project
      openstack.cloud.role_assignment:
        cloud: overcloud
        user: demo-user
        role: member
        domain: Default
        project: demo-project
 
    - name: set_fact user authentication
      set_fact:
        auth_user:
          auth_url: https://keystone-public-openstack.apps-crc.testing
          password: secret
          project_domain_name: Default
          project_name: demo-project
          user_domain_name: Default
          username: demo-user
 
    - name: user - create network
      openstack.cloud.network:
        auth: "{{ auth_user }}"
        state: present
        name: demo-net

    - name: user - create subnet
      openstack.cloud.subnet:
        auth: "{{ auth_user }}"
        state: present
        name: demo-subnet
        network_name: demo-net
        cidr: 10.0.0.0/24
        dns_nameservers: 192.168.122.1
        enable_dhcp: true
        allocation_pool_start: 10.0.0.100
        allocation_pool_end: 10.0.0.250
 
    - name: user - create router
      openstack.cloud.router:
        auth: "{{ auth_user }}"
        state: present
        name: demo-router
        network: public
        interfaces:
          - demo-subnet
 
    - name: user - create security group
      openstack.cloud.security_group:
        auth: "{{ auth_user }}"
        state: present
        name: demo-sg
 
    - name: user - add security group rule (ssh)
      openstack.cloud.security_group_rule:
        auth: "{{ auth_user }}"
        state: present
        security_group: demo-sg
        protocol: tcp
        port_range_min: 22
        port_range_max: 22
        remote_ip_prefix: 0.0.0.0/0
 
    - name: user - add security group rule (icmp)
      openstack.cloud.security_group_rule:
        auth: "{{ auth_user }}"
        state: present
        security_group: demo-sg
        protocol: icmp
        port_range_min: -1
        port_range_max: -1
        remote_ip_prefix: 0.0.0.0/0
 
    - name: admin - create flavor
      openstack.cloud.compute_flavor:
        cloud: overcloud
        state: present
        name: demo-flavor
        ram: 1024
        vcpus: 1
        disk: 0
 
    - name: user - create keypair
      openstack.cloud.keypair:
        auth: "{{ auth_user }}"
        state: present
        name: demo-key
      register: keypair_info
 
    - name: create private key
      copy:
        content: "{{ keypair_info['keypair']['private_key'] }}"
        dest: ./demo-key-private.pem
        mode: 0600
 
    - name: user - upload cirros image
      openstack.cloud.image:
        auth: "{{ auth_user }}"
        state: present
        name: demo-cirros
        container_format: bare
        disk_format: qcow2
        filename: cirros-0.6.2-x86_64-disk.img
 
    - name: user - create volume
      openstack.cloud.volume:
        auth: "{{ auth_user }}"
        state: present
        volume_type: nfs
        size: 40
        bootable: true
        image: demo-cirros
        display_name: demo-volume
 
    - name: user - create VM
      openstack.cloud.server:
        auth: "{{ auth_user }}"
        name: demo-instance
        boot_volume: demo-volume
        flavor: ce9ed399-b30b-4f92-83a6-917ad1966e72
        key_name: demo-key
        security_groups: demo-sg
        network: demo-net
        floating_ip_pools: public
        state: present

※最後のインスタンスを作成するところ、flavorの指定が UUID でないといけないようで、使いにくい……。

では実行します。

ansible-playbook all-in-one.yml -v

openstackclient に接続して確認します。

実行結果例
$ oc rsh openstackclient 
sh-5.1$ openstack server list --all
+--------------------------------------+---------------+--------+----------------------------------------+--------------------------+-------------+
| ID                                   | Name          | Status | Networks                               | Image                    | Flavor      |
+--------------------------------------+---------------+--------+----------------------------------------+--------------------------+-------------+
| 87a8dbaf-8cbf-4d9f-9a5d-83eac9296615 | demo-instance | ACTIVE | demo-net=10.0.0.147, 192.168.122.208   | N/A (booted from volume) | demo-flavor |
+--------------------------------------+---------------+--------+----------------------------------------+--------------------------+-------------+
sh-5.1$ ping -c 2 192.168.122.208
PING 192.168.122.208 (192.168.122.208) 56(84) bytes of data.
64 bytes from 192.168.122.208: icmp_seq=1 ttl=62 time=1.97 ms
64 bytes from 192.168.122.208: icmp_seq=2 ttl=62 time=1.12 ms

--- 192.168.122.208 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 1.117/1.543/1.970/0.426 ms
sh-5.1$ exit
$ ssh -i demo-key-private.pem cirros@192.168.122.208
The authenticity of host '192.168.122.208 (192.168.122.208)' can't be established.
ED25519 key fingerprint is SHA256:rviyA0kkufqxpfwJZ0Kb0EbbvGlMr5EWMmrsRXZ6x0A.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.122.208' (ED25519) to the list of known hosts.
$ cat /etc/os-release
PRETTY_NAME="CirrOS 0.6.2"
NAME="CirrOS"
VERSION_ID="0.6.2"
ID=cirros
HOME_URL="https://cirros-cloud.net"
BUG_REPORT_URL="https://github.com/cirros-dev/cirros/issues"

Ansibleによる OpenStack の各種リソース削除

詳細は省略しますが、作成のときと逆の順番で削除していきます。

---
- hosts: localhost
  tasks:
    - name: set_fact user authentication
      set_fact:
        auth_user:
          auth_url: https://keystone-public-openstack.apps-crc.testing
          password: secret
          project_domain_name: Default
          project_name: demo-project
          user_domain_name: Default
          username: demo-user
 
    - name: user - delete VM
      openstack.cloud.server:
        auth: "{{ auth_user }}"
        state: absent
        name: demo-instance
(以下略)
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?