<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yoshiyuki Watanabe</title>
    <description>The latest articles on DEV Community by Yoshiyuki Watanabe (@yoshiyuki-watanabe).</description>
    <link>https://dev.to/yoshiyuki-watanabe</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2804521%2F83c48365-3e38-48c6-bea1-ea740c897614.jpeg</url>
      <title>DEV Community: Yoshiyuki Watanabe</title>
      <link>https://dev.to/yoshiyuki-watanabe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yoshiyuki-watanabe"/>
    <language>en</language>
    <item>
      <title>Trying MiniStack and StackPort</title>
      <dc:creator>Yoshiyuki Watanabe</dc:creator>
      <pubDate>Tue, 13 Oct 2026 21:52:57 +0000</pubDate>
      <link>https://dev.to/aws-builders/trying-ministack-and-stackport-110i</link>
      <guid>https://dev.to/aws-builders/trying-ministack-and-stackport-110i</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I tried MiniStack, a free local AWS emulator, and StackPort, a browser-based viewer for its resources.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ministackorg" rel="noopener noreferrer"&gt;
        ministackorg
      &lt;/a&gt; / &lt;a href="https://github.com/ministackorg/ministack" rel="noopener noreferrer"&gt;
        ministack
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Ministack: Free, open-source local AWS emulator - 60+ services, Terraform compatible, real databases. Free forever. MIT   licensed.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/ministackorg/ministack/ministack_logo.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fministackorg%2Fministack%2FHEAD%2Fministack_logo.png" alt="MiniStack — Free Open-Source AWS Emulator" width="400"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;MiniStack&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Free, open-source local AWS emulator. Free forever.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;60+ AWS services on a single port · Multi-account &amp;amp; multi-region · Terraform compatible · Real databases · MIT licensed&lt;/p&gt;

&lt;p&gt;
  &lt;a href="https://github.com/ministackorg/ministack/releases" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/52c908839464a777dd6a1b31c1f3028180157fd1addaff60e8923aea2ccbc9be/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f6d696e69737461636b6f72672f6d696e69737461636b" alt="GitHub release"&gt;&lt;/a&gt;
  &lt;a href="https://github.com/ministackorg/ministack/actions" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/766beda2e3c8cc06bb77aafd665d23ef37689c3369c88423253d043ce8f4faf8/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6d696e69737461636b6f72672f6d696e69737461636b2f63692e796d6c3f6272616e63683d6d61696e" alt="Build"&gt;&lt;/a&gt;
  &lt;a href="https://hub.docker.com/r/ministackorg/ministack" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5116838bc9910281409a171a54931cf2d9a5e6efb95bef7d1963b3f50a86a342/68747470733a2f2f696d672e736869656c64732e696f2f646f636b65722f70756c6c732f6d696e69737461636b6f72672f6d696e69737461636b" alt="Docker Pulls"&gt;&lt;/a&gt;
  &lt;a href="https://hub.docker.com/r/ministackorg/ministack" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/c715301d18b64582eb07e0e04302c2fc549a1664f62f4b0def306e7607af715e/68747470733a2f2f696d672e736869656c64732e696f2f646f636b65722f696d6167652d73697a652f6d696e69737461636b6f72672f6d696e69737461636b2f6c6174657374" alt="Docker Image Size"&gt;&lt;/a&gt;
  &lt;a href="https://github.com/ministackorg/ministack/blob/main/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/271a55255e48c4433890c1fd054fac1e9643d364851953b52b32422bc9bb16f4/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6d696e69737461636b6f72672f6d696e69737461636b" alt="License"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/be14f9fa3603b94c1802258e6acb2f8f1b234ead6ae0bfc316ba428dbf7e9d34/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f707974686f6e2d253345253230332e31302d626c7565"&gt;&lt;img src="https://camo.githubusercontent.com/be14f9fa3603b94c1802258e6acb2f8f1b234ead6ae0bfc316ba428dbf7e9d34/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f707974686f6e2d253345253230332e31302d626c7565" alt="Python"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
  &lt;a href="https://ministack.org" rel="nofollow noopener noreferrer"&gt;Ministack.org&lt;/a&gt; · &lt;a href="https://hub.docker.com/r/ministackorg/ministack" rel="nofollow noopener noreferrer"&gt;Docker Hub&lt;/a&gt; · &lt;a href="https://www.linkedin.com/company/ministackorg/" rel="nofollow noopener noreferrer"&gt;LinkedIn&lt;/a&gt;
&lt;/p&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why MiniStack?&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;LocalStack recently moved its core services behind a paid plan. If you relied on LocalStack Community for local development and CI/CD pipelines, MiniStack is your free alternative.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;60+ AWS services&lt;/strong&gt; emulated on a single port (4566)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drop-in compatible&lt;/strong&gt; — works with &lt;code&gt;boto3&lt;/code&gt;, AWS CLI, Terraform, CDK, Pulumi, any SDK&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-account &amp;amp; multi-region&lt;/strong&gt; — a 12-digit access key becomes the account, the SigV4 region scopes the state; isolated tenants and regions on one endpoint, like real AWS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon Bedrock locally&lt;/strong&gt; — Converse / InvokeModel with AWS-exact wire shapes; point &lt;code&gt;MINISTACK_BEDROCK_PROXY_URL&lt;/code&gt; at Ollama, llama.cpp, or vLLM and get real completions through the Bedrock API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real infrastructure&lt;/strong&gt; — RDS spins up actual Postgres/MySQL containers, ElastiCache spins…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/ministackorg/ministack" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/DaviReisVieira" rel="noopener noreferrer"&gt;
        DaviReisVieira
      &lt;/a&gt; / &lt;a href="https://github.com/DaviReisVieira/stackport" rel="noopener noreferrer"&gt;
        stackport
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Open-source universal AWS resource browser for MiniStack, Floci, LocalStack, Moto, and real AWS
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;p&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/stackport_logo.svg"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FDaviReisVieira%2Fstackport%2Fmain%2Fdocs%2Fimages%2Fstackport_logo.svg" alt="StackPort — Universal AWS Resource Browser" width="150"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;StackPort&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Universal AWS resource browser for local emulators and real AWS accounts.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Browse, inspect, and manage resources across 35 AWS services with dedicated UIs for S3, DynamoDB, Lambda, SQS, IAM, EC2, CloudWatch Logs, and Secrets Manager.&lt;/p&gt;
&lt;p&gt;
  &lt;a href="https://github.com/DaviReisVieira/stackport/actions/workflows/ci.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/DaviReisVieira/stackport/actions/workflows/ci.yml/badge.svg" alt="CI"&gt;&lt;/a&gt;
  &lt;a href="https://pypi.org/project/stackport/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/37faf86b4888cdc61a642be882355406e35ac86cc35b484bc2b8584637e01d03/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f737461636b706f7274" alt="PyPI Version"&gt;&lt;/a&gt;
  &lt;a href="https://hub.docker.com/r/davireis/stackport" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/73e0499df7a4a8f5ac87f59e64393f004b2b82cec4d11d5eda3cbc56a35acd4f/68747470733a2f2f696d672e736869656c64732e696f2f646f636b65722f70756c6c732f64617669726569732f737461636b706f7274" alt="Docker Pulls"&gt;&lt;/a&gt;
  &lt;a href="https://hub.docker.com/r/davireis/stackport" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/19d80b4c38d6b577ca6b48074d362d6d086ca0d9d123bc0dd58ca1f7e5fefc0e/68747470733a2f2f696d672e736869656c64732e696f2f646f636b65722f696d6167652d73697a652f64617669726569732f737461636b706f72742f6c6174657374" alt="Docker Image Size"&gt;&lt;/a&gt;
  &lt;a href="https://github.com/DaviReisVieira/stackport/blob/master/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/9c557d9e0bf169c335a2659db0338d7a36368430aa31d792ee441e913fca4834/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f44617669526569735669656972612f737461636b706f7274" alt="License"&gt;&lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/a479a6cadba72bc83a7a99ee8f32433b25b1a8d0b2d8379b666b343b5c7e5e3c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f707974686f6e2d332e31322d736c696d"&gt;&lt;img src="https://camo.githubusercontent.com/a479a6cadba72bc83a7a99ee8f32433b25b1a8d0b2d8379b666b343b5c7e5e3c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f707974686f6e2d332e31322d736c696d" alt="Python"&gt;&lt;/a&gt;
  &lt;a href="https://github.com/DaviReisVieira/stackport/stargazers" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ade0aff7334ec8bac5d0d1426656a3e05260c0a41512f97e6555cc442b072e20/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f44617669526569735669656972612f737461636b706f7274" alt="GitHub stars"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Screenshots&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Dashboard&lt;/strong&gt; — Service overview with resource counts and health status
&lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/dashboard.jpeg?v=2.1"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FDaviReisVieira%2Fstackport%2Fmain%2Fdocs%2Fimages%2Fdashboard.jpeg%3Fv%3D2.1" alt="StackPort Dashboard"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lambda Browser&lt;/strong&gt; — Function list with config, aliases, versions, event sources, and invocation panel
&lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/lambda.jpeg?v=2.1"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FDaviReisVieira%2Fstackport%2Fmain%2Fdocs%2Fimages%2Flambda.jpeg%3Fv%3D2.1" alt="Lambda Resources"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;S3 Browser&lt;/strong&gt; — File browser with upload, download, folder navigation, and tagging
&lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/s3.jpeg?v=2.1"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FDaviReisVieira%2Fstackport%2Fmain%2Fdocs%2Fimages%2Fs3.jpeg%3Fv%3D2.1" alt="S3 Browser"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Browse and inspect resources across &lt;strong&gt;35 AWS services&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8 dedicated service UIs&lt;/strong&gt; for S3, DynamoDB, Lambda, SQS, IAM, EC2, CloudWatch Logs, and Secrets Manager&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write operations&lt;/strong&gt; — upload/delete S3 objects, query DynamoDB, invoke Lambda, send/receive SQS messages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real AWS support&lt;/strong&gt; — connect to real AWS accounts with read-only mode by default&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-endpoint authentication&lt;/strong&gt; — default credentials, AWS profiles (SSO/AssumeRole), or static keys per endpoint&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Guided lessons&lt;/strong&gt; — hands-on AWS tutorials that run inside the console and…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/DaviReisVieira/stackport" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;This article builds the following pipeline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;EventBridge Scheduler invokes a Lambda function on a schedule&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Lambda function calls an API and publishes the result to SNS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SNS triggers a second Lambda function, which posts to a Slack Incoming Webhook&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The API key and the Webhook URL are stored as SecureString parameters in SSM Parameter Store&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Are MiniStack and StackPort?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  MiniStack
&lt;/h3&gt;

