のべラボ.blog

謙虚に、臆せず、さぼらずにブログを書く

AWS での分散負荷テスト ソリューションを試してみた

AWS ソリューションライブラリの一つである「AWS での分散負荷テスト」ソリューションを試してみました。

aws.amazon.com

このソリューションは、Amazon ECS の Fargateのタスクをクライアントとして任意のWebのエンドポイントに負荷テストを実施できるようで、 前からその存在は知っていたんですが、実際に試してみるのは初めてです。

なおこの記事に記述している内容は、2022年9月24日時点の内容に基づいていますのでご了承ください。

このソリューションを導入する事前準備としては、基本的に VPC と 2つ以上のサブネットが存在してればいけそうです。

詳細についてはソリューションガイドを参照しましょう。

https://d1.awsstatic.com/Solutions/ja_JP/distributed-load-testing-on-aws.pdf

では、このソリューションを導入していきます。

まず自分のAWSアカウントにサインインした状態にして、このソリューションのページにある [AWS コンソールで起動する] をクリックします。

https://cdn-ak.f.st-hatena.com/images/fotolife/n/neob/20220924/20220924185908.png

そうすると CloudFormation でスタックを作成するページが表示されるので、必要なパラメータの入力を行います。

ここで入力する管理者の ID は、ソリューションが導入された後にテストを管理するコンソールにサインインするために必要になります。

https://cdn-ak.f.st-hatena.com/images/fotolife/n/neob/20220924/20220924203340.png

なお、サブネットは Fargate のタスクの実行に使用するものを指定します。Public でも Private でも大丈夫ですが、Private の場合は Fargate がイメージを Pull するために NAT ゲートウェイを構成しておく必要があります。

必要なパラメータを入力後、CloudFormation でスタックを作成します。

無事にスタック作成が完了すると、パラメータで指定した管理者のメールアドレスに次のようなメールが届きます。

サブジェクト:

Welcome to Distributed Load Testing

本文:

Please use the credentials below to login to the Distributed Load Testing console. 
Username: admin1 
Password: B2ZXkPR0D.1d 
Console: https://xxxxxxxxxxxxxx.cloudfront.net/

このメールに記載されている [Console:] のURL で、テストを実行、管理するためのコンソールへのアクセスできます。

アクセスすると、次のようにサインインが求められます。( 少し前の AWS Amplify の 認証の UI ですね。)

https://cdn-ak.f.st-hatena.com/images/fotolife/n/neob/20220924/20220924185832.png

ここで、メールに記載されている [Username:] の値と [Password:] の値を入力してサインインを行います。

入力内容が正しければ、パスワード変更が求められますので新しいパスワードを入力します。

そうすると、テストを管理するコンソールが開き、テストシナリオ一覧が表示されます。まだテストは実行していないので何も表示されません。

https://cdn-ak.f.st-hatena.com/images/fotolife/n/neob/20220924/20220924185836.png

これからテストシナリオを作成するので、[CREATE TEST] をクリックします。

そして、次の図のようにテストの設定を入力します。

https://cdn-ak.f.st-hatena.com/images/fotolife/n/neob/20220924/20220924185841.png

今回は、シンプルに単一のエンドポイントにアクセスを行うだけの設定にすることにしました。

なお、上図ではチェックされていませんが、今回はテスト中も Liveデータをモニタリングしたいので [Include Live Data ] をチェックします。

すぐにテストを実行したかったので、[Run Now] を選択してページ右下にある [RUN NOW]ボタンをクリックします。

すると、テストの詳細ページに切り替わります。

https://cdn-ak.f.st-hatena.com/images/fotolife/n/neob/20220924/20220924185847.png

この詳細ページを少し下にスクロールすると、Amazon ECS の Fargate のタスクの起動状況も表示されます。

[Running] の値が指定したタスク数になることを確認します。

https://cdn-ak.f.st-hatena.com/images/fotolife/n/neob/20220924/20220924185851.png

ここには Amazon ECS のコンソールへのリンクも表示されています。タスクの状況はこのリンクをクリックして表示される Amazon ECS のコンソールからでも確認できます。

https://cdn-ak.f.st-hatena.com/images/fotolife/n/neob/20220924/20220924185855.png

さらにページを下にスクロールすると、チャートでLive データが表示されます。これは、[Include Live Data ] をチェックした場合に表示されます。

https://cdn-ak.f.st-hatena.com/images/fotolife/n/neob/20220924/20220924185859.png

もしページの内容が更新されない場合は、右上にある [REFRESH] ボタンを選択してみましょう。

テストが終了すると、結果が表示されます。

https://cdn-ak.f.st-hatena.com/images/fotolife/n/neob/20220924/20220924185903.png

今回はシンプルなシナリオでテストしてみましたが、JMeterを使用したテストや、複数のリージョンを使用したテストなどもできるようです。

多くの AWS サービスのリソースを使用して構築されているソリューションですが、CloudFormation を使用して比較的シンプルに導入できるのがいいですね!

Amazon EKS で Pod から AWS Secrets Manager のシークレットを取得する

今回は、AWS Secrets Manager で管理しているシークレットの情報を Amazon EKS の Pod から取得させてみます。

これを実現するために、AWS Secrets and Config Provider (ASCP) を使用します。

下図がそのイメージです。

https://cdn-ak.f.st-hatena.com/images/fotolife/n/neob/20220913/20220913083939.png

ASCP については、次の AWS ブログの記事や、AWS のドキュメントにも情報があるので、併せてご参照ください。

aws.amazon.com

docs.aws.amazon.com

ここに記述している内容は、2022 年 9 月13 日時点で動作を確認しています。

また、対象にしている Kubernetes のバージョンは 1.23 です。


前提と環境

今回は、大阪リージョンの「 ASCP-cluster 」という名前の EKS クラスター (バージョンは 1.23 ) を使う前提とします。

kubectl や eksctl 、AWS CLI 、Helm、git が使用でき、対象のクラスターに接続できる Amazon Linux2 の環境で実施していきます。


AWS Secrets and Config Provider (ASCP) のインストール

これは、AWS のドキュメントに基づいて行います。

まず Helm を使って Secrets Store CSI ドライバーをインストールします。

helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts
helm install -n kube-system csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver

次に ASCP をインストールします。

kubectl apply -f https://raw.githubusercontent.com/aws/secrets-store-csi-driver-provider-aws/main/deployment/aws-provider-installer.yaml

環境変数の作成

このあとの手順でよく利用する情報を環境変数に格納しておきます。

REGION=ap-northeast-3
CLUSTERNAME=ASCP-cluster

AWS Secrets Manager のシークレットの作成

今回は、ユーザー名: admin とパスワード: admin1234 という値をシークレットとして作成します。

aws --region "$REGION" secretsmanager  create-secret --name ascp-demo-secret --secret-string '{"username":"admin", "password":"admin1234"}'

作成後に表示されるシークレットの ARN をメモしておきましょう。


Service Account の作成

Amazon EKS の Pod には、 AWS Secrets Manager のシークレットを取得するための権限を付与する必要があるので、Service Account を作成します。

まず 作成したシークレットの取得を許可する IAM ポリシーを作成します。次の例では、ポリシー名を ascp-demo-secret-policy にしています。

下記で、 <作成したシークレットのARN> の部分に、メモしておいた ARN を記載します。

POLICY_ARN=$(aws --region "$REGION" --query Policy.Arn --output text iam create-policy --policy-name ascp-demo-secret-policy --policy-document '{
    "Version": "2012-10-17",
    "Statement": [ {
        "Effect": "Allow",
        "Action": ["secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret"],
        "Resource": ["<作成したシークレットのARN>"]
    } ]
}')

次に EKS クラスターの OIDC プロバイダを AWS IAM に関連付けます。これはクラスター単位で 1回行うだけで OK です。

eksctl utils associate-iam-oidc-provider --region="$REGION" --cluster="$CLUSTERNAME" --approve 

そして、Service Account を作成します。次の例では、Service Account 名を ascp-demo-secret-sa にしています。

eksctl create iamserviceaccount --name ascp-demo-secret-sa --region="$REGION" --cluster "$CLUSTERNAME" --attach-policy-arn "$POLICY_ARN" --approve --override-existing-serviceaccounts

SecretProviderClass の作成

SecretProviderClass を作成するためのマニフェストを用意します。

次の例では、secret-provider-class.yaml というファイルで作成しています。

このマニフェストobjectName に作成したシークレットの名前を指定します。

apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: ascp-demo-secrets-provider-class
spec:
  provider: aws
  parameters:
    objects: |
        - objectName: "ascp-demo-secret"
          objectType: "secretsmanager"

マニフェスト作成後、適用します。

kubectl apply -f secret-provider-class.yaml 

Deployment の作成

それでは、Pod から シークレットの情報を取得してみます。

まず Deployment のマニフェストを作成します。Pod の spec には、Service Account や SecretProviderClass を正しく指定しましょう。

次の例では、/mnt/secrets-store をマウントに指定し、シークレットを取得できるようにして example-deployment.yaml というファイルに保存しています。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      serviceAccountName: ascp-demo-secret-sa
      volumes:
      - name: secrets-store-inline
        csi:
          driver: secrets-store.csi.k8s.io
          readOnly: true
          volumeAttributes:
            secretProviderClass: "ascp-demo-secrets-provider-class"
      containers:
      - name: nginx-deployment
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: secrets-store-inline
          mountPath: "/mnt/secrets-store"
          readOnly: true

マニフェスト作成後、適用します。

kubectl apply -f example-deployment.yaml

無事に Deployment の Pod が作成されたことを確認します。

kubectl get deploy nginx-deployment

次の出力例ように、2つの Pod が READY になっていれば OK です。

出力例

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2/2     2            2           15s

もし Pod が作成されない場合は、kubectl describe で イベントに エラー情報が出力されているか確認しましょう。

kubectl get pods
kubectl describe pod   <Pod名>

Pod が作成されたら、シークレットの値を参照してみます。

まず、Pod 名を確認します。

kubectl get pods

次に Pod 名を指定して コンテナのシェルに接続します。

kubectl exec -it  <Pod名>  -- /bin/bash

シェルに接続したらシークレットの情報を参照してみます。

cat /mnt/secrets-store/ascp-demo-secret

次の例のように表示されれば OK です。

出力例

{"username":"admin", "password":"admin1234"}

最後に

Kubernetes には Secrets というリソースがありますが、Amazon EKS にて Pod から AWS Secrets Manager を使い、認証情報などのシークレットを取得したい場合は、この AWS Secrets and Config Provider (ASCP) が役立ちそうですね。

Amazon EKS で Amazon EFS CSI ドライバー を使ってみる

今回は、Amazon EKS で Amazon EFS CSI ドライバー を使って、Podから EFSボリュームにアクセスしてみます。

手順としては前回の「Amazon EKS で Amazon EBS CSI ドライバー を使ってみる 」の記事の内容と似ているところが多いので、今回の記事も内容や構成が似ていることはご容赦下さいww

ここに記述している内容は、2022 年 9 月11 日時点で動作を確認しています。

また、対象にしている Kubernetes のバージョンは 1.23 です。

今後の Update により、手順等が変更される可能性があることをご留意ください。

なお、下記のドキュメントを参考にしていますので、こちらも併せてご参照ください。

docs.aws.amazon.com

aws.amazon.com


前提と環境

今回は、東京リージョンの「 test123-cluster 」という名前の EKS クラスター (バージョンは 1.23 ) を使う前提とします。

kubectl や eksctl 、AWS CLI 、git が使用でき、対象のクラスターに接続できる Amazon Linux2 の環境で実施していきます。

記事の中で出てくる AWS アカウント ID は、12 桁すべてゼロで表記しています。


Amazon EFS CSI ドライバー用の Service Account の作成

Amazon EFS CSI ドライバーには、Amazon EFS のファイルシステムを操作する権限を付与する必要があります。

その権限を付与するため、AWS の IAM ロールと関連づいた Kubernetes の Service Account を作成します。

まず、クラスター用に IAM OpenID Connect (OIDC) プロバイダーを用意します。 (もし前に IAM ロールと関連付けた Service Account を作成したことがあるなら、すでに実施済のはずなので、その場合は不要です。)

