Blogs

    in  Ansible

    ansible_specを試してみた

    以前試したServerspecですが、Ansibleと連携するプロダクトがあるということで試してみました。 その名もansible_specです。 Ansibleで構成したサーバーの接続情報を共有したいというモチベーションはTestinfraと同様です。 やはり同じ接続設定をいろんなところに設定するのは避けたいところですよね。

    インストール

    gemでサクッとインストールします。特につまづくところはありませんでした。

    1
    
    $ sudo gem install ansible_spec
    

    設定

    ansibleの設定がおいてあるディレクトリで下記を実行。

    1
    2
    3
    4
    5
    6
    
    $ ansiblespec-init
                    create  spec
                    create  spec/spec_helper.rb
                    create  Rakefile
                    create  .ansiblespec
                    create  .rspec
    

    .ansiblespec の内容は下記の通りです。 dynamic inventoryもサーポートしていて、inventoruyにはansibleのiオプションで指定するdynamic inventoryを実現するpythonスクリプトを指定します。

    1
    2
    3
    4
    
    ---
    -
      playbook: site.yml
      inventory: ec2.py
    

    site.ymlは下記の通りです。 hostsにはEC2のtagを指定しています。KeyはNameです。 roleにはテストのある位置を指定しています。

    1
    2
    3
    4
    
    - name: gside-TDD
      hosts: tag_Name_gside_gentoo
      roles:
        - apache
    

    テストはAnsibleでいうroleと同じディレクトリに配置します。 今回は roles/apache/spec/apache_spec.rb にファイルをおきました。内容は以前ServerSpecを試した時のものと同じです。。 ファイル名は *_spec.rb の形式でないといけないようです。 ディレクトリ構成に関しては確かに多くの構成はroleベースで書くことが多いので、roleを前提としている構成は実用には困らないかもしれません。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    require 'spec_helper'
    
    describe service('apache2'), :if => os[:family] == 'gentoo' do
      it { should be_enabled }
      it { should be_running }
    end
    
    describe port(80) do
      it { should be_listening }
    end
    

    実行

    rake allで実行してもいいのですが、rake -T でテスト対象を一覧表示した上で個別に実行できます。

    1
    2
    3
    4
    
    $ rake -T
    /usr/lib64/ruby/2.2.0/open3.rb:193: warning: Insecure world writable dir /usr/local/bin in PATH, mode 040757
    rake all                   # Run serverspec to all test
    rake serverspec:gside-TDD  # Run serverspec for gside-TDD
    

    これでテスト実行できると思ったのですが、このままだとうまく実行できませんでした。 実行結果の一部抜粋です。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    $ rake serverspec:gside-TDD
    /usr/lib64/ruby/2.2.0/open3.rb:193: warning: Insecure world writable dir /usr/local/bin in PATH, mode 040757
    Run serverspec for gside-TDD to {"uri"=>"52.198.30.198", "port"=>22}
    /usr/bin/ruby22 -I/usr/local/lib64/ruby/gems/2.2.0/gems/rspec-support-3.5.0/lib:/usr/local/lib64/ruby/gems/2.2.0/gems/rspec-core-3.5.4/lib /usr/local/lib64/ruby/gems/2.2.0/gems/rspec-core-3.5.4/exe/rspec --pattern \{roles\}/\{apache\}/spec/\*_spec.rb
    /usr/lib64/ruby/2.2.0/open3.rb:193: warning: Insecure world writable dir /usr/local/bin in PATH, mode 040757
    No backend type is specified. Fall back to :exec type.
    No backend type is specified. Fall back to :exec type.
    No backend type is specified. Fall back to :exec type.
    ....
     should be listening (FAILED - 3)
    
    Failures:
    
      1) Service "apache2" should be enabled
         On host `52.198.30.198'
         Failure/Error: it { should be_enabled }
           expected Service "apache2" to be enabled
           /bin/sh -c rc-update\ show\ \|\ grep\ --\ \\\\s\\\*apache2\\\\s\\\*\\\\\\\|\\\\s\\\*\\\(boot\\\|default\\\)
    
         # ./roles/apache/spec/apache_spec.rb:5:in `block (2 levels) in <top (required)>'
    
    ...
    

    自動生成される spec/spec_helper.rbspec を下記のように修正したら動きました。

    1
    2
    
    - connection = ENV['TARGET_CONNECTION']
    + connection = 'ssh'
    

    これで実行すると正しく動きました。 なんか設定が漏れているのかもしれませんが、一旦良しとしています。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    
    $ rake serverspec:gside-TDD
    /usr/lib64/ruby/2.2.0/open3.rb:193: warning: Insecure world writable dir /usr/local/bin in PATH, mode 040757
    Run serverspec for gside-TDD to {"uri"=>"52.198.30.198", "port"=>22}
    /usr/bin/ruby22 -I/usr/local/lib64/ruby/gems/2.2.0/gems/rspec-support-3.5.0/lib:/usr/local/lib64/ruby/gems/2.2.0/gems/rspec-core-3.5.4/lib /usr/local/lib64/ruby/gems/2.2.0/gems/rspec-core-3.5.4/exe/rspec --pattern \{roles\}/\{apache\}/spec/\*_spec.rb
    /usr/lib64/ruby/2.2.0/open3.rb:193: warning: Insecure world writable dir /usr/local/bin in PATH, mode 040757
    
    Service "apache2"
      should be enabled
      should be running
    
    Port "80"
      should be listening
    
    Finished in 0.09668 seconds (files took 1.2 seconds to load)
    3 examples, 0 failures
    

    まとめ

    インフラの構成管理とテストを色々試してきました。 Terraform, Ansibleを構成管理ツールとして、Testinfra又は Serverspec + ansible_spec で低レベルのテスト、infratasterで高レベルのテストを実施することができました。 それぞれのツールをもう少し深掘りしたいところですが、これでモダンなインフラへの入り口に立てたかなと思います。


    in  Book

    「Infrastructure as Code」を読んだ

    Infrastructure as Code(IaC)もずいぶん使い古された感のあるワードですね。

    出始めの頃は自分もChefとかPuppetを使いさえすればいいもんだと勘違いしていました。

    実際はもっと大きな考え方であり、この本は網羅的にIaCの考え方を抑えていってくれるので、 視野狭窄にならないようにするためにも、読んでおいて損はない本だと思いました。

    内容

    この本はIaCに関する技術的トピッックを取り上げるというよりかは、概念とか思想とかそういったものを教えてくれます。 よくあるアンチパターンとどうやってIoCを取り入れていくか、トピックごとにパターンを提示していきながら、 再現可能でセキュアで品質の高いシステムを作っていく方法が書かれています。

    そう、システム。当たり前だけどシステムはインフラだけで動いてるんじゃないんです。

    読んでる間は結局うちの組織にどうやって適用すればいいんだよっていう葛藤との戦いでした。 何度この本を読みながら天を仰いだことか。 IaCを適用していく上での組織論みたいな部分もあるにはあるんですが、 100個組織があったら100個の文化があるわけで、そんな綺麗に当てはまるわけもないですし、 そんな細かいところまでこの本も解決するつもりはなく、こんなベストプラクティスがあるよって程度です。

    それでも、この本が提示してくれたメリットには夢がありました。

    特に面白かった所

    結局、アプリケーション開発の良い部分を、インフラに持って行こうという点が、特に後半では強くなります。 ユニットテストやCIをインフラに適応させていく話は、数年前はアプリケーション開発をやってた身としては、非常に納得感のあるものでした。 コードを描いてて、テストがあることによる安心感は相当なもんです。 そしてインフラに何か変更を加えるとき、様々な要素が検証環境と違うことがある中で本番環境に手を入れる時の緊張感も相当なもんです。

    考えたこと

    自分の組織に如何に適応していくかを考え続けた読書であったことは前述の通りです。 そして最後に思ったのは、結局アプリ・インフラとあまりに分かれている組織はダメなんだなということでした。 アプリはもっとインフラを理解しないといけないし、インフラももっとアプリを理解しないといけない。 これもずっと言われ続けてきていることですけど。

    アプリ屋さんがセルフサービでインフラを構築できないと、IoCの求めている姿にはならないし、そのためにはインフラの知識が必要です。 そしてインフラ屋さんは、アプリケーションのニーズを理解しつつ、アプリ屋さんがセルフサービスでインフラを構築できるような基盤を整えていくことが必要になっていくんでしょう。

    まとめ

    古き良きインフラ運用のデメリットと、IaCがもたらしてくれる明るい未来を予感させてくれました。 まだまだやることがあるなと途方に暮れつつも、ワクワクさせてくれる本でした。


    in  Infra

    Testinfra使ってみた

    前回、ServerSpecを使ってインフラのテストを書いてみましたが、 同じ思想でpythonベースのプロダクトを教えてもらったので試してみました。

    1
    
    Testinfra aims to be a Serverspec equivalent in python
    

    インストール

    pipが入っていれば簡単にインストールできちゃいます。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    
    $ sudo pip install testinfra
    Collecting testinfra
      Downloading testinfra-1.5.4-py2.py3-none-any.whl (60kB)
        100% |████████████████████████████████| 61kB 1.9MB/s
    Requirement already satisfied (use --upgrade to upgrade): six>=1.4 in /usr/lib64/python2.7/site-packages (from testinfra)
    Collecting pytest!=3.0.2 (from testinfra)
      Downloading pytest-3.0.7-py2.py3-none-any.whl (172kB)
        100% |████████████████████████████████| 176kB 1.7MB/s
    Requirement already satisfied (use --upgrade to upgrade): py>=1.4.29 in /usr/lib64/python2.7/site-packages (from pytest!=3.0.2->testinfra)
    Requirement already satisfied (use --upgrade to upgrade): setuptools in /usr/lib64/python2.7/site-packages (from pytest!=3.0.2->testinfra)
    Installing collected packages: pytest, testinfra
    Successfully installed pytest-3.0.7 testinfra-1.5.4
    

    テストの実行

    テストを書きます。 assertで書けるのはxunitの方が慣れている身としては書きやすいですね。

    1
    2
    3
    4
    
    def test_apache_running_and_enabled(Service):
        apache = Service("apache2")
        assert apache.is_running
    #    assert apache.is_enabled
    

    実行してみます。 Ansibleのダイナミックインベントリをそのまま使えるのは便利ですね。 下記のようにNameタグの値でテスト対象を指定しています。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    
    $ testinfra -v --connection=ansible --ansible-inventory=./ec2.py --hosts=tag_Name_gside_gentoo test.py
    ============================================================================== test session starts ===============================================================================
    platform linux2 -- Python 2.7.12, pytest-3.0.7, py-1.4.30, pluggy-0.4.0 -- /usr/bin/python2.7
    cachedir: .cache
    rootdir: /home/hoge/Dropbox/ansible_private, inifile:
    plugins: testinfra-1.5.4
    collected 1 items
    
    test.py::test_apache_running_and_enabled[ansible://13.112.48.230] PASSED
    
    ============================================================================= pytest-warning summary =============================================================================
    WP1 None Module already imported so can not be re-written: testinfra
    ================================================================== 1 passed, 1 pytest-warnings in 7.90 seconds ===================================================================
    

    ランレベルに登録されているかのテストは、今回テスト対象だったGentooには対応していないようでした。 そこはServerSpecはきっちり対応してるのがすごい所ですね。

    まとめ

    assertで書ける、ansibleの接続設定がそのまま使えるところは非常に使いよいです。


    in  GCP

    QwikLabsでGoogle Cloud Platform(GCP)に触ってみた

    触ったことのあるPublicクラウドといえばAWSとAzureが主で、 国内だとIDCFとかホワイトクラウドが少々といったところでした。

    QwiklabsというAWSのセルフペースラボを受けられるサイトがあるのですが、 Google Coud Platformに関する結構な数のコースが期間限定で無料で受けられるということで試してみました。

    とりあえず体験しとくの大事。

    インスタンスの設定が柔軟

    インスタンスタイプもあるけど、 VCPU数とメモリ容量を決め打ちで指定することもできるんですね。 AWS触りだしてからインスタンスタイプの世界にすっかり慣れてたけど、 プライベートクラウドでリソースを指定してた頃の懐かしさが思い出されました。

    WebからSSHできる

    WebベースのSSHクライアントがコンソールについてるんですね。 動きはもっさりしているので、常用には耐えれないですけど、 場合によっては秘密鍵を配らなくていいってのは精神衛生上も非常にいいですね。

    モニタリングツール(StackDriver)はAWSもモニタリングできるみたい?

    モニタリングツールはAWSみたいにコンソールと統合されていなくて、 若干野暮ったく感じたのですが、AWSもモニタリングできるようですね。 なるほど、モニタリングツールとして独り立ちしているイメージなんでしょうか。 本来であれば監視するものとされるものは分離されているべきでしょうから、 AWSをStackDriverで監視というのはアリですね。今度試してみよう。

    まとめ

    Docker管理のKubernetesまで体験できたのはめっけもんでした。 Docker環境下のローリングアップデートはなかなか素敵ですね。

    GCPで運用していくってなると、まだまだ知らなければいけないことは多いんだろうけど、 最初のハードルを超えれたのはお得な体験でした。


    in  Book

    「The DevOps 逆転だ!究極の継続的デリバリー」を読んだ

    DevOpsは最近ではバズワードでもなんでもなくて、 普通に考えなきゃいけない概念になってきました。

    と言っても自分の周辺ではまだまだという感があるので、 とりあえず軽い気持ちで読んでみたのが本書です。 あまり考えずに買ったので、物語調で始まった時には少し面食らいました。

    内容

    ボロボロのIT組織を立て直していくサクセスストーリーです。 新規開発は遅れに遅れ、リリースしたものは障害を繰り返している中で、 最後にはビジネス・開発・運用の流れをスムーズににし、DevOpsで大逆転という内容です。

    DevOpsの周辺技術についての解説書ではありません。 組織の根幹を支えるITをどう作り上げて行くか、組織論的な内容です。

    特に面白かった所

    同じ業界の人間なので、最初のうちはあまりの試練に身につまされる思いでした。 その分、DevOpsに対する甘い考えだけでなく、そこに至るまでの苦労を追体験することができました。 DevOpsに至るまでに組織をどのように変えていかなければならないかを知るいい手がかりになりました。

    考えたこと

    新たに動くものを立ち上げること、動いているシステムに手を加えるという変化は、 常になんらかの障害と隣り合わせです。 このリスクをコントロールして変化のスピード上げて行ったところが、ビジネスで成功を納める。 当たり前ではありますが、まだまだできていない組織が大半ではないでしょうか。

    本書ではそんな当たり前とは程遠い、ITとビジネスが足を引っ張りあってる状態からスタートしています。 こんなダメな状態がよく聞く話だったりして、共感とともに危機感が湧きました。

    こんな足の引っ張り合いは、組織的・技術的両面で解決していかなければならないことなのですが、 今の世の中では技術的側面はずいぶん整備されてきたと感じます。 となると、残る難題は組織的な部分なわけですが、ここはなかなか特効薬はありません。 そこでDevOps完成後の理想である「1日10回リリース」みたいな、わかりやすい指標を持つのが、一つの解だなと感じました。

    まとめ

    物語とはいえ、組織と技術の両輪がうまく回った時にこれだけの良い流れが作り上げられて行くのかと。 翻って自分の周辺を見渡すと、両輪ともまだまだという感じ。 とはいえあがいて見ようかなという勇気を本書がくれたのも確かでした。


    in  AWS

    S3をマウントするgoofysを試してみた

    S3をEC2からマウントするgoofysを試してみた。 昔s3fsを試したことがあるんだけど、パフォーマンスが問題になったりしたことがありました。 巷では爆速と噂のgoofysですが、とりあえずパフォーマンスは置いておいて、できないことが何かを見ておきました。

    何ができないのか

    公式にもPOSIXは二の次ということで、できないことを書いてくれています。 group,modeとかは固定,simlinkは動かないそうです。 後、atime,mtime,ctimeが全部同じになります。

    インストール

    とはいえ使い心地を見ときたかったので、インストールして見ました。 ansibleで環境を作って見ました。 fuseとgoが必要です。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    
    ---
    - hosts: tag_Name_gside_goofys
      remote_user: gentoo
      become: true
      tasks:
        - name: install sys-fs/fuse
          portage: >
            package=sys-fs/fuse
            state=present
        - name: install dev-lang/go
          portage: >
            package=dev-lang/go
            state=present
        - name: goofys Download
          get_url: url="https://github.com/kahing/goofys/releases/download/v0.0.10/goofys" sha256sum="78baba6f9c3d8cb06a55a872f0380bc8b37af649a0a7d6961d0789a3bdcd62d4" dest="/usr/local/bin" mode="744"
    

    実はmountの設定も書いていたのですが、IAM RoleでEC2に権限を与えて動作させようとした場合、fstabの設定ではマウントしてくれませんでした。 Credentialを置きたくない・置けないポリシーの場合はネックになりそうですね。

    検証

    IAM Role + fstabは動作しなかったので、コマンドでマウントします。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    $ goofys gside-goofys /mnt/s3/
    
    $ df -h
    ファイルシス   サイズ  使用  残り 使用% マウント位置
    udev              10M     0   10M    0% /dev
    /dev/xvda2       8.6G  2.3G  5.9G   28% /
    tmpfs             49M  240K   49M    1% /run
    shm              242M     0  242M    0% /dev/shm
    cgroup_root       10M     0   10M    0% /sys/fs/cgroup
    gside-goofys     1.0P     0  1.0P    0% /mnt/s3
    

    ファイルを作ってみました。

    1
    2
    3
    
    $ touch /mnt/s3/hoge
    $ ls -la /mnt/s3/hoge
    -rw-r--r-- 1 root root 0  2月 19 21:09 /mnt/s3/hoge
    

    ヘルプにもありますが、fileのモードは644,uid,gidは0がデフォルトで固定です。 これらの固定値はオプションで違う値に変更は可能ですが、固定値であることは変わりません。

    1
    2
    
    $ ln -sf hige /mnt/s3/foo
    ln: シンボリックリンク '/mnt/s3/foo' の作成に失敗しました: 関数は実装されていません
    

    シンボリックリンクは作れません。

    まとめ

    この割り切りが受け入れれるかというところでしょうね。 それでも爆速という点を重視して、制限を受け入れた上での使い道はいくらでもあると思います。 が、IAM Role+fstabの部分は対応を切望したいところです。


    in  Book

    Web API The Good Partsを読んだ

    昔はWebAPIを作る事が多かったんだけど、ここ数年はすっかりインフラ寄りになって、機能寄りの設計をやらなくなってました。 そんな中に読んだのが、Web API The Good Parts。 技術書の中にはかつての自分の成果物に赤面してしまう本が多々ありますが、この本は赤面度上位に位置しますね。

    内容

    大きく分けるとエンドポイント、レスポンス、HTTPへの準拠という点に関して細かいところにまで突っ込んだ考察を繰り広げてくれます。 実例なんかもあげてくれるので、理想と現実という部分にも配慮されています。

    特に面白かった所

    プログラマーならプログラミングをする上で変数の名付けというのには意識を向けるものと思います。 そういった名付けにも通じる内容なのですが、エンドポイントやレスポンスに関して、WebAPIの世界で改めて説明されると新鮮なものがありました。 あとは、最近インフラ屋として関わる事が多いHTTPプロトコルをいかに利用するかという内容。 インフラもアプリケーションも両方経験してきた中で、自分の中の溝を埋めてくれるものでした。

    考えたこと

    普段何気なく使ってるAPIですが、こういった設計の指針を包括的に提示してくれる本は本当に貴重ですね。 そして何よりも、自分のアプリケーションの知識が時代遅れになっていることを痛感しました。 Rest Level3って知らなかったなー、Martin Fowlerさん、こんなところにも出てくるんですね。

    そして、こういったアプリケーションの設計に関する本も読んでおかないと、 その基盤であるインフラに何を求められているのか、どう使われているのか、おざなりになってしまうと感じました。

    まとめ

    冒頭に書いてある通り、赤面する事この上なかったです。 今後自分の関わるWebAPIはできる限り恥ずかしくしたくないものです。 とりあえず、今のプロジェクトでこの本で学んだことを発表しておきました。


    in  Infra

    infratasterに入門してみた

    「infratasterも使いましょう」という神の啓示が降りたので導入してみました。

    infratasterのインストール

    Infratasterを実行するマシンにインストールします。 テスト対象のマシンではなくて、テストを実行する側のサーバーです。 Ruby2.2が入っている前提です。

    1
    2
    
    $ sudo gem install serverspec
    $ rspec --init
    

    infratasterはruby2.2が必要なので、注意してください。

    Apacheの起動をテストする

    spec/spec_helper.rbを編集します。 Infratasterのインクルードと、サーバーのIPアドレスの定義をします。

    1
    2
    3
    4
    5
    
    require 'infrataster/rspec'
    
    Infrataster::Server.define(:app) do |server|
        server.address = '54.64.10.41/32'
    end
    

    spec/gside.org/sample_spec.rb を編集します。 HTTPで接続して、コンテンツの中身に “It works!“が含まれること、content-typeが text/htmlであることをテストしています。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    describe port(80) do
      it { should be_listening }
    end
    
    describe server(:app) do
      describe http('http://app') do
        it "responds content including 'It works!'" do
          expect(response.body).to include('It works!')
        end
        it "responds as 'text/html'" do
          expect(response.headers['content-type']).to eq("text/html")
        end
      end
    end
    

    それではテストを実行していきます。 先日作成したserverspecのテストも同時に流れます。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    $ rake spec
    /usr/bin/ruby22 -I/usr/local/lib64/ruby/gems/2.2.0/gems/rspec-support-3.5.0/lib:/usr/local/lib64/ruby/gems/2.2.0/gems/rspec-core-3.5.4/lib /usr/local/lib64/ruby/gems/2.2.0/gems/rspec-core-3.5.4/exe/rspec --pattern spec/gside.org/\*_spec.rb
    /usr/local/lib64/ruby/gems/2.2.0/gems/rspec-core-3.5.4/lib/rspec/core/rake_task.rb:79: warning: Insecure world writable dir /usr/local/bin in PATH, mode 040757
    
    Service "apache2"
      should be enabled
      should be running
    
    Port "80"
      should be listening
    
    server 'app'
      http 'http://app' with {:params=>{}, :method=>:get, :headers=>{}}
        responds content including 'It works!'
        responds as 'text/html'
    
    Finished in 0.18223 seconds (files took 1.36 seconds to load)
    5 examples, 0 failures
    

    失敗した時の出力はこんな感じ。 “It works!” -> “t works!” にしてみました。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    server 'app'
      http 'http://app' with {:params=>{}, :method=>:get, :headers=>{}}
        responds content including 'It works!' (FAILED - 1)
        responds as 'text/html'
    
    Failures:
    
      1) server 'app' http 'http://app' with {:params=>{}, :method=>:get, :headers=>{}} responds content including 'It works!'
         On host `gside.org'
         Failure/Error: expect(response.body).to include('It works!')
           expected "<html><body><h1>t works!</h1></body></html>\n" to include "It works!"
           Diff:
           @@ -1,2 +1,2 @@
           -It works!
           +<html><body><h1>t works!</h1></body></html>
    
    
         # ./spec/gside.org/sample_spec.rb:15:in `block (3 levels) in <top (required)>'
    

    まとめ

    serverspecとinfratasterを合わせれば内部・外部からのインフラのテストまで自動化できて、非常に安心です。 UnitTestとSeleniumを合わせて使っているような安心感です。


    in  Ansible

    AnsibleでGentooにApacheをインストール

    AnsibleでGentooの環境を作れるのかなあと思ったら、モジュールが提供されていました。

    Apacheをインストールしてデフォルトランレベルに登録するところまでやってみました。

    Apacheのインストール

    Ansibleの設定ファイルを書きます。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    ---
    - hosts: tag_Name_gside_gentoo
      remote_user: gentoo
      become: true
      tasks:
        - name: install apache
          portage: >
            package=apache
            state=present
        - name: add apache default runlevel
          service: >
            name=apache2
            state=started
            enabled=yes
    

    ここでちょっとハマったのが、Ansibleを実行するホストだけでなくて、対象のホストのpythonのバージョンにも注意しないといけないことでした。 対象ホストがpython3系がデフォルトだったため、AttributeError: ‘dict’ object has no attribute ‘iteritems’ みたいなエラーが出てたので、pythonのデフォルトバージョンを2系にセットします。

    1
    2
    3
    4
    5
    
    $ eselect python list
    Available Python interpreters:
      [1]   python2.7
      [2]   python3.4 *
    $ eselect python set 1
    

    作成した設定ファイルを実行します。

    1
    
    $ ansible-playbook  gside.yaml -i ./ec2.py
    

    Apacheの起動をテストする

    Apacheをインストール・起動・デフォルトランレベルへの登録までできましたので、先日作ったServerSpecのテストを流してみます。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    $ rake spec
    (in /home/hoge)
    /usr/bin/ruby21 -I/usr/local/lib64/ruby/gems/2.1.0/gems/rspec-support-3.5.0/lib:/usr/local/lib64/ruby/gems/2.1.0/gems/rspec-core-3.5.4/lib /usr/local/lib64/ruby/gems/2.1.0/gems/rspec-core-3.5.4/exe/rspec --pattern spec/gside.org/\*_spec.rb
    /usr/local/lib64/ruby/gems/2.1.0/gems/rspec-core-3.5.4/lib/rspec/core/rake_task.rb:79: warning: Insecure world writable dir /usr/local/bin in PATH, mode 040757
    
    Service "apache2"
      should be enabled
      should be running
    
    Port "80"
      should be listening
    
    Finished in 0.09901 seconds (files took 1.02 seconds to load)
    3 examples, 0 failures
    

    まとめ

    インスタンスの起動もTerraformでやったので、起動・セットアップ・テストまでコンソールからスムーズにできました。 TDDみたいな感覚でWebサーバーのセットアップができるのは非常い気持ちがいいですね。


    in  Infra

    ServerSpec事始め

    以前から気になってたServerspecに入門してみました。

    インストール(実行元)

    ServerSpecを実行するマシンにインストールします。 テスト対象のマシンではなくて、テストを実行する側のサーバーです。 Rubyが入っている前提です。

    1
    
    $ sudo gem install serverspec
    

    初期化します。 テスト対象はUN*X、バックエンドはSSHでVagrantではない環境です。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    $ serverspec-init
    Select OS type:
    
      1) UN*X
      2) Windows
    
    Select number: 1
    
    Select a backend type:
    
      1) SSH
      2) Exec (local)
    
    Select number: 1
    
    Vagrant instance y/n: n
    Input target host name: gside.org
     + spec/
     + spec/gside.org/
     + spec/gside.org/sample_spec.rb
     + spec/spec_helper.rb
     + Rakefile
     + .rspec
    

    Apacheの起動をテストする(NG編)

    自動生成された spec/gside.org/sample_spec.rb を編集します。 OSはGentooですが、対応しているOSであればOSの違いは吸収してくれます。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    require 'spec_helper'
    
    describe service('apache2'), :if => os[:family] == 'gentoo' do
      it { should be_enabled }
      it { should be_running }
    end
    
    describe port(80) do
      it { should be_listening }
    end
    

    このコードでApacheが起動していて、自動起動が設定されていること、Port80がListenであることがテストされます。 テストを実行すると、Apacheもインストールしていなけりゃ起動もしていないのでエラーになります。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    
    $ rake spec
    (in /home/hoge)
    /usr/bin/ruby21 -I/usr/local/lib64/ruby/gems/2.1.0/gems/rspec-support-3.5.0/lib:/usr/local/lib64/ruby/gems/2.1.0/gems/rspec-core-3.5.4/lib /usr/local/lib64/ruby/gems/2.1.0/gems/rspec-core-3.5.4/exe/rspec --pattern spec/gside.org/\*_spec.rb
    /usr/local/lib64/ruby/gems/2.1.0/gems/rspec-core-3.5.4/lib/rspec/core/rake_task.rb:79: warning: Insecure world writable dir /usr/local/bin in PATH, mode 040757
    
    Service "apache2"
      should be enabled (FAILED - 1)
      should be running (FAILED - 2)
    
    Port "80"
      should be listening (FAILED - 3)
    
    Failures:
    
      1) Service "apache2" should be enabled
         On host `gside.org'
         Failure/Error: it { should be_enabled }
           expected Service "apache2" to be enabled
           sudo -p 'Password: ' /bin/sh -c rc-update\ show\ \|\ grep\ --\ \\\\s\\\*apache2\\\\s\\\*\\\\\\\|\\\\s\\\*\\\(boot\\\|default\\\)
    
         # ./spec/gside.org/sample_spec.rb:4:in `block (2 levels) in <top (required)>'
    
      2) Service "apache2" should be running
         On host `gside.org'
         Failure/Error: it { should be_running }
           expected Service "apache2" to be running
           sudo -p 'Password: ' /bin/sh -c /etc/init.d/apache2\ status
            * status: stopped
    
         # ./spec/gside.org/sample_spec.rb:5:in `block (2 levels) in <top (required)>'
    
      3) Port "80" should be listening
         On host `gside.org'
         Failure/Error: it { should be_listening }
           expected Port "80" to be listening
           sudo -p 'Password: ' /bin/sh -c netstat\ -tunl\ \|\ grep\ --\ :80\\\
    
         # ./spec/gside.org/sample_spec.rb:9:in `block (2 levels) in <top (required)>'
    
    Finished in 0.09776 seconds (files took 0.81785 seconds to load)
    3 examples, 3 failures
    
    Failed examples:
    
    rspec ./spec/gside.org/sample_spec.rb:4 # Service "apache2" should be enabled
    rspec ./spec/gside.org/sample_spec.rb:5 # Service "apache2" should be running
    rspec ./spec/gside.org/sample_spec.rb:9 # Port "80" should be listening
    

    Apacheの起動をテストする(OK編)

    Apacheをインストール・起動・デフォルトランレベルへの登録まで済ますと、ServerSpec実行後は下記のようになります。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    $ rake spec
    (in /home/home)
    /usr/bin/ruby21 -I/usr/local/lib64/ruby/gems/2.1.0/gems/rspec-support-3.5.0/lib:/usr/local/lib64/ruby/gems/2.1.0/gems/rspec-core-3.5.4/lib /usr/local/lib64/ruby/gems/2.1.0/gems/rspec-core-3.5.4/exe/rspec --pattern spec/gside.org/\*_spec.rb
    /usr/local/lib64/ruby/gems/2.1.0/gems/rspec-core-3.5.4/lib/rspec/core/rake_task.rb:79: warning: Insecure world writable dir /usr/local/bin in PATH, mode 040757
    
    Service "apache2"
      should be enabled
      should be running
    
    Port "80"
      should be listening
    
    Finished in 0.09332 seconds (files took 0.83872 seconds to load)
    3 examples, 0 failures
    

    まとめ

    導入も簡単だし、テスト対象のOSも自動検出してくれたりと素敵ですね。