EC2インスタンスを業務時間だけ自動起動する処理をAWS SDK for PHP 2で作成するを使っているので、これを早速 AWS SDK for PHPのVersion 3で動かした時に、ハマった所を紹介したいと思います。
感想
- 単純にSDKをVersion3に変更しただけではエラー吐いて動かない。後方互換はほぼ無し。
- クライアント生成時に引数 'Version' の指定が必須になったのと、factoryじゃなくnewで生成するように変更されたので、変更コストがでかい。
- API実行後の戻り値のデータ取得方法も変更されたので、そのままだとエラー吐くよ。getPathがsearchになって、渡す引数も変更された。
- RDSとかの戻り値が違うらしいので、戻り値確認しての作り直しが大変そう。
- SDK自体の更新はcomposer.jsonを書き換えてupdateするだけなので簡単。
SDKをVersion 2からVersion 3に更新
- composer.jsonを書き換える
composer.json
{
"require": {
"aws/aws-sdk-php": "3.*"
}
}
- composer updateすると依存関係とAWS SDK for PHP Version 3がインストールされる
$ php composer.phar update
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Removing guzzle/guzzle (v3.9.2)
- Removing symfony/event-dispatcher (v2.6.3)
- Installing mtdowling/jmespath.php (2.2.0)
Downloading: 100%
- Installing guzzlehttp/promises (1.0.0)
Downloading: 100%
- Installing psr/http-message (1.0)
Downloading: 100%
- Installing guzzlehttp/psr7 (1.0.0)
Downloading: 100%
- Installing guzzlehttp/guzzle (6.0.1)
Downloading: 100%
- Removing aws/aws-sdk-php (2.6.16)
- Installing aws/aws-sdk-php (3.0.1)
Downloading: 100%
Writing lock file
Generating autoload files
Version 2の記述スタイルのまま、EC2自動起動処理のphpを実行してみる(エラー出る)
- Ec2Clientを生成する時に必須の引数 'Version' に'2015-04-15'(日付スタイル)を指定しろとエラー。
- Versionはどこに書いてあるの?→ここhttp://docs.aws.amazon.com/aws-sdk-php/v3/api/index.html
- 各サービスのクライアントでそれぞれ日付がちがう!マジか!
各サービスのAPIバージョンの一部
Amazon Elastic Compute Cloud 2015-04-15
Amazon Simple Storage Service 2006-03-01
Amazon DynamoDB 2012-08-10
Amazon Glacier 2012-06-01
$ php ec2_start.php
...省略...
PHP Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Missing required client configuration options:
version: (string)
A "version" configuration value is required. Specifying a version constraint
ensures that your code will not be affected by a breaking change made to the
service. For example, when using Amazon S3, you can lock your API version to
"2006-03-01".
Your build of the SDK has the following version(s) of "ec2": * "2015-04-15"
You may provide "latest" to the "version" configuration value to utilize the
most recent available API version that your client's API provider can find.
Note: Using 'latest' in a production application is not recommended.
A list of available API versions can be found on each client's API documentation
page: http://docs.aws.amazon.com/aws-sdk-php/v3/api/index.html. If you are
unable to load a specific API version, then you may need to update your copy of
the SDK.'...省略
Ec2Clientの生成のスタイル比較
- Version 3ではfactoryは非推奨 → newを使おう。
- 必須の引数 'version' を指定する。
// Version 2
$ec2client = Ec2Client::factory([
'region' => 'us-east-2'
]);
// Version 3
$ec2client = new Ec2Client([
'region' => 'us-east-2',
'version' => '2015-04-15'
]);
処理実行後の戻り値の処理方法の比較
- まず戻り値の$instancesには大量の他のデータやら何やらが入れ子の配列で格納されている。
- この中からインスタンスIDを取得したい場合便利なデータ取得関数(getPathとかsearch)を利用する。
- Version 3 では戻り値getPathじゃなくて、searchで取得する。
- getPathをそのまま使うとエラーを吐いたよ。
PHP Fatal error: Uncaught exception 'JmesPath\SyntaxErrorException' with message 'Syntax error at character 25
Reservations.*.Instances.0.InstanceId
^
記述スタイル比較
// インスタンスの一覧を取得
$instances = $ec2client->describeInstances();
// version 2 このまま実行するとVersion 3ではエラー
$ids_v2 = $instances->getPath('Reservations/*/Instances/0/InstanceId');
// version 3
$ids_v3 = $instances->search('Reservations[].Instances[].InstanceId');
searchの使い方
- 取得方法の例とサンプル http://jmespath.org/tutorial.html
まとめ
- SDKはcomposerで簡単にVersion 3 に更新できる。
- 変更すべき箇所はクライアント生成処理と戻り値のデータから目的のIDを取得する箇所など。
- APIの呼び出し方法は変更無いのでそのまま使えた。
自分の技術ブログではフリーランス界隈の情報や最新のIT情報の発信していますので、よろしくお願いします。