&lt;p&gt;MiniStack is a local AWS emulator under the MIT license. You can use more than 60 AWS services directly from the AWS CLI, boto3, Terraform, and CDK.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://ministack.org/" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fministack.org%2Fog-image.png" height="438" class="m-0" width="800"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://ministack.org/" rel="noopener noreferrer" class="c-link"&gt;
            MiniStack — The Best AWS Emulator | Free Open-Source LocalStack Alternative
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            The best AWS emulator and the best alternative to LocalStack. 60+ AWS services free forever — real Postgres, Redis, Docker containers, full Terraform / CDK / Pulumi support. MIT licensed.
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fministack.org%2Fministack_symbol.svg%3Fv%3D2" width="566" height="566"&gt;
          ministack.org
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  StackPort
&lt;/h3&gt;

&lt;p&gt;StackPort is a tool for browsing the resources of local emulators and real AWS accounts in a browser. It connects to emulators other than MiniStack (such as LocalStack) and to real AWS accounts.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://stackport.cloud/" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstackport.cloud%2Fimages%2Fdashboard.png" height="500" class="m-0" width="800"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://stackport.cloud/" rel="noopener noreferrer" class="c-link"&gt;
            StackPort: open-source web console for AWS emulators
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            StackPort is a free, open-source web console for MiniStack, Floci, LocalStack, Moto and real AWS. Browse 35 services, use 13 dedicated views, and learn AWS with guided lessons. One Docker image.
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstackport.cloud%2Ffavicon.svg" width="1024" height="1024"&gt;
          stackport.cloud
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;StackPort lets you browse the resources of 35 services.&lt;/p&gt;

&lt;p&gt;Eight of them have dedicated screens: S3, DynamoDB, Lambda, SQS, IAM, EC2, CloudWatch Logs, and Secrets Manager. For example, CloudWatch Logs lets you drill down from log groups to log streams to log events.&lt;/p&gt;

&lt;p&gt;The other services (such as SSM in this article) are shown as a searchable resource table with a JSON detail view.&lt;/p&gt;

&lt;p&gt;Note that StackPort does not support EventBridge Scheduler. The &lt;code&gt;events&lt;/code&gt; service only shows EventBridge rules and event buses, so I check the schedule with the CLI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;Locally, I run a mock server (&lt;code&gt;mock-api&lt;/code&gt;) in place of the external API. For Slack, I use a real Incoming Webhook, with separate channels for the local and AWS environments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl8ylejsuc9hrv18bwtl2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl8ylejsuc9hrv18bwtl2.png" alt="Local environment architecture" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two things differ between the local environment and real AWS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;External API: &lt;code&gt;mock-api&lt;/code&gt; locally, API Gateway (MOCK integration) on real AWS. Both return &lt;code&gt;GET /v1/status&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Slack destination: &lt;code&gt;#notify-demo-local&lt;/code&gt; locally, &lt;code&gt;#notify-demo-aws&lt;/code&gt; on real AWS&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The directory structure is as follows. Terraform is split into a shared module (&lt;code&gt;modules/notify&lt;/code&gt;) and one directory per environment (&lt;code&gt;environments/local&lt;/code&gt; and &lt;code&gt;environments/aws&lt;/code&gt;). Each environment has its own state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;code/
├── lambda/                          # Shared: the same code runs locally and on real AWS
│   ├── fetch_status/
│   │   └── app.py
│   └── notify_slack/
│       └── app.py
├── mock-api/                        # Local only: mock server standing in for the external API
│   ├── Dockerfile
│   └── server.py
├── scripts/
│   ├── put-parameters-aws.sh        # AWS only: registers parameters in the real SSM
│   └── put-parameters.sh            # Local only: registers parameters in MiniStack's SSM
├── terraform/
│   ├── environments/
│   │   ├── aws/                     # For real AWS: points at real AWS
│   │   │   ├── main.tf
│   │   │   ├── outputs.tf
│   │   │   ├── providers.tf
│   │   │   ├── terraform.tfvars
│   │   │   ├── terraform.tfvars.example
│   │   │   └── variables.tf
│   │   └── local/                   # For local: points at MiniStack
│   │       ├── main.tf
│   │       ├── outputs.tf
│   │       ├── providers.tf
│   │       ├── terraform.tfvars
│   │       ├── terraform.tfvars.example
│   │       └── variables.tf
│   └── modules/
│       └── notify/                  # Shared: Lambda, SNS, Scheduler, IAM, and more
│           ├── main.tf
│           ├── outputs.tf
│           ├── variables.tf
│           └── versions.tf
└── docker-compose.yml               # Local only: starts MiniStack, StackPort, and mock-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Building the Local Environment
&lt;/h2&gt;

&lt;p&gt;You need Docker (Docker Desktop, OrbStack, and so on), Terraform, and the AWS CLI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Start MiniStack, StackPort, and the Mock Server
&lt;/h3&gt;

&lt;p&gt;Start three containers with &lt;code&gt;docker-compose.yml&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ministack&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ministackorg/ministack:latest&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;4566:4566"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MINISTACK_REGION=ap-northeast-1&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;[&lt;/span&gt;
          &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;python"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-c"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;import&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;urllib.request;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;urllib.request.urlopen('http://localhost:4566/_ministack/health')"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
        &lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;3s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;

  &lt;span class="na"&gt;stackport&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;davireis/stackport:latest&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:8080"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;AWS_ENDPOINT_URL=http://ministack:4566&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;AWS_REGION=ap-northeast-1&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;AWS_ACCESS_KEY_ID=test&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;AWS_SECRET_ACCESS_KEY=test&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;[&lt;/span&gt;
          &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;python"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-c"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;import&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;urllib.request;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;urllib.request.urlopen('http://localhost:8080/api/health')"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
        &lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10s&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;3s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;ministack&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;service_healthy&lt;/span&gt;

  &lt;span class="c1"&gt;# Mock server standing in for the external API&lt;/span&gt;
  &lt;span class="na"&gt;mock-api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./mock-api&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8000:8000"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;EXPECTED_API_KEY=local-dummy-api-key&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The three containers are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ministack&lt;/code&gt;: the local AWS emulator. It accepts AWS API calls on port &lt;code&gt;4566&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;stackport&lt;/code&gt;: a web UI for browsing MiniStack's resources. It opens on port &lt;code&gt;8080&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mock-api&lt;/code&gt;: a mock server standing in for the external API. It runs on port &lt;code&gt;8000&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;mock-api&lt;/code&gt; is written with only the Python standard library. It has one endpoint that validates the &lt;code&gt;x-api-key&lt;/code&gt; header and returns a status.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;do_GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/v1/status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x-api-key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;EXPECTED_API_KEY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Forbidden&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ok&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;not found&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start the containers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;code
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;http://localhost:8080&lt;/code&gt; in a browser to see the StackPort dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9u9nkz5jd6hku83hei47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9u9nkz5jd6hku83hei47.png" alt="StackPort dashboard" width="800" height="1338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Register SecureString Parameters in SSM Parameter Store
&lt;/h3&gt;

&lt;p&gt;I register the API key and the Webhook URL outside Terraform.&lt;/p&gt;

&lt;p&gt;If you create them as &lt;code&gt;aws_ssm_parameter&lt;/code&gt; resources in Terraform, the values remain in the state file in plain text. Write-only arguments (&lt;code&gt;value_wo&lt;/code&gt;) in Terraform 1.11 and later keep them out of the state, but I don't use them here.&lt;/p&gt;

&lt;p&gt;I prepared a script (&lt;code&gt;scripts/put-parameters.sh&lt;/code&gt;) to register them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-euo&lt;/span&gt; pipefail

: &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SLACK_WEBHOOK_URL&lt;/span&gt;:?Set&lt;span class="p"&gt; SLACK_WEBHOOK_URL&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;test
export &lt;/span&gt;&lt;span class="nv"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;test
export &lt;/span&gt;&lt;span class="nv"&gt;AWS_DEFAULT_REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ap-northeast-1
&lt;span class="nv"&gt;ENDPOINT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localhost:4566

aws &lt;span class="nt"&gt;--endpoint-url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENDPOINT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; ssm put-parameter &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; /notify-demo/api-key &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--type&lt;/span&gt; SecureString &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--value&lt;/span&gt; local-dummy-api-key &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--overwrite&lt;/span&gt;

