NATインスタンス を用いて、VPC内でLambdaを実行

# はじめに
APIサービスを利用するにあたり固定のIPにする必要があったため、Lambda + 固定IPのNATインスタンスを構築しましたので、まとめます。
NATゲートウェイの方が、運用は楽ですが、サービスが小規模かつ、コスト面でNATインスタンスの方が安いため、こちらを利用しました。


##コスト
NATゲートウェイ：稼働時間料金で46 USD/月、+ データ処理および転送料金
NATインスタンス：稼働時間料金で10 USD/月(t3.micro)、+ 転送料金

# 完成図

![スクリーンショット 2022-02-14 22.44.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/89af707f-3fea-37c7-cec8-fbdd81886d49.png)


# 事前構築
VPCやサブネットは以下のように作成しましょう。

![スクリーンショット 2022-02-14 22.41.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/c86ad3f3-9935-454d-04b0-9f59e599a72a.png)

可用性を考えて、AZを2つ作成するため、サブネットを4つ作成するのもよいです。

パブリックサブネット：10.0.0.0/24、10.0.1.0/24
プライベートサブネット：10.0.2.0/24、10.0.3.0/24



# NATインスタンス起動
1. AMIは、 バージョンが新しいものが良いので、↓網かけの部分が新しい年度のものを選択します。
    **amzn-ami-vpc-nat-2018.03.0.`20210408.0`-x86_64-ebs**
![スクリーンショット 2022-02-14 22.35.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/0a178a83-458e-118f-fe5a-98ce620607df.png)

1. サブネットは、パブリックサブネットを選択し、パブリックIPは不要です。
![スクリーンショット 2022-02-14 22.47.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/76c03d94-48fd-e8eb-447e-3b8f1e4a895d.png)

1. ボリュームタイプは、`gp3`を選択します。
（デフォルトは、マグネティックです。マグネティックの理由がわかりません。。）
![スクリーンショット 2022-02-14 22.50.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/65540ad6-c292-3195-5f23-6f1b2c59eed7.png)

4. セキュリティーグループは、プライベートサブネットをソースにし、HTTP,HTTPSそれぞれ許可するCIDRを設定する。
    また、SSH接続できるように、自分のマイIPアドレスを指定する。（今回は、`0.0.0.0/0`）
![スクリーンショット 2022-02-14 22.59.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/f6d003a9-8281-deb3-5c81-5c09e637090d.png)

1. 起動後、`Elastic IP`をNATインスタンスにアタッチする
![スクリーンショット 2022-02-16 0.01.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/0876ad24-ea65-51d1-b773-06424f86b297.png)

![スクリーンショット 2022-02-16 0.00.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/5c0f8ae9-81ca-5d93-f051-2e3847bd30c0.png)


#NATインスタンスの送信元/送信先チェックの無効化
インスタンスを選択し、`[ネットワーキング]`→`[ソース/宛先チェックを変更]`をクリックします。

`送信元/送信先チェック中`の`停止`にチェックします。
![スクリーンショット 2022-02-15 21.26.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/6eddd4e9-1719-8f0e-78f3-f0bd244a0758.png)
![スクリーンショット 2022-02-15 21.26.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/b6fb3cb0-7987-8062-5d8c-cf8b82a58c5a.png)

チェックする理由として、パケット送信先がNATインスタンスでない場合でも、パケットは一度NATインスタンスを通る必要があるためです。

# プライベートサブネットからのインターネット接続をNATインスタンス経由にする
プライベートサブネットのルートテーブルに、ターゲットをNATインスタンス経由にして、インターネット接続できるよう以下の設定を加えます。

|送信先  |ターゲット|
|---|---|
| 0.0.0.0/0 | NATインスタンスID |

![スクリーンショット 2022-02-15 21.32.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/16d7d848-293a-9a19-c59e-dfea4872f1f1.png)

![スクリーンショット 2022-02-16 0.00.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/e6412e4d-461f-2ce0-c757-cebdd2455998.png)


# Lambda作成

IAMロールは、`基本的な Lambda アクセス権限で新しいロールを作成`にして作成します。

### タイムアウト
3秒から20秒に変更
### IAMロール
`AWSLambdaVPCAccessExecutionRole`ポリシーの権限をIAMロールに割り当てる
### VPC設置
プライベートサブネットにLambdaを設置し、セキュリティーグループは、デフォルトにしました。
EC2用のセキュリティーグループでもよいです。
![スクリーンショット 2022-02-15 22.53.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/0336b182-8e8e-9d76-cc94-a3ebc87aecf5.png)

### コード
インターネットにアクセスできることを確認します。

```py
import json
import urllib.request

url = "https://qiita.com/"

def lambda_handler(event, context):
    response = urllib.request.urlopen(url)
    return {
        'url': response.geturl(),
        'code': response.getcode(),
        'Content-Type': response.info()['Content-Type']
    }
```

###テスト実行
タイムアウトエラーが出ず以下の結果が出ると成功です。

```
Response
{
  "url": "https://qiita.com/",
  "code": 200,
  "Content-Type": "text/html; charset=utf-8"
}
```

![スクリーンショット 2022-02-14 22.44.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/89af707f-3fea-37c7-cec8-fbdd81886d49.png)

##エラー①
`AWSLambdaVPCAccessExecutionRole`がアタッチされていない場合、VPC内にLambdaは設置できずエラーになります。
![スクリーンショット 2022-02-15 22.55.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/7d397685-b336-5a89-a579-7612575c9d18.png)

##エラー②
Lambdaがタイムアウトエラーになる場合、`Elastic IP`をNATインスタンスにアタッチしているか確認しましょう。

# 参考

https://qiita.com/kojiisd/items/a15c1807c5c6bb08add0

https://qiita.com/tu-kun/items/b3e82cc6e3cbf812a233

https://atmarkit.itmedia.co.jp/ait/articles/1910/15/news018.html