読者です 読者をやめる 読者になる 読者になる

戦場のプログラマー

名前は誰も知らない。

AWS SDK for PHP 2 入門(Composer編)

AWS PHP SDK Amazon S3

今年の春頃に無料枠で契約してそのままになってたAWSをもう少し本格的に習得してみようと最近しこしこと本やらネットやらで勉強していました。
バックアップとかスケールアウト、障害対応であまり頭を悩ませなくて良さそうなので最近とても魅力的に見える。 インフラまわりの管理は意外と大変なんですよね・・・。

とりあえずAWS Management ConsoleからEC2のインスタンスを立ち上げたり、S3にファイルをアップロードしたり、Route53でDNSゾーンを管理したりしてみてそれっぽく使うことはできるようになったけど、どうも何かが違う気がする。
機能が多すぎて使いどころや、定石みたいなのがわからないので体系的な知識を得るために本を購入してみました。
こういうのから基本的な考え方を吸収していけるのはいいね。

やっぱりAWSの着目すべき点はインフラに統合されたAPIが提供されているところにあるんですかね。 実際にS3のAPI叩いてみたけど、少しずつ面白さがわかってきた。少しだけね。

躓いたところ

さて、一番最初のサンプルを作成しようと思って、一番最初に躓いたのですが、本書ではAWS SDK for PHPをインストールするように言われているのですが、どこからダウンロードしたらいいのかよくわかりませんでした。

ここで aws.phar というファイルがダウンロードできるのですが、これをどうしたらいいのかわからない・・・。

こちらも aws.phar。pharという拡張子はPHP Archiveの略のようなのですが、どうもこのファイルをインクルードして使うようです。

いろいろ試行錯誤してやっとネットに掲載されていた簡単なサンプルが動くようになったのですが、どうも本のサンプルと書き方がぜんぜん違うように思えて、よくよく調べてみたら本に載っているのはバージョン1のもののようです。

バージョン1で合わせてサンプルをやっていってもいいのですが、どうせ今後は2系にシフトしていくので、2系のイディオムに読み替えながら進むようにしました。

上のようにpharをインクルードしてもいいのですが、AWS SDK for PHP 2開発ではComposerを併用して開発するのが推奨されているようなので、それに従います。

それでは始まり始まり。

環境

VagrantとChef Soloあたりでちゃちゃっと作れちゃうと思います。
それか普通にEC2のインスタンスや他の既成の仮想マシンにインストールすればいいと思います。

  • CentOS6.4 x64 または Ubuntu 12.04 LTS
  • Apache2
  • PHP5.3.3

Composerのインストール

ComposerはRailsのBundlerみたいなもんですね。

curl -s http://getcomposer.org/installer | php

#!/usr/bin/env php
All settings correct for using Composer
Downloading...

Composer successfully installed to: /var/www/aws/s3/composer.phar
Use it: php composer.phar

ここで composer.phar がカレントに作成されます。

composer.json の作成

jsonファイルを作成します。Gemfileみたいなものです。

{
  "require": {
    "aws/aws-sdk-php": "*"
  }
}

Composerで依存パッケージのインストール

ここで composer.json に記述された依存パッケージがインストールされる。
カレントディレクトリの vendor ディレクトリにインストールされます。 .gitignorecomposer.phar とか vendor/ は外したほうがいいかもしれませんね。

$ php composer.phar install

Loading composer repositories with package information
Installing dependencies (including require-dev)
  - Installing symfony/event-dispatcher (v2.3.7)
    Downloading: 100%         

  - Installing guzzle/guzzle (v3.7.4)
    Downloading: 100%         

  - Installing aws/aws-sdk-php (2.4.11)
    Downloading: 100%         