eksctl utils associate-iam-oidc-provider --cluster test123-cluster --approve

次に、IAM ロール に付与する許可ポリシーを作成します。

ここでは、ポリシー名を AmazonEKS_EFS_CSI_Driver_Policy にしています。

curl -o iam-policy-example.json https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/docs/iam-policy-example.json

aws iam create-policy \
    --policy-name AmazonEKS_EFS_CSI_Driver_Policy \
    --policy-document file://iam-policy-example.json

ダウンロードした iam-policy-example.json にも目を通しておくと、どのようなポリシーが必要か確認できます。

そして、Service Account を作成します。

ここでは、Service Account 名を ebs-csi-controller-sa に、IAM ロール名を AmazonEKS_EBS_CSI_DriverRole にしています。

eksctl create iamserviceaccount \
    --cluster test123-cluster \
    --namespace kube-system \
    --name efs-csi-controller-sa \
    --attach-policy-arn arn:aws:iam::000000000000:policy/AmazonEKS_EFS_CSI_Driver_Policy \
    --approve \
    --region ap-northeast-1

Amazon EFS CSI ドライバー を Amazon EKS アドオンとしてインストールする

インストールではHelm も使用できますが、今回は kubectl でマニフェストを使って行います。

また、マニフェストで参照するイメージは、パブリック Amazon ECR レジストリに保存されているイメージを使う前提とします。

最初にマニフェストを取得します。

kubectl kustomize \
    "github.com/kubernetes-sigs/aws-efs-csi-driver/deploy/kubernetes/overlays/stable/?ref=release-1.4" > public-ecr-driver.yaml

public-ecr-driver.yaml ファイルを編集して、次の行を削除します。 これは、Service Account は前の手順ですでに作成しているためです。 この作業は注意して下さい。ファイル内に Service Account のマニフェストが複数存在している場合、削除する対象を間違えないようにしましょう。

apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app.kubernetes.io/name: aws-efs-csi-driver
  name: efs-csi-controller-sa
  namespace: kube-system
---

これでマニフェストの準備が完了したので、適用します。

kubectl apply -f public-ecr-driver.yaml

インストールを確認します。

kubectl get deploy efs-csi-controller -n kube-system

次の出力例のように、efs-csi-controller の Deployment が起動できていることを確認します。

NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
efs-csi-controller   2/2     2            2           3m1s

 EFS ファイルシステムを作成する

EFS ファイルシステムを作成するために、まずは VPC の情報を環境変数に入れておきます。

EKSクラスターの VPC の ID の取得

vpc_id=$(aws eks describe-cluster \
    --name test123-cluster \
    --query "cluster.resourcesVpcConfig.vpcId" \
    --output text)

EKSクラスターの VPC の CIDR の取得

cidr_range=$(aws ec2 describe-vpcs \
    --vpc-ids $vpc_id \
    --query "Vpcs[].CidrBlock" \
    --output text)

次に EFS ファイルシステムのマウントポイントに適用するセキュリティグループを作成します。 今回は、セキュリティグループ名を MyEfsSecurityGroup にしています。

security_group_id=$(aws ec2 create-security-group \
    --group-name MyEfsSecurityGroup \
    --description "My EFS security group" \
    --vpc-id $vpc_id \
    --output text)

作成したセキュリティグループに イングレスルールを設定します。

今回は、アクセス元がクラスターの VPC の CIDR であれば NFS トラフィックを許可するルールにします。

aws ec2 authorize-security-group-ingress \
    --group-id $security_group_id \
    --protocol tcp \
    --port 2049 \
    --cidr $cidr_range

これで EFS ファイルシステムを作成する準備ができました。

リージョンを指定して EFS ファイルシステムを作成します。

file_system_id=$(aws efs create-file-system \
    --region ap-northeast-1 \
    --performance-mode generalPurpose \
    --query 'FileSystemId' \
    --output text)

EFS ファイルシステムのマウントターゲットを作成します。

そのために、まず EKS クラスターのVPCのサブネットの ID を取得します。

aws ec2 describe-subnets \
    --filters "Name=vpc-id,Values=$vpc_id" \
    --query 'Subnets[*].{SubnetId: SubnetId,AvailabilityZone: AvailabilityZone,CidrBlock: CidrBlock}' \
    --output table

出力された表形式の内容から、EKS で EFS ファイルシステムをマウントするノードのサブネットの ID をメモしておきます。

そのサブネット ID を指定して、EFS のマウントターゲットを作成します。 次の例では、サブネット ID を subnet-0b10aaaaaaaaaaaaa と指定しています。

aws efs create-mount-target \
    --file-system-id $file_system_id \
    --subnet-id subnet-0b10aaaaaaaaaaaaa \
    --security-groups $security_group_id

 サンプルアプリケーションで確認する

では、Pod から EFS ファイルシステムにアクセスできるかをサンプルアプリケーションを使って試していきます。

まず、作成した EFS ファイルシステムの ID をメモしておきます。 これまでの手順で、$file_system_id という環境変数で参照できます。

echo $file_system_id

もしくは、AWS CLI でも確認できます。

aws efs describe-file-systems --query "FileSystems[*].FileSystemId" --output text

次に、EFS の StorageClass を作成するためのマニフェストを入手します。

curl -o storageclass.yaml https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/storageclass.yaml

ダウンロードした storageclass.yaml を編集し、fileSystemId: 部分をメモしておいた ファイルシステム ID に変更します。 次の例では、ファイルシステム ID として fs-54321abc を指定してます。

fileSystemId: fs-54321abc

これで準備ができたので、StorageClassを作成します。

kubectl apply -f storageclass.yaml

Storage Class の情報を表示してみます。NAME に efs-sc 、PROVISONER に efs.csi.aws.com の Storage Class が表示されることを確認します。

kubectl get sc

次にサンプルアプリケーションを取得します。

curl -o pod.yaml https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/pod.yaml

今回は、動的に EFS のボリュームをプロビジョニングするサンプルを動かしていきます。

ダウンロードしたマニフェスト pod.yaml を適用することで、Persistent Volume、Persistent Volume Claim、それを指定するサンプルの Pod が作成されます。

