ぶろとよ

ネットワーク系クラウドエンジニア(AWS)の技術ブログ。自動化に興味があるためAWS CLIを勉強&アウトプット中。

macOSでPython環境構築 後編:venvでPython仮想環境を作成する

Windowsメインで使用しているけれどmacOSの勉強中です。
macOSでPython環境を構築したので備忘的なメモを残します。

venvでの仮想環境は少し時間が立つと何の環境を作ったのか忘れるので、コマンド実行すると環境を選択できるように作ってみました(汗

macOSでPython環境構築

  • 前編:pyenvで複数バージョンのPythonをインストールする
  • 後編:venvでPython仮想環境を作成する
    • 本記事です

目次

検証環境

  • 検証日: 2024/01/31
  • 実行環境
    • PC
      • Mac mini M2チップ 2023
      • macOS Sonoma 14.2.1, Build 23C71
        • zsh 5.9 (x86_64-apple-darwin23.0)
        • Homebrew 4.2.8
        • pyenv 2.3.35
          • Python 3.10.13
          • Python 3.11.7
          • Python 3.12.1

注意事項

  • コマンド内の変数やパラメータやは検証で使用したものを記載しています。ご自身の環境に合わせ、書き換えて使用してください。
  • 個人で検証しているため実行結果に責任は持てません。必ずご自身でも検証してから使用してください。


1. ディレクトリ構造/仮想環境名

ディレクトリ構造はこのようにしています。

  1. ホームにvenv仮想環境専用の envs ディレクトリを作成。
    • ~/envs
  2. envs ディレクトリ内へ仮想環境毎にディレクトリを作成。
    • ※既に2つ作成済み。今回は1つ追加する。
    • ~/envs/bluesky
    • ~/envs/boto3
  3. 各ディレクトリ内へ仮想環境を作成。仮想環境名は .venv で統一。
    • ~/envs/bluesky/.venv
    • ~/envs/boto3/.venv


2. venv仮想環境の作成

今回は 仮想環境名 hatena を作成します。

2.1. ~/envs へ仮想環境用のディレクトリを作成する。

# ディレクトリの作成
DIRECTORY="hatena"
mkdir -p ~/envs/$DIRECTORY
# 作成したディレクトリへ移動
cd ~/envs/$DIRECTORY

2.2. 仮想環境で使うPythonバージョンを指定する

macOSにpyenvでインストールしたPythonの一覧を確認し、仮想環境で使うPythonバージョンを localコマンドで指定する。

# 変更前の確認
pyenv versions
python --version
# ディレクトリ以下で使用するPythonバージョンを指定する
pyenv local 3.10.13
# 変更後の確認
pyenv versions
python --version
which python
# 実行結果
hatena % pyenv versions

  system
  3.10.13
  3.11.7
* 3.12.1 (set by /Users/USERNAME/.pyenv/version)
hatena % python --version

Python 3.12.1

hatena % pyenv local 3.10.13

hatena % pyenv versions

  system
* 3.10.13 (set by /Users/USERNAME/envs/hatena/.python-version)
  3.11.7
  3.12.1
hatena % python --version

Python 3.10.13

hatena % which python

/Users/USERNAME/.pyenv/shims/python

localコマンドは実行したディレクトリ配下で使用するPythonバージョンのみを変更するため、仮想環境をディレクトリ毎に分けることで有効に動作する。
1つ上のディレクトリに戻ってPythonバージョンを確認すると、globalコマンドで指定したPythonバージョンになる。

hatena % cd ..
envs % python --version

Python 3.12.1

2.3. 仮想環境を作成する(名前は .venv で統一)

仮想環境名は .venv で統一しています。

cd ~/envs/$DIRECTORY
python -m venv .venv

2.4. 作成した仮想環境の有効化

source .venv/bin/activate

python --version
which python
# 実行結果
hatena % source .venv/bin/activate

(.venv) hatena % python --version

Python 3.10.13
(.venv) hatena % which python

/Users/USERNAME/envs/hatena/.venv/bin/python

2.5. 仮想環境でpipとsetuptoolsを最新化する

pip list
python -m pip install --upgrade pip
pip install --upgrade setuptools

2.6. 仮想環境から抜ける

deactivate
# 実行結果
(.venv) hatena % deactivate
hatena %


3. 次回以降、作成した仮想環境へ入る

  1. envsディレクトリへ移動
  2. envsディレクトリ内の仮想環境ディレクトリを番号で表示
  3. 番号を入力してください
  4. 選択した仮想環境ディレクトリへ移動
  5. 仮想環境を有効化する
cd ~/envs/ && select DIRECTORY in *; do [[ -d $DIRECTORY ]] && break; done && cd ~/envs/$DIRECTORY && source .venv/bin/activate
    # 番号の選択をします。仮想環境を有効化するディレクトリを選択してください。

# 実行結果
~ % cd ~/envs/ && select DIRECTORY in *; do [[ -d $DIRECTORY ]] && break; done && cd ~/envs/$DIRECTORY && source .venv/bin/activate
1) bluesky  2) boto3    3) hatena
?# 3
(.venv) hatena %

macOSでPython環境構築 前編:pyenvで複数バージョンのPythonをインストールする

Windowsメインで使用しているけれどmacOSの勉強中です。
macOSでPython環境を構築したので備忘的なメモを残します。

