kikukawa's diary

都内で活動するシステムエンジニアが書いてます。 興味を持った技術やハマったポイント、自分用メモをつけてます。 最近はweb中心

Ansible Galaxyでロールの管理 - リポジトリ編

リポジトリについて

Ansible Galaxyで管理していく場合、
リポジトリはロール単位で管理してくことになります。
それとは別にPlaybookを管理していくリポジトリも必要です。

そのため、Playbookを管理する一つのリポジトリと、
そのPlaybookに必要な分のロールのリポジトリができあがります。

Playbook用のリポジトリの雛形

前回の記事で少し触れましたが、
私はよく使う構成をPlaybookのリポジトリの雛形として
githubにおいています。 そのリポジトリ に入れているものの紹介をしたいと思います。

.editorconfig

root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
trim_trailing_whitespace = true


[*.md]
trim_trailing_whitespace = false

Ansibleはyml形式で書いていくのでその設定を入れています。
README用に *.md の設定も入れています。

ansible.cfg

Ansibleの設定ファイルです。 AnsibleのGithubリポジトリにあるexampleのものをベースとしていますが、 以下だけ変更しています。

inventory      = hosts
roles_path    = roles

リポジトリ直下にそのプロジェクト用のhostsファイルを
作成することが多いのでinventory = hosts を設定しています。

また、Ansible Galaxyでインストールするロールは、
プロジェクトディレクトリ(Playbookのリポジトリ)直下のrolesディレクトリに
インストールしたいのでroles_path = roles を設定しています。
複数プロジェクトが共存する環境下で、お互いに影響がでないことを考えてです。

.gitignore

*.retry
roles/role-*

playbookを実行すると.retryというファイルを生成する場合があるので
それをリポジトリに含めいないようにしています。
roles/role-* に関しては入れたり入れなかったりです。

ansible.cfgでroles_path = rolesの設定を入れると
リポジトリ内のrolesにAnsible Galaxyで持ってきたロール群が配置されます。
それらは、リポジトリ管理したくないので除外しています。
ただ、roles配下すべてを除外してしまうと、
そのPlaybookのリポジトリだけで必要な使い回す必要のないロールも除外されてしまいます。
なので、Ansible Galaxyでインストールするものは、
role-xxxという命名規則でインストールされるようにして、
その命名規則にあったものだけ除外しています。

require.yml

Ansible Galaxyでインストールするロールを記載しておくためのファイルです。
このファイルにPlaybookで必要なロールを記載しておくことで、
複数のロールを一気にインストールできます。
npmのpackage.josnとかcomposerのcomposer.jsonみたいなものです。
Ansible Galaxyでは、npmやcomposerほど高度なことはできませんが。。

雛形のリポジトリには、Ansible Galaxyの説明に書いてあったサンプルを
そのまま記載しています。

一番多く使うのは、Githubかつバージョン、name指定の方法です。
下記のような書き方です。

 - src: https://github.com/kkkw/ansible-role-example
   version: master
   name: role-example

phpmdで特定のメソッド、クラスだけルールを除外する

自分用メモ

phpmdで静的解析を行ってましたが、
フレームワークの仕様上
どうしても必要のない引数を定義したメソッドを
書くことになってしまいました。

今回のケースでは
unsedUnusedFormalParameter
引っかかってしまいました。
nameingShortVariableのように除外するルールを
xmlに追加しようと思ったのですが、
UnusedFormalParameterには
そういったパラメーターはありませんでした。

SuppressWarningsをphpdocに記載して回避します。 クラスかメソッドのphpdocに記載します。

/**
 *
 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 */
class Bar {

    public function foo($unusedFormalParameter)
    {
        //code
    }

}

参考

Laravelのルートパラメーターのフォーマット指定を簡略化

自分用メモ Laravel5.2で確認しました。

Laravelのルートパラメーター

下記の {id} の部分のことです。
ルートパラメーターというらしいです。

Route::get('user/{id}', function ($id) {
    return 'User '.$id;
});

フォーマットの指定の簡略化

whereメソッドを指定することで、
ルートパラメーターのフォーマットを指定することができます。

ただ、{id} などよく使うものは、何回も書きたくないって時には、 RouteServiceProviderbootメソッドに記述することで、
whereを使用することもなく、指定できます。 routes.phpが肥大化するのを防ぐ意味もあります。

public function boot(Router $router)
{
    $router->pattern('id', '[0-9]+');

    parent::boot($router);
}

参考

https://laravel.com/docs/5.2/routing

Laravelの名前空間の変更でサブ名前空間も追加する

コマンド

Laravel(ver5.2)はデフォルトでは、Appという名前空間に属するようになっています それを変更するコマンドが下記です。

php artisan app:name Foo

ただし、このコマンドでは、サブ名前空間を指定できないようです。

php artisan app:name Foo\Bar

と指定すると、Artisanコマンドでエラーになります。

サブ名前空間の編集

