PHP
AWS
EC2
AWS_SDK

AWS SDK for PHPのVersion 3に更新して、EC2自動起動処理を書き換えてみた

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の使い方


まとめ


  • SDKはcomposerで簡単にVersion 3 に更新できる。

  • 変更すべき箇所はクライアント生成処理と戻り値のデータから目的のIDを取得する箇所など。

  • APIの呼び出し方法は変更無いのでそのまま使えた。

自分の技術ブログではフリーランス界隈の情報や最新のIT情報の発信していますので、よろしくお願いします。