venvでの仮想環境は少し時間が立つと何の環境を作ったのか忘れるので、コマンド実行すると環境を選択できるように作ってみました(汗

macOSでPython環境構築

  • 前編:pyenvで複数バージョンのPythonをインストールする
    • 本記事です
  • 後編:venvでPython仮想環境を作成する

目次

検証環境

  • 検証日: 2024/01/31
  • 実行環境
    • PC
      • Mac mini M2チップ 2023
      • macOS Sonoma 14.2.1, Build 23C71
        • zsh 5.9 (x86_64-apple-darwin23.0)
        • Homebrew 4.2.8
        • pyenv 2.3.35
          • Python 3.10.13
          • Python 3.11.7
          • Python 3.12.1

注意事項

  • コマンド内の変数やパラメータやは検証で使用したものを記載しています。ご自身の環境に合わせ、書き換えて使用してください。
  • 個人で検証しているため実行結果に責任は持てません。必ずご自身でも検証してから使用してください。


1. 初期状態でのPythonインストール状態

macOSにPythonが入っているか確認したが、入っていなかった。
ただし、python3 --version のように 3 を付ける元からmacOSに入っているものは使用せず、3が付かないように新規でインストールしていく。
Windowsをメインで使っているため、3が付くことに違和感があるんです。。。 ※3が付かないpythonコマンドは2系用だったみたいだけど、今は廃止されたらしぃ。

python --version
# 実行結果
% python --version
zsh: command not found: python


2. Homebrew:パッケージマネージャー

Homebrewとは?Google Geminiに聞いてみた。

macOS上で様々なソフトウェアを簡単にインストール・アップデート・削除できるパッケージマネージャーです。

主な特徴
- 豊富なパッケージ数: 数千もの公式パッケージと、さらに多くのサードパーティ製パッケージが利用可能
- 使いやすさ: brew installのようなシンプルなコマンドでインストール
- 自動更新: パッケージを最新の状態に保つ
- 依存関係の解決: 必要なライブラリなども自動的にインストール

2.1. Homebrewのインストール

インストールコマンドは公式サイト Homebrew に記載されている。
ただ、Appleシリコン(M1, M2等)はIntel CPUの時とはインストール先が変更されたようなので、自分でPATHを通す必要がある。

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Appleシリコン(M1, M2等)の場合はパスを通す必要がある。
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zshrc
source ~/.zshrc

2.2. Homebrewのインストール確認

brew --version
# 実行結果
% brew --version
Homebrew 4.2.6


3. pyenv:Pythonのバージョン管理

ツール名 用途
pyenv Pythonのバージョン自体を管理するツール
システムに複数のPythonバージョンを同居させることが可能
venv / virtualenv Pythonの仮想環境を提供するツール
異なるプロジェクトやバージョンのパッケージを分離して管理する目的で使用

3.1. pyenvのインストール

brew install pyenv

3.2. pyenvのインストール確認

pyenv --version
# 実行結果
% pyenv --version
pyenv 2.3.35

3.3. pyenvの初期化の設定を.zshrcファイルに書き込む

echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(pyenv init -)"' >> ~/.zshrc
source ~/.zshrc

3.4. pyenvでインストールできるリストを表示する

# すべて
pyenv install --list
# Pythonの3系だけに絞る
pyenv install --list | grep "^\s*3\."
# Pythonの3.10だけに絞る
pyenv install --list | grep "^\s*3\.10\."
# 実行結果
% pyenv install --list | grep "^\s*3\.10\."
  3.10.0
  3.10.1
  3.10.2
  3.10.3
  3.10.4
  3.10.5
  3.10.6
  3.10.7
  3.10.8
  3.10.9
  3.10.10
  3.10.11
  3.10.12
  3.10.13

3.5. Pythonインストールの前にhomebrewで必要なものを入れる

そのままpyenvでPythonをインストールしたらWARNINGが出た。

# WARNINGが出た時の参考
% pyenv install 3.10.13

python-build: use openssl from homebrew
python-build: use readline from homebrew
Downloading Python-3.10.13.tar.xz...
-> https://www.python.org/ftp/python/3.10.13/Python-3.10.13.tar.xz
Installing Python-3.10.13...
python-build: use readline from homebrew
python-build: use zlib from xcode sdk
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/Users/USERNAME/.pyenv/versions/3.10.13/lib/python3.10/lzma.py", line 27, in <module>
    from _lzma import *
ModuleNotFoundError: No module named '_lzma'
WARNING: The Python lzma extension was not compiled. Missing the lzma lib?
Installed Python-3.10.13 to /Users/USERNAME/.pyenv/versions/3.10.13

調べてみるとlzmaの一部がmacで認識できていないらしい?

参考URL: pyenvでlzmaがない警告 MacOS

対策として、homebrewで必要なものを一気にいれる。lzmaはこの中の xz に相当するらしい。

brew install openssl readline sqlite3 xz zlib tcl-tk

3.6. pyenvでPythonをインストールする

pyenv install 3.10.13
# 実行結果 ※WARNING等が出ないで無事にインストールできた
% pyenv install 3.10.13
python-build: use openssl from homebrew
python-build: use readline from homebrew
Downloading Python-3.10.13.tar.xz...
-> https://www.python.org/ftp/python/3.10.13/Python-3.10.13.tar.xz
Installing Python-3.10.13...
python-build: use tcl-tk from homebrew
python-build: use readline from homebrew
python-build: use zlib from xcode sdk
Installed Python-3.10.13 to /Users/USERNAME/.pyenv/versions/3.10.13

3.7. pyenvでインストールしたPythonを確認する

pyenvでは3.10.13のPythonが入っている。

pyenv versions
# 実行結果
% pyenv versions
* system (set by /Users/USERNAME/.pyenv/version)
  3.10.13

ただ、Pythonコマンドはまだ使えない。

python --version
# 実行結果
% python --version
pyenv: python: command not found

The `python' command exists in these Python versions:
  3.10.13

Note: See 'pyenv help global' for tips on allowing both
      python2 and python3 to be found.

pyenvでシステムが利用するpythonを、インストールしたpythonに変更する必要がある。

3.8. システム全体に適用するPythonバージョンを設定する

pyenvコマンドのglobalまたはlocalコマンドを使用して、Pythonを使用できるようにします。

pyenvコマンドのgloballocalの違い - global - システム全体に適用されるPythonバージョンを設定します。 - local - コマンド実行したディレクトリに適用されるPythonバージョンを設定します。 - サブディレクトリにも適用されます。 - プロジェクト毎にPythonバージョンを分ける場合などに有効。

今回はシステム全体に適用したいため global を選択。

pyenv global 3.10.13
python --version
# 実行結果
% pyenv global 3.10.13

% python --version
Python 3.10.13


3.9. 他のPythonバージョンも入れてみる

現在のPythonバージョンのインストール状況

pyenv versions
# 実行結果
% pyenv versions

  system
* 3.10.13 (set by /Users/USERNAME/.pyenv/version)

バージョン 3.113.12 の最新を確認する。

pyenv install --list | grep "^  3\.11\." | tail -1
pyenv install --list | grep "^  3\.12\." | tail -1
# 実行結果
% pyenv install --list | grep "^  3\.11\." | tail -1

  3.11.7
% pyenv install --list | grep "^  3\.12\." | tail -1

  3.12.1

他バージョンのPythonバージョンをインストールする。

pyenv install 3.11.7
pyenv install 3.12.1

Pythonバージョンのインストール状況

pyenv versions
# 実行結果
% pyenv versions

  system
* 3.10.13 (set by /Users/USERNAME/.pyenv/version)
  3.11.7
  3.12.1

Python 3.12.1 を有効にしてみる。

pyenv global 3.12.1
pyenv versions
python --version
# 実行結果
% pyenv global 3.12.1

% pyenv versions
  system
  3.10.13
  3.11.7
* 3.12.1 (set by /Users/USERNAME/.pyenv/version)
% python --version

Python 3.12.1

PythonからBlueskyへ投稿(Post):サンプルスクリプトのリッチテキスト版を使用。

本記事では、PythonからBlueskyへ投稿する際に、公式ドキュメント: The AT Protocol SDK からリンクが貼ってある、サンプルスクリプト(Examples of using the methods.)を試した時のメモ書きです。

github.com

今回はその中から「send_rich_text.py (リッチテキスト版)」を試して見ました。

目次

検証環境

  • 検証日: 2024/2/16
  • 実行環境
    • PC
      • macOS Sonoma: 14.2.1
        • zsh 5.9 (x86_64-apple-darwin23.0)
        • Visual Studio Code: バージョン: 1.86.1 (Universal)
        • Python: 3.12.1
          • atproto: 0.0.41

注意事項

  • 僕はPython基礎試験とっただけで実務経験の無いド素人ですので、本記事は参考程度にしてください。
  • 本記事の内容はmacOSからpython3.12で検証しています。
  • コマンド内の変数やパラメータやは検証で使用したものを記載しています。ご自身の環境に合わせ、書き換えて使用してください。
  • 個人で検証しているため実行結果に責任は持てません。必ずご自身でも検証してから使用してください。


1. 必要なライブラリをインストール

The AT Protocol SDKのライブラリ atproto が必要なのでインストールしておきます。

pip install atproto


2. サンプルスクリプト(手を加える前)

github.com

from atproto import Client, client_utils

# To send links as "link card" or "quote post" look at the advanced_usage/send_embed.py example.
# There is a more advanced way to send rich text without helper class in the advanced_usage/send_rich_text.py example.


def main() -> None:
    client = Client()
    client.login('my-handle', 'my-password')

    text_builder = client_utils.TextBuilder()
    text_builder.tag('This is a rich message. ', 'atproto')
    text_builder.text('I can mention ')
    text_builder.mention('account', 'did:plc:kvwvcn5iqfooopmyzvb4qzba')
    text_builder.text(' and add clickable ')
    text_builder.link('link', 'https://atproto.blue/')

    # You can pass instance of TextBuilder instead of str to the "text" argument.
    client.send_post(text_builder)  # same with send_image method

    # Same with chaining:
    client.send_post(client_utils.TextBuilder().text('Test msg using ').link('Python SDK', 'https://atproto.blue/'))


if __name__ == '__main__':
    main()

3. 投稿用に色々書き足したスクリプト

・Google GEMINIで聞いて、コメントとか追記してます。(素人なんで色々書いてる・・・)
・変更できる箇所は日本語で書いているので、内容に応じて修正をする。

# client_utils: リッチテキストメッセージ作成のヘルパー関数を含む
from atproto import Client, client_utils


# -> None は関数が値を返さないことを示す
def main() -> None:
    # 自分のアカウントまたはメールアドレス & パスワード を平文で書いてBlueskyアカウントに認証
    client = Client()
    client.login('自分のアカウント.bsky.social', '自分のパスワード')

    # メッセージ内容を構築するために TextBuilder オブジェクトを作成
    # tag(): タグ付き文字列を追加 ※このタグに意味あるのかが解らない・・・
    # text(): 投稿(Post)する文章を書く
    # mention(): 「kvwvcn5iqfooopmyzvb4qzba」へのメンションリンクを追加
    # link(): リンク文字とURLを追加
    text_builder = client_utils.TextBuilder()
    text_builder.tag('タグ:これはリッチメッセージ. ', 'atproto')
    text_builder.text('Pythonから投稿(1つ目)!ブログ用に動作確認中。')
    text_builder.mention('メンション先アカウント', 'did:plc:kvwvcn5iqfooopmyzvb4qzba')
    text_builder.text('サンプルスクリプトを使ってみた→ ')
    text_builder.link('さんぷるすくりぷと', 'https://github.com/MarshalX/atproto/blob/main/examples/send_rich_text.py')

    # 上の「text_builder」で指定した内容を投稿(Post)する
    client.send_post(text_builder)

    # こっちの書き方もできる。同一スクリプト内に書いているのでbluskya側では 2つ投稿(Post)される。
    client.send_post(client_utils.TextBuilder().text('Pythonから投稿(2つ目)!ブログ用に動作確認中。').link('さんぷるすくりぷと', 'https://github.com/MarshalX/atproto/blob/main/examples/send_rich_text.py'))

if __name__ == '__main__':
    main()

※メンション text_builder.mention() は下記の I love Python 3 へのメンションのようです。
不必要なメンションはしないほうが良いと思ったのですが、サンプルスクリプトに書いてあるメンション先なので使いました。

bsky.app

4. 投稿(Post)結果

僕のBlueskyアカウントへ投稿しました。

bsky.app

結果はこんな感じです。上のスクリプトと見比べると、どのコマンドがどうなったかが解ると思います。

Post結果

macOS SonomaのFinderで、ファイル名変更のショートカットをF2にする

本記事では、「Windowsでファイル名の変更(リネーム)のショートカットはF2だから、macOS FinderでもF2にする!」について記載しています。

僕は長年Windowsを使ってきたのですが、ひょんなことからMac mini 2023をゲットしたため、macOSの勉強を始めました。 ただ、macOSを使い出して一番困っているのが「キーボードショートカット」です。 PC作業は基本的にショートカットを多用しているため、WindowsとmacOSの違いがホントにつらい、、、、。 普段は仕事でWindowsを使用してるから変な癖を付けたくないため、ショートカットはWindowsに寄せるようにしています。

目次

検証環境

  • 検証日: 2024/02/04
  • PC環境:
    • Mac mini 2023 (CPU Apple M2)
      • macOS Sonoma バージョン14.2.1

注意事項

  • ネットで情報を探すと間違い?情報が古くなった?なのか、書いていることが有効に動かないことがあります。本ページも何かの条件によっては動かないかもしれませんので、ご自身での検証もお願いします。


1. Finderでファイル名変更のショートカットをF2にする

1.1. Finderで名称変更(リネーム)の現在のショートカットを確認する

  1. Finder -> メニューバー -> ファイル -> 名称変更
  2. Finderメニューバー_before
  3. [名称変更] には何もショートカットが付いていません


1.2. アプリのショートカットを変更する

  1. システム設定 -> キーボード -> キーボードショートカット を開く
  2. アプリのショートカット を開く
    • アプリのショートカット_before
      • ※[Visual Studio Code] と [Google Chrome] は無視してください(汗
  3. [+] をクリックする
  4. 次の設定をする
    • アプリケーション = Finder.app
    • メニュータイトル = 名称変更 ★注意
    • キーボードショートカット = F2
    • アプリのショートカット_change
  5. [完了] をクリック、次も [完了] をクリック

★注意 について
名称変更 」という文言が大事です。間違うと動きません。
Web検索をすると「名前の変更」「名前を変更」などが見受けられましたが、どうやら「メニューバーで表示された文言が正しい」ようで、試しに他の項目でもショートカットを設定したら、ショートカットが変更されました。
今回の調査では [名称変更] でしたが、何年後かは変わってる可能性もありますね(汗


1.3. Finderで名称変更(リネーム)のショートカットが変わったことを確認する

  1. Finder -> メニューバー -> ファイル -> 名称変更

アプリのショートカット_after
3. [名称変更] には何もショートカットが付いていません

以上です。

AWS Site-to-Site VPNのサンプル設定を読み解いてみる(Fortigate、FortiOS6.4.4+GUI、IKEv2、静的ルーティング)

AWS Site-to-Site VPNを設定した際、AWS側からVPNサンプル設定をダウンロードできます。
AWSと対向するネットワーク機器用に出力するサンプル設定なのですが、中身が英語だし所々修正が必要だし、っと英語が苦手な自分にとってはあまり親切なファイルではありません(汗

本記事では、VPNサンプル設定の日本語化 & ネットワーク機器の表記に合わせて修正をしてみたいと思います。
・・・日本語化とか翻訳とか言ってますが、Google翻訳様に頼りきっています(汗

目次

検証環境

  • 検証日: 2022/09/25
  • 実行環境
    • PC
      • Windows10 Home Ver21H1
        • Google Chrome: バージョン: 105.0.5195.127(Official Build) (64 ビット)
    • VPNネットワーク機器
      • Fortigate50E: FortiOS6.2.11

注意事項

  • 本記事の内容はFortigate50E: FortiOS6.2.11で検証しています。
  • 翻訳はGoogle翻訳を利用し、所々実機を元に修正しています。
  • コマンド内の変数やパラメータやは検証で使用したものを記載しています。ご自身の環境に合わせ、書き換えて使用してください。
  • 個人で検証しているため実行結果に責任は持てません。必ずご自身でも検証してから使用してください。


1. AWS側のVPN設定

今回の目的はVPNサンプル設定の翻訳のため、AWS側の設定については省略します。
別の記事でVPN接続を書いたものがあるので参考として貼ります。

blog.toyokky.com


■ VPNサンプル設定の内容に関わる部分だけAWS設定を記載します。

AWSリソース 項目 設定値 備考
ルートテーブル ルート 宛先: 192.168.0.0/16、ターゲット: VGW Fortigate配下ネットワークCIDR含む、広い範囲で記載
カスタマーゲートウェイ IPアドレス ※FortigateのグローバルIPアドレス
カスタマーゲートウェイ BGP ASN 65000 BGP不使用のためデフォルト値
Site-to-Site VPN接続 ルーティング 静的(Static)
Site-to-Site VPN接続 ローカル IPv4 ネットワーク CIDR 0.0.0.0/0 制限しない
Site-to-Site VPN接続 リモート IPv4 ネットワーク CIDR 0.0.0.0/0 制限しない
Site-to-Site VPN接続 静的 IP プレフィックス 0.0.0.0/0 WEBで見ると0.0.0.0/0使わない人が多数(汗
Site-to-Site VPN接続 トンネル 1 オプション デフォルトを使用
Site-to-Site VPN接続 トンネル 1 オプション デフォルトを使用


2. VPNサンプル設定

2.1. VPNサンプル設定のダウンロード

以下の内容で出力しました。

項目 設定値 備考
ベンダー Fortinet
プラットフォーム Fortigate 40+ Series 検証機は Fortigate50E
ソフトウェア FortiOS 6.4.4.+ (GUI) 検証機は 6.2.11 で 6.4未満
IKEバージョン ikev2


2.2. 読み替え/置換が必要な箇所

出力したVPNサンプル設定を実際に使用する際、「読み替え/置換」が必要な箇所です。
本記事中の以下パラメータの部分で、本記事では参考値を使用しています。

■ IPsecトンネル のパラメータ

トンネル番号 項目 パラメータ 原文内の検索ワード
Tunnel 1 外部IP AWS側 1.1.1.1 「c. IP address: 」で検索の1つ目
 〃  内部IP AWS側 169.254.1.1 「b. Remote IP」で検索の1つ目
「set server」で検索の1つ目
 〃  内部IP 機器側 169.254.1.2 「a. IP :」で検索の1つ目
 〃  事前共有鍵 xxxxSharedKeyxxxTunnel_1xxxxxxxx 「h. Pre-Shared Key:」で検索の1つ目
Tunnel 2 外部IP AWS側 2.2.2.2 「c. IP address: 」で検索の2つ目
 〃  内部IP AWS側 169.254.2.1 「b. Remote IP」で検索の2つ目
「set server」で検索の2つ目
 〃  内部IP 機器側 169.254.2.2 「a. IP :」で検索の1つ目
 〃  事前共有鍵 xxxxSharedKeyxxxTunnel_2xxxxxxxx 「h. Pre-Shared Key:」で検索の1つ目

※「原文内の検索ワード」は、原文のどこに記載されているか探すための検索ワードです。原文は先にTunnel 1、次にTunnel 2と記載されているため、検索HITの1つ目がTunnel 1、2つ目がTunnel 2のパラメータです。


■ インターフェース番号

原文内でAWSとVPNを張るインターフェースが「wan1」となっています。環境によって異なる場合は読み替え/置換が必要です。


■ AWSリソース ID

AWSリソース種別 ID 原文内の検索ワード 備考
VPN接続 ID vpn-fffffffffffffffff Your VPN Connection ID 項番 2.3. 参照
仮想プライベートゲートウェイ ID vgw-01234567890abcdef Your Virtual Private Gateway ID 使用していないので無視
カスタマーゲートウェイ ID cgw-01234567890abcdef Your Customer Gateway ID 使用していないので無視


2.3. そのまま入力できず注意/修正が必要な箇所

VPNトンネルインターフェースの名前にVPN接続 IDを指定する箇所がありますが、長すぎてFortigateで設定不可です。
そのため、以下の修正が必要です。 ※所々赤字で書いてる箇所です。

VPN接続 ID 本記事での仮名前 備考
vpn-fffffffffffffffff-0 vpn-to-aws-1 環境に合わせて変更
vpn-fffffffffffffffff-1 vpn-to-aws-2 環境に合わせて変更


また、2箇所 CLI操作が出てくるのですが、どちらも設定不可(コマンドが無い)でした。
検証機が「Fortigate50E: FortiOS6.2.11」だからというのもあるようですが、CLIを実行しなくてもVPN接続はできるので、実行できないなら無視しても良いかもしれません。


3. VPNサンプル設定の原文

原文は長いので折りたたんでいます、クリックで展開。

! Amazon Web Services
! Virtual Private Cloud

! AWS utilizes unique identifiers to manipulate the configuration of
! a VPN Connection. Each VPN Connection is assigned an identifier and is
! associated with two other identifiers, namely the
! Customer Gateway Identifier and Virtual Private Gateway Identifier.
!
! Your VPN Connection ID                      : vpn-fffffffffffffffff
! Your Virtual Private Gateway ID         : vgw-01234567890abcdef
! Your Customer Gateway ID                  : cgw-01234567890abcdef
!
!
! This configuration consists of two tunnels. Both tunnels must be
! configured on your Customer Gateway.
!
! --------------------------------------------------------------------------------
! IPSec Tunnel #1
! --------------------------------------------------------------------------------
! #1: Internet Key Exchange (IKE) Configuration

Go to  VPN --> IPSEC Tunnels --> Create New (drop down) --> Select IPSEC Tunnel

VPN Creation Wizard Window appears

Select Template Type as “Custom”

Provide a Name for the VPN connection (Name must be shorter than 15 chars, best if shorter than 12): vpn-fffffffffffffffff-0

New VPN Tunnel Window Appears (Here we configure the VPN settings):

Under “Network” Section:
a. IP Version:     IPv4
b. Remote Gateway: Static IP Address
c. IP address: 1.1.1.1
d. Local Interface: wan1
e. Local Gateway: Select Specify and enter WAN port IP (Public IP)
f. Dead Peer Detection: Enable by selecting On Idle/ On Demand
g. Authentication Method: Pre-shared Key
h. Pre-Shared Key: xxxxSharedKeyxxxTunnel_1xxxxxxxx
i. IKE Version: 2
Phase 1 Proposal:
j.  Encryption: aes128
k. Authentication: sha1
l. DH group: 2     ! and deselect 5
m. Keylife: 28800 seconds

! NAT Traversal is enabled by default but if your FortiGate device is not behind a NAT/PAT device, please deselect NAT Traversal.

! --------------------------------------------------------------------------------
! #2: IPSec Configuration

Under Phase 2 Selectors --> New Phase 2
a.  Name:  vpn-fffffffffffffffff-0
b.  Local Address: LAN subnet behind Fortigate/0.0.0.0/0
c.  Remote Address: AWS Private Subnet/0.0.0.0/0

Under Advanced
d.  Encryption: aes128
e.  Authentication: sha1
f.  Select Enable Replay Detection
g.  Select Perfect Forward Secrecy
h.  DH Group: 2 ! and deselect 5
i.  Keylife: 3600 seconds
j.  Enable Auto-negotiate   ! Autokey Keep Alive is enabled automatically when Auto-negotiate is enabled
k.  Click Ok

! --------------------------------------------------------------------------------
! #3: Tunnel Interface Configuration

! A tunnel interface is configured to be the logical interface associated
! with the tunnel. All traffic routed to the tunnel interface will be
! encrypted and transmitted to the VPC. Similarly, traffic from the VPC
! will be logically received on this interface.
!
!
! The address of the interface is configured with the setup for your
! Customer Gateway.  If the address changes, the Customer Gateway and VPN
! Connection must be recreated with Amazon VPC.
!
! This is required in order for tunnel failover via gwdetect to function
!
! Perform this from the Global VDOM.

Go to Network Tab --> Interface --> wan1 and edit vpn-fffffffffffffffff-0

a. IP : 169.254.1.2
b. Remote IP: 169.254.1.1/30
c. Select Ping
d. Administrative Status: Up
e. Select Ok.

!You can set MTU and MSS on the tunnel by performing this from the CLI:
 config global
 config system interface
  edit "vpn-fffffffffffffffff-0" ! This name will be the same as the VPN tunnel name
    set mtu-override enable
    set mtu 1427
    set tcp-mss 1379
   next
end

! --------------------------------------------------------------------------------
! #4 Static Route Configuration
Your Customer Gateway needs to set a static route for the prefix corresponding to your
! VPC to send traffic over the tunnel interface.
! An example for a VPC with the prefix 10.0.0.0/16 is provided below:
!
! This is configured from the root VDOM


Go to Network Tab --> Static Routes --> Create New

a. Destination: Subnet (10.0.0.0/16)
b. Interface: vpn-fffffffffffffffff-0 ! This is the VPN tunnel interface
c. Click Ok

! Static routing does not allow for failover of traffic between tunnels. If there is a problem with one of the
! tunnels, we would want to failover the traffic to the second tunnel. This is done by using "gwdetect" in fortigate.
! The gwdetect command will ping the other end of the tunnel, and check if the tunnel is up. If the pings fail, it will
! remove the static route from the routing table, and the second route in the table will become active.
!
! This can be done only using the CLI.
!
! The following config will tell the Fortigate device, what IP it should ping to test the tunnel. This IP should be
! the inside IP address of the virtual private gateway.
! This is required in order for tunnel failover via gwtect to function. Additionally, this is required to keep the tunnel up, since
! traffic must be sent from your side of the VPN tunnel to prevent the tunnel from being taken down.

config vdom
    edit root
        config router gwdetect
        edit 1
        set interface "vpn-fffffffffffffffff-0" ! This is the VPN tunnel interface
        set server "169.254.1.1"

! server IP is the AWS inside IP

! Using the following command, you can set the interval and failtime for gwdetect. Interval is number of seconds
! between pings. Failtime is the number of lost consecutive pings.Using the respective values of 2 and 5, your tunnel
! will failover in 10 seconds.

        set interval 2
        set failtime 5
    next
end

! --------------------------------------------------------------------------------
! #5: Firewall Policy Configuration
! Create a firewall policy permitting traffic from your local subnet to the VPC subnet and vice versa
! This example policy permits all traffic from the local subnet to the VPC.
!
!This is configured from the root VDOM


Go to Policy & Object tab --> Firewall Policy --> Create New

   a. Provide a Name for the Policy
   b. Incoming Interface/Zone = internal ! This is the interface out which your local LAN resides
   c. Source Address = all
   d. Outgoing Interface/Zone = "vpn-fffffffffffffffff-0" ! This is the VPN tunnel interface
   e. Destination Address = all
   f. Schedule = always
   g. Service = ALL
   h. Action = ACCEPT
   i. Click OK

! NAT is enabled for the policy by default, you can disable it.

! Now create a policy to permit traffic going the other way

   a. Create New
   b. Provide a Name for the Policy
   c. Incoming Interface/Zone = "vpn-fffffffffffffffff-0" ! This is the VPN tunnel interface
   d. Source Address = all
   e. Outgoing Interface/Zone = internal  ! This is the interface out which your local LAN resides
   f. Destination Address = all
   g. Schedule = always
   h. Service = ALL
   i. Action = ACCEPT
   j. Click OK


! --------------------------------------------------------------------------------
! IPSec Tunnel #2
! --------------------------------------------------------------------------------
! #1: Internet Key Exchange (IKE) Configuration

Go to  VPN --> IPSEC Tunnels --> Create New (drop down) --> Select IPSEC Tunnel

VPN Creation Wizard Window appears

Select Template Type as “Custom”

Provide a Name for the VPN connection (Name must be shorter than 15 chars, best if shorter than 12): vpn-fffffffffffffffff-1

New VPN Tunnel Window Appears (Here we configure the VPN settings):

Under “Network” Section:
a. IP Version:     IPv4
b. Remote Gateway: Static IP Address
c. IP address: 2.2.2.2
d. Local Interface: wan1
e. Local Gateway: Select Specify and enter WAN port IP (Public IP)
f. Dead Peer Detection: Enable by selecting On Idle/ On Demand
g. Authentication Method: Pre-shared Key
h. Pre-Shared Key: xxxxSharedKeyxxxTunnel_2xxxxxxxx
i. IKE Version: 2
Phase 1 Proposal:
j.  Encryption: aes128
k. Authentication: sha1
l. DH group: 2     ! and deselect 5
m. Keylife: 28800 seconds

! NAT Traversal is enabled by default but if your FortiGate device is not behind a NAT/PAT device, please deselect NAT Traversal.

! --------------------------------------------------------------------------------
! #2: IPSec Configuration

Under Phase 2 Selectors --> New Phase 2
a.  Name:  vpn-fffffffffffffffff-1
b.  Local Address: LAN subnet behind Fortigate/0.0.0.0/0
c.  Remote Address: AWS Private Subnet/0.0.0.0/0

Under Advanced
d.  Encryption: aes128
e.  Authentication: sha1
f.  Select Enable Replay Detection
g.  Select Perfect Forward Secrecy
h.  DH Group: 2 ! and deselect 5
i.  Keylife: 3600 seconds
j.  Enable Auto-negotiate   ! Autokey Keep Alive is enabled automatically when Auto-negotiate is enabled
k.  Click Ok

! --------------------------------------------------------------------------------
! #3: Tunnel Interface Configuration

! A tunnel interface is configured to be the logical interface associated
! with the tunnel. All traffic routed to the tunnel interface will be
! encrypted and transmitted to the VPC. Similarly, traffic from the VPC
! will be logically received on this interface.
!
!
! The address of the interface is configured with the setup for your
! Customer Gateway.  If the address changes, the Customer Gateway and VPN
! Connection must be recreated with Amazon VPC.
!
! This is required in order for tunnel failover via gwdetect to function
!
! Perform this from the Global VDOM.

Go to Network Tab --> Interface --> wan1 and edit vpn-fffffffffffffffff-1

a. IP : 169.254.2.2
b. Remote IP: 169.254.2.1/30
c. Select Ping
d. Administrative Status: Up
e. Select Ok.

!You can set MTU and MSS on the tunnel by performing this from the CLI:
 config global
 config system interface
  edit "vpn-fffffffffffffffff-1" ! This name will be the same as the VPN tunnel name
    set mtu-override enable
    set mtu 1427
    set tcp-mss 1379
   next
end

! --------------------------------------------------------------------------------
! #4 Static Route Configuration
Your Customer Gateway needs to set a static route for the prefix corresponding to your
! VPC to send traffic over the tunnel interface.
! An example for a VPC with the prefix 10.0.0.0/16 is provided below:
!
! This is configured from the root VDOM


Go to Network Tab --> Static Routes --> Create New

a. Destination: Subnet (10.0.0.0/16)
b. Interface: vpn-fffffffffffffffff-1 ! This is the VPN tunnel interface
c. Click Ok

! Static routing does not allow for failover of traffic between tunnels. If there is a problem with one of the
! tunnels, we would want to failover the traffic to the second tunnel. This is done by using "gwdetect" in fortigate.
! The gwdetect command will ping the other end of the tunnel, and check if the tunnel is up. If the pings fail, it will
! remove the static route from the routing table, and the second route in the table will become active.
!
! This can be done only using the CLI.
!
! The following config will tell the Fortigate device, what IP it should ping to test the tunnel. This IP should be
! the inside IP address of the virtual private gateway.
! This is required in order for tunnel failover via gwtect to function. Additionally, this is required to keep the tunnel up, since
! traffic must be sent from your side of the VPN tunnel to prevent the tunnel from being taken down.

config vdom
    edit root
        config router gwdetect
        edit 2
        set interface "vpn-fffffffffffffffff-1" ! This is the VPN tunnel interface
        set server "169.254.2.1"

! server IP is the AWS inside IP

! Using the following command, you can set the interval and failtime for gwdetect. Interval is number of seconds
! between pings. Failtime is the number of lost consecutive pings.Using the respective values of 2 and 5, your tunnel
! will failover in 10 seconds.

        set interval 2
        set failtime 5
    next
end

! --------------------------------------------------------------------------------
! #5: Firewall Policy Configuration
! Create a firewall policy permitting traffic from your local subnet to the VPC subnet and vice versa
! This example policy permits all traffic from the local subnet to the VPC.
!
!This is configured from the root VDOM


Go to Policy & Object tab --> Firewall Policy --> Create New

   a. Provide a Name for the Policy
   b. Incoming Interface/Zone = internal ! This is the interface out which your local LAN resides
   c. Source Address = all
   d. Outgoing Interface/Zone = "vpn-fffffffffffffffff-1" ! This is the VPN tunnel interface
   e. Destination Address = all
   f. Schedule = always
   g. Service = ALL
   h. Action = ACCEPT
   i. Click OK

! NAT is enabled for the policy by default, you can disable it.

! Now create a policy to permit traffic going the other way

   a. Create New
   b. Provide a Name for the Policy
   c. Incoming Interface/Zone = "vpn-fffffffffffffffff-1" ! This is the VPN tunnel interface
   d. Source Address = all
   e. Outgoing Interface/Zone = internal  ! This is the interface out which your local LAN resides
   f. Destination Address = all
   g. Schedule = always
   h. Service = ALL
   i. Action = ACCEPT
   j. Click OK




! Additional Notes and Questions
!  - Amazon Virtual Private Cloud Getting Started Guide:
!       http://docs.amazonwebservices.com/AmazonVPC/latest/GettingStartedGuide
!  - Amazon Virtual Private Cloud Network Administrator Guide:
!       http://docs.amazonwebservices.com/AmazonVPC/latest/NetworkAdminGuide


4. Google翻訳と修正してみた

文中色分けの意味
通常文字色 = 設定操作する箇所
Green = 原文でコメントアウトの箇所
Blue = 記事を書いてて気づいた箇所やコメント
Red = 注意事項(そのまま設定しちゃダメな箇所)



! Amazon Web Services
! Virtual Private Cloud

! AWSは一意の識別子を使用して、VPN接続の構成を操作します。
! 各VPN接続には識別子が割り当てられ、他の2つの識別子、つまりカスタマーゲートウェイ識別子と仮想プライベートゲートウェイ識別子に関連付けられます。
!
! VPN接続 ID : vpn-fffffffffffffffff
! 仮想プライベートゲートウェイ ID : vgw-01234567890abcdef
! カスタマーゲートウェイ ID : cgw-01234567890abcdef
!
!
! この構成は、2 つのトンネルで構成されています。 カスタマー ゲートウェイで両方のトンネルを設定する必要があります。
!


4.1. トンネル 1本目

! --------------------------------------------------------------------------------
! IPSec Tunnel #1
! --------------------------------------------------------------------------------
! #1: IKE 設定

サイドメニュ- > VPN > IPsecトンネル > 新規作成のドロップダウン > IPsecトンネルを選択
※または、サイドメニュ- > VPN > IPsecウィザード

[VPN作成ウィザード] が表示されます

[テンプレートタイプ] から [カスタム] を選択します

VPNトンネルインターフェースの [名前] を入力します (名前は15文字以内であり、12文字以内がベストです): vpn-fffffffffffffffff-0
【注意】サンプル名としてなのか「vpn-fffffffffffffffff-0」が記載されていますが長すぎて設定不可、ここでは「vpn-to-aws-1」としておきます。所々で出てくるので、都度読み替えてください。

[新規VPNトンネル] ウィンドウが表示されます (ここでVPN設定を構成します)。

セクション 項目 設定値 備考
ネットワーク IPバージョン IPv4
 〃  リモートゲートウェイ スタティックIPアドレス
 〃  IPアドレス 1.1.1.1 外部IP AWS側
 〃  インターフェース wan1 AWSカスタマーゲートウェイで指定した固定グローバルIPを持つインターフェース
 〃  ローカルゲートウェイ ON > [指定]を選択 > wan1の固定グローバルIPを入力
 〃  NATトラバーサル ON or OFF OFF=固定グローバルIP使用
ON=NAT/PAT デバイスの背後にFortigateが居る
 〃  デッドピア検知 オンアイドル or オンデマンド デフォルト値:オンデマンド
認証 方式 事前共有鍵
 〃  事前共有鍵 xxxxSharedKeyxxxTunnel_1xxxxxxxx
 〃  IKE バージョン 2
フェーズ1 プロポーザル 暗号化 AES128 「暗号化/認証」のセットが複数ある場合、使わないセットは「×」で閉じる
 〃  認証 SHA1
 〃  Diffie-Hellmanグループ 2 のみにする
 〃  鍵の有効時間(秒) 28800

! NAT トラバーサルはデフォルトで有効になっていますが、FortiGate デバイスが NAT/PAT デバイスの背後にない場合は、NAT トラバーサルの選択を解除してください。

! --------------------------------------------------------------------------------
! #2: IPSec 設定

フェーズ2 セレクタ > 新規フェーズ2

セクション 項目 設定値 備考
新規フェーズ2 名前 vpn-fffffffffffffffff-0 【注意】設定したVPNトンネルインターフェース名が自動入力されます。本記事では「vpn-to-aws-1」。
 〃  ローカルアドレス サブネット、0.0.0.0/0.0.0.0 FortigateのLAN サブネット
VPNを通る通信に制限を掛けない場合は「0.0.0.0/0.0.0.0」で良い。
 〃  リモートアドレス サブネット、0.0.0.0/0.0.0.0 AWS側サブネット
VPNを通る通信に制限を掛けない場合は「0.0.0.0/0.0.0.0」で良い。

高度な設定

セクション 項目 設定値 備考
フェーズ2 プロポーザル 暗号化 AES128 「暗号化/認証」のセットが複数ある場合、使わないセットは「×」で閉じる
 〃  認証 SHA1
 〃  Replay Detectionを有効化 ON
 〃  Perfect Forward Secrecy (PFS)を有効化 ON
 〃  Diffie-Hellmanグループ 2 のみにする
 〃  鍵の有効時間 秒、3600
 〃  オートネゴシエーション ON オートネゴシエーションが有効な場合、自動鍵キープアライブは自動的に有効になります

[OK] をクリックする。

! --------------------------------------------------------------------------------
! #3: Tunnel Interface 設定

! トンネル インターフェイスは、トンネルに関連付けられた論理インターフェイスになるように構成されます。
! トンネル インターフェイスにルーティングされるすべてのトラフィックは暗号化され、VPC に送信されます。
! 同様に、VPC からのトラフィックは、このインターフェイスで論理的に受信されます。
!
!
! インターフェイスのアドレスは、カスタマー ゲートウェイのセットアップで構成されます。
! アドレスが変更された場合、カスタマー ゲートウェイと VPN 接続を Amazon VPC で再作成する必要があります。
!
! これは、gwdetect によるトンネル フェイルオーバーが機能するために必要です。
!
! これは、グローバル VDOM から実行します。

サイドメニュ- > ネットワーク > インターフェース > 物理インターフェース > wan1 を展開 > 作成したトンネルインターフェース を選択 > 編集

セクション 項目 設定値 備考
アドレス IP 169.254.1.2 内部IP 機器側
 〃  リモートIP/ネットマスク 169.254.1.1/30 内部IP AWS側
管理者アクセス IPv4 PING=ON
その他 ステータス 有効化済み

[OK] をクリックする。

! CLI からこれを実行して、トンネルに MTU と MSS を設定できます。

【注意】このCLIコマンドが弾かれて、トンネルインターフェースのMTU変更が出来ないから調べたら、FortiOS 6.4.0 以降ならできるらしいです(・・・このコマンドFortiOS 5.0版のVPNサンプル設定にも書いてるんだけどな)。

FortigateのVPNトンネルインターフェイスの MTUは、デフォルトで動的に計算されるようですし、いったん無視で良いかもしれません。※機会があればAWSへ問い合わせたい。

community.fortinet.com

#--- Fortigate CLI ---#
# config global  # 【追記】不要コマンドなのでコメントアウトしました。
config system interface
#  edit "vpn-fffffffffffffffff-0" # この名前は、VPN トンネル名と同じになります
  edit "vpn-to-aws-1"  # 【追記】設定したVPNトンネルインターフェース名を指定。
    set mtu-override enable  # 【追記】 FortiOS 6.4.0 未満は設定不可
    set mtu 1427             # 【追記】 FortiOS 6.4.0 未満は設定不可
    set tcp-mss 1379
  next
end

show system interface vpn-to-aws-1  # 【追記】確認コマンド

! --------------------------------------------------------------------------------
! #4 Static Route 設定
カスタマー ゲートウェイは、対応するプレフィックスの静的ルートを設定する必要があります。
! トンネル インターフェイス経由でトラフィックを送信する VPC。
! プレフィックスが 10.0.0.0/16 の VPC の例を以下に示します。
!
! これはルート VDOM から構成されます。
【注意】ここは実際のVPC CIDRが記載されずに参考のCIDR [10.0.0.0/16] が書かれています。実際のVPC CIDRに書き換えてください。
また、実環境の構成によっては別途ルーティング設計が必要となります。

サイドメニュ- > ネットワーク > スタティックルート > 新規作成

セクション 項目 設定値 備考
新規スタティックルート 宛先 サブネット > VPC CIDRを記入 【注意】「10.0.0.0/16」は参考です。実際のVPC CIDRに書き換えてください。
 〃  インターフェース vpn-to-aws-1 作成したVPNトンネル インターフェイスを指定

[OK] をクリックする。

! スタティック ルーティングでは、トンネル間のトラフィックのフェイルオーバーは許可されません。
! トンネルの 1 つに問題がある場合は、トラフィックを 2 番目のトンネルにフェイルオーバーします。 これは、fortigate で「gwdetect」を使用して行われます。
! gwdetect コマンドは、トンネルの反対側に ping を実行し、トンネルが稼働しているかどうかを確認します。
! ping が失敗すると、ルーティング テーブルからスタティック ルートが削除され、テーブルの 2 番目のルートがアクティブになります。
!
! これは、CLI を使用してのみ実行できます。
!
! 次の構成は、トンネルをテストするためにどの IP を ping する必要があるかを Fortigate デバイスに通知します。 この IP は、仮想プライベート ゲートウェイの内部 IP アドレスである必要があります。
!
! これは、gwtect を介したトンネル フェイルオーバーが機能するために必要です。
! さらに、トンネルがダウンするのを防ぐために VPN トンネルの側からトラフィックを送信する必要があるため、これはトンネルを維持するために必要です。

【注意】このCLIコマンドも弾かれて入力出来ませんでした。
VDOM(バーチャルドメイン)モード設定を変えてないと「config vdom」が打てないようですが、この設定をしなくても通信はできるので、私は無視しました。
将来、ここが詳しくなったら、、、、挑戦するかも(汗)

このCLIコマンドを使用しない代替案として、スタティックルートの優先度を変えれば良いと思います。
・Tunnel 1側のアドミニストレーティブ・ディスタンス = 10(優先、通常利用)
・Tunnel 2側のアドミニストレーティブ・ディスタンス = 11(非優先、Tunnel 1側Down時に利用)

config vdom
    edit root
        config router gwdetect
        edit 1
        set interface "vpn-fffffffffffffffff-0" ! これは VPN トンネル インターフェイスです。
        set server "169.254.1.1"

# 「set server 」は 内部IP AWS側 です。  

# 次のコマンドを使用して、gwdetect の間隔と失敗時間を設定できます。 
# 間隔は、ping 間の秒数です。 
# Failtime は、連続して失われた ping の数です。
# 2 と 5 のそれぞれの値を使用すると、トンネルは 10 秒でフェールオーバーします。

        set interval 2
        set failtime 5
    next
end

! --------------------------------------------------------------------------------
! #5: Firewall Policy 設定
! ローカル サブネットから VPC サブネットへのトラフィック、およびその逆のトラフィックを許可するファイアウォール ポリシーを作成する。
! このポリシー例では、ローカル サブネットから VPC へのすべてのトラフィックを許可します。
!
! これはルート VDOM から構成されます。

サイドメニュ- > ポリシー&オブジェクト > IPv4ポリシー > 新規作成

項目 設定値 備考
名前 任意の名前 例)lan-to-aws-1
着信インターフェイス internal や LAN等 LAN側インターフェイス
発信インターフェイス vpn-to-aws-1 作成したVPN トンネル インターフェイス
送信元 all
宛先 all
スケジュール always
サービス ALL
アクション ACCEPT
NAT ON or OFF NATはデフォルト有効になっていますが、無効にすることができます。

[OK] をクリックする。

! ここで、逆方向のトラフィックを許可するポリシーを作成します

項目 設定値 備考
名前 任意の名前 例)aws-to-lan-1
着信インターフェイス vpn-to-aws-1 作成したVPN トンネル インターフェイス
発信インターフェイス internal や LAN等 LAN側インターフェイス
送信元 all
宛先 all
スケジュール always
サービス ALL
アクション ACCEPT
NAT ON or OFF NATはデフォルト有効になっていますが、無効にすることができます。


3.2. トンネル 2本目

! --------------------------------------------------------------------------------
! IPSec Tunnel #2
! --------------------------------------------------------------------------------
! #1: IKE 設定

サイドメニュ- > VPN > IPsecトンネル > 新規作成のドロップダウン > IPsecトンネルを選択
※または、サイドメニュ- > VPN > IPsecウィザード

[VPN作成ウィザード] が表示されます

[テンプレートタイプ] から [カスタム] を選択します

VPNトンネルインターフェースの [名前] を入力します (名前は15文字以内であり、12文字以内がベストです): vpn-fffffffffffffffff-1
【注意】サンプル名としてなのか「vpn-fffffffffffffffff-1」が記載されていますが長すぎて設定不可、ここでは「vpn-to-aws-2」としておきます。所々で出てくるので、都度読み替えてください。

[新規VPNトンネル] ウィンドウが表示されます (ここでVPN設定を構成します)。

セクション 項目 設定値 備考
ネットワーク IPバージョン IPv4
 〃  リモートゲートウェイ スタティックIPアドレス
 〃  IPアドレス 2.2.2.2 外部IP AWS側
 〃  インターフェース wan1 AWSカスタマーゲートウェイで指定した固定グローバルIPを持つインターフェース
 〃  ローカルゲートウェイ ON > [指定]を選択 > wan1の固定グローバルIPを入力
 〃  NATトラバーサル ON or OFF OFF=固定グローバルIP使用
ON=NAT/PAT デバイスの背後にFortigateが居る
 〃  デッドピア検知 オンアイドル or オンデマンド デフォルト値:オンデマンド
認証 方式 事前共有鍵
 〃  事前共有鍵 xxxxSharedKeyxxxTunnel_2xxxxxxxx
 〃  IKE バージョン 2
フェーズ1 プロポーザル 暗号化 AES128 「暗号化/認証」のセットが複数ある場合、使わないセットは「×」で閉じる
 〃  認証 SHA1
 〃  Diffie-Hellmanグループ 2 のみにする
 〃  鍵の有効時間(秒) 28800

! NAT トラバーサルはデフォルトで有効になっていますが、FortiGate デバイスが NAT/PAT デバイスの背後にない場合は、NAT トラバーサルの選択を解除してください。

! --------------------------------------------------------------------------------
! #2: IPSec 設定

フェーズ2 セレクタ > 新規フェーズ2

セクション 項目 設定値 備考
新規フェーズ2 名前 vpn-fffffffffffffffff-1 【注意】設定したVPNトンネルインターフェース名が自動入力されます。本記事では「vpn-to-aws-2」。
 〃  ローカルアドレス サブネット、0.0.0.0/0.0.0.0 FortigateのLAN サブネット
VPNを通る通信に制限を掛けない場合は「0.0.0.0/0.0.0.0」で良い。
 〃  リモートアドレス サブネット、0.0.0.0/0.0.0.0 AWS側サブネット
VPNを通る通信に制限を掛けない場合は「0.0.0.0/0.0.0.0」で良い。

高度な設定

セクション 項目 設定値 備考
フェーズ2 プロポーザル 暗号化 AES128 「暗号化/認証」のセットが複数ある場合、使わないセットは「×」で閉じる
 〃  認証 SHA1
 〃  Replay Detectionを有効化 ON
 〃  Perfect Forward Secrecy (PFS)を有効化 ON
 〃  Diffie-Hellmanグループ 2 のみにする
 〃  鍵の有効時間 秒、3600
 〃  オートネゴシエーション ON オートネゴシエーションが有効な場合、自動鍵キープアライブは自動的に有効になります

[OK] をクリックする。

! --------------------------------------------------------------------------------
! #3: Tunnel Interface 設定

! トンネル インターフェイスは、トンネルに関連付けられた論理インターフェイスになるように構成されます。
! トンネル インターフェイスにルーティングされるすべてのトラフィックは暗号化され、VPC に送信されます。
! 同様に、VPC からのトラフィックは、このインターフェイスで論理的に受信されます。
!
!
! インターフェイスのアドレスは、カスタマー ゲートウェイのセットアップで構成されます。
! アドレスが変更された場合、カスタマー ゲートウェイと VPN 接続を Amazon VPC で再作成する必要があります。
!
! これは、gwdetect によるトンネル フェイルオーバーが機能するために必要です。
!
! これは、グローバル VDOM から実行します。

サイドメニュ- > ネットワーク > インターフェース > 物理インターフェース > wan1 を展開 > 作成したトンネルインターフェース を選択 > 編集

セクション 項目 設定値 備考
アドレス IP 169.254.2.2 内部IP 機器側
 〃  リモートIP/ネットマスク 169.254.2.1/30 内部IP AWS側
管理者アクセス IPv4 PING=ON
その他 ステータス 有効化済み

[OK] をクリックする。

! CLI からこれを実行して、トンネルに MTU と MSS を設定できます。

【注意】このCLIコマンドが弾かれて、トンネルインターフェースのMTU変更が出来ないから調べたら、FortiOS 6.4.0 以降ならできるらしいです(・・・このコマンドFortiOS 5.0版のVPNサンプル設定にも書いてるんだけどな)。

FortigateのVPNトンネルインターフェイスの MTUは、デフォルトで動的に計算されるようですし、いったん無視で良いかもしれません。※機会があればAWSへ問い合わせたい。

community.fortinet.com

#--- Fortigate CLI ---#
# config global  # 【追記】不要コマンドなのでコメントアウトしました。
config system interface
#  edit "vpn-fffffffffffffffff-1" # この名前は、VPN トンネル名と同じになります
  edit "vpn-to-aws-2"  # 【追記】設定したVPNトンネルインターフェース名を指定。
    set mtu-override enable  # 【追記】 FortiOS 6.4.0 未満は設定不可
    set mtu 1427             # 【追記】 FortiOS 6.4.0 未満は設定不可
    set tcp-mss 1379
  next
end

show system interface vpn-to-aws-2  # 【追記】確認コマンド

! --------------------------------------------------------------------------------
! #4 Static Route 設定
カスタマー ゲートウェイは、対応するプレフィックスの静的ルートを設定する必要があります。
! トンネル インターフェイス経由でトラフィックを送信する VPC。
! プレフィックスが 10.0.0.0/16 の VPC の例を以下に示します。
!
! これはルート VDOM から構成されます。
【注意】ここは実際のVPC CIDRが記載されずに参考のCIDR [10.0.0.0/16] が書かれています。実際のVPC CIDRに書き換えてください。
また、実環境の構成によっては別途ルーティング設計が必要となります。

サイドメニュ- > ネットワーク > スタティックルート > 新規作成

セクション 項目 設定値 備考
新規スタティックルート 宛先 サブネット > VPC CIDRを記入 【注意】「10.0.0.0/16」は参考です。実際のVPC CIDRに書き換えてください。
 〃  インターフェース vpn-to-aws-2 作成したVPNトンネル インターフェイスを指定

[OK] をクリックする。

! スタティック ルーティングでは、トンネル間のトラフィックのフェイルオーバーは許可されません。
! トンネルの 1 つに問題がある場合は、トラフィックを 2 番目のトンネルにフェイルオーバーします。 これは、fortigate で「gwdetect」を使用して行われます。
! gwdetect コマンドは、トンネルの反対側に ping を実行し、トンネルが稼働しているかどうかを確認します。
! ping が失敗すると、ルーティング テーブルからスタティック ルートが削除され、テーブルの 2 番目のルートがアクティブになります。
!
! これは、CLI を使用してのみ実行できます。
!
! 次の構成は、トンネルをテストするためにどの IP を ping する必要があるかを Fortigate デバイスに通知します。 この IP は、仮想プライベート ゲートウェイの内部 IP アドレスである必要があります。
!
! これは、gwtect を介したトンネル フェイルオーバーが機能するために必要です。
! さらに、トンネルがダウンするのを防ぐために VPN トンネルの側からトラフィックを送信する必要があるため、これはトンネルを維持するために必要です。

【注意】このCLIコマンドも弾かれて入力出来ませんでした。
VDOM(バーチャルドメイン)モード設定を変えてないと「config vdom」が打てないようですが、この設定をしなくても通信はできるので、私は無視しました。
将来、ここが詳しくなったら、、、、挑戦するかも(汗)

このCLIコマンドを使用しない代替案として、スタティックルートの優先度を変えれば良いと思います。
・Tunnel 1側のアドミニストレーティブ・ディスタンス = 10(優先、通常利用)
・Tunnel 2側のアドミニストレーティブ・ディスタンス = 11(非優先、Tunnel 1側Down時に利用)

config vdom
    edit root
        config router gwdetect
        edit 2
        set interface "vpn-fffffffffffffffff-1" ! これは VPN トンネル インターフェイスです。
        set server "169.254.2.1"

# 「set server 」は 内部IP AWS側 です。  

# 次のコマンドを使用して、gwdetect の間隔と失敗時間を設定できます。 
# 間隔は、ping 間の秒数です。 
# Failtime は、連続して失われた ping の数です。
# 2 と 5 のそれぞれの値を使用すると、トンネルは 10 秒でフェールオーバーします。

        set interval 2
        set failtime 5
    next
end

! --------------------------------------------------------------------------------
! #5: Firewall Policy 設定
! ローカル サブネットから VPC サブネットへのトラフィック、およびその逆のトラフィックを許可するファイアウォール ポリシーを作成する。
! このポリシー例では、ローカル サブネットから VPC へのすべてのトラフィックを許可します。
!
! これはルート VDOM から構成されます。

サイドメニュ- > ポリシー&オブジェクト > IPv4ポリシー > 新規作成

項目 設定値 備考
名前 任意の名前 例)lan-to-aws-2
着信インターフェイス internal や LAN等 LAN側インターフェイス
発信インターフェイス vpn-to-aws-2 作成したVPN トンネル インターフェイス
送信元 all
宛先 all
スケジュール always
サービス ALL
アクション ACCEPT
NAT ON or OFF NATはデフォルト有効になっていますが、無効にすることができます。

[OK] をクリックする。

! ここで、逆方向のトラフィックを許可するポリシーを作成します

項目 設定値 備考
名前 任意の名前 例)aws-to-lan-2
着信インターフェイス vpn-to-aws-2 作成したVPN トンネル インターフェイス
発信インターフェイス internal や LAN等 LAN側インターフェイス
送信元 all
宛先 all
スケジュール always
サービス ALL
アクション ACCEPT
NAT ON or OFF NATはデフォルト有効になっていますが、無効にすることができます。


! 追加の注意事項と質問
! - Amazon Virtual Private Cloud Getting Started Guide:
http://docs.amazonwebservices.com/AmazonVPC/latest/GettingStartedGuide

! - Amazon Virtual Private Cloud Network Administrator Guide:
http://docs.amazonwebservices.com/AmazonVPC/latest/NetworkAdminGuide

AWS CloudShell:VPCフローログを設定する

以前、PowerShellを使ってVPC~EC2インスタンスまでの作成記事を書いて、その中にVPCフローログ設定も書いていたのですが、、、、久しぶりに読み返してみたら量が多くてみづらい・・・。VPCフローログ設定どこが必要なものなのかが分からない(汗

blog.toyokky.com

そのため、VPCフローログ部分を分割するとともに、AWS CloudShellを利用しての作成方法へと修正していきます。


本記事では、AWS CloudShellを利用して以下のVPC系リソースを作成します。

リソース種別 用途 Name 個別情報
IAMロール VPCフローログへ割り当てる権限 system-Pxx-Irl-Mnt-Vpcflowlogs ポリシーは「インラインポリシー」へ記載
インラインポリシー CloudWatch Logsの操作権限を記載 system-Pxx-Ipl-Mnt-Vpcflowlogs IAMロール内へポリシーを直接記載
CloudWatchロググループ VPCフローログのログ保管 /aws/vpc/flowlogs/blog-P1x-Vpc ログ保持期間: 1週間
VPCフローログ VPCの通信ログを取得する blog-P1x-Vfl-All 対象VPC: P1x-Vfl-All

※Nameの命名規則は自分ルール「AWSリソースの命名規則について」を使用します。
※本手順を利用する際は、上表「Name」や、文中「★」の置換をすると思います。


目次

検証環境

  • 検証日: 2022/09/24
  • 実行環境
    • PC
      • Windows10 Home Ver21H1
        • Google Chrome: バージョン: 105.0.5195.127(Official Build) (64 ビット)
    • AWSマネジメントコンソール
      • AWS CloudShell
        • AWS CLI: aws-cli/2.7.33 Python/3.9.11 Linux/4.14.287-215.504.amzn2.x86_64 exec-env/CloudShell exe/x86_64.amzn.2 prompt/off

注意事項

  • 本記事の内容はAWS CloudShellで検証しています。
  • AWS CLIはバージョン2を使用しています(CloudShellのデフォルトがバージョン2)。
  • コマンド内の変数やパラメータやは検証で使用したものを記載しています。ご自身の環境に合わせ、書き換えて使用してください。
  • 個人で検証しているため実行結果に責任は持てません。必ずご自身でも検証してから使用してください。


1. VPCフローログとは

VPC フローログは、VPC内のネットワークインターフェイスをモニタして、IPトラフィックの通信ログを記録する機能です。ログは CloudWatch Logs や S3 に保存できます。

VPC フローログを取得していると以下のようなシーンで役立ちます。

  • AWSの通信制御(セキュリティグループ/ネットワークACL)で通信が許可されてるかどうか
    • 対象のIP通信が「REJECT(拒否)」されている場合、AWSの通信制御で許可されていない
    • 対象のIP通信が「ACCEPT(許可)」なのに通信できない場合は、EC2内のOSで通信制御してたりする
  • インスタンスに到達するトラフィックをモニタリングできるため、「このIPがREJECT(拒否)されてるけど、必要だから許可しなきゃ」などの判断ができる
  • インターフェイスに出入りするトラフィックの方向が分かる
    • Outbound通信のみでInbound(戻り通信)が無い場合は、途中で通信がロストしてる、とか
  • VPC全体ではなく、サブネットやインターフェース単位でも通信ログが取れる

ただし、VPC内の通信を見ているため「DirectConnect」や「Site-to-Site VPN」などの通信は見れません。


VPCフローログの詳細は、公式AWSドキュメントに記載されています。

docs.aws.amazon.com


2. IAMロール

VPCフローログ用のIAMロールを作成します。
IAMポリシーを作成してからIAMロールへ割り当てる方法が一般的ですが、今回は「IAMロールを作成して、インラインポリシーとして直接ポリシーを書き込む」方法で行います。

※インラインポリシーにしている理由は、VPCフローログ毎にこのIAMロールを使い廻すから固定で良いのと、個人の趣味です。
※2022/09/24時点:以前はGUIでVPCフローログを作成する際、ついでにIAMロールの作成が出来たのですが、今は出来なくなってる!?


2.1. JSONファイルの作成

以下のJSONファイルを作成し、CloudShellのHomeディレクトリへ出力します。

ファイル名 用途
VpcFlologs_AssumeRole.json AssumeRole(信頼関係)の設定用
VpcFlologs_Policy.json VPCフローログへ適用するインラインポリシーの中身


2.1.1. JSONファイルの作成: AssumeRole(信頼関係)

AssumeRoleは、混乱する代理問題 に対応する形にしているため、AWSアカウントIDを採取しています。

# JSONファイル名を変数へ格納
jsonfile_assumerole="VpcFlologs_AssumeRole.json"

# AWSアカウントID
account_id=`aws sts get-caller-identity \
    --query "Account" \
    --output text` \
     && echo ${account_id}

# JSONファイルの作成
cat << EOF > ${jsonfile_assumerole}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "vpc-flow-logs.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "${account_id}"
        },
        "ArnLike": {
          "aws:SourceArn": "arn:aws:ec2:region:${account_id}:vpc-flow-log/*"
        }
      }
    }
  ]
}
EOF

# 作成確認
ls -l
    # > VpcFlologs_AssumeRole.json があること

cat ${jsonfile_assumerole}
     # > 入力した内容が表示され、エラーが無いこと


2.1.2. JSONファイルの作成: インラインポリシー用

# JSONファイル名を変数へ格納
jsonfile_policy="VpcFlologs_Policy.json"

# JSONファイルの作成
cat << EOF > ${jsonfile_policy}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents",
        "logs:DescribeLogGroups",
        "logs:DescribeLogStreams"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
EOF

# 作成確認
ls -l
    # > VpcFlologs_Policy.json があること

cat ${jsonfile_policy}
     # > 入力した内容が表示され、エラーが無いこと


2.2. IAMロールの作成

# 変数の指定
iam_role_name="system-Pxx-Irl-Mnt-Vpcflowlogs"  #★環境により修正
iam_role_description="Allows VPCflowlogs to call CloudWatch Logs on your behalf."
jsonfile_assumerole="VpcFlologs_AssumeRole.json"

# IAMロールの作成
aws iam create-role \
    --role-name ${iam_role_name} \
    --description "${iam_role_description}" \
    --assume-role-policy-document file://${jsonfile_assumerole} \
    --tags "Key=Name,Value=${iam_role_name}"


2.3. IAMロールへインラインポリシーを適用する

# 変数の指定
iam_role_name="system-Pxx-Irl-Mnt-Vpcflowlogs"  #★環境により修正
iam_policy_name="system-Pxx-Ipl-Mnt-Vpcflowlogs"  #★環境により修正
jsonfile_policy="VpcFlologs_Policy.json"

# IAMロールへインラインポリシーを適用する
aws iam put-role-policy \
    --role-name ${iam_role_name} \
    --policy-name ${iam_policy_name} \
    --policy-document file://${jsonfile_policy}


2.4. 確認コマンド

# IAMロール
## すべて表示する
aws iam list-roles

## 名前を指定して表示
iam_role_name="system-Pxx-Irl-Mnt-Vpcflowlogs"  #★環境により修正
aws iam get-role \
    --role-name ${iam_role_name}

## IAMロールにアタッチされているインラインポリシーを表示
iam_role_name="system-Pxx-Irl-Mnt-Vpcflowlogs"  #★環境により修正
aws iam list-role-policies \
    --role-name ${iam_role_name}

## IAMロールにアタッチされているインラインポリシーの中身を表示
iam_role_name="system-Pxx-Irl-Mnt-Vpcflowlogs"  #★環境により修正
policy_name="system-Pxx-Ipl-Mnt-Vpcflowlogs"  #★環境により修正
aws iam get-role-policy \
    --role-name ${iam_role_name} \
    --policy-name ${policy_name}


3. CloudWatch Logs

3.1. ロググループの作成

# 変数の指定
loggroup_name="/aws/vpc/flowlogs/blog-P1x-Vpc"  #★環境により修正

# ロググループの作成
aws logs create-log-group \
    --log-group-name ${loggroup_name} \
    --tags "Name=${loggroup_name}"


3.2. ログの保管期間(Retention)設定

何日経過したらログを削除するかを設定します。
個人用の設定なので、とりあえず「7日」で設定しています。

# 変数の指定
loggroup_name="/aws/vpc/flowlogs/blog-P1x-Vpc"  #★環境により修正
retention_days="7"  #★環境により修正
    # 選択値: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653

# ログの保管期間(Retention)設定
aws logs put-retention-policy \
    --log-group-name ${loggroup_name} \
    --retention-in-days ${retention_days}


3.3. 確認コマンド

# すべて表示する
aws logs describe-log-groups

# 名前を指定して表示
loggroup_name="/aws/vpc/flowlogs/blog-P1x-Vpc"  #★環境により修正
aws logs describe-log-groups \
    --log-group-name-prefix ${loggroup_name}


4. VPCフローログ

「対象VPC: P1x-Vfl-All」へVPCフローログを設定します。

4.1. ログ形式(log-format)

ログ形式はデフォルトが使いづらいのでカスタム形式にしています。
日頃、インスタンスへ通信が来ているか、拒否されていないかを見ているので、あまり細かいものは見ていないです。

# ログ形式(デフォルト)
${version} ${account-id} ${interface-id} ${srcaddr} ${dstaddr} ${srcport} ${dstport} ${protocol} ${packets} ${bytes} ${start} ${end} ${action} ${log-status}

# カスタム形式 ← これで設定します。
${interface-id} ${srcaddr} ${srcport} ${dstaddr} ${dstport} ${protocol} ${action} ${log-status}
※ENI-ID, 送信元IP, 送信元ポート, 宛先IP, 宛先ポート,プロトコル, アクション, ログ状態
  • プロトコル${protocol}の番号は コチラ を参照
  • アクション${action}
    • ACCEPT : トラフィックが承認されました。
    • REJECT : トラフィックが拒否されました。 例)セキュリティグループまたはネットワーク ACL により許可されていない
  • フローログのロギングステータス${log-status}
    • OK : データは送信先に正常に記録された
    • NODATA : 集約間隔内(1分 or 10分)にネットワークトラフィックが無い
    • SKIPDATA : 集約間隔内(1分 or 10分)に一部のフローログレコードがスキップされた
      • 内部的なキャパシティー制限、または内部エラーが原因である可能性がある


4.2. VPCフローログの作成

# 対象VPCのIDを変数へ格納する
vpc_name="blog-P1x-Vpc"  #★環境により修正、対象VPCのNameタグ
vpc_id=`aws ec2 describe-vpcs \
    --filters "Name=tag:Name,Values=${vpc_name}" \
    --query "Vpcs[].VpcId" \
    --output text` \
    && echo ${vpc_id}

# IAMロールのARNを変数へ格納
iam_role_name="system-Pxx-Irl-Mnt-Vpcflowlogs"  #★環境により修正
iam_role_arn=`aws iam get-role \
    --role-name ${iam_role_name} \
    --query "Role.Arn" \
    --output text` \
    && echo ${iam_role_arn}

# VPCフローログの作成
flowlog_name="blog-P1x-Vfl-All"  #★環境により修正
loggroup_name="/aws/vpc/flowlogs/blog-P1x-Vpc"  #★環境により修正
log_format='${interface-id} ${srcaddr} ${srcport} ${dstaddr} ${dstport} ${protocol} ${action} ${log-status}'  #★環境により修正

aws ec2 create-flow-logs \
    --resource-type VPC \
    --resource-ids ${vpc_id} \
    --traffic-type ALL \
    --max-aggregation-interval 600 \
    --log-destination-type cloud-watch-logs \
    --log-group-name ${loggroup_name} \
    --deliver-logs-permission-arn ${iam_role_arn} \
    --log-format "${log_format}" \
    --tag-specifications "ResourceType=vpc-flow-log, \
        Tags=[{Key=Name,Value=${flowlog_name}}]"


4.3. 確認コマンド

# すべて表示する
aws ec2 describe-flow-logs

# 名前を指定して表示
flowlog_name="blog-P1x-Vfl-All"  #★環境により修正
aws ec2 describe-flow-logs \
    --filter "Name=tag:Name,Values=${flowlog_name}" 

AWS CloudShell:VPC基盤を作成する(VPC・サブネット・ルートテーブル等)

以前、PowerShellを使ってVPC~EC2インスタンスまでの作成記事を書いたのですが、、、、久しぶりに読み返してみたら量が多くてみづらい・・・。

blog.toyokky.com

最近はセキュリティの都合上、PowerShellにアクセスキーを入れてAWS CLIを利用するより、AWS CloudShellを利用することが多いため、上の記事の分割とCloudShell版への変更を行っていきます。


本記事では、AWS CloudShellを利用して以下のVPC系リソースを作成します。

リソース種別 AZ 個別情報 Name CIDR, その他
VPC - - blog-P1x-Vpc 192.168.128.0/17
サブネット 1a パブリック blog-P1a-Sub-Pub01 192.168.128.0/24
1a プライベート blog-P1a-Sub-Pri01 192.168.129.0/24
1c パブリック blog-P1c-Sub-Pub01 192.168.192.0/24
1c プライベート blog-P1c-Sub-Pri01 192.168.193.0/24
インターネットゲートウェイ - - blog-P1x-Igw -
ルートテーブル 1a パブリック blog-P1a-Rtb-Pub01 -
1a プライベート blog-P1a-Rtb-Pri01 -
1c パブリック blog-P1c-Rtb-Pub01 -
1c プライベート blog-P1c-Rtb-Pri01 -

※Nameの命名規則は自分ルール「AWSリソースの命名規則について」を使用します。
※サブネットはAZ毎にパブリックとプライベートを作成します。
※ルートテーブルもサブネットと同様、AZ毎にパブリックとプライベートを作成します。

目次

検証環境

  • 検証日: 2022/09/24
  • 実行環境
    • PC
      • Windows10 Home Ver21H1
        • Google Chrome: バージョン: 105.0.5195.127(Official Build) (64 ビット)
    • AWSマネジメントコンソール
      • AWS CloudShell
        • AWS CLI: aws-cli/2.7.33 Python/3.9.11 Linux/4.14.287-215.504.amzn2.x86_64 exec-env/CloudShell exe/x86_64.amzn.2 prompt/off

注意事項

  • 本記事の内容はAWS CloudShellで検証しています。
  • AWS CLIはバージョン2を使用しています(CloudShellのデフォルトがバージョン2)。
  • コマンド内の変数やパラメータやは検証で使用したものを記載しています。ご自身の環境に合わせ、書き換えて使用してください。
  • 個人で検証しているため実行結果に責任は持てません。必ずご自身でも検証してから使用してください。


1. AWS CloudShell

1.1. AWS CloudShellとは

AWS CloudShellは、AWSマネジメントコンソールからAWS CLI v2が利用できる機能です。
手元のPCからAWS CLIを利用する場合、手元のPCへAWS CLIをインストールして、IAMユーザーとアクセスキーを発行してAWS CLIへ設定するなどの作業がありますが、AWS CloudShellはブラウザ上で動くためそういった作業が不要です。
また、アクセスキーの流出も無いためセキュリティ的にも安全です。

1.2. メリット・デメリット(個人の感想)

あくまでも、私が思っているAWS CloudShellのメリット・デメリットですが、

■ メリット

  • AWSマネジメントコンソールにログインできれば使える
    • 操作権限はそのログインしたIAMユーザーの権限と同等
    • 新規顧客のAWS環境でも、直ぐにAWS CLIが利用できる
  • アクセスキーを発行しなくて良い
    • 流出の心配が無い
    • セキュリティ意識の低いメンバーへアクセスキーを発行する恐怖からの解放
  • AWS CloudShell ~ 手元PC 間でのファイル受け渡しも可能
  • 「--profile」オプションを使わなくて良い
    • 複数のAWS案件を持つ場合、手元PCで案件を分けるために「--profile」オプションを使っていた

■ デメリット

  • 使用した後に110日放置すると、ストレージ消すぞ!とメールが来て焦る
    • CloudShellにファイルを残さない運用をしていれば問題ない
    • 必要なファイルを残したい場合は一度CloudShellへログインすればOK
    • AWS側へ問い合わせた際、このメールの改善は検討している。と言っていた
  • 手元PCを使うよりもAWS CloudShell ~ 手元PC 間でのファイル受け渡しは面倒


1.3. 使用方法

AWS CloudShellを利用するには、やりたい作業の操作権限を持ったIAMユーザでAWSマネジメントコンソールへログインして、画面右上の このマークを押すか、以下のURLへアクセスします。

AWS CloudShell [東京リージョン]
https://ap-northeast-1.console.aws.amazon.com/cloudshell/home?region=ap-northeast-1

※AWS CloudShell [東京リージョン]で作成したリソースは、東京リージョンへ作成されます。他のリージョンへ作成する場合は、そのリージョンからCloudShellへ入るか、「--region」オプションを使用してください。


1.4. 長文表示時のPager設定(less)をOFFにする

AWS CLI v2からPager設定(less)が有効になっているため、コマンド入力時に出力が途中で止まります。かなり煩わしいのでOFFにする方法です。

aws configure set cli_pager ""

戻す場合は以下のコマンドです。

aws configure set cli_pager "less"

less表示から抜けたい時は「q」キーです。
※Ctrl+Cで抜けるとバグるのは何なのだろうか・・・。


2. VPC

2.1. VPCの作成

# 変数の指定 ★環境に合わせて修正
vpc_name="blog-P1x-Vpc"
vpc_cidr="192.168.128.0/17"

# VPCの作成
aws ec2 create-vpc \
    --cidr-block ${vpc_cidr} \
    --tag-specifications "ResourceType=vpc, \
        Tags=[{Key=Name,Value=${vpc_name}}]"


2.2. VPCの確認

# すべて表示
aws ec2 describe-vpcs

# Nameタグを指定して表示
vpc_name="blog-P1x-Vpc"
aws ec2 describe-vpcs \
    --filters "Name=tag:Name,Values=${vpc_name}"


3. サブネット

3.1. サブネットの作成

# ■ 作成したVPCのIDを変数へ格納する(共通利用)
vpc_name="blog-P1x-Vpc"
vpc_id=`aws ec2 describe-vpcs \
    --filters "Name=tag:Name,Values=${vpc_name}" \
    --query "Vpcs[].VpcId" \
    --output text` \
    && echo ${vpc_id}


# -------------------------------------------
# ■ サブネット作成: AZ-1a パブリック
## 変数の指定 ★環境に合わせて修正
sub_name="blog-P1a-Sub-Pub01"
sub_cidr="192.168.128.0/24"
availability_zone="ap-northeast-1a"

## サブネットの作成
aws ec2 create-subnet \
    --vpc-id ${vpc_id} \
    --cidr-block ${sub_cidr} \
    --availability-zone ${availability_zone} \
    --tag-specifications "ResourceType=subnet, \
        Tags=[{Key=Name,Value=${sub_name}}]"

## パブリックなのでEC2作成時にパブリックIPが自動付与されるようにする

### 作成したサブネットのIDを変数へ格納する
sub_id=`aws ec2 describe-subnets \
    --filters "Name=tag:Name,Values=${sub_name}" \
    --query "Subnets[].SubnetId" \
    --output text` \
    && echo ${sub_id}

### GUIの「パブリック IPv4 アドレスを自動割り当て」を「いいえ→はい」にする作業
aws ec2 modify-subnet-attribute \
    --subnet-id ${sub_id} \
    --map-public-ip-on-launch


# -------------------------------------------
# ■ サブネット作成: AZ-1a プライベート
## 変数の指定 ★環境に合わせて修正
sub_name="blog-P1a-Sub-Pri01"
sub_cidr="192.168.129.0/24"
availability_zone="ap-northeast-1a"

## サブネットの作成
aws ec2 create-subnet \
    --vpc-id ${vpc_id} \
    --cidr-block ${sub_cidr} \
    --availability-zone ${availability_zone} \
    --tag-specifications "ResourceType=subnet, \
        Tags=[{Key=Name,Value=${sub_name}}]"


# -------------------------------------------
# ■ サブネット作成: AZ-1c パブリック
## 変数の指定 ★環境に合わせて修正
sub_name="blog-P1c-Sub-Pub01"
sub_cidr="192.168.192.0/24"
availability_zone="ap-northeast-1c"

## サブネットの作成
aws ec2 create-subnet \
    --vpc-id ${vpc_id} \
    --cidr-block ${sub_cidr} \
    --availability-zone ${availability_zone} \
    --tag-specifications "ResourceType=subnet, \
        Tags=[{Key=Name,Value=${sub_name}}]"

## パブリックなのでEC2作成時にパブリックIPが自動付与されるようにする

### 作成したサブネットのIDを変数へ格納する
sub_id=`aws ec2 describe-subnets \
    --filters "Name=tag:Name,Values=${sub_name}" \
    --query "Subnets[].SubnetId" \
    --output text` \
    && echo ${sub_id}

### GUIの「パブリック IPv4 アドレスを自動割り当て」を「いいえ→はい」にする作業
aws ec2 modify-subnet-attribute \
    --subnet-id ${sub_id} \
    --map-public-ip-on-launch


# -------------------------------------------
# ■ サブネット作成: AZ-1c プライベート
## 変数の指定 ★環境に合わせて修正
sub_name="blog-P1c-Sub-Pri01"
sub_cidr="192.168.193.0/24"
availability_zone="ap-northeast-1c"

## サブネットの作成
aws ec2 create-subnet \
    --vpc-id ${vpc_id} \
    --cidr-block ${sub_cidr} \
    --availability-zone ${availability_zone} \
    --tag-specifications "ResourceType=subnet, \
        Tags=[{Key=Name,Value=${sub_name}}]"


3.2. サブネットの確認

# すべて表示
aws ec2 describe-subnets

# Nameタグを指定して表示
sub_name="blog-P1a-Sub-Pub01"
aws ec2 describe-subnets \
    --filters "Name=tag:Name,Values=${sub_name}"


4. インターネットゲートウェイ

4.1. インターネットゲートウェイの作成

# 変数の指定 ★環境に合わせて修正
igw_name="blog-P1x-Igw"

# インターネットゲートウェイの作成
aws ec2 create-internet-gateway \
    --tag-specifications "ResourceType=internet-gateway, \
        Tags=[{Key=Name,Value=${igw_name}}]"


4.2. インターネットゲートウェイとVPCの関連付け

# 作成したVPCのIDを変数へ格納する
vpc_name="blog-P1x-Vpc"
vpc_id=`aws ec2 describe-vpcs \
    --filters "Name=tag:Name,Values=${vpc_name}" \
    --query "Vpcs[].VpcId" \
    --output text` \
    && echo ${vpc_id}

# 作成したインターネットゲートウェイのIDを変数へ格納する
igw_name="blog-P1x-Igw"
igw_id=`aws ec2 describe-internet-gateways \
    --filters "Name=tag:Name,Values=${igw_name}" \
    --query "InternetGateways[].InternetGatewayId" \
    --output text` \
    && echo ${igw_id}

# インターネットゲートウェイとVPCを関連付ける
aws ec2 attach-internet-gateway \
    --vpc-id ${vpc_id} \
    --internet-gateway-id ${igw_id}


4.3. インターネットゲートウェイの確認

# すべて表示
aws ec2 describe-internet-gateways

# Nameタグを指定して表示
igw_name="blog-P1x-Igw"
aws ec2 describe-internet-gateways \
    --filters "Name=tag:Name,Values=${igw_name}"


5. ルートテーブル

5.1. ルートテーブルの作成

# ■ 作成したVPCのIDを変数へ格納する(共通利用)
vpc_name="blog-P1x-Vpc"
vpc_id=`aws ec2 describe-vpcs \
    --filters "Name=tag:Name,Values=${vpc_name}" \
    --query "Vpcs[].VpcId" \
    --output text` \
    && echo ${vpc_id}


# -------------------------------------------
# ■ ルートテーブル作成: AZ-1a パブリック
## 変数の指定 ★環境に合わせて修正
rtb_name="blog-P1a-Rtb-Pub01"

aws ec2 create-route-table \
    --vpc-id ${vpc_id} \
    --tag-specifications "ResourceType=route-table, \
        Tags=[{Key=Name,Value=${rtb_name}}]"

#"# -------------------------------------------
# ■ ルートテーブル作成: AZ-1a プライベート
rtb_name="blog-P1a-Rtb-Pri01"

aws ec2 create-route-table \
    --vpc-id ${vpc_id} \
    --tag-specifications "ResourceType=route-table, \
        Tags=[{Key=Name,Value=${rtb_name}}]"

# -------------------------------------------
# ■ ルートテーブル作成: AZ-1c パブリック
## 変数の指定 ★環境に合わせて修正
rtb_name="blog-P1c-Rtb-Pub01"

aws ec2 create-route-table \
    --vpc-id ${vpc_id} \
    --tag-specifications "ResourceType=route-table, \
        Tags=[{Key=Name,Value=${rtb_name}}]"

#"# -------------------------------------------
# ■ ルートテーブル作成: AZ-1c プライベート
rtb_name="blog-P1c-Rtb-Pri01"

aws ec2 create-route-table \
    --vpc-id ${vpc_id} \
    --tag-specifications "ResourceType=route-table, \
        Tags=[{Key=Name,Value=${rtb_name}}]"


5.2. ルートテーブルとサブネットの関連付け

関連付けの組み合わせは以下です。
※ルートテーブルの構成要素にAZの指定はありませんが、サブネットのAZと合わせます。将来的にNATゲートウェイやTransit Gatewayを使う場合など、AZ毎に分けておいた方が利点があると思うからです。

AZ 用途 ルートテーブル サブネット
1a パブリック blog-P1a-Rtb-Pub01 blog-P1a-Sub-Pub01
1a プライベート blog-P1a-Rtb-Pri01 blog-P1a-Sub-Pri01
1c パブリック blog-P1c-Rtb-Pub01 blog-P1c-Sub-Pub01
1c プライベート blog-P1c-Rtb-Pri01 blog-P1c-Sub-Pri01

本手順をAWS CLIで行う際の注意点
1つのルートテーブルへ2つ以上のサブネットを関連付けする場合、関連付けコマンドassociate-route-tableはサブネット数分の実行が必要です。1回のコマンド実行で同時に2つは付けられない。

また、関連付け対象のサブネットがDefaultルートテーブルに紐付いている必要があります。他のルートテーブルへ明示的に関連付けしているサブネットは別の方法で付け替えますが、方法が面倒になるためGUIで付け替えたほうが楽です。


# -------------------------------------------
# ■ 関連付け: AZ-1a パブリック
## ルートテーブルのIDを変数へ格納する
rtb_name="blog-P1a-Rtb-Pub01"
rtb_id=`aws ec2 describe-route-tables \
    --filters "Name=tag:Name,Values=${rtb_name}" \
    --query "RouteTables[].RouteTableId" \
    --output text` \
    && echo ${rtb_id}

## サブネットのIDを変数へ格納する
sub_name="blog-P1a-Sub-Pub01"
sub_id=`aws ec2 describe-subnets \
    --filters "Name=tag:Name,Values=${sub_name}" \
    --query "Subnets[].SubnetId" \
    --output text` \
    && echo ${sub_id}

## ルートテーブルとサブネットの関連付け
aws ec2 associate-route-table \
    --route-table-id ${rtb_id} \
    --subnet-id ${sub_id}

# -------------------------------------------
# ■ 関連付け: AZ-1a プライベート
## ルートテーブルのIDを変数へ格納する
rtb_name="blog-P1a-Rtb-Pri01"
rtb_id=`aws ec2 describe-route-tables \
    --filters "Name=tag:Name,Values=${rtb_name}" \
    --query "RouteTables[].RouteTableId" \
    --output text` \
    && echo ${rtb_id}

## サブネットのIDを変数へ格納する
sub_name="blog-P1a-Sub-Pri01"
sub_id=`aws ec2 describe-subnets \
    --filters "Name=tag:Name,Values=${sub_name}" \
    --query "Subnets[].SubnetId" \
    --output text` \
    && echo ${sub_id}

## ルートテーブルとサブネットの関連付け
aws ec2 associate-route-table \
    --route-table-id ${rtb_id} \
    --subnet-id ${sub_id}

# -------------------------------------------
# ■ 関連付け: AZ-1c パブリック
## ルートテーブルのIDを変数へ格納する
rtb_name="blog-P1c-Rtb-Pub01"
rtb_id=`aws ec2 describe-route-tables \
    --filters "Name=tag:Name,Values=${rtb_name}" \
    --query "RouteTables[].RouteTableId" \
    --output text` \
    && echo ${rtb_id}

## サブネットのIDを変数へ格納する
sub_name="blog-P1c-Sub-Pub01"
sub_id=`aws ec2 describe-subnets \
    --filters "Name=tag:Name,Values=${sub_name}" \
    --query "Subnets[].SubnetId" \
    --output text` \
    && echo ${sub_id}

## ルートテーブルとサブネットの関連付け
aws ec2 associate-route-table \
    --route-table-id ${rtb_id} \
    --subnet-id ${sub_id}

# -------------------------------------------
# ■ 関連付け: AZ-1c プライベート
## ルートテーブルのIDを変数へ格納する
rtb_name="blog-P1c-Rtb-Pri01"
rtb_id=`aws ec2 describe-route-tables \
    --filters "Name=tag:Name,Values=${rtb_name}" \
    --query "RouteTables[].RouteTableId" \
    --output text` \
    && echo ${rtb_id}

## サブネットのIDを変数へ格納する
sub_name="blog-P1c-Sub-Pri01"
sub_id=`aws ec2 describe-subnets \
    --filters "Name=tag:Name,Values=${sub_name}" \
    --query "Subnets[].SubnetId" \
    --output text` \
    && echo ${sub_id}

## ルートテーブルとサブネットの関連付け
aws ec2 associate-route-table \
    --route-table-id ${rtb_id} \
    --subnet-id ${sub_id}


5.3. ルートテーブルへルート情報を追加する

本構成で追加するルートは、以下の2本です。
パブリックサブネットがインターネットへ出られるように、デフォルトルートを書きます。

AZ 用途 ルートテーブル 宛先ネットワーク ターゲット(NextHop)
1a パブリック blog-P1a-Rtb-Pub01 0.0.0.0/0 InternetGateway: blog-P1x-Igw
1c パブリック blog-P1c-Rtb-Pub01 0.0.0.0/0 InternetGateway: blog-P1x-Igw


# -------------------------------------------
# ■ ルート追加: AZ-1a パブリック
## ルートテーブルのIDを変数へ格納する
rtb_name="blog-P1a-Rtb-Pub01"
rtb_id=`aws ec2 describe-route-tables \
    --filters "Name=tag:Name,Values=${rtb_name}" \
    --query "RouteTables[].RouteTableId" \
    --output text` \
    && echo ${rtb_id}

## 作成したインターネットゲートウェイのIDを変数へ格納する
igw_name="blog-P1x-Igw"
igw_id=`aws ec2 describe-internet-gateways \
    --filters "Name=tag:Name,Values=${igw_name}" \
    --query "InternetGateways[].InternetGatewayId" \
    --output text` \
    && echo ${igw_id}

# ルートテーブルへルート情報を追加する
dest_cidr="0.0.0.0/0"

aws ec2 create-route \
    --route-table-id ${rtb_id} \
    --gateway-id ${igw_id} \
    --destination-cidr-block ${dest_cidr}


# -------------------------------------------
# ■ ルート追加: AZ-1c パブリック
## ルートテーブルのIDを変数へ格納する
rtb_name="blog-P1c-Rtb-Pub01"
rtb_id=`aws ec2 describe-route-tables \
    --filters "Name=tag:Name,Values=${rtb_name}" \
    --query "RouteTables[].RouteTableId" \
    --output text` \
    && echo ${rtb_id}

## 作成したインターネットゲートウェイのIDを変数へ格納する
igw_name="blog-P1x-Igw"
igw_id=`aws ec2 describe-internet-gateways \
    --filters "Name=tag:Name,Values=${igw_name}" \
    --query "InternetGateways[].InternetGatewayId" \
    --output text` \
    && echo ${igw_id}

# ルートテーブルへルート情報を追加する
dest_cidr="0.0.0.0/0"

aws ec2 create-route \
    --route-table-id ${rtb_id} \
    --gateway-id ${igw_id} \
    --destination-cidr-block ${dest_cidr}


5.4. ルートテーブルの確認

# すべて表示
aws ec2 describe-route-tables

# Nameタグを指定して表示
rtb_name="blog-P1a-Rtb-Pub01"
aws ec2 describe-route-tables \
    --filters "Name=tag:Name,Values=${rtb_name}"

全リージョンのデフォルトVPC系リソースを闇に葬ってみる

AWSアカウントを作成すると「デフォルトVPC」が作成されるのですが、いままで一度も使用したことがありません。
自分でVPCから作成しちゃった方が勉強になるし、デフォルトVPCのCIDRも変更できないので。

AWSサポートの記事を見ると、「デフォルトVPCを使用していない」を条件に、基本的には削除しちゃっても問題ないみたいです。

aws.amazon.com

※WEBで少し見た感じだと、「TransitGateway」と「Elastic Beanstalk」は少し注意が必要かもしれない・・・。


自分はデフォルトVPCをまったく使用していないし、何か邪魔なので、、、闇に葬ろうと思います!


目次

検証環境

  • 検証日: 2022/★
  • 実行環境
    • PC
      • Windows10 Home Ver21H1
        • Google Chrome: バージョン: 105.0.5195.102(Official Build) (64 ビット)
    • AWS操作
      • AWSマネジメントコンソール
        • IAMユーザー: GUI操作の管理者権限
      • AWS CloudShell
        • AWS CLI: aws-cli/2.7.29 Python/3.9.11 Linux/4.14.287-215.504.amzn2.x86_64 exec-env/CloudShell exe/x86_64.amzn.2 prompt/off

注意事項

  • 本記事の内容はAWSマネジメントコンソールAWS CloudShellで検証しています。
  • AWS CLIはバージョン2を使用しています(CloudShellのデフォルトがバージョン2)。
  • コマンド内の変数やパラメータやは検証で使用したものを記載しています。ご自身の環境に合わせ、書き換えて使用してください。
  • 個人で検証しているため実行結果に責任は持てません。必ずご自身でも検証してから使用してください。
  • ページ内のリソースIDは、既に削除済みリソースなのでそのまま記載しています。


1. アカウント作成初期状態で、デフォルトVPC系リソースを探す

今回、デフォルトVPC系のリソースを削除しようと思うのですが、「系」の部分にどんなリソースがあるのかを先に洗い出してみます。
※サブネット、セキュリティグループ等です

1.1. AWSドキュメントを見てみる

docs.aws.amazon.com

「デフォルト VPC のコンポーネント」を読んでみると、デフォルトVPC作成時に以下リソースが作成されているみたいです。
これが、リージョン数分です。

種別 個数 備考
VPC 1 CIDR: 172.31.0.0/16
サブネット AZ数分 CIDR: xx.xx.xx.xx/20
インターネットゲートウェイ 1
ルートテーブル 1 静的ルート: 0.0.0.0/0をインターネットゲートウェイ向け
セキュリティグループ 1
ネットワークACL 1
DHCP オプションセット 1


1.2. EC2 Global Viewでリソース数を見てみる

EC2 Global View とは
AWS リージョン全域で、インスタンス、VPC、サブネット、セキュリティグループ、ボリュームなどの AWS リソースを閲覧できる機能。

■ 確認方法

  1. EC2 Global View へアクセスする
  2. 「リソースの概要」「リージョンあたりのリソース数」が表示される


「リソースの概要」を見てみると、17リージョンでリソースが作成されています。


1.3. TagEditorでリソースを洗い出す

EC2 Global Viewだと以下リソースが表示されないため、TagEditorでも検索してみました。

  • インターネットゲートウェイ
  • ルートテーブル
  • ネットワークACL
  • DHCP オプションセット

※TagEditorの使い方は過去記事で書いているので、こちらを参照してください。

blog.toyokky.com


■ 確認方法

  1. TagEditorへアクセスする ※リージョン指定はありません
  2. 「タグ付けするリソースを検索」へ必要事項を入力して「リソースを検索」する
    • リージョン: All regions
    • リソースタイプ: All supported resource types
    • タグ - オプション: 空白のまま
  3. 待つ ※出力には5分ほど時間がかかる
  4. 検索が終わったら「xx resources を CSV にエクスポート」からCSVをダウンロードする
    • ※検証時は「152」
  5. CSVは文字コードがUTF-8なので、Excelで開く場合はShift-JISにする


全リージョン分のリソースが出力されています。
試しに東京リージョン(ap-northeast-1)でフィルタするとこんな感じで、AWSドキュメントの内容と一致します。


2. デフォルトVPCを削除する

2.1. 削除一覧

先にデフォルトVPC系リソース削除をする時の一覧です。
・GUIはVPC削除のみで依存関係のある他リソースも消せます。
・AWS CLIは依存関係を考慮して順番に削除していきます。
・VPC削除により ルートテーブル/セキュリティグループ/ネットワークACL は消えます。
・DHCPオプションセットは削除後も残りますが、新規VPCでも使用するのでそのままにします。

GUI AWS CLI 対象リソース 備考
一括削除 削除3番目 VPC AWS CLIでは先にサブネットとインターネットゲートウェイを削除
VPC削除で消える 削除2番目 サブネット
VPC削除で消える 削除1番目 インターネットゲートウェイ VPCからデタッチして削除
VPC削除で消える VPC削除で消える ルートテーブル
VPC削除で消える VPC削除で消える セキュリティグループ
VPC削除で消える VPC削除で消える ネットワークACL
残る 残る DHCP オプションセット 他の新規VPCでも使用するので消さない


2.2. 削除方法(GUI)

以下の方法は、AWSマネジメントコンソールで削除対象リージョン数分のVPC削除作業を繰り返します。
また、残数が見えるように「EC2 Global View」から作業しています。

  1. EC2 Global View へアクセスする
  2. 「リージョンあたりのリソース数」から、削除したいリージョンの「VPC数」をクリックする
    • ※サンプルとして「米国西部(オレゴン)us-west-2」で作業
  3. 「グローバル検索」内に対象VPCの「リソースID」が表示されるのでクリックする
  4. 対象VPCの詳細ページが開くので、「アクション > VPCの削除」を選択する
  5. 「VPCの削除」ページが表示されるので、以下入力して「削除」をクリックする
    • デフォルトVPCの削除を希望~: ■ チェックする
    • 削除を希望するには~: デフォルト VPC の削除
  6. 正常に削除された旨が表示されたら、「EC2 Global View」へ戻る
  7. 対象リージョンでVPC系が「0」になっていることを確認する
    • ※画面表示が遅れることがあるので、画面更新して待つ


2.3. 削除方法(AWS CLI)

削除対象のリソースが、全リージョンだと結構な数になります。軽く数えたら「148」くらい。
大変なのでAWS CLIで一気に消そうと思っ・・・・・たのですが、既にクラスメソッドさんに素敵な記事がありました。

dev.classmethod.jp


ただ記事を紹介するだけだと寂しいので、実際に実行してみました。

  1. CloudShellを開く
  2. URL先の「2. デフォルトVPCを削除する」に書いてあるコマンドをコピー
  3. CloudShellへコマンドをペーストして実行する
    • ※CloudShellでは ctrl + C, Ctrl + v が使える
  4. 待つ:実行時間は「4分」ほど
  5. AWSのVPC環境がキレイになる(´ω`)