aws &lt;span class="nt"&gt;--endpoint-url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENDPOINT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; ssm put-parameter &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; /notify-demo/slack-webhook-url &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--type&lt;/span&gt; SecureString &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--value&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SLACK_WEBHOOK_URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--overwrite&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the Webhook URL, I use an Incoming Webhook issued for a Slack channel dedicated to local testing (&lt;code&gt;#notify-demo-local&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;SLACK_WEBHOOK_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;Webhook URL of the &lt;span class="nb"&gt;local &lt;/span&gt;channel&amp;gt; ./scripts/put-parameters.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running the script adds the parameters.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faktqrwbcogqpo9s0eltb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faktqrwbcogqpo9s0eltb.png" alt="StackPort SSM parameter list" width="800" height="604"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The displayed value is &lt;code&gt;ENCRYPTED:&lt;/code&gt; followed by a base64 string. It is not encrypted with KMS, and anyone can decode it back to the original value, so be careful when sharing screenshots.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frhbpiswuymm2qd271inx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frhbpiswuymm2qd271inx.png" alt="A SecureString value as seen in StackPort" width="799" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Write the Lambda Code
&lt;/h3&gt;

&lt;p&gt;This is the Lambda function that calls the API (&lt;code&gt;fetch_status&lt;/code&gt;). It gets the API key from SSM and publishes the API response to SNS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urllib.request&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;

&lt;span class="n"&gt;ssm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ssm&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sns&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;API_BASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;API_BASE_URL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;API_KEY_PARAM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;API_KEY_PARAM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;RESULT_TOPIC_ARN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;RESULT_TOPIC_ARN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;_api_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_api_key&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# Fetch from SSM only on a cold start; use the cache afterwards
&lt;/span&gt;    &lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="n"&gt;_api_key&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;_api_key&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ssm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_parameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;API_KEY_PARAM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WithDecryption&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;_api_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Parameter&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_api_key&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;API_BASE_URL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/v1/status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x-api-key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;get_api_key&lt;/span&gt;&lt;span class="p"&gt;()},&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# 4xx/5xx raise HTTPError, which makes the Lambda invocation fail
&lt;/span&gt;    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;API status: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;TopicArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;RESULT_TOPIC_ARN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Subject&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;API status check&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ensure_ascii&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the Lambda function for Slack notifications (&lt;code&gt;notify_slack&lt;/code&gt;). It extracts the SNS message and posts it to the Webhook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Records&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Sns&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;astimezone&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%Y-%m-%d %H:%M:%S %Z&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:white_check_mark: API status: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

        &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nf"&gt;get_webhook_url&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;pass&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neither piece of code contains any MiniStack-specific endpoint configuration. MiniStack injects &lt;code&gt;AWS_ENDPOINT_URL&lt;/code&gt; into the Lambda execution environment, so boto3 automatically points at MiniStack. The same code can be deployed to real AWS as is.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Create the Resources with Terraform
&lt;/h3&gt;

&lt;p&gt;The resources live in the shared module (&lt;code&gt;terraform/modules/notify/main.tf&lt;/code&gt;). I don't show every resource. Instead, I excerpt the points I designed to work on both MiniStack and real AWS.&lt;/p&gt;

&lt;p&gt;The external API URL is passed through the module variable &lt;code&gt;api_base_url&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_lambda_function"&lt;/span&gt; &lt;span class="s2"&gt;"fetch_status"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;function_name&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch_name&lt;/span&gt;
  &lt;span class="nx"&gt;role&lt;/span&gt;             &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch_status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;
  &lt;span class="nx"&gt;runtime&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"python3.14"&lt;/span&gt;
  &lt;span class="nx"&gt;handler&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"app.handler"&lt;/span&gt;
  &lt;span class="nx"&gt;filename&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;archive_file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch_status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;output_path&lt;/span&gt;
  &lt;span class="nx"&gt;source_code_hash&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;archive_file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch_status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;output_base64sha256&lt;/span&gt;
  &lt;span class="nx"&gt;timeout&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;

  &lt;span class="nx"&gt;environment&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;variables&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;API_BASE_URL&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;api_base_url&lt;/span&gt;
      &lt;span class="nx"&gt;API_KEY_PARAM&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;api_key_param&lt;/span&gt;
      &lt;span class="nx"&gt;RESULT_TOPIC_ARN&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_sns_topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;depends_on&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;aws_cloudwatch_log_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch_status&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;terraform/environments/&lt;/code&gt; contains one directory per environment (&lt;code&gt;local&lt;/code&gt; and &lt;code&gt;aws&lt;/code&gt;). Each has a &lt;code&gt;main.tf&lt;/code&gt; that calls the shared module and its own environment-specific settings.&lt;/p&gt;

&lt;p&gt;The only differences are &lt;code&gt;providers.tf&lt;/code&gt;, which decides the connection target, and &lt;code&gt;terraform.tfvars&lt;/code&gt;, which decides the external API URL.&lt;/p&gt;

&lt;p&gt;Because the directories are separate, the state is also separate for each environment.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;terraform/environments/local/providers.tf&lt;/code&gt;, the provider points only the services I use at MiniStack.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;access_key&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"test"&lt;/span&gt;
  &lt;span class="nx"&gt;secret_key&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"test"&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt;                      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-1"&lt;/span&gt;
  &lt;span class="nx"&gt;skip_credentials_validation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;skip_metadata_api_check&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;skip_requesting_account_id&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

  &lt;span class="nx"&gt;endpoints&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;iam&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:4566"&lt;/span&gt;
    &lt;span class="nx"&gt;lambda&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:4566"&lt;/span&gt;
    &lt;span class="nx"&gt;logs&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:4566"&lt;/span&gt;
    &lt;span class="nx"&gt;scheduler&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:4566"&lt;/span&gt;
    &lt;span class="nx"&gt;sns&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:4566"&lt;/span&gt;
    &lt;span class="nx"&gt;ssm&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:4566"&lt;/span&gt;
    &lt;span class="nx"&gt;sts&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:4566"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are the settings that make it work with MiniStack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;access_key&lt;/code&gt;, &lt;code&gt;secret_key&lt;/code&gt;: dummy values (&lt;code&gt;test&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;region&lt;/code&gt;: the region to deploy to&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;skip_credentials_validation&lt;/code&gt;: skips validating credentials through the STS API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;skip_metadata_api_check&lt;/code&gt;: skips the check against the AWS metadata API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;skip_requesting_account_id&lt;/code&gt;: skips retrieving the account ID&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;endpoints&lt;/code&gt;: points each service at MiniStack. Specify only the services you use&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The local directory (&lt;code&gt;terraform/environments/local/main.tf&lt;/code&gt;) calls the module. The external API URL is passed through the variable &lt;code&gt;api_base_url&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;"notify"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"../../modules/notify"&lt;/span&gt;

  &lt;span class="nx"&gt;region&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-1"&lt;/span&gt;
  &lt;span class="nx"&gt;api_base_url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;api_base_url&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The variable's value goes in &lt;code&gt;terraform/environments/local/terraform.tfvars&lt;/code&gt;. Because this file is not managed in Git, create it by copying the template (&lt;code&gt;terraform.tfvars.example&lt;/code&gt;). The Lambda function runs inside the MiniStack container, so it reaches &lt;code&gt;mock-api&lt;/code&gt; by its Compose service name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;api_base_url&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"http://mock-api:8000"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;terraform/environments/local
&lt;span class="nb"&gt;cp &lt;/span&gt;terraform.tfvars.example terraform.tfvars
&lt;span class="c"&gt;# Edit terraform.tfvars if needed&lt;/span&gt;
terraform init
terraform apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the result. The resources are created in MiniStack's default account ID (&lt;code&gt;000000000000&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;terraform apply
module.notify.data.archive_file.notify_slack: Reading...
module.notify.data.archive_file.fetch_status: Reading...
module.notify.data.archive_file.notify_slack: Read &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;68fb7c506afbeeab169fb65494efc63dd8acba90]
module.notify.data.archive_file.fetch_status: Read &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;013b111cb8285884b651e501fd6f84ad373f787a]
module.notify.data.aws_iam_policy_document.lambda_assume: Reading...
module.notify.data.aws_caller_identity.current: Reading...
module.notify.data.aws_iam_policy_document.lambda_assume: Read &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2690255455]
module.notify.data.aws_caller_identity.current: Read &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;000000000000]
module.notify.data.aws_iam_policy_document.scheduler_assume: Reading...
module.notify.data.aws_iam_policy_document.notify_slack: Reading...
module.notify.data.aws_iam_policy_document.scheduler_assume: Read &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;644537899]
module.notify.data.aws_iam_policy_document.notify_slack: Read &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2364181876]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create
 &amp;lt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;data resources&lt;span class="o"&gt;)&lt;/span&gt;

