Kanji
・雲端架構工程師 / 自由職業 ・1993年出生 ・愛媛縣出身 / 現居東京都澀谷區 ・5年 AWS 實戰經驗 個人檔案詳情
目錄
LocalStack 是一個用於在本地環境中模擬 AWS 雲服務的工具。 透過在本地模仿 AWS 服務,開發人員可以在沒有 Internet 連線的情況下使用 AWS CLI 和開發工具包進行測試。
使用免費計劃,您可以在本地模擬某些 AWS 服務,但並非所有服務都可用。 支援 EC2、VPC、Lambda、S3、DynamoDB、SNS 和 SQS 等主要服務。
LocalStack 作為 Docker 容器提供,使 Docker 的設定變得簡單。
Previous2 是一個用於生成 AWS CloudFormation 模板的工具。 它使用 IAM 使用者或 STS 憑證掃描您的 AWS 賬戶中的資源,併為 CloudFormation、CDK、Terraform、Pulumi 等生成基礎設施即程式碼 (IaC) 模板。 它還支援 Draw.io(測試版),但根據我的經驗,它不適用於 VPC 和 EC2 建立。
與 LocalStack 一樣,Former2 可作為 Docker 容器使用,並且可以使用 Docker 輕鬆設定。
本文介紹了LocalStack+Former2的設定,有以下三個要點:
LocalStack 賬戶有 14 天的試用期,在此期間您可以使用 LocalStack 資源瀏覽器透過 GUI 檢視 AWS 資源。 試用後,您需要付費計劃才能使用 GUI。 透過使用Former2,您可以 視覺化並檢查AWS資源狀態,而無需擔心試用期。
雖然 Previous2 作為 Web 服務提供,但開源版本作為 Docker 容器提供,可以使用 Docker Compose 與 LocalStack 進行編排。
您可以克隆 GitHub 儲存庫並使用 Docker Compose 啟動它,如下所示:
克隆儲存庫或建立 Docker Compose 檔案並不困難,但 本文介紹了一種使用 DinD (Docker-in-Docker) 在單個容器中構建和執行 Docker 命令的方法。
前者將設定儲存在瀏覽器的本地儲存中,因此清除瀏覽器快取將刪除您的設定。 即使在 Docker 容器中執行,也沒有預設的方式來儲存設定,因此如果重置它們,您必須手動重新配置它們。 本文介紹了一種解決方法: 將 Previous2 設定寫入 JavaScript 檔案並在容器啟動時應用它們。
在繼續之前,請注意以下事項: LocalStack 的行為可能與實際的 AWS 環境不同,因此建議僅用於自學目的。
以下是我觀察到的一些行為:
即使部署在 LocalStack 中有效,部署到生產時也可能會出現問題。 使用此環境學習 AWS CLI 或 CloudFormation,或參加內部研討會,瞭解這些限制。
本文假設滿足以下先決條件:
首先,在工作目錄中建立以下三個檔案:
${WORK_DIRECTORY}/ ${WORK_DIRECTORY}/docker-compose.yml ${WORK_DIRECTORY}/Dockerfile ${WORK_DIRECTORY}/setting.js # 使用Docker在本地環境中【免費】模擬AWS ( LocalStack/Former2 ) localstack-with-former2/ localstack-with-former2/docker-compose.yml localstack-with-former2/Dockerfile localstack-with-former2/setting.js
您可以在任何地方建立工作目錄。 例如:
WORK_DIRECTORY=$(pwd)/localstack-with-former2 mkdir -p ${WORK_DIRECTORY} cd ${WORK_DIRECTORY}
使用以下內容建立“Dockerfile”。 要點:
setting.js
index.html
/root/former2
/volume
docker-compose up
# REF: https://hub.docker.com/r/docker/compose FROM docker/compose:alpine-1.29.1 WORKDIR /root RUN apk add --no-cache git RUN git clone https://github.com/iann0036/former2.git COPY docker-compose.yml . # WORKAROUND: https://stackoverflow.com/questions/37013947/force-a-docker-build-to-rebuild-a-single-step ARG SETTING_TIMESTAMP=YYYYMMDDHHMMSS COPY setting.js . RUN cp setting.js former2/lib/setting.js && \ sed -i '/<\/head>/i <script src="lib/setting.js"></script>' former2/index.html CMD cp -R /root/former2 /volume && \ docker-compose up
建立“docker-compose.yml”檔案,如下所示。 要點:
docker.sock
/var/run/docker.sock
EXTRA_CORS_ALLOWED_ORIGINS
# REF: https://docs.docker.jp/compose/compose-file/compose-versioning.html version: "3.8" services: former2: container_name: former2 image: nginx:stable-alpine ports: - "127.0.0.1:8089:80" volumes: - ${WORK_DIRECTORY}/volume/former2:/usr/share/nginx/html - "/var/run/docker.sock:/var/run/docker.sock" # REF: https://docs.localstack.cloud/getting-started/installation/#starting-localstack-with-docker localstack: container_name: localstack image: localstack/localstack ports: - "4566:4566" - "4510-4559:4510-4559" environment: - DEBUG=${DEBUG-} - DOCKER_HOST=unix:///var/run/docker.sock # REF: https://github.com/iann0036/former2 - EXTRA_CORS_ALLOWED_ORIGINS=chrome-extension://fhejmeojlbhfhjndnkkleooeejklmigi volumes: - ${WORK_DIRECTORY}/volume/localstack:/var/lib/localstack - "/var/run/docker.sock:/var/run/docker.sock"
建立“setting.js”檔案,如下所示。 這些設定基於 master·iann0036/former2 上的 former2/js/app.js 。 此處僅設定預設區域、CloudFormation 模板縮排和 LocalStack 端點使用情況。
window.localStorage.setItem('region', "ap-northeast-1"); window.localStorage.setItem('cfnspacing',"2"); window.localStorage.setItem('uselocalstackendpoint', "true"); window.localStorage.setItem('logicalidstrategy', "longtypeprefixoptionalindexsuffix"); // default window.localStorage.setItem('defaultoutput', "cloudformation"); // default window.localStorage.setItem('iaclangselect', "typescript"); // default window.localStorage.setItem('skipirrelevantresources', "true"); // default window.localStorage.setItem('relatedresourcessetting', ""); // default window.localStorage.setItem('includedefaultresources', ""); // default
使用“準備步驟 1”中的檔案構建 Docker 映像:
--platform=linux/amd64
--build-arg SETTING_TIMESTAMP=$(date +%Y%m%d%H%M%S)
docker build \ --platform=linux/amd64 \ --build-arg SETTING_TIMESTAMP=$(date +%Y%m%d%H%M%S) \ -t localstack-with-former2:latest \ .
啟動 LocalStack 和 Previous2:
--detach
docker run \ --name localstack-with-former2 \ --platform=linux/amd64 \ --privileged \ --detach \ --rm \ -it \ -e WORK_DIRECTORY=$(pwd) \ -v /var/run/docker.sock:/var/run/docker.sock \ -v $(pwd)/volume:/volume \ localstack-with-former2:latest
注意: 在構建 Docker 映像的目錄中執行這些命令。
在 docker-compose.yml 中,Former2 容器掛載 ${WORK_DIRECTORY}/volume/former2:/usr/share/nginx/html 。 由於“docker-compose up”在容器內執行,您可能期望掛載容器內的“${WORK_DIRECTORY}/volume/former2”,但實際上,源是主機目錄。 因此,安裝“/root/former2”(僅存在於容器內部)是不可能的。 請參閱: linux - Docker 中的 Docker 無法掛載卷 - 堆疊記憶體溢位
docker-compose.yml
${WORK_DIRECTORY}/volume/former2:/usr/share/nginx/html
因此,該過程是:
-v $(pwd)/volume:/volume
${WORK_DIRECTORY}/volume
首先,配置 AWS CLI 以使用 LocalStack。
您可以使用環境變數或 AWS CLI 配置檔案。 對於環境變數,您每次都必須設定它們。 使用配置檔案,您只需配置一次並指定命令的配置檔案。
aws configure set aws_access_key_id localstack --profile localstack aws configure set aws_secret_access_key localstack --profile localstack aws configure set region ap-northeast-1 --profile localstack aws configure set aws_endpoint_url http://localhost:4566 --profile localstack
export AWS_ACCESS_KEY_ID=localstack export AWS_SECRET_ACCESS_KEY=localstack export AWS_REGION=ap-northeast-1 export AWS_ENDPOINT_URL=http://localhost:4566
假設您使用配置檔案方法配置了 AWS CLI,一旦 LocalStack 執行,您就可以使用 AWS CLI 與資源互動。
首先,驗證 AWS CLI 對 LocalStack 的訪問:
aws sts \ get-caller-identity \ --profile localstack
如果您看到如下響應,則說明您的配置正確(帳戶 ID 為“000000000000”):
# Example output % aws sts get-caller-identity \ --profile localstack { "UserId": "AKIAIOSFODNN7EXAMPLE", "Account": "000000000000", "Arn": "arn:aws:iam::000000000000:root" }
接下來,建立一個示例 S3 儲存桶(儲存桶名稱不需要全域性唯一):
aws s3api \ create-bucket \ --bucket hoge-foo-bar \ --create-bucket-configuration LocationConstraint=ap-northeast-1 \ --profile localstack
# Example output % aws s3api \ create-bucket \ --bucket hoge-foo-bar \ --create-bucket-configuration LocationConstraint=ap-northeast-1 \ --profile localstack { "Location": "http://hoge-foo-bar.s3.localhost.localstack.cloud:4566/" }
注意:停止容器時資源將被刪除。要保留資源,請保持容器執行。
檢查您使用Former2 建立的儲存桶。 訪問 http://127.0.0.1:8089/ ,然後進入“儲存”->“S3”->“儲存桶”。 您應該會看到您的儲存桶顯示如下。
對於在 Previous2 中不可見的配置值,請使用 AWS CLI。 例如,要檢查 CloudFormation 堆疊的狀態,請使用 AWS CLI。 以下是名為“sample-vpc-stack”的堆疊的命令示例。使用 jq 將輸出格式化為表格。
# Stack List aws cloudformation describe-stacks \ --profile localstack \ --query "Stacks[].{StackName: StackName, StackStatus: StackStatus, CreationTime: CreationTime, LastUpdatedTime: LastUpdatedTime}" \ --output json \ | jq -r '["StackName","StackStatus","CreationTime","LastUpdatedTime"], (.[] | [.StackName, .StackStatus, .CreationTime, .LastUpdatedTime]) | @tsv' \ | column -t -s $'\t' # List of Stack Resources stack_name="sample-vpc-stack" aws cloudformation list-stack-resources \ --stack-name "${stack_name}" \ --profile localstack \ --output json \ | jq -r '["LogicalResourceId","PhysicalResourceId","ResourceType","ResourceStatus"], (.StackResourceSummaries[] | [.LogicalResourceId, .PhysicalResourceId, .ResourceType, .ResourceStatus]) | @tsv' \ | column -t -s $'\t' # Stack Events List stack_name="sample-vpc-stack" aws cloudformation describe-stack-events \ --stack-name "${stack_name}" \ --query "StackEvents[].{Timestamp: Timestamp, LogicalResourceId: LogicalResourceId, ResourceType: ResourceType, ResourceStatus: ResourceStatus, ResourceStatusReason: ResourceStatusReason}" \ --profile localstack \ --output json \ | jq -r '["Timestamp","LogicalResourceId","ResourceType","ResourceStatus","ResourceStatusReason"], (.[] | [.Timestamp, .LogicalResourceId, .ResourceType, .ResourceStatus, .ResourceStatusReason]) | @tsv' \ | column -t -s $'\t' # Stack Outputs List stack_name="sample-vpc-stack" aws cloudformation describe-stacks \ --stack-name "${stack_name}" \ --query "Stacks[].Outputs[].{OutputKey: OutputKey, OutputValue: OutputValue, ExportName: ExportName}" \ --profile localstack \ --output json \ | jq -r '["OutputKey","OutputValue"], (.[] | [.OutputKey, .OutputValue, .ExportName]) | @tsv' \ | column -t -s $'\t'
下面是執行結果的示例。本例中使用的VPC的CloudFormation模板將在單獨的文章中介紹。
# Execution Result - Stack List % aws cloudformation describe-stacks \ --profile localstack \ --query "Stacks[].{StackName: StackName, StackStatus: StackStatus, CreationTime: CreationTime, LastUpdatedTime: LastUpdatedTime}" \ --output json \ | jq -r '["StackName","StackStatus","CreationTime","LastUpdatedTime"], (.[] | [.StackName, .StackStatus, .CreationTime, .LastUpdatedTime]) | @tsv' \ | column -t -s $'\t' StackName StackStatus CreationTime LastUpdatedTime sample-vpc-stack CREATE_COMPLETE 2025-05-25T01:49:43.238000+00:00 2025-05-25T01:49:43.238000+00:00 # Execution Result - Stack Resource List % stack_name="sample-vpc-stack" aws cloudformation list-stack-resources \ --stack-name "${stack_name}" \ --profile localstack \ --output json \ | jq -r '["LogicalResourceId","PhysicalResourceId","ResourceType","ResourceStatus"], (.StackResourceSummaries[] | [.LogicalResourceId, .PhysicalResourceId, .ResourceType, .ResourceStatus]) | @tsv' \ | column -t -s $'\t' LogicalResourceId PhysicalResourceId ResourceType ResourceStatus VPC1 vpc-4bd2b9a09d788f172 AWS::EC2::VPC CREATE_COMPLETE InternetGateway igw-9bbb17a1eaf64992b AWS::EC2::InternetGateway CREATE_COMPLETE FlowLogsIAMRole AWS::IAM::Role CREATE_COMPLETE PublicSubnet1 subnet-c0c96c0f53f7f1cd7 AWS::EC2::Subnet CREATE_COMPLETE PublicSubnet2 subnet-836137197cc3767a2 AWS::EC2::Subnet CREATE_COMPLETE PrivateSubnet1 subnet-197c985876fcbfdac AWS::EC2::Subnet CREATE_COMPLETE PrivateSubnet2 subnet-a059fb7bd23898fd7 AWS::EC2::Subnet CREATE_COMPLETE ProtectedSubnet1 subnet-1ca041ff52b2493fb AWS::EC2::Subnet CREATE_COMPLETE ProtectedSubnet2 subnet-eff4ebad7049f6c6f AWS::EC2::Subnet CREATE_COMPLETE PublicRouteTable rtb-6f5f999ed1a475a4e AWS::EC2::RouteTable CREATE_COMPLETE PrivateSubnet1RouteTable AWS::EC2::RouteTable CREATE_COMPLETE PrivateSubnet2RouteTable AWS::EC2::RouteTable CREATE_COMPLETE ProtectedRouteTable rtb-453340a863a7a1059 AWS::EC2::RouteTable CREATE_COMPLETE CustomNetworkAcl acl-b0001fb613e8118d2 AWS::EC2::NetworkAcl CREATE_COMPLETE VPCFlowLog1 AWS::EC2::FlowLog CREATE_COMPLETE VPCGatewayAttachment AWS::EC2::VPCGatewayAttachment CREATE_COMPLETE PublicSubnet1RouteTableAssociation rtbassoc-c838b296a6edb9a37 AWS::EC2::SubnetRouteTableAssociation CREATE_COMPLETE PublicSubnet2RouteTableAssociation rtbassoc-5fe392e039de6701d AWS::EC2::SubnetRouteTableAssociation CREATE_COMPLETE PrivateSubnet1RouteTableAssociation AWS::EC2::SubnetRouteTableAssociation CREATE_COMPLETE PrivateSubnet2RouteTableAssociation AWS::EC2::SubnetRouteTableAssociation CREATE_COMPLETE ProtectedSubnet1RouteTableAssociation rtbassoc-896b8d426f6c0d5e4 AWS::EC2::SubnetRouteTableAssociation CREATE_COMPLETE ProtectedSubnet2RouteTableAssociation rtbassoc-8e3ec29094055a5bc AWS::EC2::SubnetRouteTableAssociation CREATE_COMPLETE CustomNetworkAclEntryInbound unknown AWS::EC2::NetworkAclEntry CREATE_COMPLETE CustomNetworkAclEntryOutbound unknown AWS::EC2::NetworkAclEntry CREATE_COMPLETE NaclAssociationPublicSubnet1 unknown AWS::EC2::SubnetNetworkAclAssociation CREATE_COMPLETE NaclAssociationPublicSubnet2 unknown AWS::EC2::SubnetNetworkAclAssociation CREATE_COMPLETE NaclAssociationPrivateSubnet1 unknown AWS::EC2::SubnetNetworkAclAssociation CREATE_COMPLETE NaclAssociationPrivateSubnet2 unknown AWS::EC2::SubnetNetworkAclAssociation CREATE_COMPLETE NaclAssociationProtectedSubnet1 unknown AWS::EC2::SubnetNetworkAclAssociation CREATE_COMPLETE NaclAssociationProtectedSubnet2 unknown AWS::EC2::SubnetNetworkAclAssociation CREATE_COMPLETE NATGateway1EIP AWS::EC2::EIP CREATE_COMPLETE NATGateway2EIP AWS::EC2::EIP CREATE_COMPLETE PublicRoute rtb-6f5f999ed1a475a4e~0.0.0.0/0 AWS::EC2::Route CREATE_COMPLETE NatGateway1 AWS::EC2::NatGateway CREATE_COMPLETE NatGateway2 AWS::EC2::NatGateway CREATE_COMPLETE PrivateSubnet2Route AWS::EC2::Route CREATE_COMPLETE PrivateSubnet1Route AWS::EC2::Route CREATE_COMPLETE # Execution Result - Stack Events List % stack_name="sample-vpc-stack" aws cloudformation describe-stack-events \ --stack-name "${stack_name}" \ --query "StackEvents[].{Timestamp: Timestamp, LogicalResourceId: LogicalResourceId, ResourceType: ResourceType, ResourceStatus: ResourceStatus, ResourceStatusReason: ResourceStatusReason}" \ --profile localstack \ --output json \ | jq -r '["Timestamp","LogicalResourceId","ResourceType","ResourceStatus","ResourceStatusReason"], (.[] | [.Timestamp, .LogicalResourceId, .ResourceType, .ResourceStatus, .ResourceStatusReason]) | @tsv' \ | column -t -s $'\t' Timestamp LogicalResourceId ResourceType ResourceStatus ResourceStatusReason 2025-05-25T01:49:44.440000+00:00 sample-vpc-stack AWS::CloudFormation::Stack CREATE_COMPLETE 2025-05-25T01:49:44.412000+00:00 PrivateSubnet1Route AWS::EC2::Route CREATE_COMPLETE 2025-05-25T01:49:44.411000+00:00 PrivateSubnet2Route AWS::EC2::Route CREATE_COMPLETE 2025-05-25T01:49:44.411000+00:00 NatGateway2 AWS::EC2::NatGateway CREATE_COMPLETE 2025-05-25T01:49:44.411000+00:00 NatGateway1 AWS::EC2::NatGateway CREATE_COMPLETE 2025-05-25T01:49:44.411000+00:00 PublicRoute AWS::EC2::Route CREATE_COMPLETE 2025-05-25T01:49:44.408000+00:00 PublicRoute AWS::EC2::Route CREATE_IN_PROGRESS 2025-05-25T01:49:44.398000+00:00 NATGateway2EIP AWS::EC2::EIP CREATE_COMPLETE 2025-05-25T01:49:44.398000+00:00 NATGateway1EIP AWS::EC2::EIP CREATE_COMPLETE 2025-05-25T01:49:44.398000+00:00 NaclAssociationProtectedSubnet2 AWS::EC2::SubnetNetworkAclAssociation CREATE_COMPLETE 2025-05-25T01:49:44.391000+00:00 NaclAssociationProtectedSubnet1 AWS::EC2::SubnetNetworkAclAssociation CREATE_COMPLETE 2025-05-25T01:49:44.384000+00:00 NaclAssociationPrivateSubnet2 AWS::EC2::SubnetNetworkAclAssociation CREATE_COMPLETE 2025-05-25T01:49:44.377000+00:00 NaclAssociationPrivateSubnet1 AWS::EC2::SubnetNetworkAclAssociation CREATE_COMPLETE 2025-05-25T01:49:44.370000+00:00 NaclAssociationPublicSubnet2 AWS::EC2::SubnetNetworkAclAssociation CREATE_COMPLETE 2025-05-25T01:49:44.363000+00:00 NaclAssociationPublicSubnet1 AWS::EC2::SubnetNetworkAclAssociation CREATE_COMPLETE 2025-05-25T01:49:44.356000+00:00 CustomNetworkAclEntryOutbound AWS::EC2::NetworkAclEntry CREATE_COMPLETE 2025-05-25T01:49:44.346000+00:00 CustomNetworkAclEntryInbound AWS::EC2::NetworkAclEntry CREATE_COMPLETE 2025-05-25T01:49:44.336000+00:00 ProtectedSubnet2RouteTableAssociation AWS::EC2::SubnetRouteTableAssociation CREATE_COMPLETE 2025-05-25T01:49:44.333000+00:00 ProtectedSubnet2RouteTableAssociation AWS::EC2::SubnetRouteTableAssociation CREATE_IN_PROGRESS 2025-05-25T01:49:44.326000+00:00 ProtectedSubnet1RouteTableAssociation AWS::EC2::SubnetRouteTableAssociation CREATE_COMPLETE 2025-05-25T01:49:44.323000+00:00 ProtectedSubnet1RouteTableAssociation AWS::EC2::SubnetRouteTableAssociation CREATE_IN_PROGRESS 2025-05-25T01:49:44.316000+00:00 PrivateSubnet2RouteTableAssociation AWS::EC2::SubnetRouteTableAssociation CREATE_COMPLETE 2025-05-25T01:49:44.316000+00:00 PrivateSubnet1RouteTableAssociation AWS::EC2::SubnetRouteTableAssociation CREATE_COMPLETE 2025-05-25T01:49:44.316000+00:00 PublicSubnet2RouteTableAssociation AWS::EC2::SubnetRouteTableAssociation CREATE_COMPLETE 2025-05-25T01:49:44.313000+00:00 PublicSubnet2RouteTableAssociation AWS::EC2::SubnetRouteTableAssociation CREATE_IN_PROGRESS 2025-05-25T01:49:44.306000+00:00 PublicSubnet1RouteTableAssociation AWS::EC2::SubnetRouteTableAssociation CREATE_COMPLETE 2025-05-25T01:49:44.299000+00:00 PublicSubnet1RouteTableAssociation AWS::EC2::SubnetRouteTableAssociation CREATE_IN_PROGRESS 2025-05-25T01:49:44.292000+00:00 VPCGatewayAttachment AWS::EC2::VPCGatewayAttachment CREATE_COMPLETE 2025-05-25T01:49:44.290000+00:00 VPCGatewayAttachment AWS::EC2::VPCGatewayAttachment CREATE_IN_PROGRESS 2025-05-25T01:49:44.283000+00:00 VPCFlowLog1 AWS::EC2::FlowLog CREATE_COMPLETE 2025-05-25T01:49:44.283000+00:00 CustomNetworkAcl AWS::EC2::NetworkAcl CREATE_COMPLETE 2025-05-25T01:49:44.280000+00:00 CustomNetworkAcl AWS::EC2::NetworkAcl CREATE_IN_PROGRESS 2025-05-25T01:49:44.269000+00:00 ProtectedRouteTable AWS::EC2::RouteTable CREATE_COMPLETE 2025-05-25T01:49:44.267000+00:00 ProtectedRouteTable AWS::EC2::RouteTable CREATE_IN_PROGRESS 2025-05-25T01:49:44.256000+00:00 PrivateSubnet2RouteTable AWS::EC2::RouteTable CREATE_COMPLETE 2025-05-25T01:49:44.256000+00:00 PrivateSubnet1RouteTable AWS::EC2::RouteTable CREATE_COMPLETE 2025-05-25T01:49:44.256000+00:00 PublicRouteTable AWS::EC2::RouteTable CREATE_COMPLETE 2025-05-25T01:49:44.253000+00:00 PublicRouteTable AWS::EC2::RouteTable CREATE_IN_PROGRESS 2025-05-25T01:49:44.242000+00:00 ProtectedSubnet2 AWS::EC2::Subnet CREATE_COMPLETE 2025-05-25T01:49:44.239000+00:00 ProtectedSubnet2 AWS::EC2::Subnet CREATE_IN_PROGRESS 2025-05-25T01:49:44.218000+00:00 ProtectedSubnet1 AWS::EC2::Subnet CREATE_COMPLETE 2025-05-25T01:49:44.215000+00:00 ProtectedSubnet1 AWS::EC2::Subnet CREATE_IN_PROGRESS 2025-05-25T01:49:44.193000+00:00 PrivateSubnet2 AWS::EC2::Subnet CREATE_COMPLETE 2025-05-25T01:49:44.190000+00:00 PrivateSubnet2 AWS::EC2::Subnet CREATE_IN_PROGRESS 2025-05-25T01:49:44.168000+00:00 PrivateSubnet1 AWS::EC2::Subnet CREATE_COMPLETE 2025-05-25T01:49:44.164000+00:00 PrivateSubnet1 AWS::EC2::Subnet CREATE_IN_PROGRESS 2025-05-25T01:49:44.143000+00:00 PublicSubnet2 AWS::EC2::Subnet CREATE_COMPLETE 2025-05-25T01:49:44.140000+00:00 PublicSubnet2 AWS::EC2::Subnet CREATE_IN_PROGRESS 2025-05-25T01:49:44.109000+00:00 PublicSubnet1 AWS::EC2::Subnet CREATE_COMPLETE 2025-05-25T01:49:44.103000+00:00 PublicSubnet1 AWS::EC2::Subnet CREATE_IN_PROGRESS 2025-05-25T01:49:44.042000+00:00 FlowLogsIAMRole AWS::IAM::Role CREATE_COMPLETE 2025-05-25T01:49:44.042000+00:00 InternetGateway AWS::EC2::InternetGateway CREATE_COMPLETE 2025-05-25T01:49:44.040000+00:00 InternetGateway AWS::EC2::InternetGateway CREATE_IN_PROGRESS 2025-05-25T01:49:44.031000+00:00 VPC1 AWS::EC2::VPC CREATE_COMPLETE 2025-05-25T01:49:43.320000+00:00 VPC1 AWS::EC2::VPC CREATE_IN_PROGRESS 2025-05-25T01:49:43.246000+00:00 sample-vpc-stack AWS::CloudFormation::Stack CREATE_IN_PROGRESS 2025-05-25T01:49:43.238000+00:00 sample-vpc-stack AWS::CloudFormation::Stack REVIEW_IN_PROGRESS # Execution Result - Stack Outputs List % stack_name="sample-vpc-stack" aws cloudformation describe-stacks \ --stack-name "${stack_name}" \ --query "Stacks[].Outputs[].{OutputKey: OutputKey, OutputValue: OutputValue, ExportName: ExportName}" \ --profile localstack \ --output json \ | jq -r '["OutputKey","OutputValue"], (.[] | [.OutputKey, .OutputValue, .ExportName]) | @tsv' \ | column -t -s $'\t' OutputKey OutputValue VPCId vpc-4bd2b9a09d788f172 sample-vpc-id PublicSubnet1Id subnet-c0c96c0f53f7f1cd7 sample-public-subnet1-id PublicSubnet2Id subnet-836137197cc3767a2 sample-public-subnet2-id PrivateSubnet1Id subnet-197c985876fcbfdac sample-private-subnet1-id PrivateSubnet2Id subnet-a059fb7bd23898fd7 sample-private-subnet2-id ProtectedSubnet1Id subnet-1ca041ff52b2493fb sample-protected-subnet1-id ProtectedSubnet2Id subnet-eff4ebad7049f6c6f sample-protected-subnet2-id