参考:出力ログをクリックで展開

Preparing your terminal...
Try these commands to get started:
aws help  or  aws <command> help  or  aws <command> --cli-auto-prompt
[cloudshell-user@ip-10-0-77-140 ~]$ aws --output text ec2 describe-regions --query "Regions[].[RegionName]" \
> | while read region; do
>   aws --region ${region} --output text \
>     ec2 describe-vpcs --query "Vpcs[?IsDefault].[VpcId]" \
>   | while read vpc; do
>     echo "# deleting vpc: ${vpc} in ${region}"
>    
>     ### IGW
>     aws --region ${region} --output text \
>       ec2 describe-internet-gateways --filters Name=attachment.vpc-id,Values=${vpc} \
>       --query "InternetGateways[].[InternetGatewayId]" \
>     | while read igw; do
>       echo "## deleting igw: ${igw} in ${vpc}, ${region}"
>       echo "--> detatching"
>       aws --region ${region} --output json \
>         ec2 detach-internet-gateway --internet-gateway-id ${igw} --vpc-id ${vpc}
>       echo "--> deleteing"
>       aws --region ${region} --output json \
>         ec2 delete-internet-gateway --internet-gateway-id ${igw}
>     done
>    
>     ### Subnet
>     aws --region ${region} --output text \
>       ec2 describe-subnets  --filters Name=vpc-id,Values=${vpc} \
>       --query "Subnets[].[SubnetId]" \
>     | while read subnet; do
>       echo "## deleting subnet: ${subnet} in ${vpc}, ${region}"
>       aws --region ${region} --output json \
>         ec2 delete-subnet --subnet-id ${subnet}
>     done
>    
>     ### VPC
>     echo "## finally, deleting vpc: ${vpc} in ${region}"
>     aws --region ${region} --output json \
>       ec2 delete-vpc --vpc-id ${vpc}  
>   done
> done
# deleting vpc: vpc-03da8d2717f74bbd6 in eu-north-1
## deleting igw: igw-0d75702fe4a7012e9 in vpc-03da8d2717f74bbd6, eu-north-1
--> detatching
--> deleteing
## deleting subnet: subnet-0930e7f1924d8de4c in vpc-03da8d2717f74bbd6, eu-north-1
## deleting subnet: subnet-0cb201e4cf78ae47f in vpc-03da8d2717f74bbd6, eu-north-1
## deleting subnet: subnet-0131379f1d6917cb1 in vpc-03da8d2717f74bbd6, eu-north-1
## finally, deleting vpc: vpc-03da8d2717f74bbd6 in eu-north-1
# deleting vpc: vpc-0a1274b6e2ce54fa6 in ap-south-1
## deleting igw: igw-05c707895c4a4f8c9 in vpc-0a1274b6e2ce54fa6, ap-south-1
--> detatching
--> deleteing
## deleting subnet: subnet-0cdf17e0731c9959b in vpc-0a1274b6e2ce54fa6, ap-south-1
## deleting subnet: subnet-096a31c11ba17dea7 in vpc-0a1274b6e2ce54fa6, ap-south-1
## deleting subnet: subnet-0c010a91263d604b4 in vpc-0a1274b6e2ce54fa6, ap-south-1
## finally, deleting vpc: vpc-0a1274b6e2ce54fa6 in ap-south-1
# deleting vpc: vpc-0b924ea784314720b in eu-west-3
## deleting igw: igw-0b8af5cbd1219ff17 in vpc-0b924ea784314720b, eu-west-3
--> detatching
--> deleteing
## deleting subnet: subnet-0073a3e79aefe26d4 in vpc-0b924ea784314720b, eu-west-3
## deleting subnet: subnet-03794e052bf66938d in vpc-0b924ea784314720b, eu-west-3
## deleting subnet: subnet-068101d9db62d7631 in vpc-0b924ea784314720b, eu-west-3
## finally, deleting vpc: vpc-0b924ea784314720b in eu-west-3
# deleting vpc: vpc-09b73d28640d11cfe in eu-west-2
## deleting igw: igw-011523493be4d7b91 in vpc-09b73d28640d11cfe, eu-west-2
--> detatching
--> deleteing
## deleting subnet: subnet-03c05ee9db69ef952 in vpc-09b73d28640d11cfe, eu-west-2
## deleting subnet: subnet-0054226ac9268f6b8 in vpc-09b73d28640d11cfe, eu-west-2
## deleting subnet: subnet-067d836269327892d in vpc-09b73d28640d11cfe, eu-west-2
## finally, deleting vpc: vpc-09b73d28640d11cfe in eu-west-2
# deleting vpc: vpc-00893fd5cecf690b6 in eu-west-1
## deleting igw: igw-04cb66cfccf4205cf in vpc-00893fd5cecf690b6, eu-west-1
--> detatching
--> deleteing
## deleting subnet: subnet-0e000e5caa73b3c43 in vpc-00893fd5cecf690b6, eu-west-1
## deleting subnet: subnet-0938a8bd38a31afb5 in vpc-00893fd5cecf690b6, eu-west-1
## deleting subnet: subnet-0742af315ad78fc9e in vpc-00893fd5cecf690b6, eu-west-1
## finally, deleting vpc: vpc-00893fd5cecf690b6 in eu-west-1
# deleting vpc: vpc-0870eacfc678d6844 in ap-northeast-3
## deleting igw: igw-07ea4ccdad0df2e77 in vpc-0870eacfc678d6844, ap-northeast-3
--> detatching
--> deleteing
## deleting subnet: subnet-0e52d208ac7714619 in vpc-0870eacfc678d6844, ap-northeast-3
## deleting subnet: subnet-057dda54892056ce7 in vpc-0870eacfc678d6844, ap-northeast-3
## deleting subnet: subnet-011c1177d5ff0499d in vpc-0870eacfc678d6844, ap-northeast-3
## finally, deleting vpc: vpc-0870eacfc678d6844 in ap-northeast-3
# deleting vpc: vpc-00f3ca9902f3b1f42 in ap-northeast-2
## deleting igw: igw-06e681bdc36f4d40c in vpc-00f3ca9902f3b1f42, ap-northeast-2
--> detatching
--> deleteing
## deleting subnet: subnet-0b048aacb6ce1a6f0 in vpc-00f3ca9902f3b1f42, ap-northeast-2
## deleting subnet: subnet-059c7b0dcacb660c2 in vpc-00f3ca9902f3b1f42, ap-northeast-2
## deleting subnet: subnet-03456c60222b3ccf4 in vpc-00f3ca9902f3b1f42, ap-northeast-2
## deleting subnet: subnet-083296c69cef32918 in vpc-00f3ca9902f3b1f42, ap-northeast-2
## finally, deleting vpc: vpc-00f3ca9902f3b1f42 in ap-northeast-2
# deleting vpc: vpc-0310232b5cfb7b5b0 in ap-northeast-1
## deleting igw: igw-0027be714b77afca3 in vpc-0310232b5cfb7b5b0, ap-northeast-1
--> detatching
--> deleteing
## deleting subnet: subnet-0862dc3f09ac5a56d in vpc-0310232b5cfb7b5b0, ap-northeast-1
## deleting subnet: subnet-032ca937ad16759d6 in vpc-0310232b5cfb7b5b0, ap-northeast-1
## deleting subnet: subnet-0c61a7e53005cf8f4 in vpc-0310232b5cfb7b5b0, ap-northeast-1
## finally, deleting vpc: vpc-0310232b5cfb7b5b0 in ap-northeast-1
# deleting vpc: vpc-0a81286d3f2772702 in sa-east-1
## deleting igw: igw-0bd80f931b342f07e in vpc-0a81286d3f2772702, sa-east-1
--> detatching
--> deleteing
## deleting subnet: subnet-0b0a79cfc42028d93 in vpc-0a81286d3f2772702, sa-east-1
## deleting subnet: subnet-0ca984de69f9a3446 in vpc-0a81286d3f2772702, sa-east-1
## deleting subnet: subnet-0e1c572334bc35adc in vpc-0a81286d3f2772702, sa-east-1
## finally, deleting vpc: vpc-0a81286d3f2772702 in sa-east-1
# deleting vpc: vpc-08f2b36181aa7f9b5 in ca-central-1
## deleting igw: igw-06810e851b8b4c360 in vpc-08f2b36181aa7f9b5, ca-central-1
--> detatching
--> deleteing
## deleting subnet: subnet-0ca8484018013ee91 in vpc-08f2b36181aa7f9b5, ca-central-1
## deleting subnet: subnet-05d622e140431ef1f in vpc-08f2b36181aa7f9b5, ca-central-1
## deleting subnet: subnet-098946d396ae27ef9 in vpc-08f2b36181aa7f9b5, ca-central-1
## finally, deleting vpc: vpc-08f2b36181aa7f9b5 in ca-central-1
# deleting vpc: vpc-056c07eefccbabaf1 in ap-southeast-1
## deleting igw: igw-0e9e3d1cb6b95d169 in vpc-056c07eefccbabaf1, ap-southeast-1
--> detatching
--> deleteing
## deleting subnet: subnet-04fb8aca1d62c373f in vpc-056c07eefccbabaf1, ap-southeast-1
## deleting subnet: subnet-00218a6234c018fa1 in vpc-056c07eefccbabaf1, ap-southeast-1
## deleting subnet: subnet-00c0b26f30cdcf658 in vpc-056c07eefccbabaf1, ap-southeast-1
## finally, deleting vpc: vpc-056c07eefccbabaf1 in ap-southeast-1
# deleting vpc: vpc-07923ceeb002d7002 in ap-southeast-2
## deleting igw: igw-0d317fd34a911fea1 in vpc-07923ceeb002d7002, ap-southeast-2
--> detatching
--> deleteing
## deleting subnet: subnet-0079c005d87aa2a6f in vpc-07923ceeb002d7002, ap-southeast-2
## deleting subnet: subnet-011908aeb4c5c25d3 in vpc-07923ceeb002d7002, ap-southeast-2
## deleting subnet: subnet-0b676f4c793f5d070 in vpc-07923ceeb002d7002, ap-southeast-2
## finally, deleting vpc: vpc-07923ceeb002d7002 in ap-southeast-2
# deleting vpc: vpc-0d30e720c87b1820c in eu-central-1
## deleting igw: igw-0f2a6e7380e016443 in vpc-0d30e720c87b1820c, eu-central-1
--> detatching
--> deleteing
## deleting subnet: subnet-0ccdfc320c6a543c9 in vpc-0d30e720c87b1820c, eu-central-1
## deleting subnet: subnet-02c30577daec1cb37 in vpc-0d30e720c87b1820c, eu-central-1
## deleting subnet: subnet-08e2ce5d4fe3afa5d in vpc-0d30e720c87b1820c, eu-central-1
## finally, deleting vpc: vpc-0d30e720c87b1820c in eu-central-1
# deleting vpc: vpc-05c2183af252f4cf7 in us-east-1
## deleting igw: igw-08682de8fd2dcdff8 in vpc-05c2183af252f4cf7, us-east-1
--> detatching
--> deleteing
## deleting subnet: subnet-07736db9efef1bd3d in vpc-05c2183af252f4cf7, us-east-1
## deleting subnet: subnet-0da0560da08abe62d in vpc-05c2183af252f4cf7, us-east-1
## deleting subnet: subnet-00275b377be0b5a4c in vpc-05c2183af252f4cf7, us-east-1
## deleting subnet: subnet-0fc8c2638457192a7 in vpc-05c2183af252f4cf7, us-east-1
## deleting subnet: subnet-0b5fdecfb0150bea5 in vpc-05c2183af252f4cf7, us-east-1
## deleting subnet: subnet-04327a186077a7afc in vpc-05c2183af252f4cf7, us-east-1
## finally, deleting vpc: vpc-05c2183af252f4cf7 in us-east-1
# deleting vpc: vpc-0f801526be63a681d in us-east-2
## deleting igw: igw-04a0c2d11999bbfc4 in vpc-0f801526be63a681d, us-east-2
--> detatching
--> deleteing
## deleting subnet: subnet-0d9332bd1485482fa in vpc-0f801526be63a681d, us-east-2
## deleting subnet: subnet-0547c362a3359c858 in vpc-0f801526be63a681d, us-east-2
## deleting subnet: subnet-07e3b1951b3240865 in vpc-0f801526be63a681d, us-east-2
## finally, deleting vpc: vpc-0f801526be63a681d in us-east-2
# deleting vpc: vpc-006a9597f9877621e in us-west-1
## deleting igw: igw-037e488ea69fd14cc in vpc-006a9597f9877621e, us-west-1
--> detatching
--> deleteing
## deleting subnet: subnet-05479399c2cac1b38 in vpc-006a9597f9877621e, us-west-1
## deleting subnet: subnet-0adf17ee9c3d34c1d in vpc-006a9597f9877621e, us-west-1
## finally, deleting vpc: vpc-006a9597f9877621e in us-west-1
# deleting vpc: vpc-0e87d631482171d64 in us-west-2
## deleting igw: igw-0ffe7ea7725f95ffe in vpc-0e87d631482171d64, us-west-2
--> detatching
--> deleteing
## deleting subnet: subnet-08959d98b75a130fc in vpc-0e87d631482171d64, us-west-2
## deleting subnet: subnet-0682a444b6953b34e in vpc-0e87d631482171d64, us-west-2
## deleting subnet: subnet-0572b50aae16e68ad in vpc-0e87d631482171d64, us-west-2
## deleting subnet: subnet-08c8079d314a552ba in vpc-0e87d631482171d64, us-west-2
## finally, deleting vpc: vpc-0e87d631482171d64 in us-west-2


