皆さんお疲れ様です!椎名です。
別の部署やグループ会社の、異なるAWSアカウントのプライベートサブネットにある特定のリソースにのみアクセスしたい、という場面に遭遇した経験はないでしょうか。こんな時にぜひ使っていただきたいのはPrivateLinkです。
はじめに
AWS PrivateLinkとは?
AWS PrivateLink
ざっくりまとめると
- VPCエンドポイントとVPCエンドポイントサービスをセットで用いて、AWS内のプライベートな接続を提供してくれるサービスです。
- 単一AWSアカウント内の異なるVPC間の接続はもちろん、異なるAWSアカウント内のVPCとサービスとの接続を簡単かつセキュアにできます。
- また、VPCのCIDRが重複しても問題なく、通信したい箇所のみ接続させるのも重要なポイントです。
というわけで、今回はPrivateLinkを利用した環境を構築していきます。
構築イメージ

- 最終目標は、ユーザーアカウントのWindowsサーバーから、サービスアカウントのプライベートなLinuxサーバーに、「privatelink.test.cloud5.jp」というドメインでHTTPS通信を行います。
- 検証のため「ap-northeast-1a」のシングルAZ構成で構築していますが、実際の環境では信頼性の高いマルチAZが推奨されます。
二つのAWSアカウントの用意が難しい場合、同じアカウント内の異なるユーザーでも検証は可能です。
前提条件
サービスアカウント
プライベートサブネットが含まれていて、DNS ホスト名とDNS 解決が有効になっているVPCを作成していること。
LinuxEC2サーバー用のセキュリティグループを作成、80と443ポートを開いていること。
ユーザーアカウント
パブリックサブネットが含まれていて、DNS ホスト名とDNS 解決が有効になっているVPCを作成していること。
WindowsEC2サーバー用のセキュリティグループを作成、80ポートを開いていること。
エンドポイント用のセキュリティグループを作成、443ポートを開いていること。
Route53
利用可能なホストゾーンを作成していること。
サービスアカウント側の構築
1. s3エンドポイントの作成
プライベートなAmazon Linux EC2のリポジトリをアップデート及びインストールするには、S3へのアクセスの許可が必要です。AWS情報センター
エンドポイントで「com.amazonaws.ap-northeast-1.s3」のgatewayタイプを選び、LinuxEC2作成用のVPCとルートテーブルを選択します。
2. LinuxEC2の作成
Amazon Linux 2023のAMIを選び、ユーザーデータに
#!/bin/bash
sudo su
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "This is test server" > /var/www/html/index.html
を入力します。
3. SSL証明書のリクエスト



今回は、「test.cloud5.jp」というドメインを所有していて、「privatelink.test.cloud5.jp」というサブドメインでLinuxサーバーにアクセスしたいので、完全修飾ドメインに「privatelink.test.cloud5.jp」を入力しています。皆さんは各自に所有しているドメインを入力してください。
以上の手順が完了したら、証明書のステータスが発行済みになっていることを確認します。
4. ターゲットグループの作成

ターゲットタイプはインスタンス、ポートはTCPを選び、次の画面でLinuxEC2をターゲットとして追加します。
5. NLBの作成


スキームは内部、プロトコルはTLSを選びます。転送先と証明書は先ほど作成したものにします。
6. エンドポイントサービスの作成

追加設定の「エンドポイントの承諾が必要」は、ユーザーアカウントからの接続がリクエストされた際に、サービスアカウント側での承諾の要否を設定できます。今回は承諾が必要にします。
「プライベートDNS名をサービスに関連付ける」にチェックを入れ、SSL証明書と同じドメインを入力します。


エンドポイントサービスを作成したら、次の画面で二回「プリンシパルを許可」を選択します。「追加するプリンシパル」にユーザーアカウントのARNを入力し、許可をします。
エンドポイントサービスの「ドメインの検証値」と「サービス名」をメモしてください。
7. ドメインの検証
TXTレコードの作成

Route 53のホストゾーンにて、新たなレコードを作成します。
レコードタイプはTXT、レコード名にサブドメインの部分を入力し値にエンドポイントサービスの「ドメインの検証値」を入力します。
ドメイン所有権の確認

エンドポイントサービスに戻り、「プライベートDNS名のドメイン所有権を確認」を実行する
しばらくすると、「ドメインの検証ステータス」が「Verified」に変われば確認完了です。
これでサービスアカウントの構築は完了です。
ユーザーアカウント側の構築
1. エンドポイントの作成

カテゴリを「その他のエンドポイントサービス」を選択し、サービス名に先ほどメモしたものを入力します。サービスの検証をクリックし、検証されましたの表示が出たら次に進みます。
ネットワークはWindowsサーバーと同じく、セキュリティグループはエンドポイント用のものを選択します。
2. エンドポイント接続リクエストの承諾

一度サービスアカウントのエンドポイントサービスに戻り、接続リクエストの承諾を実行します。
しばらくすると、状態がAvailableに変わったら接続完了です。
3. プライベートDNS名の有効化


ユーザーアカウントのエンドポイントに戻り、プライベートDNS名を有効化します。
接続の検証

「privatelink.test.cloud5.jp」(各自が設定したドメイン)にアクセスし、「This is test server」が表示されたら成功です。おめでとうございます!
上手く表示されなかった場合、URLの先頭が「https://」になっているかどうかを確認してください。自動で「http://」になっている可能性があり、アクセスはできません。
また、プライベートDNS名を有効化した直後ではアクセスできない場合がありますので、しばらく待ってから再度試してください。
最後に
PrivateLinkは単方向の通信ではあるが、双方向の通信が必要な場合は、今までの手順を逆方向に行えば対応可能になります。
また、オンプレミス環境や、AWS Marketplaceでサポートされているソリューションとの接続も可能で、様々な場面で役立ちますので、ぜひ活用してみてください。
今回のご紹介は以上となります。
では皆さん、よいクラウドライフを!