symfony/event-dispatcher suggests installing symfony/dependency-injection ()
symfony/event-dispatcher suggests installing symfony/http-kernel ()
aws/aws-sdk-php suggests installing doctrine/cache (Adds support for caching of credentials and responses)
aws/aws-sdk-php suggests installing ext-apc (Allows service description opcode caching, request and response caching, and credentials caching)
aws/aws-sdk-php suggests installing monolog/monolog (Adds support for logging HTTP requests and responses)
aws/aws-sdk-php suggests installing symfony/yaml (Eases the ability to write manifests for creating jobs in AWS Import/Export)
Writing lock file
Generating autoload files

不足しているシステムパッケージがあったらyumとapt-getを使ってインストールします。
たぶんUbuntuの場合そのままだとエラーになると思います。詳しくは下のトラブルシューティングへ。

最初のAWS SDK for PHP 2プログラミング

ここではバケットの一覧表示をするプログラムを書いてみたいと思います。 プログラムは以下のサンプルを参考にさせていただきました。

include/awssecure.inc.php

AWSのアクセスキーを設定します。これは漏れたらやばいので別ファイルとして管理するといいです。
最初アクセストークンはどこで取得すればいいんだろう?って思っていたのですが、以下で取得するようです。

ただ、警告にもあるとおり、ここで発行されるアクセストークンはAWSアカウントに直接紐づく rootユーザーみたいなとんでもない特権レベル を持っているので、あんまりおすすめされません。

なので、IAM(Identity and Access Management)でユーザーとグループを作成してそこでクレデンシャルを発行するのがスマートなようです。

ちなみに、1ユーザーあたり2つのクレデンシャルしか発行できないみたいです。

<?php
// AWSアクセストークン
$config = array(
  'key'    => 'AKIAIOSFODNN7EXAMPLE',
  'secret' => 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
);

gitで管理するときはこのファイルのトラッキングを外しましょう。 ただ、テンプレート的なファイルだけは残っていてほしいのでインデックスから無視するだけにします。

git update-index --skip-worktree include/awssecure.inc.php

list_buckets.php

以下が本命のプログラムとなります。

<?php

error_reporting(E_ALL);

// Load Composer Vendor Modules
require_once('vendor/autoload.php');
// AWS Credential
require_once('include/awssecure.inc.php');

use Aws\S3\S3Client;

$s3 = S3Client::factory($config);

$blist = $s3->listBuckets();

foreach ($blist['Buckets'] as $b)
{
  echo "${b['Name']}: created at ${b['CreationDate']}\n";
}

実行してみる

コマンドラインからでも、ブラウザ経由でもどっちでも大丈夫だと思います。

$ php list_buckets.php 

hogehogehoge: created at 2013-11-22T10:50:47.000Z
sitepoint-aws-cloud-book-wnoguchi: created at 2013-12-04T23:06:19.000Z
blhablahblah: created at 2013-12-02T03:48:40.000Z
foobarbar: created at 2013-11-09T12:13:07.000Z

これでOKです。

とりあえずAWS SDKを使ったプログラミングを始めようと思って躓いたところをまとめてみました。

トラブルシューティング

CentOSのエラー

以下は実際にXMLがからむAWS SDKを呼び出している時に発生していた気がします。

php create_bucket.php ppp

PHP Fatal error:  Class 'XMLWriter' not found in /vagrant/src/s3/vendor/guzzle/guzzle/src/Guzzle/Service/Command/LocationVisitor/Request/XmlVisitor.php on line 201

以下のようにして対応

yum -y install php-xml

Ubuntuのエラー

Composerの依存パッケージをインストールしようとしたらエラーになりました。

php composer.phar install