3. 事後確認

3.1. EC2 Global Viewでリソース数を見てみる

■ 確認方法

  1. EC2 Global View へアクセスする
  2. 「リソースの概要」「リージョンあたりのリソース数」が表示される


「リソースの概要」を見てみると、17リージョンでリソースが「0」になりました。


3.2. TagEditorで残ってるリソースを確認する

■ 確認方法

  1. TagEditorへアクセスする ※リージョン指定はありません
  2. 「タグ付けするリソースを検索」へ必要事項を入力して「リソースを検索」する
    • リージョン: All regions
    • リソースタイプ: All supported resource types
    • タグ - オプション: 空白のまま
  3. 待つ ※出力には5分ほど時間がかかる
  4. 検索が終わったら「xx resources を CSV にエクスポート」からCSVをダウンロードする
    • ※検証時は「152 → 20」まで減った
  5. CSVは文字コードがUTF-8なので、Excelで開く場合はShift-JISにする


全リージョン分のリソースが出力されています。
デフォルトVPC系リソースが削除され、DHCPオプションのみが残ってることが確認できました。


AWS~自宅ルータNAT経由~YAMAHA RTX810でSite-to-Site VPN接続する

最近、現場でオンプレミスとAWSとのVPN接続を担当することが多くなったのですが、AWS側ばかり担当しているのでオンプレミス側ネットワーク機器の設定があんまり解っていない・・・。

