VPC 間接続を気軽に試せる VPC Lattice ワークショップをやってみた

2023.07.08

VPC Lattice のワークショップをやってみました。VPC Lattice を利用した VPC 間接続はもちろん、VPC Lattice を経由して他 VPC にある API を提供しているサービス(Lambda or EC2)へアクセスをお手軽に試せる内容でした。

VPC Lattice 試してみたいけど複数 VPC と、なにかしらの API を用意するのが億劫だなと思っている方にオススメです。

どんなワークショップなの?

ワークショップのリンクです。コンテンツは英語版を推奨します。日本語へ切り替えもできるのですがコンテンツの内容が英語版と比べると古かったです。また一部は英語版でも動作しない箇所があったため後述します。

複数の VPC を VPC Lattice で接続して、EC2 や Lambda が提供する API を Client VPC にある EC2 からアクセスを試すといった内容です。CIDR が重複していても VPC 間接続ができるという VPC Lattice の特徴を示すために VPC の CIDR はすべて10.0.0.0/16となっています。

こちらのワークショップ用の検証環境構築は用意されている CloudFormation テンプレートを実行して作成できます。

主に学習できる要素

  • VPC Lattice による VPC 間接続
  • VPC Lattice の認証ポリシーを利用したアクセス制限
  • VPC Lattice を経由する通信のログ設定
  • Kubernets Gaeway API を VPC Lattice に置き換える
    • 私は未実施です

やってみた感想

環境構築

最初は日本語版で進めていたため CloudFormation テンプレートをダウンロードして実行する手順で進めました。英語版では Cloud Shell か Cloud 9 で実行する方法が案内されています。

リージョンはue-west-2指定となっており、VPC や EC2 を作成する CloudFormation スタックの実行時間は5分ほどでした。 EKS の検証まで試すつもりはなかったため EKS Cluster のデプロイはスキップしました。

Lab 1 - Servie-to-servie connectivity

VPC Lattice の設定を行い EC2 から他の VPC にある APIを提供しているサービス(実態は Lambda、EC2)へリクエストを送り、レスポンスを確認するといった内容です。VPC Lattice の基本的な接続設定を学べます。

学べたこと

  • ターゲットグループの各種紐づけ方
    • Labmda との紐づけ方
    • Auto Scaling Group との紐づけ
  • サービスの作成
  • サービスネットワークの作成
    • サービスとの関連付け方
    • VPC との関連付け方

ターゲットグループの HTTP or HTTPS の変更、ポート番号は後から変更できなく設定を誤ると作り直しになります。同じく HTTP or HTTPS とポート番号の設定があるヘルスチェックは後から設定変更可能でした。

あとは Auto Scaling Group のプロパティに VPC Lattice 統合オプションがあったことを知りました。

Lab 2 - Application-layer security

VPC Lattice 認証ポリシーという VPC Lattice のコンポーネント側で細かいアクセス制御できる機能があります。その機能を使ったアクセス制御を試すといった内容です。現時点では最新の英語版のコンテンツでも一部上手く動作しない箇所がありました。

Control access to services using auth policies - Amazon VPC Lattice

学べたこと

  • VPC Lattice のセキュリティーレイヤーの理解
    • 第1層: VPC Lattice Service を VPC に関連づける、づけないにより VPC レベルで許可する、しないの制御
    • 第2層: セキュリティーグループ、ネットワーク ACL の設定によるネットワークレベルの制御
    • 第3層: VPC Lattice 認証ポリシーによる VPC Lattice Service / Service Networ レベルの制御(オプション)

VPC Lattice 認証ポリシーによる未認証(anoymous)プリンシパルのアクセスは拒否の例

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "*",
            "Resource": "*",
            "Condition": {
                "StringNotEqualsIgnoreCase": {
                    "aws:PrincipalType": "anonymous"
                }
            }
        }
    ]
}

VPC Lattice Service のドメイン名に対してリクエス時に未認証がゆえに拒否されたメッセージ例

$ curl https://reservation-0a5915d7301cf3404.7d67968.vpc-lattice-svcs.us-west-2.on.aws
AccessDeniedException: User: anonymous is not authorized to perform: vpc-lattice-svcs:Invoke on resource: arn:aws:vpc-lattice:us-west-2:123456789012:service/svc-0a5915d7301cf3404/ because no network-based policy allows the vpc-lattice-svcs:Invoke actions

上手くいかないこと

Parking の VPC Lattice Service に認証ポリシーを設定後に以下のコマンドを発行しても期待されるレスポンスが返ってきません。

$ curl http://<parking services Domain name captured in prerequisite step 3>/rates --aws-sigv4 "aws:amz:us-west-2:vpc-lattice-svcs" --user "$AWS_ACCESS_KEY_ID:$AWS_SECRET_ACCESS_KEY" --header "x-amz-security-token:$AWS_SESSION_TOKEN" --header "x-amz-content-sha256:UNSIGNED-PAYLOAD"

以下のレスポンスが返ってきます。

IncompleteSignatureException: 'x-amz-security-token' is named as a SignedHeader, but it does not exist in the HTTP request.

トラブルシューティングしていると、同じく VPC Lattice のワークショップでハマっていると思われる Issue を見つけました。現時点では解決されていまんせでした。なので、ここの内容はスキップしました。

--aws-sigv4 does not behave well with AWS VPC Lattice services · Issue #11007 · curl/curl

ワークショップ用のインスタンスの curl コマンドのバージョンを残しておきます。

$ curl --version
curl 8.0.1 (x86_64-koji-linux-gnu) libcurl/8.0.1 OpenSSL/1.0.2k-fips zlib/1.2.7 libidn2/2.3.0 libssh2/1.4.3 nghttp2/1.41.0
Release-Date: 2023-03-20
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB SPNEGO SSL threadsafe UnixSockets