kubectl apply -f pod.yaml

Persistent Volume と Persistent Volume Claim の STATUS が Bound になっていることを確認します。

kubectl get pv
kubectl get pvc

efs-app というPod の STATUS が Running になっていることを確認します。

kubectl get pod efs-app

次のコマンドを実行し、このサンプルアプリケーションの Pod のマニフェストをみてみます。

cat  pod.yaml

次のように、Persistent Volume Claim を指定し、/data というパスにボリュームをマウントしています。

そして、echo コマンドを使用し、/data/out に日時を繰り返し書き込んでいます。 

apiVersion: v1
kind: Pod
metadata:
  name: efs-app
spec:
  containers:
    - name: app
      image: centos
      command: ["/bin/sh"]
      args: ["-c", "while true; do echo $(date -u) >> /data/out; sleep 5; done"]
      volumeMounts:
        - name: persistent-storage
          mountPath: /data
  volumes:
    - name: persistent-storage
      persistentVolumeClaim:

では、この Pod が EFS ボリュームに書き込み出来ているかを確認してみましょう。

kubectl exec efs-app -- bash -c "cat data/out"

次のような表示が確認できれば OK です。

出力例

Sun Sep 11 03:15:25 UTC 2022
Sun Sep 11 03:15:30 UTC 2022
Sun Sep 11 03:15:35 UTC 2022
Sun Sep 11 03:15:40 UTC 2022
Sun Sep 11 03:15:45 UTC 2022
Sun Sep 11 03:15:50 UTC 2022
Sun Sep 11 03:15:55 UTC 2022

ここで、もう1つ、同じ EFS のマウントターゲットを使用するPod を作成してみます。 次のマニフェストを作成して、nginx.yaml として保存します。

apiVersion: v1
kind: Pod
metadata:
  name: efs-app-nginx
spec:
  containers:
    - name: nginx
      image: nginx
      volumeMounts:
        - name: persistent-storage
          mountPath: /data
  volumes:
    - name: persistent-storage
      persistentVolumeClaim:
        claimName: efs-claim

この Pod を作成します。

kubectl create -f  nginx.yaml

作成した Pod のシェルに接続してみます。

kubectl exec efs-app-nginx -it  -- /bin/bash

次のコマンドを実行し、efs-app の Pod が書き込んだファイルを参照できることを確認します。

cat /data/out

出力例

Sun Sep 11 03:15:25 UTC 2022
Sun Sep 11 03:15:30 UTC 2022
Sun Sep 11 03:15:35 UTC 2022
Sun Sep 11 03:15:40 UTC 2022
Sun Sep 11 03:15:45 UTC 2022
Sun Sep 11 03:15:50 UTC 2022
Sun Sep 11 03:15:55 UTC 2022

これで EFS なので、2つのコンピューティング環境から同時にマウントしてアクセスできることが確認できました!

確認出来たら、シェルを終了します。

exit

サンプルアプリケーションを停止する場合は、次を実行します。

これで、EFS ボリュームも削除されます。( EFS ファイルシステムは削除されません)

kubectl delete po efs-app-nginx
kubectl delete -f pod.yaml

最後に

前回と今回の記事で、Amazon EKS の CSI ドライバーを使用して Amazon EBS や Amazon EFS のボリュームをプロビジョニングして Pod から使用する手順を確認しました。 AWS の公式のドキュメント の内容をベースにしていますが、少し補足しつつ、よりシンプルに確認できる手順にしたつもりです。 これがどなたかのお役に立てば嬉しいです。

 

Amazon EKS で Amazon EBS CSI ドライバー を使ってみる

今回は、Amazon EKS で Amazon EBS CSI ドライバー を使って、Podから EBSボリュームにアクセスしてみます。

ここに記述している内容は、2022 年 9 月1 日時点で動作を確認しています。

また、対象にしている Kubernetes のバージョンは 1.23 です。

今後の Update により、手順等が変更される可能性があることをご留意ください。

なお、下記のドキュメントを参考にしていますので、こちらも併せてご参照ください。

docs.aws.amazon.com

aws.amazon.com


前提と環境

今回は、東京リージョンの「 test123-cluster 」という名前の EKS クラスター (バージョンは 1.23 ) を使う前提とします。

kubectl や eksctl 、AWS CLI 、git が使用でき、対象のクラスターに接続できる Amazon Linux2 の環境で実施していきます。

記事の中で出てくる AWS アカウント ID は、12 桁すべてゼロで表記しています。


Amazon EBS CSI ドライバー用の Service Account の作成

Amazon EBS CSI ドライバーには、Amazon EBS のボリュームを作成したり削除する権限を付与する必要があります。

その権限を付与するため、AWS の IAM ロールと関連づいた Kubernetes の Service Account を作成します。

まず、クラスター用に IAM OpenID Connect (OIDC) プロバイダーを用意します。 (もし前に IAM ロールと関連付けた Service Account を作成したことがあるなら、すでに実施済のはずなので、その場合は不要です。)

eksctl utils associate-iam-oidc-provider --cluster test123-cluster --approve

次に、IAM ロール に 付与する許可ポリシーを作成します。

ここでは、ポリシー名を AmazonEBSCSIDriverPolicy にしています。

curl -o example-iam-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-ebs-csi-driver/v0.9.0/docs/example-iam-policy.json

aws iam create-policy --policy-name AmazonEKS_EBS_CSI_Driver_Policy --policy-document file://example-iam-policy.json

ダウンロードした example-iam-policy.json にも目を通しておくと、どのようなポリシーが必要か確認できます。

そして、Service Account を作成します。

ここでは、Service Account 名を ebs-csi-controller-sa に、IAM ロール名を AmazonEKS_EBS_CSI_DriverRole にしています。

eksctl create iamserviceaccount \
  --name ebs-csi-controller-sa \
  --namespace kube-system \
  --cluster test123-cluster \
  --attach-policy-arn arn:aws:iam::000000000000:policy/AmazonEKS_EBS_CSI_Driver_Policy \
  --approve \
  --role-only \
  --role-name AmazonEKS_EBS_CSI_DriverRole