そんなこんなから自宅NetworkでもAWSとVPN接続してみたい、ネットワーク機器側での設定や出力を見てみたいと思い立ち、中古のYAMAHA RTX810を購入してみました!頑張ってVPN接続してみます。

構築方法はGUIとAWS CLIの両方を書くようにしています。


構成図

※IPアドレス等は実際に利用したものを記載しています。VPN構成はもう削除してあるため、リソースはリリース済みです。

目次

検証環境

  • 検証日: 2022/8/27
  • PC環境:
    • Windows10 Home Ver21H1
      • Google Chrome: バージョン: 100.0.4896.127(Official Build) (64 ビット)
  • ネットワーク環境
    • 構成図を参照

注意事項

  • 本記事のAWS CLIは東京リージョンCloudShellで検証しています。
  • コマンド内の変数やパラメータやは検証で使用したものを記載しています。ご自身の環境に合わせ、書き換えて使用してください。
  • 個人で検証しているため実行結果に責任は持てません。必ずご自身でも検証してから使用してください。


1. 自宅Routerの設定

自宅Routerは「NEC Aterm WG2600HS2」を使用しています。
VPN接続に関係のある設定項目だけを記載します。

1.1. 動作モード(WAN側の接続方法)

最初にハマったのですが、我が家では動作モードをIPv6接続の「クロスパス(Xpass)」にしていたため、ポートマッピング機能が使えず、VPN接続ができませんでした。

