【アップデート】IAM 条件キーで Lambda 関数の VPC 設定を制御できるようになりました!!

記事タイトルとURLをコピーする

はじめに

こんにちは、技術1課の山中です。 外に出ると地獄のような暑さですね、体調に気をつけてがんばりましょう!

今回は AWS Lambda に関する IAM のアップデートです! IAM の条件キーを指定して、 Lambda 関数作成時に VPC 等ネットワーク設定を制御することができるようになりました!

AWS Lambda now provides IAM condition keys for VPC settings

Lambda と VPC について

Lambda のすべてのコンピューティングインフラストラクチャは Lambda サービスが所有する VPC 内で実行されてます。

f:id:swx-yamanaka:20200813144150p:plain

Lambda 関数の呼び出しは、必ず Lambda API を通して実行されるので、実行環境への直接のネットワークアクセスは発生しません。

f:id:swx-yamanaka:20200813144418p:plain

Lambda 関数が、ユーザーが所有している VPC に接続するように設定されていない場合 (Lambda on VPC でない場合)、関数は他の AWS サービス、 API の HTTPS エンドポイント、AWS 外のサービスなどパブリックインターネットで利用可能なすべてのリソースにアクセスできます。
しかしこの場合、 Lambda 関数はユーザーが所有している VPC 内のリソースにアクセスすることができません。

f:id:swx-yamanaka:20200813144934p:plain

Lambda 関数を所有している VPC 内のリソースにアクセスできるように設定すると、 VPC 内に Elastic network interfaces (以下、 ENI) が作成され、クロスアカウントでアタッチ処理が行われます。
複数の Lambda 実行環境が Hyperplane ENI を共有して、 Hyperplane ENI から VPC 内の ENI に NAT 処理を行うことで VPC 内のリソースへアクセスすることが可能となります。
ただし、この場合は AWS 外のサービスなどに直接パブリックインターネット経由でアクセスすることはできません。

f:id:swx-yamanaka:20200813164301p:plain

アクセス対象の 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 とサブネットとセキュリティグループを作成します。 f:id:swx-yamanaka:20200813182839p:plain サブネットは 2 つの AZ に 1 つずつ作成しています。 f:id:swx-yamanaka:20200813182916p:plain セキュリティグループはデフォルトのものを使用します。 f:id:swx-yamanaka:20200813183031p:plain

特定の 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 ユーザーにアタッチします。

f:id:swx-yamanaka:20200814053632p:plain

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

想定通り、アクセスが拒否されていて作成できませんでした。

f:id:swx-yamanaka:20200814052256p:plain

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

今度は作成が成功しました。

f:id:swx-yamanaka:20200814053956p:plain

マネジメントコンソールから作成されてた Lambda 関数を確認すると、きちんと指定した VPC に作成されていました。

f:id:swx-yamanaka:20200814054323p:plain

特定のサブネットおよびセキュリティグループを許可

次は 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 関数の作成と更新を許可するポリシーです。

f:id:swx-yamanaka:20200814055036p:plain

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

想定通り、アクセスが拒否されていて作成できませんでした。

f:id:swx-yamanaka:20200814055615p:plain

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

作成が成功しています!

f:id:swx-yamanaka:20200814060039p:plain

おわりに

Lambda 関数の作成時に VPC 等のネットワーク設定を IAM ポリシーで制御できるようになったことで、これまで以上に柔軟な管理がやりやすくなるのではないでしょうか。
この内容は 2020/8/19(水) 18:00 よりYouTube にて配信する「30分でわかる AWS UPDATE!」で取り上げますので、是非ご覧ください!
チャンネル登録よろしくおねがいします!!

www.youtube.com

また、以下でも今回のアップデートに触れておりますので、あわせてご覧ください。


【毎日AWS #037】起動・更新時のVPCを制御! AWS Lambda がVPC設定の IAM 条件キーをサポート 他5件 #サバワ

参考

山中 大志(記事一覧)

アプリケーションサービス部

ビールと味噌カツをこよなく愛するエンジニアです。

AWSをみなさんにより使っていただけるような情報を発信していきたいと考えてます。