Amazon EBS CSI ドライバー を Amazon EKS アドオンとしてインストールする

インストールは、AWS マネジメントコンソール や AWS CLI も使用できますが、今回は eksctl を使用します。

eksctl create addon --name aws-ebs-csi-driver --cluster test123-cluster --service-account-role-arn arn:aws:iam::000000000000:role/AmazonEKS_EBS_CSI_DriverRole --force

インストールできたか確認してみます。

eksctl get addon --name aws-ebs-csi-driver --cluster test123-cluster

STATUS が ACTIVE と表示されることを確認します。

出力例 (UPDATE AVAILABLE 列は省略しています。)

NAME                    VERSION                 STATUS    ISSUES   IAMROLE                  
aws-ebs-csi-driver      v1.10.0-eksbuild.1      ACTIVE    0        (IAMロールのARN)

 サンプルアプリケーションで確認する

では、Pod から EBS ボリュームにアクセスできるかをサンプルアプリケーションを使って試していきます。

まず、サンプルアプリケーションを取得します。

git clone https://github.com/kubernetes-sigs/aws-ebs-csi-driver.git

今回は、動的に EBS ボリュームをプロビジョニングするサンプルを動かしていきます。

次を実行することで、Storage Class、Persistent Volume Claim、それを指定するサンプルの Pod が作成され、さらに Persistent Volume として EBS ボリュームも動的に作成されます。

cd aws-ebs-csi-driver/examples/kubernetes/dynamic-provisioning/

kubectl  apply -f manifests/

Storage Class の情報を表示してみます。NAME に ebs-sc 、PROVISONER に ebs.csi.aws.com の Storage Class が表示されることを確認します。

kubectl get sc

Persistent Volume Claim、Persistent Volumeは、STATUS が Bound になっていることを確認します。

kubectl get pv
kubectl get pvc

次のコマンドを実行し、このサンプルアプリケーションの Pod のマニフェストをみてみます。

cat  manifests/pod.yaml

次のように、Persistent Volume Claim を指定し、/data というパスにボリュームをマウントしています。

そして、echo コマンドを使用し、/data/out.txt に日時を繰り返し書き込んでいます。 

apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  containers:
  - name: app
    image: centos
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo $(date -u) >> /data/out.txt; sleep 5; done"]
    volumeMounts:
    - name: persistent-storage
      mountPath: /data
  volumes:
  - name: persistent-storage
    persistentVolumeClaim:
      claimName: ebs-claim

では、この Pod が EBS ボリュームに書き込み出来ているかを確認してみましょう。

kubectl exec -it app -- cat /data/out.txt

次のような表示が確認できれば OK です。

出力例

Thu Sep 1 01:59:12 UTC 2022
Thu Sep 1 01:59:17 UTC 2022
Thu Sep 1 01:59:22 UTC 2022
Thu Sep 1 01:59:27 UTC 2022
Thu Sep 1 01:59:32 UTC 2022
Thu Sep 1 01:59:37 UTC 2022
Thu Sep 1 01:59:42 UTC 2022

ここで、このPod だけを削除してみます。

kubectl delete pod app

Pod を削除しても、Persistent Volume Claim が削除されない限り、EBS ボリュームは残っています。

その後、他の Pod を起動し、この EBSボリュームにマウントしてみます。

次のマニフェストを作成して、nginx.yaml として保存します。

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - name: persistent-storage
      mountPath: /data
  volumes:
  - name: persistent-storage
    persistentVolumeClaim:
      claimName: ebs-claim

この Pod を作成します。

kubectl create -f  nginx.yaml

作成した Pod のシェルに接続してみます。

kubectl exec -it nginx -- /bin/bash

次のコマンドを実行し、削除した 前の Pod が書き込んだファイルを参照できることを確認します。

cat /data/out.txt

出力例

Thu Sep 1 01:59:12 UTC 2022
Thu Sep 1 01:59:17 UTC 2022
Thu Sep 1 01:59:22 UTC 2022
Thu Sep 1 01:59:27 UTC 2022
Thu Sep 1 01:59:32 UTC 2022
Thu Sep 1 01:59:37 UTC 2022
Thu Sep 1 01:59:42 UTC 2022

確認出来たら、シェルを終了します。

exit

サンプルアプリケーションを停止する場合は、次を実行します。

これで、EBS ボリュームも削除されます。

app という Pod はすでに削除していますので、NotFoundのエラーが出ても無視して下さい。

kubectl delete po nginx
kubectl delete -f manifests/

最後に

Amazon EKS を触りだして間もないころは、Amazon EBS CSI ドライバーの構成方法はドキュメントをみてもよくわからなかたったり、上手くいかなかったりしたのですが、今回ようやくサンプルアプリケーションを動作させる手順をまとめることができました。 次は、Amazon EFS CSI ドライバーの構成方法の記事を書きたいと思います。

 

eksctl で Kubernetes 1.23 の Amazon EKS クラスターを作成する

2022年8月11日に、Amazon Elastic Kubernetes Service ( Amazon EKS ) で Kubernetes のバージョン 1.23 がサポートされました。

aws.amazon.com

そこで、早速 バージョン 1.23 の EKS クラスターを作成しようと思ったのですが、その時点ではまだ eksctl が対応していないことが判明しました。

1.23 のサポートがアナウンスされた後に、eksctl のバージョンはアップグレードしたのですが、次のように、eksctl のバージョンが 1.0.8 以下の場合、eksctl で EKS クラスターを作成しようとすると指定バージョンが対象外であるとエラーになります。

$ eksctl version
0.108.0
$ eksctl create cluster \
> --name test123-cluster \
> --vpc-public-subnets subnet-0b10715b2edf27dde,subnet-023105dfe3f0a2bdb  \
> --nodegroup-name test123-nodes \
> --node-type t3.small \
> --nodes 2 \
> --nodes-min 1 \
> --nodes-max 3 \
> --managed \
> --version 1.23 \
> --region ap-northeast-1
2022-08-26 13:28:34 []  eksctl version 0.108.0
2022-08-26 13:28:34 []  using region ap-northeast-1
Error: invalid version, supported values: 1.19, 1.20, 1.21, 1.22