動作モードを「PPPoEルータ」にすることで、ポートマッピング機能が使えるようになり、VPN接続が使えるようになりました。

・・・ただし、クロスパスの方が通信速度出るのでVPN検証が終わったらクロスパスに戻してます(汗)

www.aterm.jp


1.2. VPNパススルー機能

今回、「AWS ~ 自宅Routerを経由 ~ YAMAHA RTX810」でVPNを接続するため、自宅RouterでVPNパススルーが有効になっている必要があります。

ただ、自宅Routerの「NEC Aterm WG2600HS2」ではデフォルトでVPNパススルー機能が有効になっているため、気にする必要はありませんでした。

www.aterm.jp


1.3. ポートマッピング設定

「AWS ~ 自宅Routerを経由 ~ YAMAHA RTX810」でのIPsec接続をするために、自宅Routerでポートマッピング設定(ポート転送)を行う必要があります。

■ 設定方法 URL先の「設定例2」に設定例があります。 www.aterm.jp

■ 追加する転送設定

転送先のLAN側IP プロトコル ポート番号 用途
192.168.0.2 UDP 500 IKE(isakmp)
192.168.0.2 UDP 4500 IPsec NAT-Traversal※1

※1:IPsec - NATトラバーサルとは(仕組み)


1.4. 自宅RouterのGlobal IPは可変です

一般家庭用のひかり回線を利用していますし、流石にそこまでお金掛けたくないので、Global IPは可変です。再起動等で再接続するたびに変わります。

そのため、VPN接続は繋ぎっぱなしにせず、検証のたびに作り直しています。

※この記事はそのための備忘です。


2. AWSの設定

AWS Site-to-Site VPNの設定方法は、AWSドキュメントを参考に作成していきます。

docs.aws.amazon.com

2.1. VPC/サブネット/EC2

下記のAWSリソースは作成済みのものを利用。

AWSリソース Name CIDR/IP 用途
VPC blog-P1x-Vpc 10.0.0.0/16
サブネット blog-P1a-Sub-Pub01 10.0.11.0/24 パブリック
ルートテーブル blog-P1x-Rtb-Pub01 パブリック
EC2 blog-P1a-Ec2-Nat-NatServer 10.0.11.4 NATインスタンス


2.2. カスタマーゲートウェイを作成する

最初、「カスタマーゲートウェイ」って何?となったのですが、「AWSから見てVPN接続する対向ネットワーク機器の情報を入力するとこ」が自分の中でしっくり来ました。

今回は「自宅Networkの YAMAHA RTX810」が該当します。

■ 作成するAWSリソース

AWSリソース Name 用途
カスタマーゲートウェイ blog-P1x-Cgw-RTX810 VPN接続するルータの情報

■ 作成方法

  1. 東京リージョン > VPC > カスタマーゲートウェイ
  2. 「カスタマーゲートウェイを作成」をクリックする
  3. パラメータを入力して作成する
    • 名前タグ: blog-P1x-Cgw-RTX810
    • BGP ASN: 64513
    • IP アドレス: a.a.a.a ※自宅RouterのWAN側Global IP
    • デバイス - オプション: YAMAHA RTX810

■ (参考) 東京リージョンCloudShell AWS CLIコマンド

create-customer-gateway — AWS CLI 2.7.27 Command Reference

describe-customer-gateways — AWS CLI 2.7.27 Command Reference

## 作成
cgw_name="blog-P1x-Cgw-RTX810"
bgp_asn_cgw="64513"  #YAMAHA RTX810側のAS番号
jitaku_ip_address="122.208.220.101"  #自宅RouterのWAN側Global IP
device_name="YAMAHA RTX810"  #オプション - 機器名

aws ec2 create-customer-gateway \
    --region "ap-northeast-1" \
    --bgp-asn "${bgp_asn_cgw}" \
    --ip-address "${jitaku_ip_address}" \
    --type "ipsec.1" \
    --device-name "${device_name}" \
    --tag-specifications "ResourceType=customer-gateway, \
        Tags=[{Key=Name,Value=${cgw_name}}]"


## 確認(NameタグでFilter)
cgw_name="blog-P1x-Cgw-RTX810"

aws ec2 describe-customer-gateways \
    --filters \
        "Name=state,Values=available" \
        "Name=tag:Name,Values=${cgw_name}"


2.3. ターゲットゲートウェイを作成する

ターゲットゲートウェイと言われると「AWSから見て対向のネットワーク機器??」と思ってしまいましたが、「仮想プライベートゲートウェイ」や「Transit Gateway 」のことです。・・・わかりづらい(汗)

今回は「仮想プライベートゲートウェイ」を使用するので、作成していきます。

2.3.1. 仮想プライベートゲートウェイの作成

■ 作成するAWSリソース

AWSリソース Name 用途
仮想プライベートゲートウェイ blog-P1x-Vgw VPN接続するAWS側のルータみたいなもの

■ 作成方法

  1. 東京リージョン > VPC > 仮想プライベートゲートウェイ
  2. 「仮想プライベートゲートウェイを作成」をクリックする
  3. パラメータを入力して作成する
    • 名前タグ: blog-P1x-Vgw
    • 自律システム番号 (ASN): カスタム ASN
    • カスタム ASN の入力: 64512

■ (参考) 東京リージョンCloudShell AWS CLIコマンド

create-vpn-gateway — AWS CLI 2.7.27 Command Reference

describe-vpn-gateways — AWS CLI 2.7.27 Command Reference

## 作成
vgw_name="blog-P1x-Vgw"
bgp_asn_vgw="64512"  #AWS側のAS番号

aws ec2 create-vpn-gateway \
    --region "ap-northeast-1" \
    --type "ipsec.1" \
    --amazon-side-asn ${bgp_asn_vgw} \
    --tag-specifications "ResourceType=vpn-gateway, \
        Tags=[{Key=Name,Value=${vgw_name}}]"

## 確認(NameタグでFilter)
vgw_name="blog-P1x-Vgw"

aws ec2 describe-vpn-gateways \
    --filters \
        "Name=state,Values=available" \
        "Name=tag:Name,Values=${vgw_name}"


2.3.2. VPCへアタッチ

作成した仮想プライベートゲートウェイは、VPCに接続(アタッチ)しないと使用できないので、アタッチします。

■ 対象AWSリソース

AWSリソース Name
VPC blog-P1x-Vpc
仮想プライベートゲートウェイ blog-P1x-Vgw

■ アタッチ方法

  1. 東京リージョン > VPC > 仮想プライベートゲートウェイ
  2. 作成した仮想プライベートゲートウェイを選択する
  3. アクション > VPCへアタッチ
  4. 「使用可能な VPC」からアタッチ対象のVPCを選択してアタッチする

■ (参考) 東京リージョンCloudShell AWS CLIコマンド

## NameタグからIDの取得
vpc_name="blog-P1x-Vpc"
vgw_name="blog-P1x-Vgw"

vpc_id=$(aws ec2 describe-vpcs \
    --filters "Name=tag:Name,Values=${vpc_name}" \
    --query "Vpcs[].VpcId" \
    --output text) \
    && echo ${vpc_id}

vgw_id=$(aws ec2 describe-vpn-gateways \
    --filters \
        "Name=state,Values=available" \
        "Name=tag:Name,Values=${vgw_name}" \
    --query "VpnGateways[].VpnGatewayId" \
    --output text) \
    && echo ${vgw_id}

## VPCへアタッチ
aws ec2 attach-vpn-gateway \
    --vpc-id ${vpc_id} \
    --vpn-gateway-id ${vgw_id}


2.4. ルーティングを設定する

ルーティングを動的(BGP)にする場合、BGPで受信したルート情報をルートテーブルに載せるためには「ルート伝搬をON」にする必要があります。

今回は、既存のルートテーブルを使用するので、そちらの設定を変更します。

■ 対象AWSリソース

AWSリソース Name 備考
ルートテーブル blog-P1x-Rtb-Pub01 ルート伝播の有効化
仮想プライベートゲートウェイ blog-P1x-Vgw AWS CLIで指定

■ 設定変更方法

  1. 東京リージョン > VPC > ルートテーブル
  2. 対象のルートテーブルを選択する
  3. 「ルート伝播」タブを選択する
  4. 「ルート伝播の編集」をクリックする
  5. 「伝播」を有効化して保存する

■ (参考) 東京リージョンCloudShell AWS CLIコマンド

enable-vgw-route-propagation — AWS CLI 2.7.27 Command Reference

describe-route-tables — AWS CLI 2.7.27 Command Reference

## NameタグからIDの取得
vgw_name="blog-P1x-Vgw"
rtb_name="blog-P1x-Rtb-Pub01"

vgw_id=$(aws ec2 describe-vpn-gateways \
    --filters \
        "Name=state,Values=available" \
        "Name=tag:Name,Values=${vgw_name}" \
    --query "VpnGateways[].VpnGatewayId" \
    --output text) \
    && echo ${vgw_id}

rtb_id=$(aws ec2 describe-route-tables \
    --filters "Name=tag:Name,Values=${rtb_name}" \
    --query "RouteTables[].RouteTableId" \
    --output text) \
    && echo ${rtb_id}

## ルート伝播の有効化
aws ec2 enable-vgw-route-propagation \
    --gateway-id ${vgw_id} \
    --route-table-id ${rtb_id}


2.5. セキュリティグループを更新する

環境によって設定内容が異なるため、詳細は割愛します。

今回は、「EC2 NATインスタンス」へ「自宅Network 172.16.0.0/24 からのHTTP & HTTPS通信」をインバウンド許可しました。


2.6. Site-to-Site VPN 接続の作成

注意!お金掛かります、結構高い!使い終わったら削除。
VPN 1本、 0.048USD / 時間(月730H稼働で 35USD、為替137円で約4,800円)

VPN接続のトンネルオプションですが、AWS側では色々なパラメータ候補がデフォルトで設定されていて、カスタマーゲートウェイ側の設定に合わせたものをNegotiationして選択されるようです。
ただし、どのトンネルパラメータが選択されているかはAWS側で分からないため、カスタマーゲートウェイ側の機器での確認が必要です。

AWS側で利用可能なトンネルオプションはこちらのリンクを参照。

Site-to-Site VPN 接続のトンネルオプション - AWS Site-to-Site VPN

■ 作成するAWSリソース

AWSリソース Name 用途
VPN接続 blog-P1x-Vpn-RTX810

|仮想プライベートゲートウェイ|blog-P1x-Vgw|AWS CLIで指定| |カスタマーゲートウェイ|blog-P1x-Cgw-RTX810|VPN接続するルータの情報|

■ 作成方法

  1. 東京リージョン > VPC > Site-to-Site VPN 接続
  2. 「VPN接続を作成する」をクリックする
  3. パラメータを入力して作成する
    • 名前タグ: blog-P1x-Vpn-RTX810
    • ターゲットゲートウェイのタイプ: 仮想プライベートゲートウェイ
    • 仮想プライベートゲートウェイ: blog-P1x-Vgw を選択
    • カスタマーゲートウェイ: 既存
    • カスタマーゲートウェイ ID: blog-P1x-Cgw-RTX810 を選択
    • ルーティングオプション: 動的 (BGP が必要)

■ (参考) 東京リージョンCloudShell AWS CLIコマンド

create-vpn-connection — AWS CLI 2.7.27 Command Reference

modify-vpn-tunnel-options — AWS CLI 2.7.27 Command Reference

describe-vpn-connections — AWS CLI 2.7.27 Command Reference

## 変数
vpn_name="blog-P1x-Vpn-RTX810"
vgw_name="blog-P1x-Vgw"
cgw_name="blog-P1x-Cgw-RTX810"

## IDの取得
vgw_id=$(aws ec2 describe-vpn-gateways \
    --filters \
        "Name=state,Values=available" \
        "Name=tag:Name,Values=${vgw_name}" \
    --query "VpnGateways[].VpnGatewayId" \
    --output text) \
    && echo ${vgw_id}

cgw_id=$(aws ec2 describe-customer-gateways \
    --filters \
        "Name=state,Values=available" \
        "Name=tag:Name,Values=${cgw_name}" \
    --query "CustomerGateways[].CustomerGatewayId" \
    --output text) \
    && echo ${cgw_id}

## VPN作成
aws ec2 create-vpn-connection \
    --vpn-gateway-id ${vgw_id} \
    --customer-gateway-id ${cgw_id} \
    --type "ipsec.1" \
    --tag-specifications "ResourceType=vpn-connection, \
        Tags=[{Key=Name,Value=${vpn_name}}]"

## 確認
vpn_name="blog-P1x-Vpn-RTX810"

aws ec2 describe-vpn-connections \
    --no-cli-pager \
    --filters \
        "Name=state,Values=available" \
        "Name=tag:Name,Values=${vpn_name}"


2.7. 設定ファイルをダウンロードする

VPN設定を行った後、カスタマーゲートウェイ側ネットワーク機器用にサンプル設定ファイルをダウンロードできるようになります 。

■ 設定ファイルの取得方法

  1. 東京リージョン > VPC > Site-to-Site VPN 接続
  2. 対象のVPNを選択する
  3. 「設定をダウンロードする」をクリックする
  4. サンプルが欲しい機器情報を入力してダウンロードする
    • 今回は「Yamaha」「ikev2」を指定してダウンロード

■ 設定ファイルを出力できるベンダー/機器

こちらのAWSドキュメントを参考にしてください。

docs.aws.amazon.com

他にはAWS CLIで一覧を出力することも可能です。

aws ec2 get-vpn-connection-device-types --output table


2.8. (任意) 新機能、VPNログ記録の有効化

AWSドキュメントの手順外ですが、最近のアップデートでVPN接続のログが取得できるようになったようです。
これまで、ログが取れないから状態分からない、、、と嘆いていたのが過去になるのか!?

dev.classmethod.jp


2.8.1. CloudWatch Logsロググループの作成

CloudWatch Logsへログ保存できるとのことなので、専用にロググループを作成します。
ロググループは保管料が掛かるので、14日経ったら古いログが消えるようにしておきます。

■ 作成するAWSリソース

AWSリソース Name ログ保持期間 用途
ロググループ /aws/blog-P1x-Vpc/vpnlogs 14日 VPN接続ログの保存

■ 作成方法

  1. 東京リージョン > CloudWatch > ログ > ロググループ
  2. 「ロググループを作成」をクリックする
  3. パラメータを入力して作成する
    • ロググループ名: /aws/blog-P1x-Vpc/vpnlogs
    • 保持期間の設定: 2週間(14日間)
    • タグ: {Name: /aws/blog-P1x-Vpc/vpnlogs}

■ (参考) 東京リージョンCloudShell AWS CLIコマンド

# 変数
cwl_name="/aws/blog-P1x-Vpc/vpnlogs"
retention_days="14"   #選択値: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653

# 作成
aws logs create-log-group \
    --log-group-name "${cwl_name}" \
    --tags "Name=${cwl_name}"

# ログ保持期間の設定(今回は14日間)
aws logs put-retention-policy \
    --log-group-name "${cwl_name}" \
    --retention-in-days "${retention_days}"

# 確認
aws logs describe-log-groups \
    --log-group-name-prefix "${cwl_name}"


2.8.2. VPNログ記録の有効化

■ 有効化の方法(設定変更)

Tunnel 1本毎に設定変更が必要なので、下記を2本分実行します。

  1. 東京リージョン > VPC > Site-to-Site VPN 接続
  2. 対象のVPN接続を選択する
  3. アクション > VPNトンネルオプションを変更する
  4. 「IP アドレス外の VPN トンネル」で2つIPアドレスが表示されるので1本目を選択
  5. パラメータを入力して変更を保存する
    • トンネルアクティビティログ: ■ 有効化
    • Amazon CloudWatch ロググループ: /aws/blog-P1x-Vpc/vpnlogs
    • 出力形式: json or テキスト ※お好みで選択

■ (参考) 東京リージョンCloudShell AWS CLIコマンド

新しいもの好きで、VPNログ記録をAWS CLIで適用したいがために、めんどくさいコマンドになってます(汗)

最初に、CloudShell AWS CLI v2を最新化する必要がありました。
VPNログ記録は2022/08/19頃?に出てきたばかりのため、そこの部分は最新のAWS CLIじゃないと対応していません。 aws ec2 modify-vpn-tunnel-options helpを打っても、途中にLogOptionsの塊がない場合はAWS CLIが古いです。

検証の時のAWS CLIがaws-cli/2.7.24だったのですが、最新化してaws-cli/2.7.27にしたところ、無事に設定コマンドが通るようになりました。
ただ、CloudShellへ繋ぐたびにVersionが戻ってるなぁ、、、。

# ----- CloudShell AWS CLI v2の最新化 -----
aws --version

cd /tmp
curl -s "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip -q awscliv2.zip
sudo ./aws/install --update
cd ~

aws --version



# ----- VPNログ記録 -----

# ※VPNのステータスが「available」になってから実施すること

## 変数
vpn_name="blog-P1x-Vpn-RTX810"
cwl_name="/aws/blog-P1x-Vpc/vpnlogs"

## VPN-IDの取得
vpn_id=$(aws ec2 describe-vpn-connections \
    --filters \
        "Name=state,Values=available" \
        "Name=tag:Name,Values=${vpn_name}" \
    --query "VpnConnections[].VpnConnectionId" \
    --output text) \
    && echo ${vpn_id}

## CloudWatch Logs ロググループのARNを取得
## ※そのままARNを取得すると末尾の「:*」が邪魔なので消しています。
cwl_arn=$(aws logs describe-log-groups \
    --log-group-name-prefix "${cwl_name}" \
    --query "logGroups[].arn" \
    --output text)
cwl_arn=$(echo "${cwl_arn}" | sed -e "s/\:\*//") && echo "${cwl_arn}"


## Tunnelの外部IPアドレスを取得
tunnel1_outside_ip=$(aws ec2 describe-vpn-connections \
    --filters \
        "Name=state,Values=available" \
        "Name=tag:Name,Values=${vpn_name}" \
    --query "VpnConnections[].Options[].TunnelOptions[0].OutsideIpAddress" \
    --output text) \
    && echo ${tunnel1_outside_ip}

tunnel2_outside_ip=$(aws ec2 describe-vpn-connections \
    --filters \
        "Name=state,Values=available" \
        "Name=tag:Name,Values=${vpn_name}" \
    --query "VpnConnections[].Options[].TunnelOptions[1].OutsideIpAddress" \
    --output text) \
    && echo ${tunnel2_outside_ip}

## VPNログ記録を追加
## ※AWS CLI v2の最新化が必要
## ※ダブルクォーテーションの入れ子の書き方で迷った・・・(汗)
### Tunnel 1 側
aws ec2 modify-vpn-tunnel-options \
    --no-cli-pager \
    --vpn-connection-id "${vpn_id}" \
    --vpn-tunnel-outside-ip-address "${tunnel1_outside_ip}" \
    --tunnel-options "LogOptions={CloudWatchLogOptions={LogEnabled=true,LogGroupArn=\"${cwl_arn}\",LogOutputFormat=json}}"


#  ※連続で設定はできません。VPNのステータスが「available」になってから実施すること


### Tunnel 2 側
aws ec2 modify-vpn-tunnel-options \
    --no-cli-pager \
    --vpn-connection-id "${vpn_id}" \
    --vpn-tunnel-outside-ip-address "${tunnel2_outside_ip}" \
    --tunnel-options "LogOptions={CloudWatchLogOptions={LogEnabled=true,LogGroupArn=\"${cwl_arn}\",LogOutputFormat=json}}"

## 確認
vpn_name="blog-P1x-Vpn-RTX810"

aws ec2 describe-vpn-connections \
    --no-cli-pager \
    --filters \
        "Name=state,Values=available" \
        "Name=tag:Name,Values=${vpn_name}"


3. YAMAHA RTX810の設定

3.1. VPN設定追加前のshow config

基本的な設定だけの状態から開始します。
※YAMAHA初心者の簡易設定だけです(汗)

# show config
# RTX810 Rev.11.01.34 (Tue Nov 26 18:39:12 2019)
# MAC Address : ac:44:f2:aa:aa:aa, ac:44:f2:bb:bb:bb
# Memory 128Mbytes, 2LAN
# main:  RTX810 ver=00 serial=S3K3***** MAC-Address=ac:44:f2:aa:aa:aa MAC-Address=ac:44:f2:bb:bb:bb
# Reporting Date: Aug 28 13:49:32 2022
login user testuser*
console columns 150
console lines infinity
console prompt vpn-router
login timer 3600
ip route default gateway 192.168.0.1
ip lan1 address 172.16.0.1/24
ip lan2 address 192.168.0.2/24
provider lan1 name LAN:naibu
provider lan2 name WAN:gateway
telnetd host lan
dns server 1.1.1.1
sshd service on
sshd host key generate *


3.2. 先ずはAWSからダウンロードした設定を投入

AWSからダウンロードしたままの設定をそのまま使用したあと、変更が必要な箇所の変更を行います。

  1. ターミナルソフトでYAMAHA RTX810へ接続し、Administratorにログインする
  2. ダウンロードしたテキストファイルをエディタで開く
  3. Ctrl + A (全選択)
  4. Ctrl + C (コピー)
  5. ターミナルソフトへ戻り、コピーした設定を丸ごと貼り付ける
    • 設定ファイル内の説明書き等は「#」でコメントアウトされているのでそのまま貼り付けることができます。


3.3. 変更が必要な箇所の修正

