【開発環境向け】NATインスタンスを利用して費用を削減する

## 1．はじめに
以下記事に感化され、

[開発環境のNAT GatewayをNAT InstanceにしてAWS利用費を削減した話](https://dev.classmethod.jp/articles/cost-cut-by-nat-instance/)

確かに、開発環境や学習用環境はNAT GatewayをNAT Instanceに代えたらAWS利用費を削減できそう！
と思い手順を検証してみました。



某C社様のブログにはいつもお世話になっております。

あと、公式ドキュメントの手順で簡単にできるだろうと思っていたら
案外、躓くポイントがありました。




NATインスタンスとは？
---

* NATインスタンスの基本
AWS公式ドキュメント：[NAT インスタンス](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/VPC_NAT_Instance.html)
    * NAT インスタンスにはインターネットアクセスが必要
    * パブリックサブネットに存在し、パブリック IP アドレスまたは Elastic IP アドレスを持っている必要がある。
    * NAT AMI を作成し、NAT インスタンスのセキュリティグループを作成してから起動する。
<br>

* NATゲートウェイとNATインスタンスの比較については以下を参照
　AWS公式ドキュメント：[NAT ゲートウェイと NAT インスタンスを比較する](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-comparison.html)



## 2. 事前準備
### 2.1. VPC を作成する
1. VPC作成します。
  1. Amazon VPC コンソール (https://console.aws.amazon.com/vpc/) を開きます。
  1. [VPC の作成] を選択し、「VPC など」 を選択します。
      * VPC 名を入力:Nat-test
      * アベイラビリティーゾーンの数:1
      * パブリックサブネットの数:1
      * プライベートサブネットの数:1
  1. [VPC の作成] を選択します。
      ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/1f981d2a-b0a0-ff1c-6891-313097dec27d.png)


5. 実行結果を確認します。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/00e581bb-10f2-6bf8-b7d5-ed242b28f1d1.png)

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/bb28d7fe-2601-a6a5-0ba4-c254d301fcab.png)


### 2.2. セキュリティグループを作成

1. セキュリティグループ名：Nat-instance-sg
1. インバウンドルール：<br>
    | タイプ    | ポート |ソース|    
    | :-----    |:-----| :----- |      
    | ssh      | 22   |マイIP |
    | http      | 80   |プライベートサブネットのCIDR |
    | https     | 443   |プライベートサブネットのCIDR |

1. アウトバウンドルール：0.0.0.0/0
作成画面：
  ![a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/b4da0702-d368-2783-8691-2e418ba8af53.jpeg)



### 2.3. NAT AMIを作成
:::note warn
警告
AWS公式ドキュメントの手順には、この後NAT AMIを作成すると書いてありますが、
インスタンスをAMIにして再作成しなくても、手順のコマンド実行すれば
NATインスタンスとして機能するため割愛します。
:::

※イメージ化するとお金が余計にかかってしまうデメリットもあります。

## 3.NAT インスタンスの作成
1. インスタンスを起動します。
    | 項目  | 値  |      
    | ----- |-----|              
    | 名前                 | Nat-instance-1                      |
    | AMI                  | Amazon Linux 2023          |
    | インスタンスタイプ   | T3.micro                            |
    | ネットワーキング設定 | VPC、パブリックサブネットを選択 |
    |パブリックIPの自動割当て| 有効|
    | セキュリティグループ | Nat-instance-sg                     |

1. ssh接続し、次のコマンドを実行して、iptables を有効にします。
    ```
    sudo yum install iptables-services -y
    sudo systemctl enable iptables
    sudo systemctl start iptables
    ```
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/019994b2-3790-ea36-ceab-2cec5a3b80cb.png)