Terraform will perform the following actions:

  &lt;span class="c"&gt;# module.notify.data.aws_iam_policy_document.fetch_status will be read during apply&lt;/span&gt;
  &lt;span class="c"&gt;# (config refers to values not yet known)&lt;/span&gt;
 &amp;lt;&lt;span class="o"&gt;=&lt;/span&gt; data &lt;span class="s2"&gt;"aws_iam_policy_document"&lt;/span&gt; &lt;span class="s2"&gt;"fetch_status"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + json          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + minified_json &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + statement &lt;span class="o"&gt;{&lt;/span&gt;
          + actions   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
              + &lt;span class="s2"&gt;"ssm:GetParameter"&lt;/span&gt;,
            &lt;span class="o"&gt;]&lt;/span&gt;
          + resources &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
              + &lt;span class="s2"&gt;"arn:aws:ssm:ap-northeast-1:000000000000:parameter/notify-demo/api-key"&lt;/span&gt;,
            &lt;span class="o"&gt;]&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
      + statement &lt;span class="o"&gt;{&lt;/span&gt;
          + actions   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
              + &lt;span class="s2"&gt;"sns:Publish"&lt;/span&gt;,
            &lt;span class="o"&gt;]&lt;/span&gt;
          + resources &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
              + &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;,
            &lt;span class="o"&gt;]&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.data.aws_iam_policy_document.scheduler will be read during apply&lt;/span&gt;
  &lt;span class="c"&gt;# (config refers to values not yet known)&lt;/span&gt;
 &amp;lt;&lt;span class="o"&gt;=&lt;/span&gt; data &lt;span class="s2"&gt;"aws_iam_policy_document"&lt;/span&gt; &lt;span class="s2"&gt;"scheduler"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + json          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + minified_json &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + statement &lt;span class="o"&gt;{&lt;/span&gt;
          + actions   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
              + &lt;span class="s2"&gt;"lambda:InvokeFunction"&lt;/span&gt;,
            &lt;span class="o"&gt;]&lt;/span&gt;
          + resources &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
              + &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;,
            &lt;span class="o"&gt;]&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_cloudwatch_log_group.fetch_status will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_cloudwatch_log_group"&lt;/span&gt; &lt;span class="s2"&gt;"fetch_status"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + arn                         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + deletion_protection_enabled &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + log_group_class             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + name                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/aws/lambda/notify-demo-fetch-status"&lt;/span&gt;
      + name_prefix                 &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + region                      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-1"&lt;/span&gt;
      + retention_in_days           &lt;span class="o"&gt;=&lt;/span&gt; 7
      + skip_destroy                &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + tags_all                    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_cloudwatch_log_group.notify_slack will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_cloudwatch_log_group"&lt;/span&gt; &lt;span class="s2"&gt;"notify_slack"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + arn                         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + deletion_protection_enabled &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + log_group_class             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + name                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/aws/lambda/notify-demo-notify-slack"&lt;/span&gt;
      + name_prefix                 &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + region                      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-1"&lt;/span&gt;
      + retention_in_days           &lt;span class="o"&gt;=&lt;/span&gt; 7
      + skip_destroy                &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + tags_all                    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_iam_role.fetch_status will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_iam_role"&lt;/span&gt; &lt;span class="s2"&gt;"fetch_status"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + arn                   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + assume_role_policy    &lt;span class="o"&gt;=&lt;/span&gt; jsonencode&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;{&lt;/span&gt;
              + Statement &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
                  + &lt;span class="o"&gt;{&lt;/span&gt;
                      + Action    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;
                      + Effect    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
                      + Principal &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                          + Service &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"lambda.amazonaws.com"&lt;/span&gt;
                        &lt;span class="o"&gt;}&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt;,
                &lt;span class="o"&gt;]&lt;/span&gt;
              + Version   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;)&lt;/span&gt;
      + create_date           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + force_detach_policies &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + managed_policy_arns   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + max_session_duration  &lt;span class="o"&gt;=&lt;/span&gt; 3600
      + name                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-fetch-status-role"&lt;/span&gt;
      + name_prefix           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + path                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt;
      + tags_all              &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + unique_id             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + inline_policy &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_iam_role.notify_slack will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_iam_role"&lt;/span&gt; &lt;span class="s2"&gt;"notify_slack"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + arn                   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + assume_role_policy    &lt;span class="o"&gt;=&lt;/span&gt; jsonencode&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;{&lt;/span&gt;
              + Statement &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
                  + &lt;span class="o"&gt;{&lt;/span&gt;
                      + Action    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;
                      + Effect    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
                      + Principal &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                          + Service &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"lambda.amazonaws.com"&lt;/span&gt;
                        &lt;span class="o"&gt;}&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt;,
                &lt;span class="o"&gt;]&lt;/span&gt;
              + Version   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;)&lt;/span&gt;
      + create_date           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + force_detach_policies &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + managed_policy_arns   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + max_session_duration  &lt;span class="o"&gt;=&lt;/span&gt; 3600
      + name                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-notify-slack-role"&lt;/span&gt;
      + name_prefix           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + path                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt;
      + tags_all              &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + unique_id             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + inline_policy &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_iam_role.scheduler will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_iam_role"&lt;/span&gt; &lt;span class="s2"&gt;"scheduler"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + arn                   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + assume_role_policy    &lt;span class="o"&gt;=&lt;/span&gt; jsonencode&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;{&lt;/span&gt;
              + Statement &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
                  + &lt;span class="o"&gt;{&lt;/span&gt;
                      + Action    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;
                      + Condition &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                          + StringEquals &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                              + &lt;span class="s2"&gt;"aws:SourceAccount"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"000000000000"&lt;/span&gt;
                            &lt;span class="o"&gt;}&lt;/span&gt;
                        &lt;span class="o"&gt;}&lt;/span&gt;
                      + Effect    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
                      + Principal &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                          + Service &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"scheduler.amazonaws.com"&lt;/span&gt;
                        &lt;span class="o"&gt;}&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt;,
                &lt;span class="o"&gt;]&lt;/span&gt;
              + Version   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;)&lt;/span&gt;
      + create_date           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + force_detach_policies &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + managed_policy_arns   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + max_session_duration  &lt;span class="o"&gt;=&lt;/span&gt; 3600
      + name                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-scheduler-role"&lt;/span&gt;
      + name_prefix           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + path                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt;
      + tags_all              &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + unique_id             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + inline_policy &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_iam_role_policy.fetch_status will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_iam_role_policy"&lt;/span&gt; &lt;span class="s2"&gt;"fetch_status"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + name        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + name_prefix &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + policy      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + role        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_iam_role_policy.notify_slack will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_iam_role_policy"&lt;/span&gt; &lt;span class="s2"&gt;"notify_slack"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + name        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + name_prefix &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + policy      &lt;span class="o"&gt;=&lt;/span&gt; jsonencode&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;{&lt;/span&gt;
              + Statement &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
                  + &lt;span class="o"&gt;{&lt;/span&gt;
                      + Action   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ssm:GetParameter"&lt;/span&gt;
                      + Effect   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
                      + Resource &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:ssm:ap-northeast-1:000000000000:parameter/notify-demo/slack-webhook-url"&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt;,
                &lt;span class="o"&gt;]&lt;/span&gt;
              + Version   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;)&lt;/span&gt;
      + role        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_iam_role_policy.scheduler will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_iam_role_policy"&lt;/span&gt; &lt;span class="s2"&gt;"scheduler"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + name        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + name_prefix &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + policy      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + role        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_iam_role_policy_attachment.fetch_status_logs will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_iam_role_policy_attachment"&lt;/span&gt; &lt;span class="s2"&gt;"fetch_status_logs"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + policy_arn &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"&lt;/span&gt;
      + role       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-fetch-status-role"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_iam_role_policy_attachment.notify_slack_logs will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_iam_role_policy_attachment"&lt;/span&gt; &lt;span class="s2"&gt;"notify_slack_logs"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + policy_arn &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"&lt;/span&gt;
      + role       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-notify-slack-role"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_lambda_function.fetch_status will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_lambda_function"&lt;/span&gt; &lt;span class="s2"&gt;"fetch_status"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + architectures                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + arn                            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + code_sha256                    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + filename                       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./build/fetch_status.zip"&lt;/span&gt;
      + function_name                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-fetch-status"&lt;/span&gt;
      + handler                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"app.handler"&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + invoke_arn                     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + last_modified                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + memory_size                    &lt;span class="o"&gt;=&lt;/span&gt; 128
      + package_type                   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Zip"&lt;/span&gt;
      + publish                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + qualified_arn                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + qualified_invoke_arn           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + region                         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-1"&lt;/span&gt;
      + reserved_concurrent_executions &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;
      + response_streaming_invoke_arn  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + role                           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + runtime                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"python3.14"&lt;/span&gt;
      + signing_job_arn                &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + signing_profile_version_arn    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + skip_destroy                   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + source_code_hash               &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"So5oKi3b/bEDekVIzzKxoKwo1aO2n/JdG+Ioj2nhtVw="&lt;/span&gt;
      + source_code_size               &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + tags_all                       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + &lt;span class="nb"&gt;timeout&lt;/span&gt;                        &lt;span class="o"&gt;=&lt;/span&gt; 30
      + version                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + environment &lt;span class="o"&gt;{&lt;/span&gt;
          + variables &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

      + ephemeral_storage &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + logging_config &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + tracing_config &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_lambda_function.notify_slack will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_lambda_function"&lt;/span&gt; &lt;span class="s2"&gt;"notify_slack"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + architectures                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + arn                            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + code_sha256                    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + filename                       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./build/notify_slack.zip"&lt;/span&gt;
      + function_name                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-notify-slack"&lt;/span&gt;
      + handler                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"app.handler"&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + invoke_arn                     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + last_modified                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + memory_size                    &lt;span class="o"&gt;=&lt;/span&gt; 128
      + package_type                   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Zip"&lt;/span&gt;
      + publish                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + qualified_arn                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + qualified_invoke_arn           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + region                         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-1"&lt;/span&gt;
      + reserved_concurrent_executions &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;
      + response_streaming_invoke_arn  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + role                           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + runtime                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"python3.14"&lt;/span&gt;
      + signing_job_arn                &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + signing_profile_version_arn    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + skip_destroy                   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + source_code_hash               &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"M+ENHhkFRJqThFhPFiREbrEpiqqEf0cJLzdvTNzrMUY="&lt;/span&gt;
      + source_code_size               &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + tags_all                       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + &lt;span class="nb"&gt;timeout&lt;/span&gt;                        &lt;span class="o"&gt;=&lt;/span&gt; 30
      + version                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + environment &lt;span class="o"&gt;{&lt;/span&gt;
          + variables &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
              + &lt;span class="s2"&gt;"TZ"&lt;/span&gt;                &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Asia/Tokyo"&lt;/span&gt;
              + &lt;span class="s2"&gt;"WEBHOOK_URL_PARAM"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/notify-demo/slack-webhook-url"&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

      + ephemeral_storage &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + logging_config &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + tracing_config &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_lambda_permission.notify_slack_from_sns will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_lambda_permission"&lt;/span&gt; &lt;span class="s2"&gt;"notify_slack_from_sns"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + action              &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"lambda:InvokeFunction"&lt;/span&gt;
      + function_name       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-notify-slack"&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + principal           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sns.amazonaws.com"&lt;/span&gt;
      + region              &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-1"&lt;/span&gt;
      + source_arn          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + statement_id        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"AllowExecutionFromSNS"&lt;/span&gt;
      + statement_id_prefix &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_scheduler_schedule.fetch_status will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_scheduler_schedule"&lt;/span&gt; &lt;span class="s2"&gt;"fetch_status"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + action_after_completion      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + arn                          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + group_name                   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + name                         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-fetch-status"&lt;/span&gt;
      + name_prefix                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + region                       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-1"&lt;/span&gt;
      + schedule_expression          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"rate(1 minute)"&lt;/span&gt;
      + schedule_expression_timezone &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"UTC"&lt;/span&gt;
      + state                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ENABLED"&lt;/span&gt;

      + flexible_time_window &lt;span class="o"&gt;{&lt;/span&gt;
          + mode &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"OFF"&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

      + target &lt;span class="o"&gt;{&lt;/span&gt;
          + arn      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
          + input    &lt;span class="o"&gt;=&lt;/span&gt; jsonencode&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="o"&gt;{&lt;/span&gt;
                  + &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"scheduler"&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;)&lt;/span&gt;
          + role_arn &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_sns_topic.result will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_sns_topic"&lt;/span&gt; &lt;span class="s2"&gt;"result"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + arn                         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + beginning_archive_time      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + content_based_deduplication &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + fifo_throughput_scope       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + fifo_topic                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + maximum_message_size        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + name                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-result"&lt;/span&gt;
      + name_prefix                 &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + owner                       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + policy                      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + region                      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-1"&lt;/span&gt;
      + signature_version           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + tags_all                    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + tracing_config              &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_sns_topic_subscription.result_to_notify_slack will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_sns_topic_subscription"&lt;/span&gt; &lt;span class="s2"&gt;"result_to_notify_slack"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + arn                             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + confirmation_timeout_in_minutes &lt;span class="o"&gt;=&lt;/span&gt; 1
      + confirmation_was_authenticated  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + endpoint                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + endpoint_auto_confirms          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + filter_policy_scope             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                              &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + owner_id                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + pending_confirmation            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + protocol                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"lambda"&lt;/span&gt;
      + raw_message_delivery            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + region                          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-1"&lt;/span&gt;
      + topic_arn                       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

Plan: 16 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + fetch_status_function_name &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-fetch-status"&lt;/span&gt;

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only &lt;span class="s1"&gt;'yes'&lt;/span&gt; will be accepted to approve.

  Enter a value: &lt;span class="nb"&gt;yes

&lt;/span&gt;module.notify.aws_cloudwatch_log_group.notify_slack: Creating...
module.notify.aws_cloudwatch_log_group.fetch_status: Creating...
module.notify.aws_iam_role.fetch_status: Creating...
module.notify.aws_iam_role.scheduler: Creating...
module.notify.aws_sns_topic.result: Creating...
module.notify.aws_iam_role.notify_slack: Creating...
module.notify.aws_iam_role.fetch_status: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify-demo-fetch-status-role]
module.notify.aws_iam_role.scheduler: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify-demo-scheduler-role]
module.notify.aws_iam_role.notify_slack: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify-demo-notify-slack-role]
module.notify.aws_cloudwatch_log_group.fetch_status: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/aws/lambda/notify-demo-fetch-status]
module.notify.aws_cloudwatch_log_group.notify_slack: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/aws/lambda/notify-demo-notify-slack]
module.notify.aws_sns_topic.result: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arn:aws:sns:ap-northeast-1:000000000000:notify-demo-result]
module.notify.aws_iam_role_policy_attachment.fetch_status_logs: Creating...
module.notify.data.aws_iam_policy_document.fetch_status: Reading...
module.notify.aws_iam_role_policy_attachment.notify_slack_logs: Creating...
module.notify.aws_iam_role_policy.notify_slack: Creating...
module.notify.data.aws_iam_policy_document.fetch_status: Read &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;193309822]
module.notify.aws_lambda_function.notify_slack: Creating...
module.notify.aws_lambda_function.fetch_status: Creating...
module.notify.aws_iam_role_policy_attachment.fetch_status_logs: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify-demo-fetch-status-role/arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]
module.notify.aws_iam_role_policy.notify_slack: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify-demo-notify-slack-role:terraform-0c334b43e9f77ddf68c66755f5]
module.notify.aws_iam_role_policy_attachment.notify_slack_logs: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify-demo-notify-slack-role/arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]
module.notify.aws_iam_role_policy.fetch_status: Creating...
module.notify.aws_iam_role_policy.fetch_status: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify-demo-fetch-status-role:terraform-5e557969d0acd65274a217f306]
module.notify.aws_lambda_function.notify_slack: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 5s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify-demo-notify-slack]
module.notify.aws_lambda_permission.notify_slack_from_sns: Creating...
module.notify.aws_lambda_permission.notify_slack_from_sns: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;AllowExecutionFromSNS]
module.notify.aws_sns_topic_subscription.result_to_notify_slack: Creating...
module.notify.aws_sns_topic_subscription.result_to_notify_slack: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arn:aws:sns:ap-northeast-1:000000000000:notify-demo-result:8876cdbc-24f6-49f7-b09e-14fb507ff76e]
module.notify.aws_lambda_function.fetch_status: Still creating... &lt;span class="o"&gt;[&lt;/span&gt;00m10s elapsed]
module.notify.aws_lambda_function.fetch_status: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 10s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify-demo-fetch-status]
module.notify.data.aws_iam_policy_document.scheduler: Reading...
module.notify.data.aws_iam_policy_document.scheduler: Read &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1455079044]
module.notify.aws_scheduler_schedule.fetch_status: Creating...
module.notify.aws_iam_role_policy.scheduler: Creating...
module.notify.aws_scheduler_schedule.fetch_status: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;default/notify-demo-fetch-status]
module.notify.aws_iam_role_policy.scheduler: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify-demo-scheduler-role:terraform-db943e5a1f8c21b3a1a29f7c69]

