11
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PHPerだけどAWS STSを活用してSaaSをマルチテナント化した

Last updated at Posted at 2017-06-07

本記事はcloudpack あら便利カレンダー2017の06/07(水)の記事です。

AWSアカウント:プロジェクト = 1:n なSaaSをβでリリースしてたけど、本番稼働にあたってAWSの請求情報わけられないじょん!
っていうヤバさを解決したい人生でした。

経緯

S3(Web) - EC2(API) - Device Farm
ユーザ認証:Cognito User Pools/DynamoDB
  1. ひとつのアカウント内のDevice FarmをSaaSで提供したい
  2. こんな感じのアーキテクチャ構想で組んで、これでいけるぜ!ってなった
  3. Device Farmには複数のProjectを立てることができる
  4. Cognitoに登録したユーザとProjectのヒモ付はDynamoDBで行っている
  5. サービスの課金形態的に、Projectごとの利用時間を計算する必要がある
  6. そんなことすっかり忘れてた!!
  7. 四則演算絶対やりたくない == ズレたときに燃えるのが目に見えてる
  8. Device Farmを別のアカウントにわけちゃおうぜ!!

どうやって実現したか

AWSには、他アカウントのリソースにアクセスする仕組みが用意されているため、それを使って実現しました。
STSの仕組みについてはこちらを参考にしてください。

  1. Cognitoのログインユーザーを特定して
  2. それをキーにDynamoDBからRoleのARNをひいて
  3. そのアカウントのDeviceFarmClientを取得する

こうすることで、

  • 請求情報はクライアント毎のアカウントに紐づくため請求処理も楽ちんに!!(ログインして請求情報見るだけ)
  • 今までプログラム上で「このProjectはこのユーザと紐付けて...」みたいな認証処理が不要に!! == セキュアに!

みたいなメリットが得られました!便利だね!すごいね2017年!

結論

AWS STS AssumeRoleつかったクロスアカウントアクセスは便利

コードのっけておきます

なんとなくstaticなSingletonで実装しました。

呼び出し側.php
<?php

use App\AwsClient;

$arn = ''; // なんかしらとってくる
$DeviceFarmClient = AwsClient::DeviceFarm($arn);

return $DeviceFarmClient->listProjects()->toArray();
呼び出され側.php
<?php

namespace App;

use Aws\CognitoIdentityProvider\CognitoIdentityProviderClient;
use Aws\Credentials\AssumeRoleCredentialProvider;
use Aws\DeviceFarm\DeviceFarmClient;
use Aws\Sts\StsClient;

class AwsClient
{
    private static $DeviceFarm;

    private function __construct()
    {
    }

    final function __clone()
    {
        throw new \Exception('__clone() is not allowed'); 
    }
    
    public static function DeviceFarm($arn = null)
    {
        if (!self::$DeviceFarm) {
            $assumeRoleCredentials = new AssumeRoleCredentialProvider([
                'client' => new StsClient([
                    'region' => 'us-west-2',
                    'version' => 'latest'
                ]),
                'assume_role_params' => [
                    'RoleArn' => $arn,
                    'RoleSessionName' => 'service-' . time(),
                ]
            ]);

            self::$DeviceFarm = new DeviceFarmClient([
                'region' => 'us-west-2',
                'version' => 'latest',
                'credentials' => $assumeRoleCredentials
            ]);
        }

        return self::$DeviceFarm;
    }
}

参考:http://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/credentials.html#assume-role-credentials

11
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?