Tambourine作業メモ

主にスキル習得のためにやった作業のメモ。他人には基本的に無用のものです。

Ansibleで遊んでみる(1)

ちょっと仕事でAnsibleを使うことになったので勉強してみる。

コンピュータの性能が向上して、HWとしてのサーバ1台につき複数のOSを起動できるようになってきたのがゼロ年代の後半ぐらい。それまではインフラ担当者がセットアップしなければならいサーバというのは数台から十数台ぐらいまでだった。しかし、物理CPUを複数の論理CPUに分割してバーチャルマシン(VM)に割り当てられるようになると、それまで扱っていた数台のHWごとに10ぐらいのOSが起動するようになる。すると、インフラ担当者がセットアップするOSは一気に数十台規模になり、それまでと同じ手段でセットアップしていたのではやってられなくなった。

そこで、OSのセットアップ内容を記述したらそれで自動的にセットアップをしてくれる仕組みが登場した。ChefとかPuppetが代表的なものである。セットアップ内容を記述したものをプログラムコードと同じようにバージョン管理もできるようになった。さらに、ソフトウェア開発で当たり前になってきたCI/CDをこれらのセットアップコードに適用して、セットアップ内容のテストを自動化も出来るようになった。ChefやPuppetはRubyで書かれていたので、自然とこのテストはRubyのテストフレームワークであるRSpecで行うようになり、Serverspecというフレームワークが作られた。このようにソフトウェア開発と同じようにサーバ構成をCI/CDする手法を指して、Infrastracture as Code(IaC)と呼ばれるようになる。

さらに、時代はクラウドになり、サーバは欲しいときにいつでもプロビジョニングできるようになった。しかし、ChefやPuppetはあらかじめエージェントをインストールされたターゲットしか操作できない。自分で作ったVMイメージを使っている場合には問題にならないが、クラウドではそれは使いづらい。そこで、だいたいどこにでもあらかじめインストールされているPythonを使うことにした。コントロールサーバでPythonスクリプトを構成にあわせて生成し、SSHで送り込んで実行する。これがAnsibleである。

そして、IaCであるからには、Ansibleで作成した構成情報(Playbook)もCI/CDで管理されなければならない。そのためにはテストフレームワークが必要になるはずだ。

インフラから足を洗ったはずの私がなぜAnsibleをやっているプロジェクトに呼ばれたかというと、単にAnsibleのPlaybookを書いてくれというのではなく、CI/CDを前提としたIaCをAnsibleでやりたいのでソフトウェア開発の知見を活かして仕組みを組み立てて欲しいとのことだった。Ruby LoverなのでAnsibleに積極的ではなかったんでまるっと最初からお勉強しているところだ。

さっぱりわからないなりに数日ネットを彷徨った結果、AnsibleのテストフレームワークはMoleculeというものがあるらしい。2015年頃に出来たものなのでかなり新しめで、Playbookをロール(Playbookの構成要素)単位でテストすることが出来る。ものがインフラなので、普通のテストフレームワークのsetup/teardownをどうするかが問題になるわけだが、テスト実行単位でコンテナやVMを作るところまでセットでやってくれる。有り難い。

というわけで、まずはインストール。ひとまず、macOS上でテストにDockerを使う前提とする。 すべてPython上で動かすので、必要に応じてvirtualenvなどを使うこと。私は面倒でやらなかった。また今度泣くことにする。

よくわからないなりに順次いれていく。

まずは、ansible。pipで入れてもいいみたいだけど、Homebrewでいれた。brew install ansibleでOK。

次にmolecule。DockerとLintも使うので、pip install molecule[docker, lint]でOK。

先にAnsibleの疎通確認をしておこう。

qiita.com

これを参考にする。

とりあえずは、localhostを操作するようにするので、localhostsshできるようにする。

  • [システム環境設定] - [共有] でリモートログインにチェックを入れる
  • ssh-copy-id -i キー名 localhost
  • ssh localhostして接続出来ればOK

動作を確認。

> ansible-console --inventory localhost, --user tambara
Welcome to the ansible console.
Type help or ? to list commands.

tambara@all (1)[f:5]$ ping
[WARNING]: Platform darwin on host localhost is using the discovered Python interpreter at /usr/bin/python, but future
installation of another Python interpreter could change the meaning of that path. See
https://docs.ansible.com/ansible/2.10/reference_appendices/interpreter_discovery.html for more information.
localhost | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

ふむふむ

ヘルプ出してみる

tambara@all (1)[f:5]$ ?

Documented commands (type help <topic>):
========================================
EOF             dnf              include_role   service_facts      
add_host        dpkg_selections  include_tasks  set_fact           
apt             exit             include_vars   set_stats          
apt_key         expect           iptables       setup              
apt_repository  fail             known_hosts    shell              
assemble        fetch            lineinfile     slurp              
assert          file             list           stat               
async_status    find             meta           subversion         
async_wrapper   forks            package        systemd            
become          gather_facts     package_facts  sysvinit           
become_method   get_url          pause          tempfile           
become_user     getent           ping           template           
blockinfile     git              pip            unarchive          
cd              group            raw            uri                
check           group_by         reboot         user               
command         help             remote_user    verbosity          
copy            hostname         replace        wait_for           
cron            import_playbook  rpm_key        wait_for_connection
debconf         import_role      script         yum                
debug           import_tasks     serial         yum_repository     
diff            include          service      

tambara@all (1)[f:5]$ help user
Manage user accounts
Parameters:
  name Name of the user to create, remove or modify.
  uid Optionally sets the I(UID) of the user.
  comment Optionally sets the description (aka I(GECOS)) of user account.
  hidden macOS only, optionally hide the user from the login window and system preferences.
  non_unique Optionally when used with the -u option, this option allows to change the user ID to a non-unique value.
  seuser Optionally sets the seuser type (user_u) on selinux enabled systems.
  group Optionally sets the user's primary group (takes a group name).
  groups List of groups user will be added to. When set to an empty string C(''), the user is removed from all groups except the primary group.
  append If C(yes), add the user to the groups specified in C(groups).
  shell Optionally set the user's shell.
  home Optionally set the user's home directory.
  skeleton Optionally set a home skeleton directory.
  password Optionally set the user's password to this crypted value.
  state Whether the account should exist or not, taking action if the state is different from what is stated.
  create_home Unless set to C(no), a home directory will be made for the user when the account is created or if the home directory does not exist.
  move_home If set to C(yes) when used with C(home: ), attempt to move the user's old home directory to the specified directory if it isn't there already and the old home exists.
  system When creating an account C(state=present), setting this to C(yes) makes the user a system account.
  force This only affects C(state=absent), it forces removal of the user and associated directories on supported platforms.
  remove This only affects C(state=absent), it attempts to remove directories associated with the user.
  login_class Optionally sets the user's login class, a feature of most BSD OSs.
  generate_ssh_key Whether to generate a SSH key for the user in question.
  ssh_key_bits Optionally specify number of bits in SSH key to create.
  ssh_key_type Optionally specify the type of SSH key to generate.
  ssh_key_file Optionally specify the SSH key filename.
  ssh_key_comment Optionally define the comment for the SSH key.
  ssh_key_passphrase Set a passphrase for the SSH key.
  update_password C(always) will update passwords if they differ.
  expires An expiry time for the user in epoch, it will be ignored on platforms that do not support this.
  password_lock Lock the password (C(usermod -L), C(usermod -U), C(pw lock)).
  local Forces the use of "local" command alternatives on platforms that implement it.
  profile Sets the profile of the user.
  authorization Sets the authorization of the user.
  role Sets the role of the user.

なるほど。