Apply &lt;span class="nb"&gt;complete&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; Resources: 16 added, 0 changed, 0 destroyed.

Outputs:

fetch_status_function_name &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-fetch-status"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two functions appear on the StackPort Lambda screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpx7aj4p4o4l6i3smjnra.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpx7aj4p4o4l6i3smjnra.png" alt="StackPort Lambda function list" width="800" height="604"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;StackPort does not show schedules, so I check them with the CLI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;aws &lt;span class="nt"&gt;--endpoint-url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localhost:4566 &lt;span class="nt"&gt;--region&lt;/span&gt; ap-northeast-1 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;   scheduler list-schedules
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"Schedules"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"Arn"&lt;/span&gt;: &lt;span class="s2"&gt;"arn:aws:scheduler:ap-northeast-1:000000000000:schedule/default/notify-demo-fetch-status"&lt;/span&gt;,
            &lt;span class="s2"&gt;"CreationDate"&lt;/span&gt;: &lt;span class="s2"&gt;"2026-10-12T09:56:36.343454+09:00"&lt;/span&gt;,
            &lt;span class="s2"&gt;"GroupName"&lt;/span&gt;: &lt;span class="s2"&gt;"default"&lt;/span&gt;,
            &lt;span class="s2"&gt;"LastModificationDate"&lt;/span&gt;: &lt;span class="s2"&gt;"2026-10-12T09:56:36.343454+09:00"&lt;/span&gt;,
            &lt;span class="s2"&gt;"Name"&lt;/span&gt;: &lt;span class="s2"&gt;"notify-demo-fetch-status"&lt;/span&gt;,
            &lt;span class="s2"&gt;"State"&lt;/span&gt;: &lt;span class="s2"&gt;"ENABLED"&lt;/span&gt;,
            &lt;span class="s2"&gt;"Target"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"Arn"&lt;/span&gt;: &lt;span class="s2"&gt;"arn:aws:lambda:ap-northeast-1:000000000000:function:notify-demo-fetch-status"&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Verify the Behavior
&lt;/h3&gt;

&lt;p&gt;After a short wait, &lt;code&gt;API status: ok&lt;/code&gt; is posted to &lt;code&gt;#notify-demo-local&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9rd1thwjdcza8k12fjt5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9rd1thwjdcza8k12fjt5.png" alt="Notification posted to Slack from the local environment" width="517" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can check the Lambda execution logs on the StackPort CloudWatch Logs screen. First, the log group list shows &lt;code&gt;/aws/lambda/notify-demo-notify-slack&lt;/code&gt; and &lt;code&gt;/aws/lambda/notify-demo-fetch-status&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn2o24azci7bx590mg4rl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn2o24azci7bx590mg4rl.png" alt="StackPort log group list" width="800" height="604"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Opening &lt;code&gt;/aws/lambda/notify-demo-notify-slack&lt;/code&gt; shows a list of log streams, one per execution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmxahzvfdhmf1u3akkax9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmxahzvfdhmf1u3akkax9.png" alt="StackPort log stream list" width="800" height="604"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Opening a log stream shows &lt;code&gt;START&lt;/code&gt;, &lt;code&gt;END&lt;/code&gt;, and &lt;code&gt;REPORT&lt;/code&gt;, plus what the Lambda function printed: the same &lt;code&gt;API status: ok (…)&lt;/code&gt; that went to Slack.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa5pxsbuhlp80kc8b4nid.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa5pxsbuhlp80kc8b4nid.png" alt="StackPort log events" width="800" height="604"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying to Real AWS and Verifying the Same Behavior
&lt;/h2&gt;

&lt;p&gt;I deploy the pipeline I verified locally to a real AWS account and check that it behaves the same way.&lt;/p&gt;

&lt;p&gt;The Lambda code and the Terraform module are shared with the local environment. Only the environment directory (&lt;code&gt;environments/aws&lt;/code&gt;) and the values registered in SSM change.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg4rly1gl2qoy4r8qqxn6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg4rly1gl2qoy4r8qqxn6.png" alt="Real AWS architecture" width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The thick red borders show what differs from the local environment. An API Gateway created in advance stands in for the external API, and Slack notifications go to the AWS channel (&lt;code&gt;#notify-demo-aws&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Register the SSM Parameters
&lt;/h3&gt;

&lt;p&gt;The API key was generated by the API Gateway. I retrieve its value and register it in SSM as a SecureString, together with the Incoming Webhook URL of the AWS channel.&lt;/p&gt;

&lt;p&gt;Apart from retrieving the API key, the script is the same as the local one, so I omit its contents.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;API_KEY_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;API key ID&amp;gt; &lt;span class="nv"&gt;SLACK_WEBHOOK_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;Webhook URL of the AWS channel&amp;gt; ./scripts/put-parameters-aws.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the Parameter Store in the AWS console after registration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpc7427c8iifofsvkd28c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpc7427c8iifofsvkd28c.png" alt="AWS SSM parameter list" width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Opening a parameter shows its SecureString value as &lt;code&gt;********&lt;/code&gt;. Turn on "Show decrypted value" to see the value.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3zjbko0oeqhurn69pi72.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3zjbko0oeqhurn69pi72.png" alt="AWS SSM parameter details" width="800" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Deploy
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;terraform/environments/aws/providers.tf&lt;/code&gt; has no MiniStack-specific settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The module call (&lt;code&gt;terraform/environments/aws/main.tf&lt;/code&gt;) is the same as the local one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;"notify"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"../../modules/notify"&lt;/span&gt;

  &lt;span class="nx"&gt;region&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-1"&lt;/span&gt;
  &lt;span class="nx"&gt;api_base_url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;api_base_url&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only the external API URL changes, in &lt;code&gt;terraform/environments/aws/terraform.tfvars&lt;/code&gt;. This file is not managed in Git either, so create it by copying the template (&lt;code&gt;terraform.tfvars.example&lt;/code&gt;) and rewrite it with the URL of the API Gateway you created in advance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;api_base_url&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://&amp;lt;API ID&amp;gt;.execute-api.ap-northeast-1.amazonaws.com/prod"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;terraform/environments/aws
