こんにちは。AS部の兼安です。
私のサンドボックス環境で、今月のコストが思ったより高くなりました。NAT Gatewayのコストが思ったよりかかったのが原因です。NAT Gatewayについてはこれまでもうっかりしていてコストがかかったことが何度があるので、節約のために、NAT GatewayだけでなくNATインスタンスをサッと使えるようにしておきたいと思いました。
- 本記事の概要
- 思ったよりコストがかかった原因をNAT Gatewayだと特定するまで
- Nat GatewayとNATインスタンスの違い
- NATインスタンスを作るCloudFormationテンプレート
- CloudFormationテンプレートの実行方法
- CloudFormationテンプレートの作成後の作業
- Cloud AutomatorでNATインスタンスの自動起動・停止を設定する
- 最後に
本記事の概要
NATインスタンスを作り、パブリックサブネットに配置する。
ここまでをCloudFormationテンプレートにまとめて、NATインスタンスを作って設定する手順を少し手軽にしてみました。
思ったよりコストがかかった原因をNAT Gatewayだと特定するまで
最初に思ったよりコストがかかった原因がNAT Gatewayだと特定するまでの経緯を書いておきます。
まず、AWS Cost Explorerを見てみました。
ディメンション
をサービス
にしたところ、EC2 その他
の割合が妙に高いことがわかりました。
EC2 その他
のままでは、対策のしようがないので、これが何なのか?をこちらの記事を参考に、ディメンション
を使用タイプ
にしたところ、大半はNAT Gatewayであることがわかりました。
余談ですが、この使用タイプ
を選ぶという操作がなかなか憶えられません。どうもピンとこず、すぐに忘れてしまいます(汗)
Nat GatewayとNATインスタンスの違い
Nat GatewayとNATインスタンスは、どちらもNATの機能を提供するものです。
Nat Gatewayは、サイズの変更や開始・停止ができません。しかし、多くの機能を自動で処理してくれるため、管理が容易です。本番環境での利用を考えると、Nat Gatewayを選択するのが推奨されます。
NATインスタンスは、NAT Gatewayと同様に、プライベートサブネットからインターネットにアクセスするためのものです。EC2を基にしたインスタンスなので、サイズの指定や開始・停止が可能です。ただし、構築や性能不足の際の対処など、管理の面での負担が比較的高くなっています。開発用の限定的な環境におけるコスト観点だと、NATインスタンスの方が有効である場合もあります。
NATインスタンスの作成手順については、以下のページが参考になります。本記事のCloudFormationテンプレートも、これらのページの手順をまとめたものです。
NATインスタンスを作るCloudFormationテンプレート
このCloudFormationテンプレートは、以下のようにパブリックサブネットとプライベートサブネットがあるVPCを想定しており、実行すると、赤字の部分のように、NATインスタンスがパブリックサブネットに配置されます。
CloudFormationテンプレートのポイント
NATインスタンス用のセキュリティグループのポイント
NatInstanceSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Sub ${Suffix}-sg-nat-instance GroupDescription: Security group for NAT instance VpcId: !Ref VPC Tags: - Key: Name Value: !Sub ${Suffix}-sg-nat-instance SecurityGroupEgress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 0.0.0.0/0
NATインスタンス用のセキュリティグループは以下のページを参考にしています。
インバウンドルールは省略し、アウトバウンドルールだけを設定しています。インバウンドルールは後で手動で設定した方が柔軟性があってよいだろうと思い、設定していません。
NATインスタンス用のIAMロールのポイント
NatInstanceRole: Type: AWS::IAM::Role Properties: RoleName: !Sub ${Suffix}-role-nat-instance AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
NATインスンス用のIAMロールは、セッションマネージャーを使用するためのマネージドポリシーをアタッチしています。
NATインスタンスにするEC2のポイント
NatInstanceEC2: Type: AWS::EC2::Instance Properties: # (中略) # 送信元/送信先チェックを無効にする SourceDestCheck: false
NATインスタンスそのものになるEC2は、まずこちらを参考に送信元/送信先チェックを無効にしています。
NAT インスタンス - 送信元/送信先チェックを無効にする
[送信元/宛先を確認] には、[停止] を選択します。
# (中略) UserData: Fn::Base64: !Sub | #!/bin/bash -xe # パッケージの更新 yum -y upgrade yum -y install iptables-services sysctl -w net.ipv4.ip_forward=1 # 主要なネットワークインターフェースを動的に取得 PRIMARY_INTERFACE=$(ip -o -4 route show to default | awk '{print $5}') /sbin/iptables -t nat -A POSTROUTING -o $PRIMARY_INTERFACE -j MASQUERADE service iptables save
次に、こちらを参考に、NATインスタンスの起動時に、iptablesを設定しています。
参考元ページとの違いは、以下の通りです。
- AMIを作っておくのではなく、起動時にUserDataでipatablesを設定する
- UserDataはルートで実行されるので、
sudo
は不要なので削除 - yumパッケージの更新をしている(念の為追加しましたが、これはやってもやらなくてもどちらでもよいと思います。)
- iptablesに設定するネットワークインターフェースを動的に取得している
CloudFormationテンプレートの実行方法
- CloudFormationの画面で、
スタックの作成
からテンプレートの指定
で実行します。 スタックの詳細を指定
でパラメータ名を入力します。- Suffix:各種リソース名のサフィックス
- VPC:NATインスタンスを配置するVPCのID
- PublicSubnet:NATインスタンスを配置するパブリックサブネットのID
- KeyPairName:NATインスタンスにログインするためのキーペア名
- NatInstanceAMIID: NATインスタンスのAMI ID(初期値はARM64用のAmazon Linux 2023)
- 次の
オプションのタグ
は何も変更せずそのまま進めて問題ありません。 - 最後の
レビュー
では、このCloudFormationテンプレートがIAMロールを作るため、確認をしてきます。
チェックを入れて実行してください。
CloudFormationテンプレートの作成後の作業
セキュリティグループの更新
上記ページを参考に、NATインスタンス用のセキュリティグループのインバウンドルールに、HTTPとHTTPSを追加します。ソースはプライベートサブネットのCIDRを指定します。プライベートサブネットは2つあるとしたら、以下のように4つのルールを追加します。
アウトバウンドルールは、CloudFormationテンプレートで設定しているので、そのままで大丈夫です。
プライベートサブネットから、HTTP・HTTPS以外のリクエストが発生する場合、インバウンドルールを追加してください。
なお、本記事では参考ページとは異なり、インバウンドルールにSSHを設定しませんでした。NATインスタンスに対してセッションマネージャーを利用可能にしているので、不要だと思ったからです。
ルートテーブルの更新
プライベートサブネットに紐づくルートテーブルの、0.0.0.0/0
のルートを、NATインスタンスに向けます。
送信先
に「0.0.0.0/0」、ターゲット
にインスタンス
を選択してから、インスタンス
のドロップダウンリストから、NATインスタンスを選択します。
これで準備完了です。プライベートサブネットに配置したEC2に入れるなら、yum install
などを実行して、インターネットにアクセスできることを確認してください。HTTP・HTTPSを通信許可していないと、yum install
は通りません。
Cloud AutomatorでNATインスタンスの自動起動・停止を設定する
NATインスタンスはEC2なので、Cloud AutomatorでNATインスタンスを自動停止させることができます。これで使わない時間は止めておくことができます。
こちらの記事では、タグを使ってEC2を特定して停止させています。NATインスタンスのEC2に任意のタグを付けて、それを条件にすればOKです。もしくは、インスタンスIDを条件にして自動停止させることもできます。
最後に
本記事が皆様の開発ライフに少しでも役立てば嬉しいです。
兼安 聡(執筆記事の一覧)
アプリケーションサービス部 DS3課所属
2024 Japan AWS Top Engineers (Database)
2024 Japan AWS All Certifications Engineers
Certified ScrumMaster
PMP
広島在住です。今日も明日も修行中です。