3.3.1. ポート転送しているのでLocal IPアドレス書き換え

今回、自宅側が自宅Routerでポート転送して、YAMAHA RTX810とVPN接続するため、Local IPアドレス部分の書き換えが必要です。

今回で言うと「自宅RouterのGlobal IP」で設定されている箇所を「YAMAHA RTX810のLAN2(WAN)」に変更です。

## 変更対象 ※「自宅RouterのGlobal IP」の箇所
~~~途中略~~~
ipsec ike local address 1 <自宅RouterのGlobal IP>
ipsec ike local name 1 <自宅RouterのGlobal IP> ipv4-addr
~~~途中略~~~
ipsec ike local address 2 <自宅RouterのGlobal IP>
ipsec ike local name 2 <自宅RouterのGlobal IP> ipv4-addr
~~~途中略~~~

## 変更コンフィグ ※「YAMAHA RTX810のLAN2(WAN)」に変更
## ※上書き可能なので、no コマンド不要
ipsec ike local address 1 192.168.0.2
ipsec ike local name 1 192.168.0.2 ipv4-addr

ipsec ike local address 2 192.168.0.2
ipsec ike local name 2 192.168.0.2 ipv4-addr


3.3.2. (任意) BGPでAWSへ送る経路情報を指定する

AWSの設定ファイルをそのまま設定すると、YAMAHA RTX810からAWSへデフォルトルートの「0.0.0.0/0」を送ります。

自分の環境の問題ですが、AWS側のEC2がNATインスタンスのためインターネットへ接続できるように「0.0.0.0/0 宛先: InternetGateway」を書いてしまっています(汗)

同じプレフィックスのルートが存在する場合の優先度ですが、今回はインターネット向けのルートが「静的」、VPNで追加したルートが「動的」なため前者が勝ってしまい、自宅側と通信できません・・・・。

ルートテーブルを設定する - Amazon Virtual Private Cloud

そのため、YAMAHA RTX810からAWSへは「172.16.0.0/24」のみを送るように書き換えます。

# BGPへ取り込むルートの変更
no bgp import filter 1 equal 0.0.0.0/0
bgp import filter 1 equal 172.16.0.0/24

# 設定の反映
bgp configure refresh

変更後、ルートテーブル側を確認すると「172.16.0.0/24」が伝播されてきたことが分かります。


3.4. VPN設定追加後のshow config

長いので折りたたみます、クリックで展開

# show config
# RTX810 Rev.11.01.34 (Tue Nov 26 18:39:12 2019)
# MAC Address : ac:44:f2:aa:aa:aa, ac:44:f2:bb:bb:bb
# Memory 128Mbytes, 2LAN
# main:  RTX810 ver=00 serial=S3K3***** MAC-Address=ac:44:f2:aa:aa:aa MAC-Address=ac:44:f2:bb:bb:bb
# Reporting Date: Aug 28 14:21:33 2022
login user toyokky *
console columns 150
console lines infinity
console prompt vpn-router
login timer 3600
ip route default gateway 192.168.0.1
ip lan1 address 172.16.0.1/24
ip lan2 address 192.168.0.2/24
provider lan1 name LAN:naibu
provider lan2 name WAN:gateway
tunnel select 1
 ipsec tunnel 201
  ipsec sa policy 201 1 esp aes-cbc sha-hmac
  ipsec ike version 1 2
  ipsec ike duration ipsec-sa 1 3600
  ipsec ike duration isakmp-sa 1 28800
  ipsec ike encryption 1 aes-cbc
  ipsec ike group 1 modp1024
  ipsec ike hash 1 sha
  ipsec ike keepalive use 1 on rfc4306 10 3
  ipsec ike local address 1 192.168.0.2
  ipsec ike local name 1 192.168.0.2 ipv4-addr
  ipsec ike pfs 1 on
  ipsec ike message-id-control 1 on
  ipsec ike child-exchange type 1 2
  ipsec ike pre-shared-key 1 *
  ipsec ike remote address 1 3.113.97.185
  ipsec ike remote name 1 3.113.97.185 ipv4-addr
  ipsec ike negotiation receive 1 off
 ipsec tunnel outer df-bit clear
 ip tunnel address 169.254.26.82/30
 ip tunnel remote address 169.254.26.81
 ip tunnel tcp mss limit auto
 tunnel enable 1
tunnel select 2
 ipsec tunnel 202
  ipsec sa policy 202 2 esp aes-cbc sha-hmac
  ipsec ike version 2 2
  ipsec ike duration ipsec-sa 2 3600
  ipsec ike duration isakmp-sa 2 28800
  ipsec ike encryption 2 aes-cbc
  ipsec ike group 2 modp1024
  ipsec ike hash 2 sha
  ipsec ike keepalive use 2 on rfc4306 10 3
  ipsec ike local address 2 192.168.0.2
  ipsec ike local name 2 192.168.0.2 ipv4-addr
  ipsec ike pfs 2 on
  ipsec ike message-id-control 2 on
  ipsec ike child-exchange type 2 2
  ipsec ike pre-shared-key 2 *
  ipsec ike remote address 2 35.79.134.19
  ipsec ike remote name 2 35.79.134.19 ipv4-addr
  ipsec ike negotiation receive 2 off
 ipsec tunnel outer df-bit clear
 ip tunnel address 169.254.81.50/30
 ip tunnel remote address 169.254.81.49
 ip tunnel tcp mss limit auto
 tunnel enable 2
bgp use on
bgp autonomous-system 64513
bgp neighbor 1 64512 169.254.26.81 hold-time=30 local-address=169.254.26.82
bgp neighbor 2 64512 169.254.81.49 hold-time=30 local-address=169.254.81.50
bgp import filter 1 equal 172.16.0.0/24
bgp import 64512 static filter 1
ipsec use on
ipsec auto refresh on
telnetd host lan
dns server 1.1.1.1
sshd service on
sshd host key generate *


4. 接続確認

4.1. AWS側:GUIで確認

  1. 東京リージョン > VPC > Site-to-Site VPN 接続
  2. 対象のVPN接続を選択する
  3. 「トンネルの詳細」タブを選択し、トンネルの状態でステータスが「Up」であることを確認する

4.2. AWS側:VPNログ記録で確認

「2.8. (任意) 新機能、VPNログ記録の有効化」で機能を有効化している場合は、こういったログが見れるようです。
IKEが「established"」しているのが分かります。


4.3. YAMAHA RTX810側:showコマンド

検証の時に使用した確認コマンドを載せます。

# TunnelやIPsecの確認
show status tunnel 1
show status tunnel 2
show ipsec sa
show ipsec sa gateway 1 detail
show ipsec sa gateway 2 detail

# ルート情報の確認
show ip route

# BGPの確認
show status bgp neighbor
show status bgp neighbor | grep "BGP neighbor is"
show status bgp neighbor <IP_ADDRESS> received-routes
show status bgp neighbor <IP_ADDRESS> advertised-routes


4.4. クライアントPCからEC2へPing確認

試験用にPCを用意するのが面倒で、Pingだけできれば良いと思いCisco 892ルータを代替で使用しました。

VPN接続により、クライアントPCからEC2へPing疎通することを確認しました。

AWS CLI: VPC機能でAWSリソース間の通信可否を分析する(Reachability Analyzer)

AWSリソース間で通信ができるのかどうか確認できるVPC機能で、Reachability Analyzerがあります。通信経路上のセキュリティグループやネットワークACLの穴開け忘れ等が確認できる機能です。

職場でAWSのネットワークや通信制御を担当しているため、マネジメントコンソールからポチポチと利用していたのですが、「あれ、CLI化できるのでは?」と思い立ち、AWSCLI化してみました。


本記事では以下の内容をPowerShell+AWSCLIで行っています。

  • EC2インスタンス~EC2インスタンスでの通信可否を確認
    1. パスの作成(送信元と送信先を指定する)
    2. 作成したパスを使って、分析を実行する
    3. 分析結果から、通信可能か否かを確認する
    4. 分析結果の詳細をマネジメントコンソールで確認する

パス・・・送信元リソース、送信先リソース、送信先ポート番号を予め決めておく設定です。
分析・・・作成したパスを使って通信経路の分析を行い、通信可否や問題点を表示してくれます。


※Reachability Analyzer自体の説明は省略していますので、どのような機能か確認したい場合はこちらの記事などを確認してみてください。
AWSブログ: VPC Reachability Analyzer


ちなみにですが、分析を1回行うと「$ 0.1」掛かるので、使いすぎ注意です(汗)

目次

検証環境

  • 検証日: 2022/07/02
  • PC環境:
    • Windows10 Home Ver21H1
      • PowerShell: Ver7.1.5
      • AWS CLI: aws-cli/2.7.12 Python/3.9.11 Windows/10 exe/AMD64 prompt/off
        • region : ap-northeast-1
        • output : yaml
        • cli_pager : " "
        • profile
          • default : 読み取り専用
          • aws_RW : 書き込み権限あり
            • ※ 誤操作防止のため、変更操作時のみ-- profileオプション付与。
          • aws_PF : SystemsManagerポートフォワーディング用

注意事項

  • 本記事の内容はWindows PowerShellで検証しています。
  • AWS CLIはバージョン2を使用しています。
    • 本記事のコマンド出力でYAMLを使用してますが、これはバージョン2の機能です。
  • コマンド内の変数やパラメータやは検証で使用したものを記載しています。ご自身の環境に合わせ、書き換えて使用してください。
  • 個人で検証しているため実行結果に責任は持てません。必ずご自身でも検証してから使用してください。


1. VPC Reachability AnalyzerをAWS CLIで使用する

1.1. パスの作成(送信元と送信先を指定する)

コマンドリファレンス: create-network-insights-path

## 変数部分 ※環境ごとに修正が必要
${profile}             = "aws_RW" # Create操作のため、書き込み権限を指定。
${ec2_id_source}       = "i-1234567890aaaaaaa"  # 送信元 EC2インスタンスID
${ec2_id_destination}  = "i-1234567890bbbbbbb"  # 送信先 EC2インスタンスID
${protocol}            = "TCP" # TCP or UDP
${destination_port}    = "22"  # 疎通確認したいPort番号
${path_name_tag}       = "ServerA_to_ServerB_Port22" # 作成するパスにNameタグを付ける

## パスの作成、送信元と送信先を指定する
aws ec2 create-network-insights-path `
    --profile ${profile} `
    --source ${ec2_id_source} `
    --destination ${ec2_id_destination} `
    --protocol ${protocol} `
    --destination-port ${destination_port} `
    --tag-specifications "ResourceType=network-insights-path, `
            Tags=[{Key=Name,Value=${path_name_tag}}]"

## <出力例>
NetworkInsightsPath:
  CreatedDate: '2022-07-02T04:15:05.058000+00:00'
  Destination: i-1234567890bbbbbbb
  DestinationPort: 22
  NetworkInsightsPathArn: arn:aws:ec2:ap-northeast-1:123456789012:network-insights-path/nip-0ce505740fb1267bb
  NetworkInsightsPathId: nip-0ce505740fb1267bb
  Protocol: tcp
  Source: i-1234567890aaaaaaa
  Tags:
  - Key: Name
    Value: ServerA_to_ServerB_Port22


1.2. 作成したパスを使って、分析を実行する

コマンドリファレンス: start-network-insights-analysis

## 変数部分 ※環境ごとに修正が必要
${profile}       = "aws_RW" # Start操作のため、書き込み権限を指定。
${path_name_tag} = "ServerA_to_ServerB_Port22" # 作成するパスにNameタグを付ける

## Nameタグを使って、作成したパスのIDを変数へ格納する
${path_id} = aws ec2 describe-network-insights-paths `
    --filters "Name=tag:Name,Values=${path_name_tag}" `
    --query "NetworkInsightsPaths[].NetworkInsightsPathId" `
    --output text `
    ;${path_id}

## パスIDを指定して分析を実行する
aws ec2 start-network-insights-analysis `
    --profile ${profile} `
    --network-insights-path-id ${path_id}

## <出力例>
NetworkInsightsAnalysis:
  NetworkInsightsAnalysisArn: arn:aws:ec2:ap-northeast-1:123456789012:network-insights-analysis/nia-0f13e9806754cda0b
  NetworkInsightsAnalysisId: nia-0f13e9806754cda0b
  NetworkInsightsPathId: nip-0ce505740fb1267bb
  StartDate: '2022-07-02T04:26:46.307000+00:00'
  Status: running


1.3. 分析結果から、通信可能か否かを確認する

1つのパスを使って何度も分析することができるため、1つのパスの中に複数の分析結果が残ります。
そのため、パスIDを指定して分析結果をdescribeすると、複数の結果が出てしまうのが難点です。

本記事では、パスIDの分析結果の中から「最新の1つのみ」の情報を抜き出すように記載しています。
※コマンド内の「reverse(sort_by(NetworkInsightsAnalyses, &StartDate))[0]」で実現。

コマンドリファレンス: describe-network-insights-paths

## 分析の結果だけ確認したい場合
aws ec2 describe-network-insights-analyses `
    --network-insights-path-id ${path_id} `
    --query "reverse(sort_by(NetworkInsightsAnalyses, &StartDate))[0].NetworkPathFound" `
    --output text

## 出力結果を確認する
  # True    ・・・OK, AWSリソース間は通信可能
  # False   ・・・NG, AWSリソース間は通信不可


## 詳細を見たい場合、、、ただ、長くて見づらいのでオススメはしません。
aws ec2 describe-network-insights-analyses `
    --network-insights-path-id ${path_id} `
    --query "reverse(sort_by(NetworkInsightsAnalyses, &StartDate))[0]" `


1.4. 分析結果の詳細をマネジメントコンソールで確認する

describeで表示された結果を加工して、通信経路等を調べようと思ったのですが、、、、諦めました。
結果を解析するよりもマネジメントコンソールから見たほうが通信経路や失敗箇所を見やすいので、そちらで確認することをおすすめします。

デフォルトブラウザで分析結果を表示するコマンドを記載します。

## URL内に分析IDを埋め込むので、分析IDを変数へ格納する
## ※パスのNameタグを使って、パスID取得、分析ID取得します。
${path_name_tag} = "ServerA_to_ServerB_Port22"

${path_id} = aws ec2 describe-network-insights-paths `
    --filters "Name=tag:Name,Values=${path_name_tag}" `
    --query "NetworkInsightsPaths[].NetworkInsightsPathId" `
    --output text `
    ;${path_id}

${analyses_id} = aws ec2 describe-network-insights-analyses `
    --network-insights-path-id ${path_id} `
    --query "reverse(sort_by(NetworkInsightsAnalyses, &StartDate))[0].NetworkInsightsAnalysisId" `
    --output text `
    ;${analyses_id}

## デフォルトブラウザで分析結果を表示する
## ※東京リージョン指定しています。別リージョンの場合はリージョンコード部分を変更してください。
Start-Process "https://ap-northeast-1.console.aws.amazon.com/vpc/home?region=ap-northeast-1#NetworkPathAnalysis:analysisId=${analyses_id}"


2. 参考にさせていただいた記事

aws.amazon.com

PowerShell: コマンドでJST(現在/指定時刻)からUST世界標準時に変換する

AWS CLIでコマンドを作っていると、UTCやJSTのタイムゾーンが混じってて泣くことがあります。。。
毎回毎回、JSTからUTCへの変換を電卓やWebサイトを使って行っていたのですが、、、流石に効率が悪いので、PowerShellでの変換方法を調べてみました。

目次

検証環境

  • 検証日: 2022/06/25
  • PC環境:
    • Windows10 Home Ver21H1
      • PowerShell: Ver7.1.5
      • AWS CLI: aws-cli/2.1.34 Python/3.8.8 Windows/10 exe/AMD64 prompt/off
        • -- profile default : 読み取り専用
        • -- profile aws_RW : 書き込み権限あり
          • ※ 誤操作防止のため、変更操作時のみ-- profileオプション付与。
        • -- profile aws_PF : SystemsManagerポートフォワーディング用

注意事項

  • 本記事の内容はWindows PowerShellで検証しています。
  • AWS CLIはバージョン2を使用しています。
    • 本記事のコマンド出力でYAMLを使用してますが、これはバージョン2の機能です。
  • コマンド内の変数やパラメータやは検証で使用したものを記載しています。ご自身の環境に合わせ、書き換えて使用してください。
  • 個人で検証しているため実行結果に責任は持てません。必ずご自身でも検証してから使用してください。


1. PCのタイムゾーンを確認する

僕は日本在住なので、タイムゾーンは東京(JST, GMT+9)です。

Get-TimeZone

## 出力例
PS C:\Users\blotoyo> Get-TimeZone

Id                         : Tokyo Standard Time
DisplayName                : (UTC+09:00) 大阪、札幌、東京
StandardName               : 東京 (標準時)
DaylightName               : 東京 (夏時間)
BaseUtcOffset              : 09:00:00
SupportsDaylightSavingTime : False


2. JST(現在時刻)をUTCで出力する

2.1. 現在時刻をUTCに変換して出力する

  • Get-Dateコマンドレット: 日付・時刻情報を取得する
  • ToUniversalTimeメソッド: Get-Dateの値をUTCに変換する
  • 複数行あるのは出力(整形)のフォーマットを変えています