EKS で サポートされる Kubernetes のバージョンが追加されたからといって、同時に そのバージョンに対応した eksctl がリリースされているわけではないんですね。

で、約 2週間ほど経って、 eksctl のリリース情報を確認すると、どうやら バージョン 1.109.0 で Kubernetes のバージョン 1.23 に対応したことがわかりました。

newreleases.io

この eksctl のリリース情報をみると、EKS で 1.23 のサポートがアナウンスされてから、約 1週間後 くらいにリリースされたようです。

AWSAmazon EKS のドキュメントで eksctl のインストールの説明部分をみると、英語版の方では、バージョンの表示例が 1.0.9 になっていました。(2022年8月27日現在)

Installing or updating eksctl - Amazon EKS

If you have eksctl installed in the path of your device, the example output is as follows. If you want to update the version that you currently have installed with a later version, complete the next step, making sure to install the new version in the same location that your current version is in. 0.109.0

ただし、日本語の方では、バージョンの表示例は まだ 1.0.5 になっていました。(2022年8月27日現在)いずれ更新されると思います。

eksctl のインストールまたは更新 - Amazon EKS

eksctl がデバイスのパスにインストールされている場合、出力例は次のようになります。現在インストールされているバージョンを新しいバージョンで更新する場合は、次の手順を完了し、新しいバージョンを現在のバージョンと同じ場所にインストールするようにします。 0.105.0

ともあれ、eksctl で バージョン 1.23 の EKS クラスターを作成できるようになったのは、嬉しい事です。

早速、eksctl のバージョンを 1.109.0 にアップグレードして、EKSクラスター 1.23 の作成を試してみました。

$ eksctl version
0.109.0
$ eksctl create cluster \
> --name test123-cluster \
> --vpc-public-subnets subnet-0b10715b2edf27dde,subnet-023105dfe3f0a2bdb  \
> --nodegroup-name test123-nodes \
> --node-type t3.small \
> --nodes 2 \
> --nodes-min 1 \
> --nodes-max 3 \
> --managed \
> --version 1.23 \
> --region ap-northeast-1
2022-08-26 13:15:16 []  eksctl version 0.109.0
2022-08-26 13:15:16 []  using region ap-northeast-1
2022-08-26 13:15:16 []  using existing VPC (vpc-0260526e8e00b9bb6) and subnets (private:map[] public:map[ap-northeast-1a:{subnet-0b10715b2edf27dde ap-northeast-1a 10.0.0.0/24 0} ap-northeast-1c:{subnet-023105dfe3f0a2bdb ap-northeast-1c 10.0.10.0/24 0}])
2022-08-26 13:15:16 [!]  custom VPC/subnets will be used; if resulting cluster doesn't function as expected,make sure to review the configuration of VPC/subnets
2022-08-26 13:15:16 [ℹ]  nodegroup "test123-nodes" will use "" [AmazonLinux2/1.23]
2022-08-26 13:15:16 [ℹ]  using Kubernetes version 1.23
2022-08-26 13:15:16 [ℹ]  creating EKS cluster "test123-cluster" in "ap-northeast-1" region with managed nodes
2022-08-26 13:15:16 [ℹ]  will create 2 separate CloudFormation stacks for cluster itself and the initial managed nodegroup
2022-08-26 13:15:16 [ℹ]  if you encounter any issues, check CloudFormation console or try 'eksctl utils describe-stacks --region=ap-northeast-1 --cluster=test123-cluster'
2022-08-26 13:15:16 [ℹ]  Kubernetes API endpoint access will use default of {publicAccess=true, privateAccess=false} for cluster "test123-cluster" in "ap-northeast-1"
2022-08-26 13:15:16 [ℹ]  CloudWatch logging will not be enabled for cluster "test123-cluster" in "ap-northeast-1"
2022-08-26 13:15:16 [ℹ]  you can enable it with 'eksctl utils update-cluster-logging --enable-types={SPECIFY-YOUR-LOG-TYPES-HERE (e.g. all)} --region=ap-northeast-1 --cluster=test123-cluster'
2022-08-26 13:15:16 [ℹ]
2 sequential tasks: { create cluster control plane "test123-cluster",
    2 sequential sub-tasks: {
        wait for control plane to become ready,
        create managed nodegroup "test123-nodes",
    }
}
2022-08-26 13:15:16 [ℹ]  building cluster stack "eksctl-test123-cluster-cluster"
2022-08-26 13:15:16 [ℹ]  deploying stack "eksctl-test123-cluster-cluster"
2022-08-26 13:15:46 [ℹ]  waiting for CloudFormation stack "eksctl-test123-cluster-cluster"
(中略)
2022-08-26 13:29:18 [ℹ]  building managed nodegroup stack "eksctl-test123-cluster-nodegroup-test123-nodes"
2022-08-26 13:29:18 [ℹ]  deploying stack "eksctl-test123-cluster-nodegroup-test123-nodes"
2022-08-26 13:29:18 [ℹ]  waiting for CloudFormation stack "eksctl-test123-cluster-nodegroup-test123-nodes"
(中略)
2022-08-26 13:33:01 [ℹ]  waiting for the control plane availability...
2022-08-26 13:33:03 [ℹ]  saved kubeconfig as "/home/ssm-user/.kube/config"
2022-08-26 13:33:03 [ℹ]  no tasks
2022-08-26 13:33:03 [ℹ]  all EKS cluster resources for "test123-cluster" have been created
2022-08-26 13:33:03 [ℹ]  nodegroup "test123-nodes" has 2 node(s)
2022-08-26 13:33:03 [ℹ]  node "ip-10-0-0-138.ap-northeast-1.compute.internal" is ready
2022-08-26 13:33:03 [ℹ]  node "ip-10-0-10-72.ap-northeast-1.compute.internal" is ready
2022-08-26 13:33:03 [ℹ]  waiting for at least 1 node(s) to become ready in "test123-nodes"
2022-08-26 13:33:03 [ℹ]  nodegroup "test123-nodes" has 2 node(s)
2022-08-26 13:33:03 [ℹ]  node "ip-10-0-0-138.ap-northeast-1.compute.internal" is ready
2022-08-26 13:33:03 [ℹ]  node "ip-10-0-10-72.ap-northeast-1.compute.internal" is ready
2022-08-26 13:33:05 [ℹ]  kubectl command should work with "/home/ssm-user/.kube/config", try 'kubectl get nodes'
2022-08-26 13:33:05 [ℹ]  EKS cluster "test123-cluster" in "ap-northeast-1" region is ready
$