認証ポリシーを無効に戻す(ポリシーの記述を削除)も、内部的には認証ポリシーが残っている様子でもとに戻せませんでした。

$ curl http://parking-07609973b35c5dbb6.7d67968.vpc-lattice-svcs.us-west-2.on.aws/rates
AccessDeniedException: User: anonymous is not authorized to perform: vpc-lattice-svcs:Invoke on resource: arn:aws:vpc-lattice:us-west-2:123456789012:service/svc-07609973b35c5dbb6/rates because no network-based policy allows the vpc-lattice-svcs:Invoke action

Lab 3 - Observability

オブザーバビリティと題名ですが実施内容は VPC Lattice を経由する通信のログを残す設定だけです。CloudWatch Logs と S3 へ保存する 2 種類を試しました。

学べたこと

  • ログは以下の 3 サービスのどれかに保存ができる
    • CloudWatch Logs
    • S3
    • Kinesies Data Firehose

S3 へ保存したログの出力例

VPC Lattice Service Network のログ設定で S3 へ保存しました。

{
    "startTime": "2023-07-07T13:14:40Z",
    "requestMethod": "GET",
    "requestPath": "/",
    "protocol": "HTTP/2",
    "responseCode": 403,
    "bytesReceived": 82,
    "bytesSent": 460,
    "duration": 8,
    "userAgent": "curl/8.0.1",
    "hostHeader": "reservation-0a5915d7301cf3404.7d67968.vpc-lattice-svcs.us-west-2.on.aws",
    "targetIpPort": "-",
    "targetGroupArn": "arn:aws:vpc-lattice:us-west-2:123456789012:targetgroup/tg-0badc940d27c68835",
    "sourceIpPort": "10.0.0.159:41264",
    "serverNameIndication": "reservation-0a5915d7301cf3404.7d67968.vpc-lattice-svcs.us-west-2.on.aws",
    "sourceVpcId": "vpc-0068976d77cd32bba",
    "destinationVpcId": "-",
    "serviceArn": "arn:aws:vpc-lattice:us-west-2:123456789012:service/svc-0a5915d7301cf3404",
    "serviceNetworkArn": "arn:aws:vpc-lattice:us-west-2:123456789012:servicenetwork/sn-0da3e9d6fe591c374",
    "requestToTargetDuration": 0,
    "responseFromTargetDuration": 0,
    "sslCipher": "ECDHE-RSA-AES128-GCM-SHA256",
    "tlsVersion": "TLSv1.2",
    "resolvedUser": "Anonymous",
    "authDeniedReason": "Network"
}

CloudWatch Logs へ保存したログの出力例

VPC Lattice Service のログ設定で CloudWatch Logs へ保存しました。

{
	"hostHeader": "lambda",
	"sslCipher": "ECDHE-RSA-AES128-GCM-SHA256",
	"serviceNetworkArn": "arn:aws:vpc-lattice:us-west-2:123456789012:servicenetwork/sn-0da3e9d6fe591c374",
	"resolvedUser": "arn:aws:sts::123456789012:assumed-role/lattice-workshop-SSMRole-1R6J9FPY38CSV/i-02869a48cb6620128",
	"authDeniedReason": "-",
	"requestMethod": "POST",
	"targetGroupArn": "arn:aws:vpc-lattice:us-west-2:123456789012:targetgroup/tg-0badc940d27c68835",
	"tlsVersion": "TLSv1.2",
	"userAgent": "-",
	"serverNameIndication": "reservation-0a5915d7301cf3404.7d67968.vpc-lattice-svcs.us-west-2.on.aws",
	"destinationVpcId": "-",
	"sourceIpPort": "10.0.0.159:54938",
	"targetIpPort": "34.223.18.218:443",
	"serviceArn": "arn:aws:vpc-lattice:us-west-2:123456789012:service/svc-0a5915d7301cf3404",
	"sourceVpcId": "vpc-0068976d77cd32bba",
	"requestPath": "/",
	"startTime": "2023-07-07T13:15:48Z",
	"protocol": "HTTP/1.1",
	"responseCode": 200,
	"bytesReceived": 306,
	"bytesSent": 2583,
	"duration": 482,
	"requestToTargetDuration": 55,
	"responseFromTargetDuration": 0
}

Lab 4 - Gateway Controller

マイクロサービスでの利用を想定しているサービスなため EKS を利用した演習です。EKS の準備はと思いスキップしました。あとから気づきましたが英語版だと EKS の構築の CloudFormation テンプレートが用意されていました。

Amazon VPC Lattice Workshop - Lab4 - Gateway Controller

Cleanup

作成したリソースを削除する手順が用意されています。手動で作成した VPC Latttice を削除したあとに、CloudFormation スタックを削除するといった内容です。

おわりに

VPC Lattice を試そうと思うと複数の VPC となにかしらのリクエストを受けるリソースを用意しないといけないのですが、こちらのワークショップでは事前準備は CloudFormation テンプレートで一撃で終わります。VPC Lattice の設定にすばやく取りかかれるのでちょっと試してみたい方には敷居が低くよいのではないでしょうか。とくに VPC Lattice のセキュリティで認証ポリシーを利用するのは私ははじめてで良い経験になりました。

ワークショップで気にになった点としては、VPC Lattice のアクセス制御で必要なセキュリティグループの設定は CloudFormation で作成しているためユーザーが意識することはありませんでした。個人的には VPC Lattice を実際に使うときはセキュリティグループの設定を忘れがちなので以下の記事も参考にしていただき、セキュリティグループの設定も意識してもらえればと思います。