Web制作・開発会社 プレスマンのスタッフブログ

PRESSMAN*Tech

DokcerのPHPからクロスアカウント上のS3へアクセスする方法

以前、弊社の案件で、既に運用中のDokcer上のPHPから、
クロスアカウント上のS3へアクセスする必要がありました。

単純にDockerコンテナにAWS CLIを追加する方法もありますが、
運用中のサイトの場合は、再検証に時間が掛かってしまいます。

そこで今回、運用中のDokcerコンテナ自体は作り直さず、
S3へアクセス出来るようにした方法をご紹介します。

前提

アクセス元をアカウントA、アクセス先をアカウントBとします。

また、アカウントAにはEC2がある状態、かつ、
Docker上でPHPが動ける事前提です。

*記事の中ではDcokerのインストールに関しては割愛しています。

アカウントA側でやる事

■ステップ1.アカウントAのVPCに、S3のVPCエンドポイント作成。


AWSのVPCのダッシュボードからVPCエンドポイントを作成します。

■ステップ2.アカウントAにIAMRoleを作成。


次に、IAMのダッシューボードの左メニューから「ロールを作成」を選択し、
IAMRoleで、S3のアクセス用Roleを作成します。

■ステップ3.RoleをアカウントAのEC2に付与する。


ステップ2で作成したRoleを、EC2に付与します。

■ステップ4.AWS SDK for PHPのアーカイブを読み込む。

PHPでS3コマンドが利用出来るように、今回はAWS SDK for PHPを使用します。
AWS SDK for PHPをインストール方法は幾つかあるのですが、
今回は、お手軽にする為に、パッケージ済み phar をダウンロードしてPHPで読み込むようにします。

アカウントB側でやる事

■ステップ1.S3バケットを作成。


S3のダッシュボードから、バケットを作成します。

■ステップ2.バケットポリシーを設定。


ステップ1で作成したバケットにバケットポリシーを設定します。
この時、アカウントAで作成したRoleを指定します。

【バケットポリシー記載例】

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Example permissions",
            "Effect": "Allow",
            "Principal": {
                "AWS": "(ここにアカウントAで作ったRoleを書く)"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::(ここにポリシーを設定するバケット名)",
                "arn:aws:s3:::(ここにポリシーを設定するバケット名/*"
            ]
        }
    ]
}

実際にAWS SDK for PHPでアクセスしてみる

APIの詳しい使い方は、公式ドキュメントを参考にしてみてください。

PHPサンプル


// aws.pharを読み込んでおく require '/path/to/aws.phar'; $bucket_name = 'hogehoge_bucket'; $bucket_dir = 'hogehoge_dir'; $s3_file = 'hogehoge.txt'; $sdk = new Aws\Sdk([ 'version' => 'latest', 'region' => 'ap-northeast-1' ]); $client = $sdk->createS3(); $listObjects = $client->listObjects([ 'Bucket' => $bucket_name, 'Prefix' => $bucket_dir ]); // バケット含めたディレクトリが存在しない場合は以降の処理をスキップ if ( !$listObjects['Contents'] ) { return; } $s3 = new Aws\S3\S3Client([ 'version' => 'latest', 'region' => 'ap-northeast-1' ]); // ファイルの中身を取得 try { $csv_file_result = $s3->getObject([ 'Bucket' => $bucket_name, 'Key' => $s3_file, 'ResponseContentType' => 'text/plain' ]); // $file_dataにファイルの中身が入ってくるので、後はご自由に $file_data = $csv_file_result['Body']->getContents(); } catch (S3Exception $e) { // エラーコードをログに出す場合はここで取得 $status_code = $e->getStatusCode(); }

今回のポイント

今回の一番のポイントとなる部分は、やはりコンテナ自体には手を入れない点です。
もし、Docker+PHPで運用中のサイトで、S3のクロスアカウントアクセスが必要になったら、
是非参考にしてみて下さい。