(Get-Date).ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss")
(Get-Date).ToUniversalTime().ToString("yyyy/MM/dd HH:mm")
(Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mmZ")

## 出力例
PS C:\Users\blotoyo> (Get-Date).ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss")
2022-06-24 22:48:51
PS C:\Users\blotoyo> (Get-Date).ToUniversalTime().ToString("yyyy/MM/dd HH:mm")
2022/06/24 22:48
PS C:\Users\blotoyo> (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mmZ")
2022-06-24T22:48Z

2.2. 現在時刻から-9時間して出力する

  • ToUniversalTimeメソッド: Get-Dateの値に時間数を加減して出力する
  • 複数行あるのは出力(整形)のフォーマットを変えています
Get-Date (Get-Date).AddHours(-9) -format "yyyy/MM/dd HH:mm:ss"
Get-Date (Get-Date).AddHours(-9) -format "yyyyMMdd_HH:mm:ss"
Get-Date (Get-Date).AddHours(-9) -format "yyyy-MM-ddTHH:mmZ"

## 出力例
PS C:\Users\blotoyo> Get-Date (Get-Date).AddHours(-9) -format "yyyy/MM/dd HH:mm:ss"
2022/06/24 23:04:04
PS C:\Users\blotoyo> Get-Date (Get-Date).AddHours(-9) -format "yyyyMMdd_HH:mm:ss"
20220624_23:04:04
PS C:\Users\blotoyo> Get-Date (Get-Date).AddHours(-9) -format "yyyy-MM-ddTHH:mmZ"
2022-06-24T23:04Z


3. JST(指定時刻)をUTCで出力する

  • System.DateTimeへ指定時刻を入れてTypeをDateTimeにし、
  • .AddHours(-9)で-9時間して、
  • .ToStringでフォーマットを修正しています。

※【注意】.AddHours(-9).ToStringの前に持ってくること。
 .ToStringを先にしてしまうとTypeがStringに変わってしまい、.AddHours(-9)が処理出来ない。

([System.DateTime]"2022/06/01 09:00:00").AddHours(-9).ToString("yyyy-MM-dd HH:mm:ss")
([System.DateTime]"2022-06-01 09:00:00").AddHours(-9).ToString("yyyy-MM-ddTHH:mm:ssZ")
([System.DateTime]"2022-06-01 09:00").AddHours(-9).ToString("yyyy/MM/dd HH:mm:ss")

## 出力例
PS C:\Users\blotoyo> ([System.DateTime]"2022/06/01 09:00:00").AddHours(-9).ToString("yyyy-MM-dd HH:mm:ss")
2022-06-01 00:00:00
PS C:\Users\blotoyo> ([System.DateTime]"2022-06-01 09:00:00").AddHours(-9).ToString("yyyy-MM-ddTHH:mm:ssZ")
2022-06-01T00:00:00Z
PS C:\Users\blotoyo> ([System.DateTime]"2022-06-01 09:00").AddHours(-9).ToString("yyyy/MM/dd HH:mm:ss")
2022/06/01 00:00:00


指定時刻部分を変数にしてみる。

${specify_time} = "2022-06-01 09:00"
([System.DateTime]"${specify_time}").AddHours(-9).ToString("yyyy/MM/dd HH:mm:ss")

## 出力例
PS C:\Users\blotoyo> ${specify_time} = "2022-06-01 09:00"
PS C:\Users\blotoyo> ([System.DateTime]"${specify_time}").AddHours(-9).ToString("yyyy/MM/dd HH:mm:ss")
2022/06/01 00:00:00

AWS CLI: PowerShellでパラメータストアの作成/変更/中身だけ出力/比較確認

こちらの記事の続きとなります。

blog.toyokky.com

前回はSystems Manager-パラメータストアを中身を個別ファイル化するだけでしたが、本記事ではパラメータストアの作成/変更も含む内容になっています。


EC2のCloudWatchエージェント設定をSystems Manager-パラメータストアに置いているのですが、実務で40台分ほどのパラメータストア変更があり、流石に手作業での変更は時間とミス防止から無理でしたので、AWS CLIで実行しました。
時間も短縮できましたし、パラメータストア変更前後の中身をWinMergeで比較表示までCLIで出来たため、かなり楽に作業を実施することが出来ました。

目次

検証環境

  • 検証日: 2022/06/19
  • PC環境:
    • Windows10 Home Ver21H1
      • PowerShell: Ver7.1.5
      • AWS CLI: aws-cli/2.1.34 Python/3.8.8 Windows/10 exe/AMD64 prompt/off
        • -- profile default : 読み取り専用
        • -- profile aws_RW : 書き込み権限あり
          • ※ 誤操作防止のため、変更操作時のみ-- profileオプション付与。
        • -- profile aws_PF : SystemsManagerポートフォワーディング用

注意事項

  • 本記事の内容はWindows PowerShellで検証しています。
  • AWS CLIはバージョン2を使用しています。
    • 本記事のコマンド出力でYAMLを使用してますが、これはバージョン2の機能です。
  • コマンド内の変数やパラメータやは検証で使用したものを記載しています。ご自身の環境に合わせ、書き換えて使用してください。
  • 個人で検証しているため実行結果に責任は持てません。必ずご自身でも検証してから使用してください。


1. 事前準備

1.1 jq のインストール

AWSCLIでパラメータストアの中身を書き出すと、改行やTAB等が正規表現でテキスト化されてしまうため、「jq -r」を使用して正規表現から戻します。そのためjqが必要。
公式サイトからexeファイルを落として、リネーム後にPATHが通っているフォルダへ格納すれば使えます。

  1. 公式サイトからWindows用のexeファイルをDownloadする
    • https://stedolan.github.io/jq/
      • 「Download jq 1.6」 > 「Windows(64bit)」の順にクリック
      • ファイル「jq-win64.exe」がDownloadフォルダに格納される
  2. Downloadしたファイルのリネーム
    • 「jq-win64.exe」 > 「jq.exe」
  3. PATHが通っているフォルダへ「jq.exe」を格納する
    • 例: C:\Windows


1.2. WinMerge のインストール

WinMerge 日本語版のサイトからインストーラをダウンロードしてインストールします。

「WinMerge日本語版のサイト > 64bit版ダウンロード > 画面遷移して自動ダウンロードされる」

winmergejp.bitbucket.io


1.3 ファイル出力フォルダの作成

ファイル出力するフォルダを作成します。
C:\#work\AWSCLI\YYYYMMDD-hhmmss\ParameterStore

${LogDir} = "C:\#work\AWSCLI\$(Get-Date -Format yyyyMMdd-HHmmss)" + "\ParameterStore"
New-Item "${LogDir}" -type directory -Force ; Invoke-Item "${LogDir}"

# ※好きなフォルダを指定する場合は「${LogDir}」の中身を変えます。
# `${LogDir} = "C:\Users\aws"`


2. パラメータストアの新規作成

2.1 テスト用のJSONファイル作成

# パラメータストア名、「a-zA-Z0-9_.-」を利用可能。
${param_name} = "Test-param_01"
${parama_version} = "v1"

# インデントをTABにしたいのですが、ヒアドキュメントはTABを削除してしまうため、TABを「`t」にして出力しています。
${json_content} = @"
{
`t"Version": "01",
`t"Content": [
`t`t{
`t`t`t"Key1": "Vlaue1",
`t`t`t"Key2": "Vlaue2"
`t`t}
`t]
}
"@
Write-Output ${json_content} | Out-File -Encoding ascii ${LogDir}\${param_name}_${parama_version}.json


2.2 パラメータストアの作成

${profile} = "aws_RW"

aws ssm put-parameter `
    --profile ${profile} `
    --description "Test Parametor Store." `
    --name "${param_name}" `
    --type "String" `
    --value file://${LogDir}\${param_name}_${parama_version}.json `
    --tags "Key=Name,Value=${param_name}" `
            "Key=Env,Value=Test"


2.3 作成したパラメータストアの中身をJSONファイルで出力する

パラメータストアの中身のみを個別にテキストファイル化(JSON)します。
ファイル名はパラメータストア名です。
AWSCLIで中身を書き出すと、改行やTAB等が正規表現でテキスト化されてしまうため、「jq -r」を使用して正規表現から戻します。

中身に日本語が無いことを想定していますが、日本語を含む場合は文字コードの調整が必要です。

  • 日本語無し(今回): Out-File -Encoding ascii
  • shift-jis: Out-File -Encoding default
  • utf-8(BOM付き): Out-File -Encoding utf8
${param_create} = "${LogDir}\${param_name}_1-create.json"
aws ssm get-parameter --name ${param_name} --output json `
    | jq -r .Parameter.Value `
    | Out-File -Encoding ascii ${param_create}


3. パラメータストアの変更

3.1 変更用のJSONファイル作成

# 既存パラメータストア名を指定。Versionはv2。
${param_name} = "Test-param_01"
${parama_version} = "v2"

# インデントをTABにしたいのですが、ヒアドキュメントはTABを削除してしまうため、TABを「`t」にして出力しています。
${json_content} = @"
{
`t"Version": "02",
`t"Content": [
`t`t{
`t`t`t"Key1": "Vlaue1",
`t`t`t"Key2": "Vlaue2",
`t`t`t"Key3": "Vlaue3"
`t`t}
`t]
}
"@
Write-Output ${json_content} | Out-File -Encoding ascii ${LogDir}\${param_name}_${parama_version}.json


3.2 パラメータストアの変更

${profile} = "aws_RW"

# 上書きはオプション「--overwrite」が必要。
# 変更するオプションを記載する。今回は中身のみ変えるので「--value」を記載。
aws ssm put-parameter `
    --profile ${profile} `
    --name "${param_name}" `
    --overwrite `
    --value file://${LogDir}\${param_name}_${parama_version}.json


3.3 変更したパラメータストアの中身をJSONファイルで出力する

${param_after} = "${LogDir}\${param_name}_2-after.json"
aws ssm get-parameter --name ${param_name} --output json `
    | jq -r .Parameter.Value `
    | Out-File -Encoding ascii ${param_after}


4. WinMergeで作成時と変更後のJSONファイルを比較する

これまでの手順で作成時と変更後で、パラメータストアのJSONファイルを出力していますので、これらの比較確認をWinMergeで行います。

${param_create} = 出力ファイル名: Test-param_01_1-create.json
${param_after} = 出力ファイル名: Test-param_01_2-after.json

# JSONファイルの変数はこれまでの手順で入ってます。

# WinMerge.exe のフルパスを指定。
# インストール型はこのままでOK、ポータブル型は環境に合わせて修正。
${winmerge_exe} = "C:\Program Files\WinMerge\WinMergeU.exe"

# JSONファイルを指定してGUIのWinMergeを開きます。
# 左ペインが作成時、右ペインが変更後。
Start-Process `
    -FilePath "${winmerge_exe}" `
    -ArgumentList "/wl /wr `"${param_create}`" `"${param_after}`""


GUIのWinMergeが開いて、差分を表示します。

AWS CLI: パラメータストアの中身だけを抜き出して個別ファイル化する

EC2のCloudWatchエージェント設定をSystems Manager-パラメータストアに置いているのですが、40台分ほど本文のみを抜き出す作業が発生・・・。
手入力は辛かったのでAWSCLIで実施しました。これはその時の備忘メモです。

やったこと

  • パラメータストアの中身(本文)を個別にテキストファイルとして出力
  • 出力フォルダの作成
  • パラメータスト名でテキストファイル出力

目次

検証環境

  • 検証日: 2022/05/02
  • PC環境:
    • Windows10 Home Ver21H1
      • PowerShell: Ver7.1.5
      • AWS CLI: aws-cli/2.1.34 Python/3.8.8 Windows/10 exe/AMD64 prompt/off
        • -- profile default : 読み取り専用
        • -- profile aws_RW : 書き込み権限あり
          • ※ 誤操作防止のため、変更操作時のみ-- profileオプション付与。
        • -- profile aws_PF : SystemsManagerポートフォワーディング用

注意事項

  • 本記事の内容はWindows PowerShellで検証しています。
  • AWS CLIはバージョン2を使用しています。
    • 本記事のコマンド出力でYAMLを使用してますが、これはバージョン2の機能です。
  • コマンド内の変数やパラメータやは検証で使用したものを記載しています。ご自身の環境に合わせ、書き換えて使用してください。
  • 個人で検証しているため実行結果に責任は持てません。必ずご自身でも検証してから使用してください。


1. jq のインストール

AWSCLIでパラメータストアの中身を書き出すと、改行やTAB等が正規表現でテキスト化されてしまうため、「jq -r」を使用して正規表現から戻します。そのためjqが必要。
公式サイトからexeファイルを落として、リネーム後にPATHが通っているフォルダへ格納すれば使えます。

  1. 公式サイトからWindows用のexeファイルをDownloadする
    • https://stedolan.github.io/jq/
      • 「Download jq 1.6」 > 「Windows(64bit)」の順にクリック
      • ファイル「jq-win64.exe」がDownloadフォルダに格納される
  2. Downloadしたファイルのリネーム
    • 「jq-win64.exe」 > 「jq.exe」
  3. PATHが通っているフォルダへ「jq.exe」を格納する
    • 例: C:\Windows


2. パラメータストアの中身のJSONファイルを個別テキスト化する

2.1 ファイル出力フォルダの作成

ファイル出力するフォルダを作成します。
C:\#work\AWSCLI\YYYYMMDD-hhmmss\ParameterStore

${LogDir} = "C:\#work\AWSCLI\$(Get-Date -Format yyyyMMdd-HHmmss)" + "\ParameterStore"
New-Item "${LogDir}" -type directory -Force ; Invoke-Item "${LogDir}"

# ※好きなフォルダを指定する場合は「${LogDir}」の中身を変えます。
# `${LogDir} = "C:\Users\aws"`


2.2 パラメータストア名の一覧を出力する

aws ssm describe-parameters --query Parameters[].Name

## 出力例(パラメータストア名)
- Parameter01
- Parameter02
- Parameter03


2.3 変数の指定

「2.2」で出力した内容を元に変数を作成する。

${param_name_01} = "Parameter01"
${param_name_02} = "Parameter02"
${param_name_03} = "Parameter03"


2.4 個別でパラメータストアの中身をJSON出力

パラメータストアの中身のみを個別にテキストファイル化(JSON)します。
ファイル名はパラメータストア名です。
AWSCLIで中身を書き出すと、改行やTAB等が正規表現でテキスト化されてしまうため、「jq -r」を使用して正規表現から戻します。

中身に日本語が無いことを想定していますが、日本語を含む場合は文字コードの調整が必要です。

  • 日本語無し(今回): Out-File -Encoding ascii
  • shift-jis: Out-File -Encoding default
  • utf-8(BOM付き): Out-File -Encoding utf8
${param}=${param_name_01} ; aws ssm get-parameter --name ${param} --output json --query Parameter.Value | jq -r | Out-File -Encoding ascii ${LogDir}\${param}.json
${param}=${param_name_02} ; aws ssm get-parameter --name ${param} --output json --query Parameter.Value | jq -r | Out-File -Encoding ascii ${LogDir}\${param}.json
${param}=${param_name_03} ; aws ssm get-parameter --name ${param} --output json --query Parameter.Value | jq -r | Out-File -Encoding ascii ${LogDir}\${param}.json

AWS CLI: CloudWatch Logs ロググループの作成

AWS CLI v2で、CloudWatch Logs の以下操作をするコマンドを記載しています。

  • ロググループの作成とタグ設定
  • ログ保持期間の設定
  • 後からタグだけを追加する
  • ロググループの削除
  • 大量のロググループを一気に作成する時のコマンド例

目次

検証環境

  • 検証日: 2022/04/18
  • PC環境:
    • Windows10 Home Ver21H1
      • PowerShell: Ver7.1.5
      • AWS CLI: aws-cli/2.1.34 Python/3.8.8 Windows/10 exe/AMD64 prompt/off
        • -- profile default : 読み取り専用
        • -- profile aws_RW : 書き込み権限あり
          • ※ 誤操作防止のため、変更操作時のみ-- profileオプション付与。

注意事項

  • 本記事の内容はWindows PowerShellで検証しています。
  • AWS CLIはバージョン2を使用しています。
    • 本記事のコマンド出力でYAMLを使用してますが、これはバージョン2の機能です。
  • コマンド内の変数やパラメータやは検証で使用したものを記載しています。ご自身の環境に合わせ、書き換えて使用してください。
  • 個人で検証しているため実行結果に責任は持てません。必ずご自身でも検証してから使用してください。
  • ★特に注意したいことは赤字で記載★。


1. CloudWatch Logs ロググループ

1.1. ロググループの作成とタグ設定

AWS CLI v2マニュアル: create-log-group

# 変数の指定
${profile}  = "aws_RW"
${cwl_name} = "Test_loggroup"
${tag1} = "tag1-Contents"
${tag2} = "tag2-Contents"

# ロググループの作成とタグ設定
aws logs create-log-group `
    --profile ${profile} `
    --log-group-name ${cwl_name} `
    --tags "Name=${cwl_name}, `
        Tag1=${tag1}, `
        Tag2=${tag2}"


1.2. ログ保持期間の設定

ログ保持期間はロググループの作成と同時にできないため、後から別コマンドで設定します。

AWS CLI v2マニュアル: put-retention-policy

# 変数の指定
${profile}  = "aws_RW"
${cwl_name} = "Test_loggroup"
${retention_days} = "14"
    # 選択値: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653

# ログの保持期間(Retention Policy)の設定
aws logs put-retention-policy `
    --profile ${profile} `
    --log-group-name ${cwl_name} `
    --retention-in-days ${retention_days}


1.3. 設定の確認

AWS CLI v2マニュアル: describe-log-groups

# すべてのロググループを表示する
aws logs describe-log-groups

# ロググループ名を指定して表示する
aws logs describe-log-groups --log-group-name-prefix ${cwl_name}


1.4. 後からタグだけを追加する

AWS CLI v2マニュアル: tag-log-group
AWS CLI v2マニュアル: list-tags-log-group

# 変数の指定
${profile}  = "aws_RW"
${cwl_name} = "Test_loggroup"
${tag3} = "tag3-Contents"

# タグ(Tag3)の追加
aws logs tag-log-group `
    --log-group-name ${cwl_name} `
    --tags "Tag3=${tag3}"

# 確認
aws logs list-tags-log-group --log-group-name ${cwl_name}


1.5. ロググループの削除

AWS CLI v2マニュアル:

# 変数の指定
${profile}  = "aws_RW"
${cwl_name} = "Test_loggroup"

# ロググループの削除
aws logs delete-log-group `
    --profile ${profile} `
    --log-group-name ${cwl_name}


2. 大量のロググループを一気に作成する時のコマンド例

# 変数の指定
${cwl_name_01} = "LogGroup01"
${cwl_name_02} = "LogGroup02"
${cwl_name_03} = "LogGroup03"
${cwl_name_04} = "LogGroup04"
${cwl_name_05} = "LogGroup05"

# ロググループの作成とNameタグの付与
${profile} = "aws_RW"
aws logs create-log-group --profile ${profile} --log-group-name ${cwl_name_01} --tags "Name=${cwl_name_01}"
aws logs create-log-group --profile ${profile} --log-group-name ${cwl_name_02} --tags "Name=${cwl_name_02}"
aws logs create-log-group --profile ${profile} --log-group-name ${cwl_name_03} --tags "Name=${cwl_name_03}"
aws logs create-log-group --profile ${profile} --log-group-name ${cwl_name_04} --tags "Name=${cwl_name_04}"
aws logs create-log-group --profile ${profile} --log-group-name ${cwl_name_05} --tags "Name=${cwl_name_05}"

# ログの保管期間(Retention)設定
${profile} = "aws_RW"
${retention_days} = "14"
aws logs put-retention-policy --profile ${profile} --log-group-name ${cwl_name_01} --retention-in-days ${retention_days}
aws logs put-retention-policy --profile ${profile} --log-group-name ${cwl_name_02} --retention-in-days ${retention_days}
aws logs put-retention-policy --profile ${profile} --log-group-name ${cwl_name_03} --retention-in-days ${retention_days}
aws logs put-retention-policy --profile ${profile} --log-group-name ${cwl_name_04} --retention-in-days ${retention_days}
aws logs put-retention-policy --profile ${profile} --log-group-name ${cwl_name_05} --retention-in-days ${retention_days}

# 作成後の確認
aws logs describe-log-groups --log-group-name-prefix ${cwl_name_01}
aws logs describe-log-groups --log-group-name-prefix ${cwl_name_02}
aws logs describe-log-groups --log-group-name-prefix ${cwl_name_03}
aws logs describe-log-groups --log-group-name-prefix ${cwl_name_04}
aws logs describe-log-groups --log-group-name-prefix ${cwl_name_05}

AWS CLI: AWS CloudShellで操作ログを取得してローカルPCへ保存する

AWS CloudShell で、操作ログを保存して、作業後にローカルPCへダウンロードする方法のメモ。

目次

検証環境

  • 検証日: 2022/01/08
  • PC環境:
    • Windows10 Home Ver21H1
      • Google Chrome: バージョン: 97.0.4692.71(Official Build) (64 ビット))
        • AWSマネジメントコンソールへログイン

注意事項

  • 本記事の内容はAWS CloudShellで検証しています。
  • AWS CloudShell の AWS CLIはバージョン2を使用しています。
  • コマンド内の変数やパラメータやは検証で使用したものを記載しています。ご自身の環境に合わせ、書き換えて使用してください。
  • 個人で検証しているため実行結果に責任は持てません。必ずご自身でも検証してから使用してください。


1. AWS CloudShellでの操作ログ取得

1.1. scriptコマンド

コマンドの書式

script [オプション] [ファイル名]
ターミナルの操作ログを作成するコマンド。
ファイル名無しで実行するとカレントディレクトリへ typescript というファイルが作成され、そこへ記録される。

オプション 説明
-a, --append 既存ファイルへの追記
-f, --flush コマンド実行毎にファイルへ記録する
指定しない場合は最後にまとめて記録する
-T, --log-timing タイムスタンプの追加
-q, --quiet 開始や終了のメッセージを出力しない

参考にさせていただいたWEBサイト

https://linuxjm.osdn.jp/html/util-linux/man1/script.1.html
【script】Linuxで操作ログを記録するコマンド | UX MILK


1.2. 操作ログ取得で実行するコマンド

AWS CloudShell を開いて以下コマンドを実行すると、操作ログが取得開始します。
※開始中はプロンプトが変わり、変数は引き継がれません。

# 変数にログ名を設定
## SAMPLE:  20220108_135500_CloudShell.log
LOGS_NAME="$(TZ=JST-9 date +%Y%m%d_%H%M%S)_CloudShell.log" && echo "${LOGS_NAME}"

# 操作ログの取得開始
script ${HOME}/${LOGS_NAME}

操作ログの取得停止

# 終了するコマンド(または ctrl + d)
exit

操作ログの保存場所PATHの取得

# 操作ログの保存場所(後で Download file する時に使える)
echo "${HOME}/${LOGS_NAME}"

ダウンロード後に操作ログファイルを削除する。

# 操作ログファイルの削除
rm "${HOME}/${LOGS_NAME}"


1.3. 操作ログファイルをダウンロードする

ダウンロードするためには、操作ログファイルのPATHが必要です。 操作ログを終了した時に表示されるのでcopyしておきます。
※SAMPLE: 下記画像の選択範囲

GUI操作で、AWS CloudShell画面右上の[Actions]から[Download file]をクリックする。

操作ログファイルのPATHを入力して[Download]をクリックすると、操作ログファイルがダウンロードされます。


1.4. 操作ログファイルに [m が混ざる場合

ハイライトされた結果の表示やBackspace等の記録が混ざる場合があります。

ここら辺の仕組みがいまいち解っていないので、邪魔な場合はダウンロードしてから正規表現で置換しています。

(例)サクラエディタでの正規表現置換

置換前: \S\[([0-9]{1,2}(;[0-9]{1,2})*)?[mK]
置換後: (空欄)


2. SAMPLE: 操作ログ

[cloudshell-user@ip-10-0-26-82 ~]$ # 変数にログ名を設定
[cloudshell-user@ip-10-0-26-82 ~]$ LOGS_NAME="$(TZ=JST-9 date +%Y%m%d_%H%M%S)_CloudShell.log" && echo "${LOGS_NAME}"
20220108_142606_CloudShell.log
[cloudshell-user@ip-10-0-26-82 ~]$ 
[cloudshell-user@ip-10-0-26-82 ~]$ 
[cloudshell-user@ip-10-0-26-82 ~]$ # 操作ログ開始前にユーザや変数を見る
[cloudshell-user@ip-10-0-26-82 ~]$ whoami
cloudshell-user
[cloudshell-user@ip-10-0-26-82 ~]$ uname -r
4.14.252-195.483.amzn2.x86_64
[cloudshell-user@ip-10-0-26-82 ~]$ echo ${PS1}
[\u@\h \W]\$
[cloudshell-user@ip-10-0-26-82 ~]$ echo ${LOGS_NAME}
20220108_142606_CloudShell.log
[cloudshell-user@ip-10-0-26-82 ~]$ 
[cloudshell-user@ip-10-0-26-82 ~]$ 
[cloudshell-user@ip-10-0-26-82 ~]$ # 操作ログの取得開始
[cloudshell-user@ip-10-0-26-82 ~]$ script ${HOME}/${LOGS_NAME}
Script started, file is /home/cloudshell-user/20220108_142606_CloudShell.log

sh-4.2$ 
sh-4.2$ # メモ: プロンプトが変更され、変数は引き継がれない。
sh-4.2$ 
sh-4.2$ # 操作ログ開始中にユーザや変数を見る
sh-4.2$ whoami
cloudshell-user
sh-4.2$ uname -r
4.14.252-195.483.amzn2.x86_64
sh-4.2$ echo ${PS1}
\s-\v\$
sh-4.2$ echo ${LOGS_NAME}

sh-4.2$ 
sh-4.2$ 
sh-4.2$ 
sh-4.2$ # 終了するコマンド(または ctrl + d)
sh-4.2$ exit
exit
Script done, file is /home/cloudshell-user/20220108_142606_CloudShell.log
[cloudshell-user@ip-10-0-26-82 ~]$ # 操作ログ終了後にユーザや変数を見る
[cloudshell-user@ip-10-0-26-82 ~]$ whoami
cloudshell-user
[cloudshell-user@ip-10-0-26-82 ~]$ uname -r
4.14.252-195.483.amzn2.x86_64
[cloudshell-user@ip-10-0-26-82 ~]$ echo ${PS1}
[\u@\h \W]\$
[cloudshell-user@ip-10-0-26-82 ~]$ echo ${LOGS_NAME}
20220108_142606_CloudShell.log
[cloudshell-user@ip-10-0-26-82 ~]$ 
[cloudshell-user@ip-10-0-26-82 ~]$ 
[cloudshell-user@ip-10-0-26-82 ~]$ # 操作ログの保存場所(後で Download file する時に使える)
[cloudshell-user@ip-10-0-26-82 ~]$ echo "${HOME}/${LOGS_NAME}"
/home/cloudshell-user/20220108_142606_CloudShell.log
[cloudshell-user@ip-10-0-26-82 ~]$ 
[cloudshell-user@ip-10-0-26-82 ~]$ 
[cloudshell-user@ip-10-0-26-82 ~]$ # 操作ログの中身を見てみる
[cloudshell-user@ip-10-0-26-82 ~]$ # メモ: 課題、Windowsで操作していると改行コードの違いで「[m」が出る時がある。
[cloudshell-user@ip-10-0-26-82 ~]$ cat "${HOME}/${LOGS_NAME}"
Script started on 2022-01-08 05:26:06+0000

sh-4.2$ 
sh-4.2$ # メモ: プロンプトが変更され、変数は引き継がれない。
sh-4.2$ 
sh-4.2$ # 操作ログ開始中にユーザや変数を見る
sh-4.2$ whoami
cloudshell-user
sh-4.2$ uname -r
4.14.252-195.483.amzn2.x86_64
sh-4.2$ echo ${PS1}
\s-\v\$
sh-4.2$ echo ${LOGS_NAME}

sh-4.2$ 
sh-4.2$ 
sh-4.2$ 
sh-4.2$ # 終了するコマンド(または ctrl + d)
sh-4.2$ exit
exit

Script done on 2022-01-08 05:26:23+0000
[cloudshell-user@ip-10-0-26-82 ~]$ 
[cloudshell-user@ip-10-0-26-82 ~]$ ls
20220108_142606_CloudShell.log
[cloudshell-user@ip-10-0-26-82 ~]$ 
[cloudshell-user@ip-10-0-26-82 ~]$ # 操作ログファイルの削除
[cloudshell-user@ip-10-0-26-82 ~]$ rm "${HOME}/${LOGS_NAME}"
[cloudshell-user@ip-10-0-26-82 ~]$ 
[cloudshell-user@ip-10-0-26-82 ~]$ ls
[cloudshell-user@ip-10-0-26-82 ~]$