期待通り、問題なく作成できました!

EKS クラスターは、eksctl 以外でも、AWS マネジメントコンソール や AWS CLI でも作成できますが、私は、EKS クラスターを作成する場合は、eksctl を使う派ですので、ようやく バージョン1.23 を eksctl で作成することができた、と感じています。

Amazon EKS でサポートされる バージョンが追加されたとき、どれくらいのタイムラグで、そのバージョンに対応した eksctl がリリースされるのかは、今後も注目していきたいと思います。

AWS SAM における Lambda 関数のエイリアスとバージョンの重みづけについて

以前から、AWS SAM を使用して AWS Lambda 関数のエイリアスとバージョンの重みづけを設定したいなーと思ってました。

ただ、結論から言うと、AWS SAM 仕様では重みづけの設定する方法は無く、AWS CloudFormation のプロパティとして設定する必要があることがわかりました。


エイリアスやバージョンの発行、という観点だと、AWS SAM では、AutoPublishAlias というプロパティを使用できます。

docs.aws.amazon.com

このプロパティの指定だけで、AWS Lambda 関数のエイリアスと、それに関連付けられた AWS Lambda 関数のバージョンが自動的に発行されます。

AutoPublishAlias を指定している場合、SAM でスタックが作成、更新される都度に新しいバージョンが発行され、エイリアスの重みづけは常に 100% に設定されます。

AutoPublishAlias を指定したうえで、さらに DeploymentPreference というプロパティを指定すると、 新バージョンへの段階的な移行が可能になり、例えば Canary や Linear などの手法で、時間の経過とともに新バージョンに振り分けるトラフィック量を自動的に変更したり、CloudWatch Alarm と連動させて、デプロイをロールバックすることもできます。 docs.aws.amazon.com

この AutoPublishAliasDeploymentPreference は、非常に強力かつ便利ではあるのですが、意外に単純なことができないことがわかりました。

それは、Canary や Linear などの手法ではなく、単に エイリアスと複数バージョンの重みづけを設定すること です。これができないのです。

例えば、次のような手順を AWS SAM AutoPublishAliasDeploymentPreference を指定して 行うことはできません。

  1. AWS Lambda関数の バージョン 1を発行する。エイリアスと関連付けて重みづけは 100% とする。
  2. AWS Lambda関数のコードを更新して、バージョン 2を発行する。エイリアスで、バージョン 1 は90%、バージョン 2は 10%の重みづけにする。
  3. AWS Lambda関数の バージョン 2の、エイリアスて重みづけを 100% とする。

DeploymentPreference で Canary や Linear を指定するのも便利ですが、その場合は、あくまであらかじめ用意されている、Canary10Percent15Minutes や Linear10PercentEvery10Minutes というタイプから選ぶしかありません。

トラフィックを移行する割合を手動で指定したい、自分でトラフィックを切り替えるタイミングを制御したいという場合は、AWS SAM 仕様のプロパティでは対応するものが無いのです。


では、どうすればいいかというと、AWS CloudFormation のプロパティで指定する、という方法があります。

まず、AWS Lambda 関数の バージョン 1を発行し、エイリアスと関連付けて重みづけは 100% とするための SAM テンプレートの例をみてみましょう。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Globals:
  Function:
    Timeout: 3
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function 
    Properties:
      FunctionName: HelloSAMAliasVersion
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.7
  HelloWorldFunctionVersion1:
      Type: AWS::Lambda::Version
      Properties:
        FunctionName: !Ref HelloWorldFunction
        Description: v1
  HelloWorldFunctionAlias:
      Type: AWS::Lambda::Alias
      Properties:
        FunctionName: !Ref HelloWorldFunction
        FunctionVersion: !GetAtt HelloWorldFunctionVersion1.Version
        Name: live

SAM テンプレートとして記載していますが、AWS Lambda 関数のエイリアスやバージョンを発行する指定は、Type: AWS::Lambda::VersionType: AWS::Lambda::Alias と、AWS CloudFormation のプロパティを指定しています。

このSAM テンプレートを使用して デプロイし、スタックを作成すると、エイリアス名 live で、最初のバージョンが重みづけ 100% で設定された状態になります。

https://cdn-ak.f.st-hatena.com/images/fotolife/n/neob/20220821/20220821114557.png


次に、AWS Lambda 関数のコードを更新し、新しいバージョン 2として、エイリアス live に 10% の重みづけでトラフィックを振り分けたいとします。

その場合は、SAM テンプレートを次のように変更してデプロイします。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Globals:
  Function:
    Timeout: 3
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function 
    Properties:
      FunctionName: HelloSAMAliasVersion
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.7

  HelloWorldFunctionVersion1:
      Type: AWS::Lambda::Version
      Properties:
        FunctionName: !Ref HelloWorldFunction
        Description: v1
  HelloWorldFunctionVersion2:
      Type: AWS::Lambda::Version
      Properties:
        FunctionName: !Ref HelloWorldFunction
        Description: v2
  HelloWorldFunctionAlias:
      Type: AWS::Lambda::Alias
      Properties:
        FunctionName: !Ref HelloWorldFunction
        FunctionVersion: !GetAtt HelloWorldFunctionVersion1.Version
        Name: live
        RoutingConfig:
          AdditionalVersionWeights:
            - FunctionVersion: !GetAtt HelloWorldFunctionVersion2.Version
              FunctionWeight: 0.1

デプロイが完了すると、バージョン 1が 90%、バージョン 2が 10% になったことを確認できます。

https://cdn-ak.f.st-hatena.com/images/fotolife/n/neob/20220821/20220821114603.png


この後、バージョン 2 へ完全に切り替えたい場合は、このテンプレートの FunctionWeight: で指定する値を 1.0 変更してデプロイします。

https://cdn-ak.f.st-hatena.com/images/fotolife/n/neob/20220821/20220821114608.png


