Laravel コンソールアプリ、およびその実行環境など

# TL;DR

AWS インスタンスの一覧表示や起動／停止を行う、Laravel コンソールアプリを作成しました。また、これを実行するためのベースとなる Vagrant Box、および環境構築用の ansible-playbook も合わせて作成しました。

- ベースとなる Vagrant Box(Vagrantfile) https://github.com/hotta/vagrant-cent72-box
- Laravel 環境構築用 ansible-playbook https://github.com/hotta/laravel-centos7
- Laravel コンソールアプリのサンプル https://github.com/hotta/ec2-autostop

# 実行時イメージ

```bash
$ php artisan -V
Laravel Framework version 5.2.45

$ php artisan | grep ec2
 ec2
  ec2:list            EC2 インスタンスの一覧を表示します
  ec2:start           インスタンスを開始します
  ec2:stop            インスタンスを停止します

$ php artisan ec2:list

Tag Name      Private IP    Status         Instance ID
------------------------------------------------------------
dev-ad        172.16.1.9    stopped    i-0d74d9XXXX27c74e3
dev-comgw     172.16.1.12   stopped    i-XXXXXXXXf69dfb422
dev-comsh     172.16.1.10   stopped    i-07d6ca0f2XXXXXX96
...

$ php artisan ec2:start
インスタンスIDかタグ名のいずれかを指定してください。

$ php artisan ec2:start -h
Usage:
  ec2:start [options]

Options:
      --instanceid[=INSTANCEID]  開始するインスタンスのインスタンスID
      --tagname[=TAGNAME]        開始するインスタンスのタグ名（これらのいずれかを指定）
  -h, --help                     Display this help message
  -q, --quiet                    Do not output any message
  -V, --version                  Display this application version
      --ansi                     Force ANSI output
      --no-ansi                  Disable ANSI output
  -n, --no-interaction           Do not ask any interactive question
      --env[=ENV]                The environment the command should run under.
  -v|vv|vvv, --verbose           Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Help:
 インスタンスを開始します
```

# 経緯

以前、AWS インスタンスの起動／停止などを行うアプリを書きました。このアプリを cron から呼び、インスタンスの動作を平日の業務時間中だけとすることで、AWS の利用コストを節約しています。

しかしながら、これは Linux 上で動かす CLI アプリのため、サービス時間延長や休日の運用にはシステム管理者の介入が必要です。このため今後 Web ベースの GUI を提供することで、他のスタッフでも運用ができるようにしたいと考えています。

Laravel には artisan というコマンドラインインターフェイスが用意されており、これを利用して各種スケルトンソースの作成やデータベーステーブルの作成等を行います。Web ベースのアプリの作成はこれからですが、その前提となる artisan コンソールベースのアプリが動いたので、後はコントローラーから artisan の機能を呼び出せばよいだろうという構想です（詳細はまだ調べていません）。

# laravel の学習について

最近は PHP 界隈だと laravel が流行ってそうなので、使ってみたいと思いました。laravel の学習には以下を利用しました。

- [Laravel リファレンス Ver.5.1 LTS 対応 Web職人好みの新世代PHPフレームワーク](https://www.amazon.co.jp/Laravel-%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9-Ver-5-1-LTS-Web%E8%81%B7%E4%BA%BA%E5%A5%BD%E3%81%BF%E3%81%AE%E6%96%B0%E4%B8%96%E4%BB%A3PHP%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF/dp/4844339451)
  - タイトルの通り、内容は laravel-5.1 ベースです。Laravel は最新の安定版が 5.2 ですが、マイナーバージョンが変わると使い方もかなり変わるようです。
  - 実はまだ最初の４分の１程度しか読めていません。これからじっくり読みます。
  - 最初のほうで laravel 以前に Composer 等の説明があったので、これを元に ansible-2.x の変更点なんぞを調べつつ環境を作成しました。
- [ドットインストール - Laravel5入門（全29回）](http://dotinstall.com/lessons/basic_laravel)
  - これはかなり有用でした。途中から有料会員でないと読めなくなりますが、お布施する価値は充分にありました。
  - laravel-5.2 ベースです。5.2 の途中から仕様が変わってサンプルが動かなくなったりますが、その旨の注釈を入れたりと、ちゃんと追随されているようです。
- [Laravel 日本語ドキュメント](https://readouble.com/)
  - チュートリアルを終えてから、実際にプログラムを書く際に非常に役立ちました。ただ、初めてのフレームワークが laravel だという向きには、これだけではちょっと辛そうです。

# Laravel で aws 関連の機能を使うには

- PHP から AWS API を使う場合、[AWS SDK for PHP](http://docs.aws.amazon.com/aws-sdk-php/v3/guide/) を使います。
- さらに laravel 対応版の Composer パッケージ [aws-sdk-php-laravel](https://github.com/aws/aws-sdk-php-laravel)が公開されています。これを入れれば依存関係で前者も入ります。
- インストール方法等は README にある通りですが、前述の ansible-playbook の中で、これらの手順もすべて吸収しています。
- config/app.php の providers と aliases にパッケージの情報を（自動）登録していますので、アプリでは以下のように非常に簡単に AWS の機能が呼び出せました。

- スケルトンの作成

```php
$ php artisan make:console Ec2List --command=ec2:list
```
これで app/Console/Commands/Ec2List.php が作られますので、以下の通り変更しました。

```app/Console/Commands/Ec2List.php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use AWS;                                              // 追加
...
   protected $ec2client;                              // 追加
...
class Ec2List extends Command
...
   public function __construct()
    {
        parent::__construct();

        $this->ec2client = AWS::createClient('ec2'); // 初期化
    } //  Ec2List :: __construct()
...
    public function handle()
    {
      $di = $this->ec2client->DescribeInstances();   // 利用
（以下略）
```

後は、この新しいコマンドをカーネルに登録すればOKです。
 
```app/Console/Kernel.php
    protected $commands = [
        // Commands\Inspire::class,
        Commands\Ec2List::class,                     // 追加
    ];
```

詳細はソースをごらんください。メッセージやコメントも日本語で入れています。なお、artisan コンソールコマンドの追加については以下のマニュアルが詳しいです。

https://readouble.com/laravel/5.2/ja/artisan.html