&lt;span class="nb"&gt;cp &lt;/span&gt;terraform.tfvars.example terraform.tfvars
&lt;span class="c"&gt;# Rewrite &amp;lt;API ID&amp;gt; in terraform.tfvars&lt;/span&gt;
terraform init
terraform apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For comparison with the &lt;code&gt;apply&lt;/code&gt; against MiniStack, here is the result. The account ID is masked.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;terraform apply
module.notify.data.archive_file.fetch_status: Reading...
module.notify.data.archive_file.notify_slack: Reading...
module.notify.data.archive_file.notify_slack: Read &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;68fb7c506afbeeab169fb65494efc63dd8acba90]
module.notify.data.archive_file.fetch_status: Read &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;013b111cb8285884b651e501fd6f84ad373f787a]
module.notify.data.aws_iam_policy_document.lambda_assume: Reading...
module.notify.data.aws_caller_identity.current: Reading...
module.notify.data.aws_iam_policy_document.lambda_assume: Read &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2690255455]
module.notify.data.aws_caller_identity.current: Read &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;123456789012]
module.notify.data.aws_iam_policy_document.scheduler_assume: Reading...
module.notify.data.aws_iam_policy_document.notify_slack: Reading...
module.notify.data.aws_iam_policy_document.notify_slack: Read &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3754217979]
module.notify.data.aws_iam_policy_document.scheduler_assume: Read &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;991516426]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create
 &amp;lt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;data resources&lt;span class="o"&gt;)&lt;/span&gt;

