Lambda 関数を専有の VPC に接続するにはどうしたらよいですか?

最終更新日: 2019 年 07 月 30 日

AWS Lambda 関数を専有の仮想プライベートクラウド (VPC) 内のリソースに接続したいと思っています。設定する方法を教えてください。

簡単な説明

現在のところ、Lambda では専有テナント VPC での実行がサポートされていないため、専有テナント VPC を Lambda 関数を含むデフォルトテナント VPC にピアリング接続する必要があります。Amazon Elastic Compute Cloud (Amazon EC2) インスタンスのテナントおよび VPC の詳細については、「ハードウェア専有インスタンスの基礎」を参照してください。

重要: この記事は Node.js についてと Lambda 関数を作成する方法を理解していることを前提としています。このソリューションでは、Amazon Elastic Compute Cloud (Amazon EC2) のハードウェア専有インスタンスを使用する必要があります。このインスタンスにより AWS アカウントに料金の支払いが発生する点にご注意ください。

解決方法

VPC を作成および設定する

1.    Amazon VPC コンソール VPC を作成します。作成中、[IPv4 CIDR ブロック] に 12.0.0.0/16 と入力します。[テナンシー] で、[デフォルト] を選択します。

2.    別の VPC を作成します。作成中、[IPv4 CIDR ブロック] に 11.0.0.0/16 と入力します。[テナンシー] で、[専用] を選択します。

注: 別の CIDR ブロックを使用するように選択した場合は、2 つの VPC でブロックが重複しておらず、別々のものになっていることを確認します。

3.    インターネットゲートウェイを作成して、専有テナント VPC にアタッチします。

注: [Test the connectivity] で後に作成する HTTP サーバー用にインターネットゲートウェイが必要です。詳細については、「インターネットアクセスを有効にする」を参照してください。

4.    各 VPC にサブネットを作成します。デフォルトのテナント VPC (後で Lambda 関数でアクセスする) 用に、2 つ以上のサブネットを異なるアベイラビリティーゾーンで作成します。これは冗長性におけるベストプラクティスで、これにより Lambda は関数の高可用性を提供することができます。

注: VPC にサブネットを 1 つしか作成しない場合、VPC と同じ CIDR ブロックを使用できます。各 VPC で複数のサブネットがある場合は、VPC の CIDR ブロックのサブセットを使用します。詳細については、「IPv4 用の VPC とサブネットのサイズ設定」を参照してください。

5.    作成した 2 つの VPC 間で VPC ピアリング接続を作成します。[Create Peering Connection] ページで、次の操作を実行します。
(任意) [Peering connection name tag] に,、VPC ピアリング接続の名前を入力します。
[VPC (Requester)] で、作成したデフォルトテナント VPC を選択します。
[Account] で、[My account] を選択します。
[Region] で、[This region] を選択します。
[VPC (Accepter)] で、作成した専有テナント VPC を選択します。
[Create Peering Connection] を選択します。

6.    VPC ピアリング接続を承諾します

7.    ここに示したように、新しい VPC のルートテーブルにそれぞれルートを追加します。詳細については、「ルートテーブルでルートを追加および削除する」を参照してください。

pcx-... で始まる [Target] 値に、[Peering Connection] を選択し、作成したピアリング接続を選択します。
igw-... で始まる [Target] 値には、[Internet Gateway] を選択し、作成したインターネットゲートウェイを選択します。

デフォルトテナント VPC:

Destination Target Status Propagated
12.0.0.0/16 Local Active いいえ
11.0.0.0/16 pcx-1a2b3c4d5e6f7g8h9 Active いいえ

専有テナント VPC:

Destination Target Status Propagated
11.0.0.0/16 Local Active いいえ
12.0.0.0/16 pcx-1a2b3c4d5e6f7g8h9 Active いいえ
0.0.0.0/0 igw-12345678a90b12c34 Active いいえ

Amazon VPC の Lambda 実行ロールを作成する

注: Amazon VPC アクセスの Lambda 実行ロールが既に存在している場合は、このセクションはスキップしてかまいません。

