あざらし備忘録。

音ゲー好きなウェッブエンジニアがいろいろ思った事やった事を書いていくブログです

Macの環境構築を通じて0からAnsibleに触れる[Ansible][Mac]

こんにちは。

今回は、以前@t-wadaさんが書かれていた

t-wada.hatenablog.jp

を読んで「めっちゃ良いじゃないですか」と思ったので実際に自環境もやってみました。

上記エントリをはじめ、リンクとして書かれていた@hnakamurさんやmawatariさんのブログも参考にさせて頂きましたmm

ありがとうございますmm

AnsibleでHomebrew, Cask, Atomエディターのパッケージを管理する - Qiita

HomebrewとAnsibleでMacの開発環境構築を自動化する | mawatari.jp

Ansibleも触ったことがないのでちょうどいいやということで。 また、今までHomebrew Caskも使ってみた事がなかったのでちょうどいいやということで。

なのでそのあたりの説明等も自分なりに書きつつまとめたいと思います。

基本は@t-wadaさんのブログを見ながら進めてみるということで、以下作業メモ程度に残しておきます。

Ansibleの構成

Ansibleは構成管理ツールであるということはわかっているのですがなんせ初心者なので、まずはAnsibleの構成から。

Ansibleは以下の3つによって主に構成されています。

  • インベントリ(hosts)
    • 作業対象のホストを記述します。
    • 今回はローカル環境で動かすだけなのでlocalhostとなります。
  • モジュール
    • 実際の具体的な実行内容を記述します。
    • 例えばファイルをコピーしたり、コマンドを実行したり、と言った部分です。
  • playbook
    • 前述のモジュール群を用いた処理を記述します。
    • このplaybookがプロビジョニングの内容となっていきます。

モジュールは標準で用意されてるものや、その他公開されているもので足りればそれらを用いれば良く、なければ自作すれば良い、といった感じですね。

サーバーで実行可能なのであればモジュールの言語自体は問わないようです。(てっきりPythonで書かなきゃいけないもんだと思っていた)

また、playbookを用意しなくてもansibleコマンドで実行も可能なようですが、今回はおそらく入れる物量も多くなりますしplaybookをサッと書こうと思います。

playbookを用いたプロビジョニングの実行は以下のコマンドになります。

ansible-playbook <playbook.yml>

これでざっくり概要のまとめは完了したので、プロビジョニングの準備を行っていきます。

プロビジョニング準備

t-wadaさんのブログに習って進めて行きます。

ディレクトリ作成

作業用のディレクトリを掘る。

mkdir .macbook-provisioning
cd .macbook-provisioning

ansibleのために必要な物を用意

先に述べた

  • インベントリ(hosts)
  • モジュール
  • playbook

を準備していく。

インベントリ(hosts)の用意

今回はローカルの環境構築のみなのでlocalhostとだけ。

echo 'localhost' > hosts

モジュールの用意

いい感じのがあったら使う、なければ作る、といったところですが、今回は

があるので、こちらを使いました。

playbookの用意

@t-wadaさんの記事を存分に参考にさせていただきつつ、記述していたものの意味をまとめてみました。

他にも色々と設定もできるようですが、まずは第一歩ということで...

# hosts
#
# hostsファイルに記述したホスト情報の中からプロビジョニング対象とするホストを選択する
# hosts: プロビジョニング対象ホスト名
# hosts: host1,host2,host3
# hosts:
#   - host1
#   - host2
#   - host3
- hosts: localhost
  # connection
  #
  # connection: local とすることでlocalhostの場合必要のないSSHをしないようにできる
  # [http://docs.ansible.com/playbooks_delegation.html#local-playbooks]
  connection: local
  # gather_facts
  #
  # 対象サーバーから情報を収集するかどうか
  # noとすれば取得しない。デフォルトはyes
  # 集めた情報は配列形式となっていて、playbook内で使用可能
  gather_facts: no
  # sudo
  #
  # sudoで実行するかどうか
  # noならばしないし、yesならばrootで実行する
  # ユーザ名を指定するとそのユーザで実行する
  sudo: no
  # vars
  #
  # タスク実行の際に必要な変数を定義しておける
  vars:
   # homebrew_taps
   # 
   # brew tapする必要がある場合はこの項目に記述しておく
    homebrew_taps:
      - hoge/hogehoge
    # homebrew_packages
    #
    # brew installでインストールするものをこの項目に記述しておく
    # [http://docs.ansible.com/homebrew_module.html]
    # [http://kiririmode.hatenablog.jp/entry/20150101/1420074034]
    homebrew_packages:
      - foo
      - { name: fuga, state: linked, install_options: force }
    # homebrew_cask_packages
    #
    # brew cask installでインストールするものをこの項目に記述しておく
    # [http://docs.ansible.com/homebrew_cask_module.html]
    homebrew_cask_packages:
      - bar
      - { name: piyo }
  # tasks
  #
  # ここに書いたタスクが上から順番に実行される
  # もし途中から実行したい場合は
  # ansible-playbook localhost.yml --start-at-task="タスク名"
  # ステップ実行したい場合は
  # ansible-playbook localhost.yml --step
  tasks:
   # name:
   # 
   # タスク名を記述
    - name: homebrew の tap リポジトリを追加
      # モジュール名: モジュールのオプション
      # 
      # このタスクでどのモジュールを実行するかとどんなオプションで実行するかを指定
      # with_itemsでforeachっぽく処理して順番にtapしている
      # [http://docs.ansible.com/homebrew_tap_module.html]
      homebrew_tap: tap={{ item }} state=present
      with_items: homebrew_taps
    - name: homebrew をアップデート
      homebrew: update_homebrew=yes

    # brew
    - name: brew パッケージをインストール
      homebrew: >
        name={{ item.name }}
        state={{ item.state | default('latest') }}
        install_options={{
          item.install_options | default() | join(',')
          if item.install_options is not string
          else item.install_options
        }}
      with_items: homebrew_packages
      register: brew_result
    - name: brew パッケージの情報保存先ディレクトリを作成
      file: path=brew_info state=directory
    - name: brew パッケージの情報を保存
      shell: brew info {{ item }} > brew_info/{{ item }}
      with_items: brew_result.results | selectattr('changed') | map(attribute='item') | map(attribute='name') | list

    # cask
    - name: homebrew-cask のインストール
      homebrew: name=brew-cask state=latest
    - name: cask パッケージをインストール
      homebrew_cask: name={{ item.name }} state={{ item.state|default('installed') }}
      with_items: homebrew_cask_packages
      register: cask_result
    - name: cask パッケージの情報保存先ディレクトリを作成
      file: path=cask_info state=directory
    - name: cask パッケージの情報を保存
      shell: brew cask info {{ item }} > cask_info/{{ item }}
      with_items: cask_result.results | selectattr('changed') | map(attribute='item') | map(attribute='name') | list
  # handlers
  #
  # playbookの終了時に実行される
  # 基本はタスクの記述と変わらない
  # サービスの再起動等に用いる事が多い
  # [https://docs.ansible.com/playbooks_intro.html#handlers-running-operations-on-change]
  # タスクにnotify: ハンドラー名 といった形で指定を加えるとそのタスクがトリガーとなってハンドラーが起動する
  handlers:

今回はbrewで入れるものの吟味や記述までは手が回らなかったので、時間を作ってコツコツ進めて行きたいですmm

ざっとですがAnsibleに触れられたので、良い体験になりました。 また、本当に構造がシンプルで書きやすくて良いですね!気に入りました!

次は現状chefで書いていたvagrantのプロビジョニングを試しにAnsibleで書いてみたりするのもいいかなぁ。