仕方ないので一旦Fooに変更して、 その後、手動で編集していきました。 編集対象のファイルは下記

  • app/Console/Commands/Inspire.php
  • app/Console/Kernel.php
  • app/Events/Event.php
  • app/Exceptions/Handler.php
  • app/Http/Controllers/Auth/AuthController.php
  • app/Http/Controllers/Auth/PasswordController.php
  • app/Http/Controllers/Controller.php
  • app/Http/Kernel.php
  • app/Http/Middleware/Authenticate.php
  • app/Http/Middleware/EncryptCookies.php
  • app/Http/Middleware/RedirectIfAuthenticated.php
  • app/Http/Middleware/VerifyCsrfToken.php
  • app/Http/Requests/Request.php
  • app/Jobs/Job.php
  • app/Providers/AppServiceProvider.php
  • app/Providers/AuthServiceProvider.php
  • app/Providers/EventServiceProvider.php
  • app/Providers/RouteServiceProvider.php
  • app/User.php
  • bootstrap/app.php
  • composer.json
  • config/app.php
  • config/auth.php
  • config/services.php
  • database/factories/ModelFactory.php

もっとよい方法があれば教えて下さい。

追記

php artisan app:name 'Foo\Bar'

とシングルクォーテーションでくくれば普通にできました。 Laravel(5.3)で確認

Ansible Galaxyでロールの管理 - Playbookの準備 複数ロール編

前回はAnsible Galaxyのinitコマンドで作成される
testsディレクトリを利用して、ダミーのPlaybookを作りました。
しかし、それだと複数のロールを同時に開発していくときに若干不便です。

複数のロールを開発していく場合は、ダミーのPlaybook用のプロジェクトを利用します。
自分でよく使う設定などをgithubに登録してあるので、
これをcloneして使っています。

このプロジェクトのroles配下に
開発しようとしているロールのシンボリックリンクを貼って開発しています。

ディレクトリツリー

ansible-template
├── ansible.cfg
├── hosts
├── localhost.yml
├── require.yml
└── roles
    ├── role-foo -> ../../role-foo
    └── role-bar -> ../../role-bar
role-foo
├── README.md
├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── tasks
│   └── main.yml
├── templates
├── tests
│   ├── inventory
│   ├── test.retry
│   └── test.yml
└── vars
    └── main.yml
role-bar
├── README.md
├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── tasks
│   └── main.yml
├── templates
├── tests
│   ├── inventory
│   ├── test.retry
│   └── test.yml
└── vars
    └── main.yml

シンボリックリンクにしている理由

シンボリックリンクにしているのはAnsible Galaxyのインストールコマンドで
どのようにインストールされるかのテストをすることがあるためです。

ansible-galaxy install -rf require.yml のようにして依存解決の確認などをしたい時に
実態だと、リポジトリの内容で上書きされてしまいます。

一度痛い目にあってから、シンボリックリンクにするようにしました。

Ansible Galaxyでロールの管理 - Playbookの準備

Ansible Galaxyに登録するまでもない
もしくは登録できないようなものでも
Ansible Galaxyでロールを管理したかったので、
その手順を調べました。 今回はとりあえず、ロールを開発するためのPlaybookの準備です。

ロール開発時のPlaybook

最初、Playbookがない状態でどうやって、
ロールを開発していけばよいかとまどいました。
分かってみれば、簡単でダミーのPlaybookを作れば良かったです。

testsディレクトリを使って開発する

ひとつのロールを開発する場合は、testsディレクトリを使ったほうが
すぐに始められるので普段はそうしています。

Ansible Galaxyのinitコマンドを使うと、 testsディレクトリが作成されます。 中身にinventoryとtest.ymlがあるので、これをダミーのplaybookにします。

testsディレクトリが作成されるのはAnsibleのバージョンが2.0以降です。 2.0より前は、自分でダミーのplaybookを作成する必要があります。

tests/test.ymlに手を加える

そのままだと動かないのでちょっと編集します。
ロールのパスだけ直して上げればいいのですが、
最初はVagrant上でlocalhostを対象に実行することが多いので
connection: localも指定しています

@@ -1,5 +1,6 @@
 ---
 - hosts: localhost
+  connection: local
   remote_user: root
   roles:
-    - role-foo2
+    - ../../role-foo

実行してみる

実行してみて下記のようにできたら
あとは、ロールを開発していくだけです。

$ cd path/to/role
$ cd tests
$ ansible-playbook -i inventory test.yml

PLAY [localhost] ***************************************************************

TASK [setup] *******************************************************************
ok: [localhost]

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

springの導入時にapplication.rbが見つからない

railsのplugin開発をしていてrspecの速度を上げたくてspringを導入しようとしました。 その時にエラーがでました。 その対処法をメモ。

bundle exec spring binstub rspec

上記コマンドを実行した時に下記のエラーが出ました

Spring was unable to find your config/application.rb file. Your project root was detected at /path/to/plugin, so spring looked for /path/to/plugin/config/application.rb but it doesn't exist. You can configure the root of your application by setting Spring.application_root in config/spring.rb.

pluginなのでapplication.rbはないです。 メッセージに表示されているようにconfig/spring.rb を用意します。

vi config/spring.rb

中身は下記のようなものを書きます。

Spring.application_root = './spec/dummy'
Spring.watch 'app/modles', 'lib'

で下記のように実行すれば使えました。

./spec/dummy/bin/rspec  ./spec/path/to/xxxx_spec.rb

参考