Terraform will perform the following actions:

  &lt;span class="c"&gt;# module.notify.data.aws_iam_policy_document.fetch_status will be read during apply&lt;/span&gt;
  &lt;span class="c"&gt;# (config refers to values not yet known)&lt;/span&gt;
 &amp;lt;&lt;span class="o"&gt;=&lt;/span&gt; data &lt;span class="s2"&gt;"aws_iam_policy_document"&lt;/span&gt; &lt;span class="s2"&gt;"fetch_status"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + json          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + minified_json &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + statement &lt;span class="o"&gt;{&lt;/span&gt;
          + actions   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
              + &lt;span class="s2"&gt;"ssm:GetParameter"&lt;/span&gt;,
            &lt;span class="o"&gt;]&lt;/span&gt;
          + resources &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
              + &lt;span class="s2"&gt;"arn:aws:ssm:ap-northeast-1:123456789012:parameter/notify-demo/api-key"&lt;/span&gt;,
            &lt;span class="o"&gt;]&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
      + statement &lt;span class="o"&gt;{&lt;/span&gt;
          + actions   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
              + &lt;span class="s2"&gt;"sns:Publish"&lt;/span&gt;,
            &lt;span class="o"&gt;]&lt;/span&gt;
          + resources &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
              + &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;,
            &lt;span class="o"&gt;]&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.data.aws_iam_policy_document.scheduler will be read during apply&lt;/span&gt;
  &lt;span class="c"&gt;# (config refers to values not yet known)&lt;/span&gt;
 &amp;lt;&lt;span class="o"&gt;=&lt;/span&gt; data &lt;span class="s2"&gt;"aws_iam_policy_document"&lt;/span&gt; &lt;span class="s2"&gt;"scheduler"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + json          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + minified_json &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + statement &lt;span class="o"&gt;{&lt;/span&gt;
          + actions   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
              + &lt;span class="s2"&gt;"lambda:InvokeFunction"&lt;/span&gt;,
            &lt;span class="o"&gt;]&lt;/span&gt;
          + resources &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
              + &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;,
            &lt;span class="o"&gt;]&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_cloudwatch_log_group.fetch_status will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_cloudwatch_log_group"&lt;/span&gt; &lt;span class="s2"&gt;"fetch_status"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + arn                         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + deletion_protection_enabled &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + log_group_class             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + name                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/aws/lambda/notify-demo-fetch-status"&lt;/span&gt;
      + name_prefix                 &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + region                      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-1"&lt;/span&gt;
      + retention_in_days           &lt;span class="o"&gt;=&lt;/span&gt; 7
      + skip_destroy                &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + tags_all                    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_cloudwatch_log_group.notify_slack will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_cloudwatch_log_group"&lt;/span&gt; &lt;span class="s2"&gt;"notify_slack"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + arn                         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + deletion_protection_enabled &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + log_group_class             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + name                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/aws/lambda/notify-demo-notify-slack"&lt;/span&gt;
      + name_prefix                 &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + region                      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-1"&lt;/span&gt;
      + retention_in_days           &lt;span class="o"&gt;=&lt;/span&gt; 7
      + skip_destroy                &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + tags_all                    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_iam_role.fetch_status will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_iam_role"&lt;/span&gt; &lt;span class="s2"&gt;"fetch_status"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + arn                   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + assume_role_policy    &lt;span class="o"&gt;=&lt;/span&gt; jsonencode&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;{&lt;/span&gt;
              + Statement &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
                  + &lt;span class="o"&gt;{&lt;/span&gt;
                      + Action    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;
                      + Effect    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
                      + Principal &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                          + Service &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"lambda.amazonaws.com"&lt;/span&gt;
                        &lt;span class="o"&gt;}&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt;,
                &lt;span class="o"&gt;]&lt;/span&gt;
              + Version   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;)&lt;/span&gt;
      + create_date           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + force_detach_policies &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + managed_policy_arns   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + max_session_duration  &lt;span class="o"&gt;=&lt;/span&gt; 3600
      + name                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-fetch-status-role"&lt;/span&gt;
      + name_prefix           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + path                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt;
      + tags_all              &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + unique_id             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + inline_policy &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_iam_role.notify_slack will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_iam_role"&lt;/span&gt; &lt;span class="s2"&gt;"notify_slack"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + arn                   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + assume_role_policy    &lt;span class="o"&gt;=&lt;/span&gt; jsonencode&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;{&lt;/span&gt;
              + Statement &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
                  + &lt;span class="o"&gt;{&lt;/span&gt;
                      + Action    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;
                      + Effect    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
                      + Principal &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                          + Service &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"lambda.amazonaws.com"&lt;/span&gt;
                        &lt;span class="o"&gt;}&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt;,
                &lt;span class="o"&gt;]&lt;/span&gt;
              + Version   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;)&lt;/span&gt;
      + create_date           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + force_detach_policies &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + managed_policy_arns   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + max_session_duration  &lt;span class="o"&gt;=&lt;/span&gt; 3600
      + name                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-notify-slack-role"&lt;/span&gt;
      + name_prefix           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + path                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt;
      + tags_all              &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + unique_id             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + inline_policy &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_iam_role.scheduler will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_iam_role"&lt;/span&gt; &lt;span class="s2"&gt;"scheduler"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + arn                   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + assume_role_policy    &lt;span class="o"&gt;=&lt;/span&gt; jsonencode&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;{&lt;/span&gt;
              + Statement &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
                  + &lt;span class="o"&gt;{&lt;/span&gt;
                      + Action    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;
                      + Condition &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                          + StringEquals &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                              + &lt;span class="s2"&gt;"aws:SourceAccount"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"123456789012"&lt;/span&gt;
                            &lt;span class="o"&gt;}&lt;/span&gt;
                        &lt;span class="o"&gt;}&lt;/span&gt;
                      + Effect    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
                      + Principal &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                          + Service &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"scheduler.amazonaws.com"&lt;/span&gt;
                        &lt;span class="o"&gt;}&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt;,
                &lt;span class="o"&gt;]&lt;/span&gt;
              + Version   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;)&lt;/span&gt;
      + create_date           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + force_detach_policies &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + managed_policy_arns   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + max_session_duration  &lt;span class="o"&gt;=&lt;/span&gt; 3600
      + name                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-scheduler-role"&lt;/span&gt;
      + name_prefix           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + path                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt;
      + tags_all              &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + unique_id             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + inline_policy &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_iam_role_policy.fetch_status will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_iam_role_policy"&lt;/span&gt; &lt;span class="s2"&gt;"fetch_status"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + name        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + name_prefix &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + policy      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + role        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_iam_role_policy.notify_slack will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_iam_role_policy"&lt;/span&gt; &lt;span class="s2"&gt;"notify_slack"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + name        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + name_prefix &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + policy      &lt;span class="o"&gt;=&lt;/span&gt; jsonencode&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;{&lt;/span&gt;
              + Statement &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
                  + &lt;span class="o"&gt;{&lt;/span&gt;
                      + Action   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ssm:GetParameter"&lt;/span&gt;
                      + Effect   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
                      + Resource &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:ssm:ap-northeast-1:123456789012:parameter/notify-demo/slack-webhook-url"&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt;,
                &lt;span class="o"&gt;]&lt;/span&gt;
              + Version   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;)&lt;/span&gt;
      + role        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_iam_role_policy.scheduler will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_iam_role_policy"&lt;/span&gt; &lt;span class="s2"&gt;"scheduler"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + name        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + name_prefix &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + policy      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + role        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_iam_role_policy_attachment.fetch_status_logs will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_iam_role_policy_attachment"&lt;/span&gt; &lt;span class="s2"&gt;"fetch_status_logs"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + policy_arn &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"&lt;/span&gt;
      + role       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-fetch-status-role"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_iam_role_policy_attachment.notify_slack_logs will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_iam_role_policy_attachment"&lt;/span&gt; &lt;span class="s2"&gt;"notify_slack_logs"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + policy_arn &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"&lt;/span&gt;
      + role       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-notify-slack-role"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_lambda_function.fetch_status will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_lambda_function"&lt;/span&gt; &lt;span class="s2"&gt;"fetch_status"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + architectures                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + arn                            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + code_sha256                    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + filename                       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./build/fetch_status.zip"&lt;/span&gt;
      + function_name                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-fetch-status"&lt;/span&gt;
      + handler                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"app.handler"&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + invoke_arn                     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + last_modified                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + memory_size                    &lt;span class="o"&gt;=&lt;/span&gt; 128
      + package_type                   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Zip"&lt;/span&gt;
      + publish                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + qualified_arn                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + qualified_invoke_arn           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + region                         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-1"&lt;/span&gt;
      + reserved_concurrent_executions &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;
      + response_streaming_invoke_arn  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + role                           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + runtime                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"python3.14"&lt;/span&gt;
      + signing_job_arn                &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + signing_profile_version_arn    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + skip_destroy                   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + source_code_hash               &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"So5oKi3b/bEDekVIzzKxoKwo1aO2n/JdG+Ioj2nhtVw="&lt;/span&gt;
      + source_code_size               &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + tags_all                       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + &lt;span class="nb"&gt;timeout&lt;/span&gt;                        &lt;span class="o"&gt;=&lt;/span&gt; 30
      + version                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + environment &lt;span class="o"&gt;{&lt;/span&gt;
          + variables &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

      + ephemeral_storage &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + logging_config &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + tracing_config &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_lambda_function.notify_slack will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_lambda_function"&lt;/span&gt; &lt;span class="s2"&gt;"notify_slack"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + architectures                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + arn                            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + code_sha256                    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + filename                       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./build/notify_slack.zip"&lt;/span&gt;
      + function_name                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-notify-slack"&lt;/span&gt;
      + handler                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"app.handler"&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + invoke_arn                     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + last_modified                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + memory_size                    &lt;span class="o"&gt;=&lt;/span&gt; 128
      + package_type                   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Zip"&lt;/span&gt;
      + publish                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + qualified_arn                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + qualified_invoke_arn           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + region                         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-1"&lt;/span&gt;
      + reserved_concurrent_executions &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;
      + response_streaming_invoke_arn  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + role                           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + runtime                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"python3.14"&lt;/span&gt;
      + signing_job_arn                &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + signing_profile_version_arn    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + skip_destroy                   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + source_code_hash               &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"M+ENHhkFRJqThFhPFiREbrEpiqqEf0cJLzdvTNzrMUY="&lt;/span&gt;
      + source_code_size               &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + tags_all                       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + &lt;span class="nb"&gt;timeout&lt;/span&gt;                        &lt;span class="o"&gt;=&lt;/span&gt; 30
      + version                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + environment &lt;span class="o"&gt;{&lt;/span&gt;
          + variables &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
              + &lt;span class="s2"&gt;"TZ"&lt;/span&gt;                &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Asia/Tokyo"&lt;/span&gt;
              + &lt;span class="s2"&gt;"WEBHOOK_URL_PARAM"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/notify-demo/slack-webhook-url"&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

      + ephemeral_storage &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + logging_config &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;

      + tracing_config &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_lambda_permission.notify_slack_from_sns will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_lambda_permission"&lt;/span&gt; &lt;span class="s2"&gt;"notify_slack_from_sns"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + action              &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"lambda:InvokeFunction"&lt;/span&gt;
      + function_name       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-notify-slack"&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + principal           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sns.amazonaws.com"&lt;/span&gt;
      + region              &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-1"&lt;/span&gt;
      + source_arn          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + statement_id        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"AllowExecutionFromSNS"&lt;/span&gt;
      + statement_id_prefix &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_scheduler_schedule.fetch_status will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_scheduler_schedule"&lt;/span&gt; &lt;span class="s2"&gt;"fetch_status"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + action_after_completion      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + arn                          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + group_name                   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + name                         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-fetch-status"&lt;/span&gt;
      + name_prefix                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + region                       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-1"&lt;/span&gt;
      + schedule_expression          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"rate(1 minute)"&lt;/span&gt;
      + schedule_expression_timezone &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"UTC"&lt;/span&gt;
      + state                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ENABLED"&lt;/span&gt;

      + flexible_time_window &lt;span class="o"&gt;{&lt;/span&gt;
          + mode &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"OFF"&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

      + target &lt;span class="o"&gt;{&lt;/span&gt;
          + arn      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
          + input    &lt;span class="o"&gt;=&lt;/span&gt; jsonencode&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="o"&gt;{&lt;/span&gt;
                  + &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"scheduler"&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;)&lt;/span&gt;
          + role_arn &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_sns_topic.result will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_sns_topic"&lt;/span&gt; &lt;span class="s2"&gt;"result"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + arn                         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + beginning_archive_time      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + content_based_deduplication &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + fifo_throughput_scope       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + fifo_topic                  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + maximum_message_size        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + name                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-result"&lt;/span&gt;
      + name_prefix                 &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + owner                       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + policy                      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + region                      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-1"&lt;/span&gt;
      + signature_version           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + tags_all                    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + tracing_config              &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;# module.notify.aws_sns_topic_subscription.result_to_notify_slack will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_sns_topic_subscription"&lt;/span&gt; &lt;span class="s2"&gt;"result_to_notify_slack"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + arn                             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + confirmation_timeout_in_minutes &lt;span class="o"&gt;=&lt;/span&gt; 1
      + confirmation_was_authenticated  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + endpoint                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + endpoint_auto_confirms          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + filter_policy_scope             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + &lt;span class="nb"&gt;id&lt;/span&gt;                              &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + owner_id                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + pending_confirmation            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
      + protocol                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"lambda"&lt;/span&gt;
      + raw_message_delivery            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
      + region                          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-northeast-1"&lt;/span&gt;
      + topic_arn                       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;known after apply&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

Plan: 16 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + fetch_status_function_name &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-fetch-status"&lt;/span&gt;

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only &lt;span class="s1"&gt;'yes'&lt;/span&gt; will be accepted to approve.

  Enter a value: &lt;span class="nb"&gt;yes

&lt;/span&gt;module.notify.aws_cloudwatch_log_group.fetch_status: Creating...
module.notify.aws_iam_role.fetch_status: Creating...
module.notify.aws_iam_role.notify_slack: Creating...
module.notify.aws_cloudwatch_log_group.notify_slack: Creating...
module.notify.aws_sns_topic.result: Creating...
module.notify.aws_iam_role.scheduler: Creating...
module.notify.aws_cloudwatch_log_group.fetch_status: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/aws/lambda/notify-demo-fetch-status]
module.notify.aws_cloudwatch_log_group.notify_slack: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/aws/lambda/notify-demo-notify-slack]
module.notify.aws_sns_topic.result: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arn:aws:sns:ap-northeast-1:123456789012:notify-demo-result]
module.notify.data.aws_iam_policy_document.fetch_status: Reading...
module.notify.data.aws_iam_policy_document.fetch_status: Read &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3535791877]
module.notify.aws_iam_role.notify_slack: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 1s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify-demo-notify-slack-role]
module.notify.aws_iam_role.scheduler: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 1s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify-demo-scheduler-role]
module.notify.aws_iam_role_policy_attachment.notify_slack_logs: Creating...
module.notify.aws_iam_role_policy.notify_slack: Creating...
module.notify.aws_lambda_function.notify_slack: Creating...
module.notify.aws_iam_role.fetch_status: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 1s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify-demo-fetch-status-role]
module.notify.aws_iam_role_policy_attachment.fetch_status_logs: Creating...
module.notify.aws_iam_role_policy.fetch_status: Creating...
module.notify.aws_lambda_function.fetch_status: Creating...
module.notify.aws_iam_role_policy_attachment.notify_slack_logs: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 1s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify-demo-notify-slack-role/arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]
module.notify.aws_iam_role_policy_attachment.fetch_status_logs: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 1s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify-demo-fetch-status-role/arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]
module.notify.aws_iam_role_policy.notify_slack: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 1s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify-demo-notify-slack-role:terraform-22dd2cc9194bee349a41b83b49]
module.notify.aws_iam_role_policy.fetch_status: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 1s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify-demo-fetch-status-role:terraform-70ee3cf4543eabb9406936afc3]
module.notify.aws_lambda_function.notify_slack: Still creating... &lt;span class="o"&gt;[&lt;/span&gt;00m10s elapsed]
module.notify.aws_lambda_function.fetch_status: Still creating... &lt;span class="o"&gt;[&lt;/span&gt;00m10s elapsed]
module.notify.aws_lambda_function.notify_slack: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 15s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify-demo-notify-slack]
module.notify.aws_lambda_permission.notify_slack_from_sns: Creating...
module.notify.aws_lambda_permission.notify_slack_from_sns: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;AllowExecutionFromSNS]
module.notify.aws_sns_topic_subscription.result_to_notify_slack: Creating...
module.notify.aws_sns_topic_subscription.result_to_notify_slack: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arn:aws:sns:ap-northeast-1:123456789012:notify-demo-result:c13350e2-427f-446b-b1ff-341576727510]
module.notify.aws_lambda_function.fetch_status: Still creating... &lt;span class="o"&gt;[&lt;/span&gt;00m20s elapsed]
module.notify.aws_lambda_function.fetch_status: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 21s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify-demo-fetch-status]
module.notify.data.aws_iam_policy_document.scheduler: Reading...
module.notify.data.aws_iam_policy_document.scheduler: Read &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2990400390]
module.notify.aws_scheduler_schedule.fetch_status: Creating...
module.notify.aws_iam_role_policy.scheduler: Creating...
module.notify.aws_scheduler_schedule.fetch_status: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;default/notify-demo-fetch-status]
module.notify.aws_iam_role_policy.scheduler: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 0s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;notify-demo-scheduler-role:terraform-229c8ea50921716c957135f6a7]

Apply &lt;span class="nb"&gt;complete&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; Resources: 16 added, 0 changed, 0 destroyed.

Outputs:

