はじめに
こんにちは、技術1課の山中です。 外に出ると地獄のような暑さですね、体調に気をつけてがんばりましょう!
今回は AWS Lambda に関する IAM のアップデートです! IAM の条件キーを指定して、 Lambda 関数作成時に VPC 等ネットワーク設定を制御することができるようになりました!
AWS Lambda now provides IAM condition keys for VPC settings
Lambda と VPC について
Lambda のすべてのコンピューティングインフラストラクチャは Lambda サービスが所有する VPC 内で実行されてます。
Lambda 関数の呼び出しは、必ず Lambda API を通して実行されるので、実行環境への直接のネットワークアクセスは発生しません。
Lambda 関数が、ユーザーが所有している VPC に接続するように設定されていない場合 (Lambda on VPC でない場合)、関数は他の AWS サービス、 API の HTTPS エンドポイント、AWS 外のサービスなどパブリックインターネットで利用可能なすべてのリソースにアクセスできます。
しかしこの場合、 Lambda 関数はユーザーが所有している VPC 内のリソースにアクセスすることができません。
Lambda 関数を所有している VPC 内のリソースにアクセスできるように設定すると、 VPC 内に Elastic network interfaces (以下、 ENI) が作成され、クロスアカウントでアタッチ処理が行われます。
複数の Lambda 実行環境が Hyperplane ENI を共有して、 Hyperplane ENI から VPC 内の ENI に NAT 処理を行うことで VPC 内のリソースへアクセスすることが可能となります。
ただし、この場合は AWS 外のサービスなどに直接パブリックインターネット経由でアクセスすることはできません。
アクセス対象の VPC 内には、 Lambda 関数作成時もしくは、 Lambda 関数の VPC 設定が更新された際に、 サブネットとセキュリティグループの組み合わせごとに 1 つの ENI が作成されます。
Hyperplane ENI とは
Hyperplane は AWS のサービス内部で利用されている SDN (Software Defined Network) の技術で、 Hyperplane ENI は Lambda サービスが制御するマネージドなネットワークリソースです。
以前は VPC の ENI を Lambda 実行環境に直接マッピングしていましたが、 以前のアップデート でこの Hyperplane ENI を利用するようになりました。
詳細は、以下動画をご覧ください。
AWS re:Invent 2017 Keynote - Tuesday Night Live with Peter DeSantis
アップデート内容
前置きはここまでとして、今回のアップデートで IAM ポリシー定義時に、以下の新しい条件キーを指定できるようになりました。
- lambda:VpcIds
- lambda:SubnetIds
- lambda:SecurityGroupIds
この条件キーを IAM ポリシーで指定することでユーザーが Lambda 関数を作成 / 更新する際のネットワーク設定 (VPC 、サブネットグループ、セキュリティグループ) を制限することができます。
例えば、社内で AWS リソースから直接インターネットにアクセスしてはいけない、みたいなルールがある場合などに使えそうですね。
試してみる
では実際に試してみましょう。
事前準備
今回のアップデート内容を試すために、 VPC 、サブネットおよびセキュリティグループを作成しておきます。
はじめにテスト用の VPC とサブネットとセキュリティグループを作成します。
サブネットは 2 つの AZ に 1 つずつ作成しています。
セキュリティグループはデフォルトのものを使用します。
特定の VPC を許可
まずは、 Lambda 関数の作成を特定の VPC のみに許可するパターンを試してみましょう。
1. IAM ポリシーを作成し IAM ユーザーに紐付ける
以下のように ForAllValues:StringNotEquals条件演算子 を利用して必要な VPC ID を指定します。
これで、 Lambda 関数を作成および更新する際、特定の VPC 以外に作成はできなくなるはずです。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "sample", "Action": ["lambda:CreateFunction","lambda:UpdateFunctionConfiguration"], "Effect": "Deny", "Resource": "*", "Condition": {"ForAllValues:StringNotEquals": {"lambda:VpcIds":["vpc-0bef3831bfcbec5d9"]}} } ] }
今回は、この IAM ポリシーとマネージドポリシーの AWSLambdaFullAccess のみを IAM ユーザーにアタッチします。
2. VPC の設定をせずに Lambda 関数を作成
IAM ユーザーのアクセスキー ID とシークレットアクセスキーを利用してローカル環境から AWS CLI で Lambda 関数を作成します。
まずは、 VPC に接続しない Lambda 関数を作成してみます。
$ aws lambda create-function --function-name MyVPCLambda1 \ --runtime python3.8 --handler helloworld.handler --zip-file fileb://helloworld.zip \ --region ap-northeast-1 --role arn:aws:iam::123456789012:role/VPCConditionLambdaRole
想定通り、アクセスが拒否されていて作成できませんでした。
3. 許可された VPC を指定して Lambda 関数を作成
続いて、 IAM ポリシーで許可している VPC 内にあるサブネットおよびセキュリティグループを指定して作成してみます。
$ aws lambda create-function --function-name MyVPCLambda1 \ --vpc-config "SubnetIds=['subnet-08de8529dfc92ff9f'],SecurityGroupIds=['sg-0c8cc910f1eae3387']" \ --runtime python3.8 --handler helloworld.handler --zip-file fileb://helloworld.zip \ --region ap-northeast-1 --role arn:aws:iam::123456789012:role/VPCConditionLambdaRole
今度は作成が成功しました。
マネジメントコンソールから作成されてた Lambda 関数を確認すると、きちんと指定した VPC に作成されていました。
特定のサブネットおよびセキュリティグループを許可
次は VPC ではなく、特定のサブネットとセキュリティグループを許可するように IAM ポリシーを更新してみます。
1. IAM ポリシーを更新
まずは IAM ユーザーに紐付いているポリシーを以下に修正します。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "samplesubnets", "Action": ["lambda:CreateFunction","lambda:UpdateFunctionConfiguration"], "Effect": "Deny", "Resource": "*", "Condition": {"ForAllValues:StringNotEquals": {"lambda:SubnetIds": ["subnet-08de8529dfc92ff9f","subnet-09ed190ed5cef08fe"]}} }, { "Sid": "samplesg", "Action": ["lambda:CreateFunction","lambda:UpdateFunctionConfiguration"], "Effect": "Deny", "Resource": "*", "Condition": {"ForAllValues:StringNotEquals": {"lambda:SecurityGroupIds": ["sg-0c8cc910f1eae3387"]}} } ] }
特定のサブネットおよびセキュリティグループの設定がある場合のみ Lambda 関数の作成と更新を許可するポリシーです。
2. 許可されていないサブネットを指定して Lambda 関数を作成
先ほどと同様にローカル環境から AWS CLI で Lambda 関数を作成します。
まずは、 IAM ポリシーで許可していないサブネットを指定して作成を試みてみましょう。
$ aws lambda create-function --function-name MyVPCLambda2 \ --vpc-config "SubnetIds=['subnet-096fbd323f1fa3954'],SecurityGroupIds=['sg-0c8cc910f1eae3387']" \ --runtime python3.8 --handler helloworld.handler --zip-file fileb://helloworld.zip \ --region ap-northeast-1 --role arn:aws:iam::123456789012:role/VPCConditionLambdaRole
想定通り、アクセスが拒否されていて作成できませんでした。
3. 許可されたサブネットおよびセキュリティグループを指定して Lambda 関数を作成
続いて、 IAM ポリシーで許可しているサブネットおよびセキュリティグループを指定して作成してみます。
$ aws lambda create-function --function-name MyVPCLambda2 \ --vpc-config "SubnetIds=['subnet-08de8529dfc92ff9f'],SecurityGroupIds=['sg-0c8cc910f1eae3387']" \ --runtime python3.8 --handler helloworld.handler --zip-file fileb://helloworld.zip \ --region ap-northeast-1 --role arn:aws:iam::123456789012:role/VPCConditionLambdaRole
作成が成功しています!
おわりに
Lambda 関数の作成時に VPC 等のネットワーク設定を IAM ポリシーで制御できるようになったことで、これまで以上に柔軟な管理がやりやすくなるのではないでしょうか。
この内容は 2020/8/19(水) 18:00 よりYouTube にて配信する「30分でわかる AWS UPDATE!」で取り上げますので、是非ご覧ください!
チャンネル登録よろしくおねがいします!!
また、以下でも今回のアップデートに触れておりますので、あわせてご覧ください。
【毎日AWS #037】起動・更新時のVPCを制御! AWS Lambda がVPC設定の IAM 条件キーをサポート 他5件 #サバワ
参考
- AWS Lambda now provides IAM condition keys for VPC settings
- Using AWS Lambda IAM condition keys for VPC settings
- Announcing improved VPC networking for AWS Lambda functions