1. viを使用し、設定ファイルを作成します。
    * viで開きます。
      ```
       vi /etc/sysctl.d/custom-ip-forwarding.conf
      ```
    * 次の行を追加します。<br>
      ```
      net.ipv4.ip_forward=1
      ```
    * 設定ファイルを適用します。<br>
      ```
      sudo sysctl -p /etc/sysctl.d/custom-ip-forwarding.conf`
      ```
      ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/496257de-5fc4-5957-e15f-c70307c63a5f.png)


1. 次のコマンドを実行します。<br>
    `netstat -i`

      ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/b92b80c5-46d6-5a06-7f11-13f432f7e7be.png)

1. プライマリENI名を控えておきます。
    プライマリENI：**enX0**
    <br>
    
1. 次のコマンドを実行して、NAT を設定します。
    ```
    sudo /sbin/iptables -t nat -A POSTROUTING -o enX0 -j MASQUERADE
    sudo /sbin/iptables -F FORWARD
    sudo service iptables save
    ```
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/d80a8239-eb4b-d1b4-90d6-8f2b8615132a.png)


1. プライベートルートテーブルのルートを追加します。
    | 送信先    | ターゲット  |      
    | :----- |-----|              
    | 0.0.0.0/0 | Nat-instance-1(i-098ecb6fcdedf6204) |

    ![スクリーンショット 2023-11-21 151957.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/2defa4be-58f6-5674-0535-602e96b237f3.png)



1. 送信元/送信先チェックを無効にします。
  * アクション>ネットワーキング>ソース/宛先チェックの変更<br>
  * 停止にチェックを入れ、「保存」ボタンをクリックする<br>
      <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/32b615b3-4470-03c9-80ba-ad48469fbbe4.png" alt="" width="300" height="" border="">
      <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/98410cb5-86af-5d38-9e60-6a8fdbb9df04.png" alt="" width="300" height="" border="">


## 4. NAT インスタンスをテストする

### 4.1. テスト準備
1. プライベートサブネットにインスタンスを作成します。
    | 項目    | 値 |      
    | --- |-----|              
    | 名前      | test-private-ec2   |
    | AMI         |   Amazon Linux 2023  |
    | インスタンスタイプ   | T3.micro  |
    | ネットワーキング設定 | VPC、プライベートサブネットを選択  |

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/7e5d94e0-1a27-8eea-d98b-621d9e38bc47.png)

1. test-private-ec2用のセキュリティグループを作成
インバウンドルール<br>
    | タイプ    | ソース|    
    | :-----    | :----- |      
    | すべてのICMP ipv4     | VPCのCIDR |

1. 「Nat-instance-sg」のインバウンドルールにICMPへの許可を追加します。
インバウンドルール<br>
    | タイプ    | ソース|    
    | :-----    | :----- |      
    | すべてのICMP ipv4     | VPCのCIDR |

### 4.2. NATインスタンスでgoogle.comにpingを送信

1. Nat-instance-1にssh接続します。
1. google.com宛にpingを実行します。
    ```
    ping google.com
    ```
    NATインスタンスがインターネットに接続可能なことを確認しました。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/544c8fd2-c0d3-a30d-f9ff-02ab9c70444d.png)


### 4.3. プライベートEC2からgoogle.comにpingを送信
1. Natインスタンスに接続します。<br>
    以下コマンド実行
    ```
    #.sshディレクトリへ移動します。
    cd .ssh

    #キーペアを配置
    #ローカルのキーペア「Nat-test.pem」の中身をコピーして保存します。
    vi Nat-test.pem

    #権限を修正して使用可能にします。
    chmod 400 Nat-test.pem
    ```


2. プライベートサブネットのec2にssh接続します。

:::note warn
警告
AWS公式ドキュメントの手順には、NAT インスタンスから、プライベートサブネットのインスタンスに接続するコマンドとして以下が提供されています。
`ssh ec2-user@private-server-private-ip-address`
このコマンドでは下記エラーが発生してssh接続できない為、注意が必要です。
`Permission denied (publickey,gssapi-keyex,gssapi-with-mic)`.
:::

```
ssh -i "Nat-test.pem" ec2-user@10.0.129.147
```
    
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/78346f86-c3c5-8486-894c-c1f5ac5edfdd.png)

1. NATインスタンス宛にpingを実行します。
    ```
    ping 10.0.1.217
    ```
    プライベートインスタンスからNATインスタンスにping送信可能
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/230bf6b2-fd41-e38a-73a6-12f393731728.png)

1. google.com宛にpingを実行します。
    ```
    ping google.com
    ```
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558533/21517e38-e854-3cd4-b6ca-530f74cfb240.png)

    <br>

    **NATインスタンス経由でインターネットに接続出来ました**

    **以上でNATインスタンスの作成およびテスト手順は終わりです。**

## 5. 終わりに

公式ドキュメントの手順では、所々エラーが発生する箇所があって大変でした（汗
※特に、NATインスタンスからプライベートインスタンスへのssh接続のところ

何と言っても、NATインスタンスを使うメリットは費用が安いことです。
顧客に提供する環境で使えるかというと、保守等の人件費とか色々あると思うのでそこは要検討です。

**この記事がお役に立てれば幸いです。**
**お読みいただきありがとうございました！**

## 6.参考文献

【Developers IO】
[開発環境のNAT GatewayをNAT InstanceにしてAWS利用費を削減した話](https://dev.classmethod.jp/articles/cost-cut-by-nat-instance/)

【AWS公式ドキュメント】
[NAT インスタンス](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/VPC_NAT_Instance.html)
[NAT ゲートウェイと NAT インスタンスを比較する](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-comparison.html)