fetch_status_function_name &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"notify-demo-fetch-status"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I check the schedule with the CLI, as I did locally. The account ID is masked.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;aws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;--region&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ap-northeast&lt;/span&gt;&lt;span class="mi"&gt;-1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;scheduler&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;list-schedules&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Schedules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Arn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:scheduler:ap-northeast-1:123456789012:schedule/default/notify-demo-fetch-status"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"CreationDate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-10-12T10:28:05.265000+09:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"GroupName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"LastModificationDate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-10-12T10:28:05.265000+09:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"notify-demo-fetch-status"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"State"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ENABLED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Arn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:lambda:ap-northeast-1:123456789012:function:notify-demo-fetch-status"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Verify the Behavior
&lt;/h3&gt;

&lt;p&gt;After waiting about a minute from the first invocation, &lt;code&gt;API status: ok&lt;/code&gt; is posted to &lt;code&gt;#notify-demo-aws&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftlmpe8pezjales1q158a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftlmpe8pezjales1q158a.png" alt="Notification posted to Slack" width="513" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can check the Lambda logs in CloudWatch Logs. In the console, open the log group, the log stream, and the log events in that order.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv4nxzuprhmj36ezzqbvd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv4nxzuprhmj36ezzqbvd.png" alt="AWS log group list" width="800" height="263"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fakicunijbjhfbc4f4nn9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fakicunijbjhfbc4f4nn9.png" alt="AWS log stream list" width="800" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkcnqw50sqrldc2jvor7e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkcnqw50sqrldc2jvor7e.png" alt="AWS log events" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;I built the pipeline from Scheduler through Lambda and SNS to Slack notifications locally with MiniStack. The Lambda code is shared with real AWS, and Terraform uses a shared module with one directory per environment, so the pipeline could be deployed to real AWS just by switching directories.&lt;/li&gt;
&lt;li&gt;With StackPort, you can follow Lambda logs and SSM parameters on screen, which makes it easier to see what is going on than with the CLI alone.&lt;/li&gt;
&lt;li&gt;That said, MiniStack and StackPort do not simulate AWS completely. For example, SecureString values are not encrypted, and StackPort cannot display Scheduler. I recommend understanding what you can test locally, and then verifying on real AWS as well.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you for reading this far!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ministack</category>
      <category>stackport</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Why S3 list-buckets Returns a CreationDate That Doesn't Match the Actual Bucket Creation Date</title>
      <dc:creator>Yoshiyuki Watanabe</dc:creator>
      <pubDate>Sat, 08 Aug 2026 00:18:03 +0000</pubDate>
      <link>https://dev.to/aws-builders/why-s3-list-buckets-returns-a-creationdate-that-doesnt-match-the-actual-bucket-creation-date-a99</link>
      <guid>https://dev.to/aws-builders/why-s3-list-buckets-returns-a-creationdate-that-doesnt-match-the-actual-bucket-creation-date-a99</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I manage multiple AWS accounts, and while taking inventory of S3 buckets and their creation dates across accounts with &lt;code&gt;list-buckets&lt;/code&gt;, I noticed that the &lt;code&gt;CreationDate&lt;/code&gt; returned by &lt;code&gt;aws s3api list-buckets&lt;/code&gt; didn't match the actual bucket creation date shown in the S3 console.&lt;/p&gt;

&lt;p&gt;I asked about this on AWS re:Post and got solid answers from the community.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://repost.aws/ja/questions/QUI9bguausRtiUasW3rfV_Cw/why-does-listbuckets-return-incorrect-creationdate-when-called-from-a-non-us-east-1-endpoint" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fa0.awsstatic.com%2Flibra-css%2Fimages%2Flogos%2Faws_logo_smile_1200x630.png" height="420" class="m-0" width="800"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://repost.aws/ja/questions/QUI9bguausRtiUasW3rfV_Cw/why-does-listbuckets-return-incorrect-creationdate-when-called-from-a-non-us-east-1-endpoint" rel="noopener noreferrer" class="c-link"&gt;
            Why does ListBuckets return incorrect CreationDate when called from a non-us-east-1 endpoint? | AWS re:Post
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            When I call `aws s3api list-buckets` from a regional endpoint other than `us-east-1` (e.g., `ap-northeast-1`), the `CreationDate` field returns an incorrect date that does not match the actual buck...
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frepost.aws%2Ffavicon-32x32.png" width="32" height="32"&gt;
          repost.aws
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Digging further, I found a GitHub Issue on &lt;code&gt;aws-cli&lt;/code&gt; with information about this exact issue.&lt;/p&gt;

&lt;p&gt;This article cross-references the re:Post answers with that Issue to lay out the cause and the workaround.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Symptom: CreationDate Changes When Called from a Non-us-east-1 Region
&lt;/h2&gt;

&lt;p&gt;Calling &lt;code&gt;list-buckets&lt;/code&gt; against the same bucket returns a different &lt;code&gt;CreationDate&lt;/code&gt; depending on which regional endpoint you use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Called via the ap-northeast-1 endpoint&lt;/span&gt;
aws s3api list-buckets &lt;span class="nt"&gt;--region&lt;/span&gt; ap-northeast-1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Buckets[?Name==`my-bucket`].CreationDate'&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text
&lt;span class="c"&gt;# 2026-06-04T02:48:47+00:00&lt;/span&gt;

&lt;span class="c"&gt;# Called via the us-east-1 endpoint&lt;/span&gt;
aws s3api list-buckets &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Buckets[?Name==`my-bucket`].CreationDate'&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text
&lt;span class="c"&gt;# 2023-07-05T08:39:18+00:00&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This bucket was created in ap-northeast-1, and the S3 console shows its creation date as &lt;code&gt;July 5, 2023, 17:39:18 (UTC+09:00)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9tb4146km4hql6he3hlz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9tb4146km4hql6he3hlz.png" alt="Creation date shown in the Creation date column of the S3 console bucket list" width="797" height="83"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In other words, the &lt;code&gt;us-east-1&lt;/code&gt; result matches the console, while only the &lt;code&gt;ap-northeast-1&lt;/code&gt; result is off from the actual creation date.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Cause: CreationDate Isn't the "Creation Date" — It's the "Last Replication Time in That Region"
&lt;/h2&gt;

&lt;p&gt;The investigation revealed that the meaning of the &lt;code&gt;CreationDate&lt;/code&gt; returned by &lt;code&gt;list-buckets&lt;/code&gt; depends on which regional endpoint you call it from.&lt;/p&gt;

&lt;p&gt;All S3 bucket creation operations appear to be mastered in &lt;code&gt;us-east-1&lt;/code&gt; and then replicated globally.&lt;/p&gt;

&lt;p&gt;When you call &lt;code&gt;list-buckets&lt;/code&gt; against an endpoint other than &lt;code&gt;us-east-1&lt;/code&gt;, the &lt;code&gt;CreationDate&lt;/code&gt; you get back isn't the actual creation date — it's &lt;strong&gt;the last replication time for that region&lt;/strong&gt; (i.e., the timestamp of the most recent sync, such as a bucket policy change).&lt;/p&gt;

&lt;p&gt;Only when you call the &lt;code&gt;us-east-1&lt;/code&gt; endpoint do you get the original creation date registered at the master. The S3 console also reads from the &lt;code&gt;us-east-1&lt;/code&gt; data, which is why the console date always matches the &lt;code&gt;us-east-1&lt;/code&gt; endpoint's result.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;aws-cli&lt;/code&gt; GitHub Issue includes the following explanation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;All bucket creations are mastered in us-east-1, then replicated on a global scale - the resulting difference is that there are no "replication" events to the us-east-1 region.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;When using an endpoint other than us-east-1, the &lt;code&gt;CreationDate&lt;/code&gt; you receive is actually the last modified time according to the bucket's last replication time in this region. This date can change when making changes to your bucket, such as editing its bucket policy.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Source: &lt;a href="https://github.com/aws/aws-cli/issues/3597#issuecomment-424167129" rel="noopener noreferrer"&gt;aws/aws-cli#3597&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The official AWS documentation for the &lt;code&gt;Bucket&lt;/code&gt; data type's &lt;code&gt;CreationDate&lt;/code&gt; field also includes this line:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Date the bucket was created. This date can change when making changes to your bucket, such as editing its bucket policy.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Source: &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/API/API_Bucket.html" rel="noopener noreferrer"&gt;Amazon S3 API Reference - Bucket&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;However, this sentence alone doesn't make it clear that the behavior varies by region — it's an easy detail for many users to miss.&lt;/p&gt;

&lt;p&gt;I confirmed this myself: after editing a bucket policy, only the &lt;code&gt;CreationDate&lt;/code&gt; returned via the &lt;code&gt;ap-northeast-1&lt;/code&gt; endpoint changed. Changing &lt;code&gt;Block public access&lt;/code&gt; produced the same result.&lt;/p&gt;

&lt;p&gt;It seems any bucket-level configuration change — not just bucket policy edits — can trigger this replication timestamp update.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# After the configuration change&lt;/span&gt;
aws s3api list-buckets &lt;span class="nt"&gt;--region&lt;/span&gt; ap-northeast-1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Buckets[?Name==`my-bucket`].CreationDate'&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text
&lt;span class="c"&gt;# 2026-08-06T21:20:49+00:00&lt;/span&gt;

aws s3api list-buckets &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Buckets[?Name==`my-bucket`].CreationDate'&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text
&lt;span class="c"&gt;# 2023-07-05T08:39:18+00:00&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Workaround: Explicitly Specify the us-east-1 Endpoint
&lt;/h2&gt;

&lt;p&gt;To get the accurate creation date, explicitly call the API with &lt;code&gt;--region us-east-1&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3api list-buckets &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Buckets[?Name==`my-bucket`].CreationDate'&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This result matches the creation date shown in the S3 console.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;CreationDate&lt;/code&gt; returned by &lt;code&gt;list-buckets&lt;/code&gt; has a quirk: calling it from any endpoint other than &lt;code&gt;us-east-1&lt;/code&gt; returns the last replication time for that region, not the actual bucket creation date.&lt;/p&gt;

&lt;p&gt;If you need the accurate creation date, explicitly specify &lt;code&gt;--region us-east-1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I lost some time myself before figuring this out. I hope this article saves someone else from the same trap.&lt;/p&gt;

&lt;p&gt;Thank you for reading this far!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>s3</category>
      <category>beginners</category>
      <category>sre</category>
    </item>
  </channel>
</rss>
