AWS環境では、
別アカウント間でリソースを操作する際に
IAMロールを使って権限を委任することが推奨されます。

本記事では、
AWSアカウントA
(Ruby on RailsのWebサーバがあるアカウント)から、
別のAWSアカウントBのKinesisストリームに
データを書き込むための手順について解説します。

特に、IAMロールを活用して、
クロスアカウントアクセスを
安全に行う方法に焦点を当てています。

クロスアカウントアクセスとは?

AWSでは、複数のアカウントを使って
リソースを管理することが一般的です。

例えば、AWSアカウントAにWebサーバ、
AWSアカウントBにデータストリーム(Kinesis)がある場合、
アカウントAのリソースがアカウントBのリソースに
アクセスする必要があります。

このようなクロスアカウントアクセスを安全に管理するために、
IAMロールAssumeRoleというメカニズムを利用します。

IAMロールで認証を行う理由

クロスアカウントでリソースにアクセスする場合、
単純にアカウントAに直接Kinesisへの
アクセス権限を与えるのではなく、
IAMロールを使用するのがベストプラクティスです。

これにより、
次のようなメリットがあります:

  • セキュリティ強化
    必要なときだけ特定の権限を
    借りてアクセスするため、
    不要なアクセス権限を付与せずに済みます。
  • 柔軟性
    異なるAWSアカウント間で
    権限を柔軟に委任できます。
  • 短期間のアクセス
    一時的なセッションでアクセスするため、
    長期間の認証情報が漏洩するリスクが低減します。

AWSアカウントBでIAMロールを作成する

まずは、Kinesisストリームがある
AWSアカウントBにIAMロールを作成し、
アカウントAがそのロールを
AssumeRoleできるように設定します。

ステップ1: IAMロールの作成

AWSアカウントBのIAMコンソールに
アクセスし、以下の設定を行います。

ロールの作成
新しいロールを作成し、
ロールの信頼関係を設定します。

信頼関係では、
アカウントAがこのロールを
引き受けることができるようにします。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<アカウントAのID>:root"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

    ステップ2: Kinesisへの書き込み権限を付与

    作成したロールに、
    Kinesisストリームへの
    書き込み権限を付与します。

    以下は、
    Kinesisへの書き込みに必要なポリシーの例です。

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "kinesis:PutRecord",
            "kinesis:PutRecords"
          ],
          "Resource": "arn:aws:kinesis:us-east-1:<アカウントBのID>:stream/<KinesisStreamName>"
        }
      ]
    }


    このポリシーは、
    指定されたKinesisストリームに
    データを書き込む権限を許可しています。

    AWSアカウントAでAssumeRoleを実行する

    次に、AWSアカウントAの
    Railsアプリケーションから
    アカウントBのIAMロールを
    AssumeRoleしてKinesisにアクセスします。

    ステップ1: AWS SDK for Rubyのインストール

    まず、Railsアプリケーションで
    AWS SDKを使用するために、
    AWS SDK for Rubyをインストールします。

    gem install aws-sdk-sts aws-sdk-kinesis


    または、
    Gemfileに以下を追加し、
    bundle installを実行します。

    gem 'aws-sdk-sts'
    gem 'aws-sdk-kinesis'

    ステップ2: AssumeRoleの実装

    Railsアプリケーション内で、
    アカウントBのロールをAssumeRoleし、
    Kinesisにアクセスするための一時的な認証情報を取得します。

    require 'aws-sdk-sts'
    require 'aws-sdk-kinesis'
    
    class KinesisClient
      def initialize
        sts_client = Aws::STS::Client.new
        assumed_role = sts_client.assume_role({
          role_arn: 'arn:aws:iam::<アカウントBのID>:role/<RoleName>',
          role_session_name: 'KinesisAccessSession'
        })
    
        credentials = assumed_role.credentials
    
        @kinesis_client = Aws::Kinesis::Client.new(
          access_key_id: credentials.access_key_id,
          secret_access_key: credentials.secret_access_key,
          session_token: credentials.session_token
        )
      end
    
      def put_record(data)
        @kinesis_client.put_record({
          stream_name: '<KinesisStreamName>',
          data: data,
          partition_key: 'partition_key'
        })
      end
    end

    • AssumeRole
      ここで、アカウントBのロールを引き受け、
      Kinesisにアクセスするための一時的な認証情報を取得しています。
    • put_record
      一時的な認証情報を使って、
      Kinesisにデータを書き込む処理を行います。

    ステップ3: データを書き込む

    取得した認証情報を使って、
    RailsアプリケーションからKinesisにデータを書き込みます。

    client = KinesisClient.new
    client.put_record('Sample data')


    これで、AWSアカウントAから
    アカウントBのKinesisストリームに
    データを書き込むことができるようになります。

    ベストプラクティスと注意点

    セキュリティ管理の徹底

    クロスアカウントアクセスでは、
    権限管理が非常に重要です。

    IAMロールの信頼関係やポリシーは、
    最小限の権限(最小特権の原則)で設定することが推奨されます。

    セッションの管理

    AssumeRoleによって取得した認証情報は、
    一時的なものであり、デフォルトで1時間しか有効ではありません。

    長時間のプロセスの場合は、
    セッションの有効期限が切れる前に
    新しい認証情報を取得する必要があります。

    監査とロギング

    CloudTrailを利用して、
    どのアカウントがどのリソースにアクセスしたのかを監視し、
    異常な動作がないかを確認するのも良い習慣です。

    まとめ

    AWSアカウントAのRailsアプリケーションから、
    AWSアカウントBのKinesisに
    データを書き込むための手順について解説しました。

    AssumeRoleを使って、
    セキュリティを確保しながら
    別のアカウントのリソースにアクセスできるようになるため、
    クロスアカウントアクセスのベストプラクティスに
    従って安全に運用することができます。