これらの プロパティについては、次のドキュメントも参考にしてください。

docs.amazonaws.cn


AWS CloudFormation のプロパティを使うと、自分で重みづけや、切り替えタイミングを制御できるのはいいのですが、プロパティの記載量はどうしても増えます。

SAM であれば、次のように、AWS Lambda 関数 で AutoPublishAlias を指定しつつ、さらに API GatewayAPIとの統合もシンプルに指定できます。

 HelloWorldFunction:
    Type: AWS::Serverless::Function 
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.7
      AutoPublishAlias: live
      Events:
        HelloWorld:
          Type: Api 
          Properties:
            Path: /hello
            Method: get

ただし、AWS CloudFormation のプロパティでエイリアスやバージョンを手動指定すると、このような書き方はできません。

なので、AutoPublishAlias で、自分でバージョンの重みづけができればいいのですが、それは現状ではサポートされていないようです。

(次の issue にも Feature request として挙げられていましたが、DeploymentPreferences を使いなさい、と close されてました。)

github.com

ちょっと残念ですね。

AWS SAM Accelerate と POSTMAN を使って AWS Lambda の Function URLs を手早く試す

AWS Lambda の Function URLs で、Auth タイプに AWS_IAM を指定した場合のアクセスを試そうと考えていたところ、AWS SAM Accelerate と POSTMAN を使えば、手早く試せるのではと思い立ったので、やってみました。

AWS Lambda の Function URLs については、次の AWS Blog の記事を参照してください。

aws.amazon.com

また、AWS SAM Accelerate については、次の AWS Blog の記事を参照してください。

aws.amazon.com

まず、SAM CLI が使用できる環境を用意します。

今回は SAM Accelerate を使うので、バージョン 1.34 以上が必要です。

SAM CLI のバージョンを確認します。

sam --version

1.34.1以上のバージョンでなければ、アップグレードします。

まず最新版をダウンロードします。

wget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip
unzip aws-sam-cli-linux-x86_64.zip -d sam-installation

次にインストールします。

sudo ./sam-installation/install --update

再び SAM CLI のバージョンを確認します。

sam --version

次のように、1.34 以降のバージョンになったので、大丈夫ですね。

SAM CLI, version 1.53.0

では、SAM の初期化を行います。

今回は、Python の Lambda 関数を作成します。また、ここでは Cloud 9 を使っているため、Pythonのバージョンを敢えて3.7 にしています。

sam init --app-template hello-world --name sam-tutorial --package-type Zip --runtime python3.7

あっという間に、SAM のリソースが用意されました。

今回は、Function URLs でのアクセスを試したいだけなので、Lambda 関数のコードは編集せず、Hello World のレベルのままにしておきます。

編集が必要なのは、template.yaml です。これを次のように書き換えます。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.7
      FunctionUrlConfig:
        AuthType: AWS_IAM
Outputs:
  HelloWorldFunctionEndpoint:
      Description: "HelloWorldFunction Function URL Endpoint"
      Value:
        Fn::GetAtt: HelloWorldFunctionUrl.FunctionUrl

Lambda 関数のプロパティで FunctionUrlConfig を指定しています。

また、Outputs セクションで、Function URLs のエンドポイントを出力するように指定しています。

このとき、属性名として、 <Lambda関数のリソース名>に Url.FunctionUrl をつけます。

これで、SAM のテンプレートは完成です。ではリソースを作成します。

cd sam-app
sam sync  --stack-name sam-app

SAM Accelerate の sync を使っているので、SAM の build や package、deploy を行う必要がありません。

次のように確認を求められたら、Y で応答します。

Enter Y to proceed with the command, or enter N to cancel:
 [Y/n]: Y

スタックが作成され、Output セクションで指定したエンドポイントが表示されます。

--------------------
Key                 HelloWorldFunctionEndpoint                                                  
Description         HelloWorldFunction Function URL Endpoint                                    
Value               https://nbuyqvkie2c64v7mjdt7sni3qy0lbgym.lambda-url.ap-northeast-1.on.aws/

Function URLs の Auth タイプが NONE であれば、単純にこのエンドポイントにアクセスするだけでよいのですが、今回は Auth タイプは AWS_IAM なので、アクセスキー ID やシークレットアクセスキーをもとに作成した署名 (AWS の署名v4) が必要です。

docs.aws.amazon.com

AWS の署名v4 を作成する方法はいくつかありますが、今回は POSTMAN を使ってみます。

www.postman.com

POSTMAN は、RESTful API を発行するときに、AWS の 署名v4 を自動生成する機能を提供しています。

次の図のように、指定して下さい。

Service Namelambda と入力するのを忘れないようにしましょう。

https://cdn-ak.f.st-hatena.com/images/fotolife/n/neob/20220813/20220813165211.png

POSTMAN で Send ボタンを選択して、 Function URL のエンドポイントにリクエストを発行すると、次のようなレスポンスが返ってきます。

https://cdn-ak.f.st-hatena.com/images/fotolife/n/neob/20220813/20220813172724.png

正常にアクセスできましたね。

試しに、正しくないアクセスキー ID を指定してみると、ステータスコード 403で 次のようなメッセージが返されます。

{
    "message": "The security token included in the request is invalid."
}

では最後に、作成した Lambda 関数を削除します。

これも、 SAM CLI から削除できます。確認を求められたら、 y で応答します。

sam delete --stack-name sam-app
        Are you sure you want to delete the stack sam-app in the region ap-northeast-1 ? [y/N]: y
        Do you want to delete the template file a19a97a7b854a2609df1ae91982ee843.template in S3? [y/N]: y

以上です!

Lambda 関数の Function URLs を試すだけであれば、マネジメントコンソールから手作業で作成してもいいのですが、デモ環境として再利用することも考慮し、今回は SAM を使ってみました。

ただし、SAM においても、package や deploy で多くのパラメータを指定するような操作はしたくなかったので、SAM Accelerate を使いました。

また、AWS の 署名v4 の生成には、POSTMAN を活用しました。

うまくツールを活用することで、あまり時間をかけず効率的に動作検証できますね。(横着ともいわれそうですが...)