Loading composer repositories with package information
Installing dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - aws/aws-sdk-php 2.4.0 requires guzzle/guzzle ~3.7.0 -> satisfiable by guzzle/guzzle[v3.7.0, v3.7.1, v3.7.2, v3.7.3, v3.7.4].
    - aws/aws-sdk-php 2.4.1 requires guzzle/guzzle ~3.7.0 -> satisfiable by guzzle/guzzle[v3.7.0, v3.7.1, v3.7.2, v3.7.3, v3.7.4].
    - aws/aws-sdk-php 2.4.10 requires guzzle/guzzle ~3.7.0 -> satisfiable by guzzle/guzzle[v3.7.0, v3.7.1, v3.7.2, v3.7.3, v3.7.4].
    - aws/aws-sdk-php 2.4.11 requires guzzle/guzzle ~3.7.0 -> satisfiable by guzzle/guzzle[v3.7.0, v3.7.1, v3.7.2, v3.7.3, v3.7.4].
    - aws/aws-sdk-php 2.4.2 requires guzzle/guzzle ~3.7.0 -> satisfiable by guzzle/guzzle[v3.7.0, v3.7.1, v3.7.2, v3.7.3, v3.7.4].
    - aws/aws-sdk-php 2.4.3 requires guzzle/guzzle ~3.7.0 -> satisfiable by guzzle/guzzle[v3.7.0, v3.7.1, v3.7.2, v3.7.3, v3.7.4].
    - aws/aws-sdk-php 2.4.4 requires guzzle/guzzle ~3.7.0 -> satisfiable by guzzle/guzzle[v3.7.0, v3.7.1, v3.7.2, v3.7.3, v3.7.4].
    - aws/aws-sdk-php 2.4.5 requires guzzle/guzzle ~3.7.0 -> satisfiable by guzzle/guzzle[v3.7.0, v3.7.1, v3.7.2, v3.7.3, v3.7.4].
    - aws/aws-sdk-php 2.4.6 requires guzzle/guzzle ~3.7.0 -> satisfiable by guzzle/guzzle[v3.7.0, v3.7.1, v3.7.2, v3.7.3, v3.7.4].
    - aws/aws-sdk-php 2.4.7 requires guzzle/guzzle ~3.7.0 -> satisfiable by guzzle/guzzle[v3.7.0, v3.7.1, v3.7.2, v3.7.3, v3.7.4].
    - aws/aws-sdk-php 2.4.8 requires guzzle/guzzle ~3.7.0 -> satisfiable by guzzle/guzzle[v3.7.0, v3.7.1, v3.7.2, v3.7.3, v3.7.4].
    - aws/aws-sdk-php 2.4.9 requires guzzle/guzzle ~3.7.0 -> satisfiable by guzzle/guzzle[v3.7.0, v3.7.1, v3.7.2, v3.7.3, v3.7.4].
    - aws/aws-sdk-php 2.3.4 requires guzzle/guzzle ~3.6.0 -> satisfiable by guzzle/guzzle[v3.6.0].
    - aws/aws-sdk-php 2.3.1 requires guzzle/guzzle ~3.4.3 -> satisfiable by guzzle/guzzle[v3.4.3].
    - aws/aws-sdk-php 2.3.2 requires guzzle/guzzle >=3.4.3,<4 -> satisfiable by guzzle/guzzle[v3.4.3, v3.5.0, v3.6.0, v3.7.0, v3.7.1, v3.7.2, v3.7.3, v3.7.4].
    - aws/aws-sdk-php 2.3.3 requires guzzle/guzzle >=3.4.3,<4 -> satisfiable by guzzle/guzzle[v3.4.3, v3.5.0, v3.6.0, v3.7.0, v3.7.1, v3.7.2, v3.7.3, v3.7.4].
    - aws/aws-sdk-php 2.3.0 requires guzzle/guzzle ~3.4.1 -> satisfiable by guzzle/guzzle[v3.4.1, v3.4.2, v3.4.3].
    - aws/aws-sdk-php 2.2.0 requires guzzle/guzzle ~3.3.0 -> satisfiable by guzzle/guzzle[v3.3.0, v3.3.1].
    - aws/aws-sdk-php 2.2.1 requires guzzle/guzzle ~3.3.0 -> satisfiable by guzzle/guzzle[v3.3.0, v3.3.1].
    - aws/aws-sdk-php 2.1.1 requires guzzle/guzzle ~3.2.0 -> satisfiable by guzzle/guzzle[v3.2.0].
    - aws/aws-sdk-php 2.1.2 requires guzzle/guzzle ~3.2.0 -> satisfiable by guzzle/guzzle[v3.2.0].
    - aws/aws-sdk-php 2.1.0 requires guzzle/guzzle ~3.1.2 -> satisfiable by guzzle/guzzle[v3.1.2].
    - aws/aws-sdk-php 2.0.0 requires guzzle/guzzle 3.0.* -> satisfiable by guzzle/guzzle[v3.0.0, v3.0.1, v3.0.2, v3.0.3, v3.0.4, v3.0.5, v3.0.6, v3.0.7].
    - aws/aws-sdk-php 2.0.1 requires guzzle/guzzle 3.0.* -> satisfiable by guzzle/guzzle[v3.0.0, v3.0.1, v3.0.2, v3.0.3, v3.0.4, v3.0.5, v3.0.6, v3.0.7].
    - aws/aws-sdk-php 2.0.2 requires guzzle/guzzle 3.0.* -> satisfiable by guzzle/guzzle[v3.0.0, v3.0.1, v3.0.2, v3.0.3, v3.0.4, v3.0.5, v3.0.6, v3.0.7].
    - aws/aws-sdk-php 2.0.3 requires guzzle/guzzle 3.0.* -> satisfiable by guzzle/guzzle[v3.0.0, v3.0.1, v3.0.2, v3.0.3, v3.0.4, v3.0.5, v3.0.6, v3.0.7].
    - guzzle/guzzle v3.7.4 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.7.3 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.7.2 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.7.1 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.7.0 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.6.0 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.5.0 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.4.3 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.4.2 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.4.1 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.3.1 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.3.0 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.2.0 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.1.2 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.0.7 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.0.6 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.0.5 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.0.4 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.0.3 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.0.2 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.0.1 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - guzzle/guzzle v3.0.0 requires ext-curl * -> the requested PHP extension curl is missing from your system.
    - Installation request for aws/aws-sdk-php * -> satisfiable by aws/aws-sdk-php[2.0.0, 2.0.1, 2.0.2, 2.0.3, 2.1.0, 2.1.1, 2.1.2, 2.2.0, 2.2.1, 2.3.0, 2.3.1, 2.3.2, 2.3.3, 2.3.4, 2.4.0, 2.4.1, 2.4.10, 2.4.11, 2.4.2, 2.4.3, 2.4.4, 2.4.5, 2.4.6, 2.4.7, 2.4.8, 2.4.9].

PHPcurl拡張がないって言ってる気がします。

sudo apt-get -y install php5-curl

もういっかい。

php composer.phar install

Loading composer repositories with package information
Installing dependencies (including require-dev)
  - Installing symfony/event-dispatcher (v2.3.7)
    Downloading: 100%         

  - Installing guzzle/guzzle (v3.7.4)
    Downloading: 100%         

  - Installing aws/aws-sdk-php (2.4.11)
    Downloading: 100%         

symfony/event-dispatcher suggests installing symfony/dependency-injection ()
symfony/event-dispatcher suggests installing symfony/http-kernel ()
aws/aws-sdk-php suggests installing doctrine/cache (Adds support for caching of credentials and responses)
aws/aws-sdk-php suggests installing ext-apc (Allows service description opcode caching, request and response caching, and credentials caching)
aws/aws-sdk-php suggests installing monolog/monolog (Adds support for logging HTTP requests and responses)
aws/aws-sdk-php suggests installing symfony/yaml (Eases the ability to write manifests for creating jobs in AWS Import/Export)
Writing lock file
Generating autoload files

うまくいきました。

参考サイト

S3開発に関しては以下のドキュメントが良さそう。

その他。

参考文献