1.    AWS Identity and Access Management (IAM) コンソールの左側のナビゲーションペインで、[ロール] を選択します。

2.    [ロール] ペインで、[ロールの作成] を選択します。

3.    [ロールの作成] ページで、次の手順を実行します。
[信頼できるエンティティの種類の選択] では、[AWS のサービス] を選択します。
[このロールを使用するサービスを選択してください] では、[Lambda] を選択します。
[Next: Permissions] を選択します。

4.    [アクセス許可ポリシーのアタッチ] の下で、AWSLambdaVPCAccessExecutionRole を検索します。その名前のポリシーを選択してから、[次へ: タグ] を選択します。

5.    (任意) 好みに合わせてタグを追加します。

6.    [レビュー] で、次の操作を行います。
[ロール名] には、この Lambda 実行ロールの名前を入力します。例えば、lambda_vpc_basic_execution
(オプション) [ロールの説明] では、必要に応じて説明を編集してください。
[ロールの作成] を選択します。

テスト用の新しい Lambda 関数を作成する

Lambda コンソールを使用するか、独自のデプロイパッケージを構築してアップロードすることにより、新しい Lambda 関数を作成します。次の手順を確実に実行します。

  • デフォルトテナント VPC と同じ AWS リージョンで関数を作成します。
  • 作成した実行ロールにアタッチします (例:lambda_vpc_basic_execution)。

テストするには、Node. js でネイティブ HTTP インターフェイスを使用するこちらの関数コード例を参照してください。

var http = require('http')
     
exports.handler = (event, context, callback) => {
    const options = {
        hostname: event.Host,
        port: event.Port
    }
    
    const response = {};
    
   http.get(options, (res) => {
        response.httpStatus = res.statusCode
        callback(null, response)
    }).on('error', (err) =>{
        callback(null, err.message);
    })
   
};

Lambda 関数を VPC に接続する

1.    Lambda コンソールの [Configuration] ペインの [Network] で、以下の手順を実行します。
[Virtual Private Cloud (VPC)] で、作成したデフォルトテナント VPC を選択します。
[Subnets] で、VPC のサブネットを 2 つ以上選択します。
[セキュリティグループ] では、セキュリティグループを選択します。
注: デフォルトのセキュリティグループは、ほとんどのユースケースで十分に機能します。詳しくは、「VPC のセキュリティグループ」を参照してください。

2.    [保存] をクリックします。

接続をテストする

1.    専有テナント VPC で EC2 インスタンスを起動します。後でそのインスタンスに接続するには、セットアップ時に割り当て可能なパブリック IPv4 アドレスが必要になります。または、セットアップ後に Elastic IP アドレスをインスタンスに関連付けることができます。

重要: ハードウェア専有インスタンスとしてサポートされている EC2 インスタンスタイプを選択する必要があります。このインスタンスにより AWS アカウントに料金の支払いが発生する点にご注意ください。

2.    両方の VPC のネットワークアクセスコントロールリスト (ACL) が、テスト中のポート (80) と専有 EC2 インスタンスのセキュリティグループでトラフィックを許可していることを確認します。

3.    EC2 インスタンスに接続します

4.    次のコマンドを実行し、EC2 インスタンスで HTTP サーバーを起動します。

# If python version is 2.x:
$ sudo python -m SimpleHTTPServer 80
# If python version is 3.x
$ sudo python -m http.server 80

5.    Lambda コンソールで、関数用のテストイベントを設定します。この JSON をイベントに使用し、yourHost を EC2 インスタンスの IP アドレスまたはホスト名に置き換えます。

{
  "Host": "yourHost",
  "Port": 80
}

6.    Lambda コンソールで、[Test] を選択します。

7.    次のような 200 のレスポンスコードに対する実行結果の詳細をチェックし、接続が正常に行われたことを確認します。

{
  "statusCode": 200
}

関数出力において平均、最大、最小レイテンシーで non-nil 値が表示される場合、VPC ピアリング接続は正常に設定されています。

注: Lambda がタイムアウトしたら、セキュリティグループが正しく設定されていることを確認してください。ECONNREFUSED エラーが表示された場合、HTTP サーバーが実行されていることを確認します。