AWS Lambda 関数の権限

この記事では、AWS Lambda と他の_AWSサービス_が相互に接続するための権限と接続能力について探究します。

Lambda関数には、必要な権限を決定する二つの側面があります。
実行権限: 他のサービスと相互作用するためのLambda関数の認可。
呼び出し権限: 関数を呼び出す権限で、IAMリソースベースのポリシーを使用して制御されます。

詳しく見ていきましょう。

実行ロール

実行ロールは、関数に他のサービスとやり取りするための権限を与えます。関数を作成するときにこのロールを提供し、関数が呼び出されるとLambdaがそのロールを引き受けます。

実行ロールの定義
例えば、Lambda関数が読み取りと書き込みをするためにS3バケットを必要とするとしましょう。実行ロールは以下のようになります。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::your-bucket-name/*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:*"
    }
  ]
}

信頼ポリシーは、誰が(もしくは何が)そのロールを引き受けることができるかを定義します。AWS Lambdaの場合、プリンシパルはLambdaサービスであり、AWS STS AssumeRole アクションを使用してロールを引き受ける許可が与えられています。以下は信頼ポリシーの例です。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

このポリシーは、明確にAWS Lambdaサービス(サービスプリンシパル "lambda.amazonaws.com" によって識別)が_sts:AssumeRole_ アクションを呼び出すことによりロールを引き受けることが許可されていると述べています。
Lambda関数用のIAMロールを作成する際は、この信頼ポリシーをロールに添付します。これにより、Lambdaサービスがロールを引き受けて、Lambda関数をAWSアカウントに代わって実行できるようになるための必要な権限が保証されます。

以下は、関数の "実行ロール"(または権限)、そして "信頼ポリシー" を設定する場所を示すスクリーンショットです。

リソースベースのポリシー
リソースポリシー(または関数ポリシー)は、LambdaサービスにどのプリンシパルがLambda関数の呼び出し権限を持つかを伝えます。AWSプリンシパルにはユーザー、ロール、他のAWSサービス、または他のAWSアカウントが含まれます。

以下はリソースベースのポリシーの例です。

{
    "Version": "2012-10-17",
    "Id": "default",
    "Statement": [
        {
            "Sid": "lambda-allow-s3-my-function",
            "Effect": "Allow",
            "Principal": {
              "Service": "s3.amazonaws.com"
            },
            "Action": "lambda:InvokeFunction",
            "Resource":  "arn:aws:lambda:us-east-2:123456789012:function:my-function",
            "Condition": {
              "StringEquals": {
                "AWS:SourceAccount": "123456789012"
              },
              "ArnLike": {
                "AWS:SourceArn": "arn:aws:s3:::my-bucket"
              }
            }
        }
     ]
}

AWSのドキュメンテーションでリソースベースのポリシーについてさらに読むことができます。

VPC内のAWSリソースに接続するためにはどうすればいいですか?
また、プライベートサブネット内のEC2インスタンスから関数を呼び出すことは可能でしょうか?

VPC内のリソースにアクセスする
VPC内のリソースにアクセスするためにLambda関数を有効にするには、VPCサブネットIDやセキュリティグループIDなど、追加のVPC固有の構成情報が必要です。この機能により、LambdaはVPC内のリソースにアクセスできます。関数のセキュリティが変更されるわけではありません。また、弾性ネットワークインターフェイスを作成、記述、削除する権限を持つ実行ロールも必要です。Lambdaにはこの目的に "AWSLambdaVPCAccessExecutionRole" という名前の権限ポリシーがあります。

VPCにLambda関数をアタッチする方法について、AWS Lambda開発者ガイドで学ぶことができます。

LambdaとAWS PrivateLink
AWS LambdaはAWS PrivateLinkをサポートしており、VPC内またはオンプレミスのデータセンター内でLambda関数を安全に作成、管理、呼び出すことができます。トラフィックが公衆インターネットに公開されることはありません。
LambdaとVPC間のプライベートリンクをセットアップするには、インターフェイスVPCエンドポイントを設定します。これはAWS PrivateLinkを利用し、インターネットゲートウェイ、NATデバイス、VPN、AWS Direct Connectを必要とせずにLambda APIへのプライベートアクセスを可能にします。VPC内のインスタンスがLambda APIと通信するために公共IPアドレスは必要ありません。これにより、VPCとLambda間のトラフィックがAWSネットワーク内に留まることが保証されます。

AWS PrivateLinkとAWS Lambdaについての詳細は、AWS Lambda開発者ガイドで学ぶことができます。

まとめ
この記事では、AWS Lambdaおよび他のAWSサービスに関する「誰が何をすることができるか」を制御する権限についてカバーしました。
また、AWS LambdaがVPC内のAWSサービスに接続する能力、そしてプライベートなVPCリソースがプライベートにLambda関数を呼び出す必要がある場合にについても説明しました。

こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。
https://dev.to/aws-builders/aws-lambda-function-permissions-43nn