自分用メモです。
前回、Organizations+SSOを使って、開発・ステージング・本番を複数アカウントで別々に管理するのをやりました。
で、実際にはここからVPCを作ってサブネット作って・・・みたいに環境を作っていくことになりますが、環境は分けたとしてもVPCのIPアドレスは同じにしたいですよね。こんな感じに。
環境がアカウントレベルで別れているのでお互いに影響も与えることもない上、アカウントが別れているので同じIPセグメントを使えて環境ごとに設定を変えたりすることもない、とても便利です。その上、請求はOrganizationsとして一括でまとめれる。言うことないです。
でも逆にこういうふうに共通的なVPCを作りたくなる場合もあるかと思います。
VPC同士をつなぐにはいくつかの方法がありますが、ポイントは開発・ステージング・本番はIPセグメントが同じだということですね。VPC ピアリングは重複するIPセグメントのVPCだとつなげません。上記の例だとピアリングするVPC同士というわけではないのでいけそうな気がするのですが、VPCピアリングはIPルーティングなのでどこかで異なるセグメントにする必要が出て来るだろうと思っています。公式ドキュメントにも複数VPCを接続する場合の例が載っていますが、重複するVPC内の異なるサブネットと接続してたりして回避しているように見えます。
それだとせっかくアカウントを分けてVPCを同じIPセグメントにしたのに、意味がないです。ということで、IPセグメントが重複するVPC間でも接続が可能な PrivateLink を使ってやってみます。
構成
目指す構成はこうなります。
前提条件
- 確認方法として、共通サービス用AWSアカウント内に確認用のEC2インスタンスを立ててapacheを動かして、他のAWSアカウントのVPCのEC2インスタンスにSSHしてcurlで確認します。
- Organizations+SSOで、各AWSアカウントならびにSSOアカウントを用意しておきます。検証のため、権限セットはとりあえずPowerUserAccessにしますが、実際には要件に合わせて設定してください。
- 各環境でVPC・サブネット・セキュリティグループ・ルートテーブルはよしなに設定する必要があります。本来ならばサブネットやセキュリティグループの設定はもっと細かくすべきですが、今回はSSHで確認をするので、すべてパブリックサブネットにしてインターネットからのアクセスも可能にしてやります。
共通サービス側の設定
VPCの作成
VPCを作ります。172.16.0.0/16の「shared-vpc」というVPCを作りました。
上記VPC内にサブネットを作ります。検証なのでap-northeast-1aに/24のサブネット「shared-vpc-subnet-a」を一つだけ作りました。
インターネットゲートウェイを作ります。これはEC2インスタンスにSSHでログインするためのもので、他のVPCからの通信を受けるためには必須ではありません。
作成したインターネットゲートウェイをVPCにアタッチしておきます。
ルートテーブルを作成します。
サブネット「shared-vpc-subnet-a」と関連付けしておきます。
ルートを編集して、インターネットゲートウェイのルートを追加しておきます。
VPCはこれで終わりです。
EC2インスタンスの作成
EC2インスタンスを作成します。AMIはAmazon Linux 2を選択。
インスタンスタイプは検証なのでt2.microを選択。
先ほど作成したVPC「shared-vpc」のサブネット「shared-vpc-subnet-a」に配置します。パブリックIPも付与するようにしておきます。
ストレージとタグはそのまま進めます。
セキュリティグループの設定です。SSHは自分のIPからのみアクセス許可に変更、あとapacheを立てるのでVPC内からHTTPを許可するルールを追加しておきます。
起動します。キーペアはよしなに。
$ ssh -i ./shared-service-vpc-ec2.pem ec2-user@XXX.XXX.XXX.XXX [ec2-user@ip-XXX.XXX.XXX.XXX ~]$ sudo yum install -y httpd [ec2-user@ip-XXX.XXX.XXX.XXX ~]$ sudo systemctl start httpd [ec2-user@ip-XXX.XXX.XXX.XXX ~]$ echo "ok" | sudo tee -a /var/www/html/index.html [ec2-user@ip-XXX.XXX.XXX.XXX ~]$ curl http://localhost ok
EC2の準備も完了です。
NLBの作成
次にNLBです。「ロードバランサーの作成」をクリックします。
Network Load Balancerを選択します。
「shared-vpc-nlb」という名前のNLBを設定していきます。
- PrivateLinkで受けるので「内部」を選択
- apacheが待ち受けているEC2へ流すのでリスナーはTCP:80
- NLBのVPCおよびAZ、それに紐付いているサブネットを設定していきます。
- NLBのIPはサブネットから払い出すこととします。
全部設定したら次に進みます。
セキュリティ設定はそのまま進みます。
ターゲットグループの設定です。NLBから流したいEC2インスタンスグループののポートやヘルスチェックを指定します。
ターゲットグループに登録するターゲットを追加します。さきほど作成したEC2インスタンスが見えているはずですのでこれを追加します。
確認画面が表示されますので、「作成」します。
念のため、作成したNLBがActiveになっていること、ターゲットグループへのヘルスチェックがhealthyになっていることを確認しておいてください。
PrivateLinkの設定
PrivateLinkの設定です。アカウントをまたいだPrivateLinkの場合、
- 接続先(共有サービス側)でVPCエンドポイントサービスを作成しNLBを紐付け、接続元アカウントを接続許可するホワイトリストに追加
- 接続元(各環境側)でVPCエンドポイントを作成し、接続先への接続許可承認を申請
- 接続先(共有サービス側)で接続リクエストを承認
という一連の承認プロセスを経て、接続ができるようになります。
まずは、接続先となる共有サービス側で設定を行っていきます。
VPCの設定画面で「エンドポイントサービス」をクリックして、「エンドポイントサービスの作成」をクリックします。
作成したNLBを選択して、「サービスの作成」をクリックします。「エンドポイントの承諾が必要」にチェックを入れておくと承認が必要になりますが、このチェックを外すとホワイトリストに登録されているアカウントからエンドポイントを作成すると自動的に接続されます。今回はチェックを入れておきます。
エンドポイントサービスが作成されました。作成されたエンドポイントサービスの「ホワイトリストに登録されたプリンシパル」タブを開いて、「ホワイトリストにプリンシパルを追加する」をクリックします。
追加するアイデンティティに、接続許可するAWSアカウントのARNを登録していきます。「arn:aws:iam::AWSアカウントID:root」のフォーマットで登録します。
これで準備完了です。VPCエンドポイントサービスの画面を開いて、作成したVPCエンドポイントサービスの「サービス名」をメモしておいてください。各環境側から接続する際に必要になります。
各環境側の設定
では各環境側の設定をやっていきます。開発/ステージング/本番共通の手順になるのと、ここまでの手順とかぶるところもあるので割愛します。
VPCエンドポイントの作成
VPCのメニューから「エンドポイント」をクリック、「エンドポイントの作成」をクリックします。
エンドポイント作成画面で、共通サービス側のVPCエンドポイントサービスの作成時にメモしておいた「サービス名」を入力して「検証」をクリックします。共通サービス側でホワイトリストで許可されていれば、サービスが見つかりました、と表示されます。
各環境側のVPC・サブネット・セキュリティグループと紐付けます。最後に「エンドポイントの作成」をクリックします。
エンドポイントが作成されましたが、「承諾の保留中」となっていますね。接続先側のVPCエンドポイントサービスで承諾を必須としている場合、承諾が行われるまでは使えませんので、共通サービス側で承諾しましょう。
共通サービス側のVPCエンドポイントサービスの画面で、「エンドポイント接続」タブに接続元アカウントとエンドポイントが表示されていますので、これを選択して、アクションから「接続リクエストの承諾」を選択します。
承諾します。
承諾直後は「保留中」になっていますが、数分立つと「利用可能」に変わります。これで各環境からの接続が可能な状態になりました。
各環境側に戻るとVPCエンドポイントが利用可能になりました。また、ここでDNS名が表示されていますね。これでアクセスが可能になります。
各環境側のEC2インスタンスにSSHしてcurlを叩いてみましょう。
$ ssh -i ~/Downloads/dev-vpc-ec2pem.pem ec2-user@XXX.XXX.XXX.XXX [ec2-user@ip-XXX-XXX-XXX-XXX ~]$ curl vpce-XXXXXXXXXXXXXXXX-XXXXXXXX.vpce-svc-XXXXXXXXXXXXXXXX.ap-northeast-1.vpce.amazonaws.com ok
接続できました!残りは割愛しますが、同様に接続ができると思います。ただ、共通サービス側のapacheで確認してみたところ、どこからアクセスが来ているかを区別することはできませんでした。そこはもう少し追いかけてみたいと思います。
まとめ
Organizations+SSOでアカウントを分けつつも、IPアドレス帯は共通的にアクセスしたい、という場合には役に立つのではないでしょうか。
参考
基本的にここにすべて載ってますw 単にOrganizations+SSOの環境で写経しただけですね・・・