<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0"><channel><title>Pulumi Blog: Debugging</title><link>https://www.pulumi.com/blog/tag/debugging/</link><description>Pulumi blog posts: Debugging.</description><language>en-us</language><pubDate>Fri, 31 May 2024 00:00:00 +0000</pubDate><item><title>Next-level IaC: Breakpoint Debugging for Pulumi Programs</title><link>https://www.pulumi.com/blog/next-level-iac-breakpoint-debugging/</link><pubDate>Fri, 31 May 2024 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/next-level-iac-breakpoint-debugging/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/next-level-iac-breakpoint-debugging/index.png" /&gt;
&lt;p&gt;For many of us, life is suspended between presses of the &lt;a href="https://www.javatpoint.com/what-is-f5"&gt;&lt;code&gt;F5&lt;/code&gt;&lt;/a&gt; key. Our IDE is the only place where everything is organized and makes sense. And while we know that the likelihood of a code hole-in-one is very rare (that magical moment where you run your build and everything &lt;em&gt;just works&lt;/em&gt; the first time), we always hope that &lt;em&gt;this&lt;/em&gt; time, this will be the run where you see the output that lets you know you&amp;rsquo;ve gotten it right. And in between? Debugging.&lt;/p&gt;
&lt;p&gt;Debugging is a &lt;a href="https://en.wikipedia.org/wiki/Debugging"&gt;complicated topic&lt;/a&gt;. But what is not complicated is understanding &lt;a href="https://queue.acm.org/detail.cfm?id=3068754/"&gt;the cost of debugging&lt;/a&gt;. Debugging is the biggest unknown-unknown in software. It makes you miss your sprint goals, it holds back scaling and company growth, it slows your time to market. Debugging is what makes estimating so difficult, because until you know what the problem is, you don&amp;rsquo;t know how long it will take to fix, or indeed if it is even possible to fix at all. Which is why savvy developers invest a lot of time into refining their debugging process and seek out the best-in-class tools to streamline this process.&lt;/p&gt;
&lt;p&gt;In the infrastructure world, debugging is a pretty big problem. Some of the most popular tools have nothing more than simple unstructured text output logs. While tools like Terraform call themselves &amp;ldquo;Infrastructure as Code&amp;rdquo; the &amp;ldquo;code&amp;rdquo; is a proprietary DSL, not a general purpose programming language, and so there is little-to-no IDE support. There is no &lt;code&gt;F5&lt;/code&gt;. Even worse, there is no &lt;code&gt;F9&lt;/code&gt; for setting a breakpoint. There&amp;rsquo;s no way to inspect state mid-run, or more importantly to explore in an unstructured way, because this is where the &amp;ldquo;aha!&amp;rdquo; moments usually happen.&lt;/p&gt;
&lt;p&gt;Pulumi gives you a rich IaC debugging experience by enabling breakpoint debugging in your favorite IDE. Let&amp;rsquo;s walk through an example of how to enable a full-featured debugging workflow in &lt;a href="https://code.visualstudio.com/"&gt;VS Code&lt;/a&gt; for TypeScript.&lt;/p&gt;
&lt;h2 id="how-breakpoint-debugging-works"&gt;How Breakpoint Debugging Works&lt;/h2&gt;
&lt;p&gt;Using a debugger can feel like that moment in &lt;a href="https://en.wikipedia.org/wiki/The_Matrix"&gt;The Matrix&lt;/a&gt; where Neo first sees the &lt;a href="https://matrix.fandom.com/wiki/Matrix_code"&gt;green streaming code&lt;/a&gt; raining down. A debugger lifts the veil from your otherwise opaque executable code. Tools like &lt;a href="https://code.visualstudio.com/"&gt;VS Code&lt;/a&gt; provide a user experience where you set &lt;a href="https://en.wikipedia.org/wiki/Breakpoint"&gt;&lt;em&gt;breakpoints&lt;/em&gt;&lt;/a&gt;, i.e. certain lines of code that are designated as points where you want to pause execution and inspect state. Hitting the &lt;code&gt;F9&lt;/code&gt; key in VS Code sets a breakpoint on the current line of code. Later, you run your code in &lt;em&gt;debug mode&lt;/em&gt;. This is a special execution state where the underlying runtime (e.g. &lt;a href="https://nodejs.org/en/learn/getting-started/the-v8-javascript-engine"&gt;Node&amp;rsquo;s V8&lt;/a&gt;) exposes a TCP/IP port hosting a &lt;a href="https://chromedevtools.github.io/devtools-protocol/"&gt;debugging protocol&lt;/a&gt;, and when run, it will pause execution until something &lt;em&gt;attaches&lt;/em&gt; to it (i.e. connects to the port to start the &lt;a href="https://github.com/aslushnikov/getting-started-with-cdp/blob/master/README.md#targets--sessions"&gt;debugging session&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;At this point a debugging client (such as VS Code) will control the flow of the program, moving forward step-by-step, one line of code at a time. But how does it know which line of code it&amp;rsquo;s executing? When you run in debug mode, the binary code is instrumented with metadata about the line of code it represents. The debugger will tell the runtime, via the debugging protocol, &amp;ldquo;run until you reach line 109 in file &lt;code&gt;data.ts&lt;/code&gt;, then pause and wait for a signal from me before continuing&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;While paused, the protocol also allows you to inspect the values of any variables that are in scope at that moment. A more sophisticated debugger will provide a &lt;a href="https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop"&gt;REPL&lt;/a&gt; environment where you can execute ad-hoc code in the scope of the line where you are paused. This can be very powerful to inspect the values of various objects and to see in real-time what the effects of executing variations of code would be. After a debugging session you can take what you&amp;rsquo;ve learned and edit the code accordingly.&lt;/p&gt;
&lt;h2 id="example-attaching-a-debugger-to-a-typescript-pulumi-program-in-vs-code"&gt;Example: Attaching a debugger to a TypeScript Pulumi program in VS Code&lt;/h2&gt;
&lt;p&gt;For this example, we will set up a new Pulumi project from the command-line and then set up VS Code to run that program in a debugger.&lt;/p&gt;
&lt;h3 id="step-1-create-a-pulumi-project-from-a-template"&gt;Step 1: Create a Pulumi project from a template&lt;/h3&gt;
&lt;p&gt;For this example, we will create a new Pulumi project using the &lt;a href="https://www.pulumi.com/templates/static-website/aws/"&gt;TypeScript AWS static website template&lt;/a&gt;. Make sure you&amp;rsquo;ve set up Pulumi, logged into Pulumi Cloud, and configured your AWS credentials. Follow the prompts in the pulumi CLI to configure your project.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ mkdir good-morning &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; good-morning
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ pulumi new static-website-aws-typescript
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then launch this project to make sure it works as expected:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ pulumi up
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Updating &lt;span class="o"&gt;(&lt;/span&gt;dev&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;View in Browser &lt;span class="o"&gt;(&lt;/span&gt;Ctrl+O&lt;span class="o"&gt;)&lt;/span&gt;: https://app.pulumi.com/troy-pulumi-corp/good-morning/dev/updates/1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Type Name Status
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; + pulumi:pulumi:Stack good-morning-dev created &lt;span class="o"&gt;(&lt;/span&gt;200s&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; + ├─ aws:s3:Bucket bucket created &lt;span class="o"&gt;(&lt;/span&gt;1s&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; + ├─ aws:s3:BucketPublicAccessBlock public-access-block created &lt;span class="o"&gt;(&lt;/span&gt;0.57s&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; + ├─ aws:s3:BucketOwnershipControls ownership-controls created &lt;span class="o"&gt;(&lt;/span&gt;1s&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; + ├─ aws:cloudfront:Distribution cdn created &lt;span class="o"&gt;(&lt;/span&gt;196s&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; + └─ synced-folder:index:S3BucketFolder bucket-folder created &lt;span class="o"&gt;(&lt;/span&gt;0.41s&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; + ├─ aws:s3:BucketObject error.html created &lt;span class="o"&gt;(&lt;/span&gt;0.46s&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; + └─ aws:s3:BucketObject index.html created &lt;span class="o"&gt;(&lt;/span&gt;0.46s&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Outputs:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; cdnHostname : &lt;span class="s2"&gt;&amp;#34;##############.cloudfront.net&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; cdnURL : &lt;span class="s2"&gt;&amp;#34;https://##############.cloudfront.net&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; originHostname: &lt;span class="s2"&gt;&amp;#34;bucket-#######.s3-website-us-west-2.amazonaws.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; originURL : &lt;span class="s2"&gt;&amp;#34;http://bucket-#######.s3-website-us-west-2.amazonaws.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Resources:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; + &lt;span class="m"&gt;8&lt;/span&gt; created
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Great! You should be able to navigate to the website using the URL from the &lt;code&gt;cdnURL&lt;/code&gt; output value.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ open &lt;span class="k"&gt;$(&lt;/span&gt;pulumi stack output cdnURL&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If all looks good, let&amp;rsquo;s move on to the next step by opening your project directory in VS Code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ code .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="step-2-lets-break-stuff"&gt;Step 2: Lets break stuff!&lt;/h3&gt;
&lt;p&gt;Now that we have a perfectly running Pulumi program, in order to have something to debug, we will need to break it!&lt;/p&gt;
&lt;p&gt;For this example, we are going to change our &lt;code&gt;indexDocument&lt;/code&gt; from &lt;code&gt;index.html&lt;/code&gt; to &lt;code&gt;good-morning.html&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ cp ./wwww/index.html ./www/good-morning.html
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next, let&amp;rsquo;s edit the contents to say &amp;ldquo;Good morning, world!&amp;rdquo; instead of &amp;ldquo;Hello, world!&amp;rdquo;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt; &lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;en&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;meta&lt;/span&gt; &lt;span class="na"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;utf-8&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line hl"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Good morning, world!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line hl"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Good morning, world! 👋&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Deployed with 💜 by &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://pulumi.com/&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Pulumi&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once that&amp;rsquo;s edited and saved, go ahead let&amp;rsquo;s redeploy the website:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ pulumi up
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Everything runs successfully&amp;hellip; but if we navigate to the website, we don&amp;rsquo;t see our updated content?! Oh no! What went wrong? Why isn&amp;rsquo;t there an error message?! Time to put on our debugging hats and figure out what is going on. First, let&amp;rsquo;s set up VS Code to enable breakpoint debugging right in the IDE.&lt;/p&gt;
&lt;h3 id="step-3-create-a-debug-wrapper-script"&gt;Step 3: Create a debug wrapper script&lt;/h3&gt;
&lt;p&gt;VS Code can run an arbitrary command when you hit &lt;code&gt;F5&lt;/code&gt;. Typically this would be a one-liner that runs your language runtime like &lt;code&gt;node foo.js&lt;/code&gt; or &lt;code&gt;python foo.py&lt;/code&gt;. In our case, we need to run the &lt;code&gt;pulumi&lt;/code&gt; CLI and need to do more than one step. The easiest way to do this is to create a small wrapper script and call that from VS Code.&lt;/p&gt;
&lt;p&gt;In the root of the directory, create a file called &lt;code&gt;pulumi-debug.sh&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pulumi login
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pulumi stack &lt;span class="k"&gt;select&lt;/span&gt; dev
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pulumi up -f
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="note note-info"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.21047dcd83825f0caafb78a6fd28628a694219e6b6824f6b3e24ee3147bac331.svg#p-info-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;&lt;p&gt;Let&amp;rsquo;s walk through these lines to explain what&amp;rsquo;s going on here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;pulumi login&lt;/code&gt; to set up credentials for the pulumi backend&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pulumi stack select dev&lt;/code&gt; to run this against our &lt;code&gt;dev&lt;/code&gt; stack&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pulumi up -f&lt;/code&gt; to run our program update. The -f flag skips the preview phase and also skips the need to interactively confirm that we want to run the update.&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Open the VS Code terminal panel and first set it to be executable, then try running the script:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ chmod +x pulumi-debug.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ ./pulumi-debug.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ok now let&amp;rsquo;s set up VS Code to run that in debug mode when we hit &lt;code&gt;F5&lt;/code&gt;!&lt;/p&gt;
&lt;h3 id="step-4-configure-vs-code-launchjson-and-tasksjson"&gt;Step 4: Configure VS Code &lt;code&gt;launch.json&lt;/code&gt; and &lt;code&gt;tasks.json&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;To run our Pulumi program in debug mode we will need to create a couple of VS Code configuration files, &lt;code&gt;launch.json&lt;/code&gt; and &lt;code&gt;tasks.json&lt;/code&gt;, in a hidden directory called &lt;code&gt;.vscode&lt;/code&gt; within your project.&lt;/p&gt;
&lt;p&gt;Create the &lt;code&gt;.vscode&lt;/code&gt; directory and then create a new file called &lt;code&gt;tasks.json&lt;/code&gt; file in that directory, with the following contents:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2.0.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;tasks&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;pulumi-debug&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;shell&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;. ./pulumi-debug.sh&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;isBackground&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;options&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;cwd&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;${workspaceFolder}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This creates a VS Code task named &lt;code&gt;pulumi-debug&lt;/code&gt; which will run the wrapper script we just created from the root of our project.&lt;/p&gt;
&lt;p&gt;Next, create a file named &lt;code&gt;launch.json&lt;/code&gt; in the same directory. This will configure the behavior of the &lt;code&gt;F5&lt;/code&gt; key!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;0.2.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;configurations&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Launch Pulumi Program (debug)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;node&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;port&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9292&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;attach&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;preLaunchTask&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;pulumi-debug&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;continueOnAttach&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;restart&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;delay&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;maxAttempts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;skipFiles&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;${workspaceFolder}/node_modules/**/*.js&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;${workspaceFolder}/lib/**/*.js&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;lt;node_internals&amp;gt;/**/*.js&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="note note-info"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.21047dcd83825f0caafb78a6fd28628a694219e6b6824f6b3e24ee3147bac331.svg#p-info-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;&lt;p&gt;Let&amp;rsquo;s break this down a bit:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;type: node&lt;/code&gt; tells VS Code that we are using the Node runtime&lt;/li&gt;
&lt;li&gt;&lt;code&gt;port: 9292&lt;/code&gt; tells VS Code to attach the debugger to port 9292&lt;/li&gt;
&lt;li&gt;&lt;code&gt;request: attach&lt;/code&gt; tells VS Code that we want to attach to the debugger at launch&lt;/li&gt;
&lt;li&gt;&lt;code&gt;preLaunchTask: pulumi-debug&lt;/code&gt; tells VS Code to run the task we configured in &lt;code&gt;tasks.json&lt;/code&gt; before we connect the debugger. This will run our &lt;code&gt;pulumi-debug.sh&lt;/code&gt; script and then attach to the Node.js runtime&lt;/li&gt;
&lt;li&gt;&lt;code&gt;continueOnAttach: true&lt;/code&gt; tells VS Code to start running our code as soon as we attach to the waiting Node.js runtime (until we reach our first breakpoint that is, where it will pause and return control to the debugger client, aka VS Code)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;restart: {...}&lt;/code&gt; configures VS Code to wait 5 seconds and then retry connecting, up to 5 times. This is here in case it takes a while for the Node.js runtime to start running. It&amp;rsquo;s unlikely, but possible!&lt;/li&gt;
&lt;li&gt;&lt;code&gt;skipFiles: {...}&lt;/code&gt; sets up some filters of files &lt;em&gt;not&lt;/em&gt; to try to debug. This includes everything that is part of node&amp;rsquo;s internals, 3rdparty node modules, and other libraries. That way we don&amp;rsquo;t end up deep in someone else&amp;rsquo;s code unexpectedly and can just focus on our Pulumi program.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;name&lt;/code&gt; sets a human-readable name which shows up in the drop down box in VS Code when you choose which [launch configuration][vs-code-launch-configs] to run.&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Finally, we need to make one more edit to the &lt;code&gt;pulumi-debug.sh&lt;/code&gt; file we created. Here we will pass the necessary options to the Node.js runtime to set it to run in debug mode.&lt;/p&gt;
&lt;p&gt;Add the following line to the beginning of the file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line hl"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;NODE_OPTIONS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;--inspect-brk=127.0.0.1:9292&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pulumi login
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pulumi stack &lt;span class="k"&gt;select&lt;/span&gt; dev
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pulumi up -f
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="note note-info"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.21047dcd83825f0caafb78a6fd28628a694219e6b6824f6b3e24ee3147bac331.svg#p-info-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;The &lt;code&gt;NODE_OPTIONS&lt;/code&gt; environment variable passes options to the Node.js V8 runtime. In this case, we are passing &lt;code&gt;--inspect-brk&lt;/code&gt; which tells the Node.js runtime to run in debug mode, which will cause it to pause before running the code, until a debugging client connects to &lt;code&gt;localhost&lt;/code&gt; on port &lt;code&gt;9292&lt;/code&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Ok, now we should be ready to run our Pulumi program from VS Code using the &lt;code&gt;F5&lt;/code&gt; key! Let&amp;rsquo;s give it a try. You should see Pulumi running inside of the &amp;ldquo;Terminal&amp;rdquo; tab. You will also see output indicating that it is waiting for a debugger to attach:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Debugger listening on ws://127.0.0.1:9292/########-####-####-####-############
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
Waiting for the debugger to disconnect...
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="step-5-setting-a-debugging-breakpoint"&gt;Step 5: Setting a debugging breakpoint&lt;/h3&gt;
&lt;p&gt;Now we can try &lt;a href="https://code.visualstudio.com/docs/editor/debugging#_breakpoints"&gt;setting a breakpoint&lt;/a&gt; in our code. Getting back to the problem at hand &amp;ndash; our content doesn&amp;rsquo;t seem to be updating, despite no errors. Let&amp;rsquo;s start at the beginning, by investigating the inputs to our program, aka our configuration&amp;hellip; at runtime!&lt;/p&gt;
&lt;p&gt;Navigate to line &lt;code&gt;12&lt;/code&gt; within the code and hit the &lt;code&gt;F9&lt;/code&gt; key. You&amp;rsquo;ll see a small red dot appear next to the line indicating that a breakpoint has been set. This line defines the bucket our program creates and seems like a good place to stop if we want to check the input configuration before we run the AWS S3 provider call.&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.pulumi.com/blog/next-level-iac-breakpoint-debugging/set-a-breakpoint.png"
alt="Figure: A breakpoint set on line 12."&gt;&lt;figcaption&gt;
&lt;p&gt;Figure: A breakpoint set on line 12.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;You can then run the program again using &lt;code&gt;F5&lt;/code&gt;. When the execution of the code reaches the line it will pause there. At this point you can navigate around the code &lt;a href="https://code.visualstudio.com/docs/editor/debugging#_data-inspection"&gt;inspecting the state of the local variables&lt;/a&gt;, like you would in any other debugging session.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s inspect the configuration variables. On the left side of the screen you&amp;rsquo;ll find a &amp;ldquo;Variables&amp;rdquo; panel listing all the local variables that are in scope.&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.pulumi.com/blog/next-level-iac-breakpoint-debugging/local-variables-list.png"
alt="Figure: Local variables displayed in the Variables side panel."&gt;&lt;figcaption&gt;
&lt;p&gt;Figure: Local variables displayed in the Variables side panel.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;There&amp;rsquo;s also the &amp;ldquo;Debug&amp;rdquo; console which provides a &lt;a href="https://code.visualstudio.com/docs/editor/debugging#_debug-console-repl"&gt;REPL&lt;/a&gt; environment to navigate those variables and anything else that is in scope. You can run arbitrary functions here and see their output. In this case we can simply type the variable name at the prompt there, hit enter, and see the value. What&amp;rsquo;s great about the debug console is that Intellisense (e.g. using &lt;code&gt;TAB&lt;/code&gt; to auto-complete) works here, so you can quickly navigate possible options.&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.pulumi.com/blog/next-level-iac-breakpoint-debugging/debug-console-tab-completion-inspect-value.png"
alt="Figure: Debug console tab completion and inspecting variable values."&gt;&lt;figcaption&gt;
&lt;p&gt;Figure: Debug console tab completion and inspecting variable values.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In our case, we&amp;rsquo;re interested in the value of &lt;code&gt;indexDocument&lt;/code&gt; variable. We can see that it is getting set to &lt;code&gt;index.html&lt;/code&gt;&amp;hellip; not &lt;code&gt;good-morning.html&lt;/code&gt;. The Pulumi program didn&amp;rsquo;t error because &lt;code&gt;index.html&lt;/code&gt; still exists. So we are still publishing our old &lt;code&gt;index.html&lt;/code&gt;. That makes sense. A quick fix here is to modify &lt;code&gt;index.ts&lt;/code&gt; and set the default to &lt;code&gt;good-morning.html&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/pulumi&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/aws&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;synced_folder&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/synced-folder&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Import the program&amp;#39;s configuration settings.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kr"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;path&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;./www&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line hl"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;indexDocument&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kr"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;indexDocument&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;good-morning.html&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errorDocument&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kr"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;errorDocument&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;error.html&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ok, we edited the document, which fixes the program for future runs, but for the current run that we are debugging, &lt;code&gt;indexDocument&lt;/code&gt; is still set to &lt;code&gt;index.html&lt;/code&gt;. Let&amp;rsquo;s use the debug console to set the value to &lt;code&gt;good-morning.html&lt;/code&gt; before we continue the run.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;indexDocument&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nx"&gt;good&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;morning&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="sb"&gt;`
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The output in the debug window will show the new value, and if you hover over the inputs being passed to the bucket creation call, it will now show as &lt;code&gt;good-morning.html&lt;/code&gt;:&lt;/p&gt;
&lt;figure&gt;&lt;img src="https://www.pulumi.com/blog/next-level-iac-breakpoint-debugging/after-edit-value-debug-console-and-hover.png"
alt="Figure: Screenshots of debug console and editor window after changing the indexDocument variable"&gt;&lt;figcaption&gt;
&lt;p&gt;Figure: Screenshots of debug console and editor window after changing the &lt;code&gt;indexDocument&lt;/code&gt; variable&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;When you&amp;rsquo;re ready for the program to continue on, hit &lt;code&gt;F5&lt;/code&gt; once again and the program will resume operation, either until the program exits or until it reaches the next breakpoint. Optionally you can step through line-by-line using the &lt;code&gt;F10&lt;/code&gt; key. VS Code provides a variety of &lt;a href="https://code.visualstudio.com/docs/editor/debugging#_debug-actions"&gt;debug actions&lt;/a&gt; once the session is established.&lt;/p&gt;
&lt;p&gt;Most importantly, check the published website and make sure we fixed the issue! You can find the &lt;code&gt;cdnURL&lt;/code&gt; output in the &lt;code&gt;Terminal&lt;/code&gt; tab and click on it from there to open the link.&lt;/p&gt;
&lt;h2 id="considerations-and-limitations"&gt;Considerations and Limitations&lt;/h2&gt;
&lt;p&gt;Breakpoint debugging is a powerful tool for inspecting the state of your Pulumi program. However, there are some important limitations to consider:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Pulumi programs are only part of the story:&lt;/strong&gt; This technique will let you inspect the program you authored, but it doesn&amp;rsquo;t give access to what&amp;rsquo;s happening with the Pulumi backend, the providers, or anything else outside of the program itself. You might find yourself needing to dig deeper to resolve a problem with the stack as a whole. Luckily there are other techniques we can use for that, which we will delve into in an upcoming post.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Inputs and Outputs are asynchronous futures:&lt;/strong&gt; If you&amp;rsquo;ve used Pulumi before you will have encountered &lt;a href="https://www.pulumi.com/docs/concepts/inputs-outputs/#inputs"&gt;&lt;code&gt;Input&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://www.pulumi.com/docs/concepts/inputs-outputs/#outputs"&gt;&lt;code&gt;Output&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/a&gt; values, which are a core function of the tool. However, at the time that the debugger hits a breakpoint on those values, they are likely not populated with their final value. That means you won&amp;rsquo;t be able to inspect them in the debugger very well. Instead, you will need to add an &lt;a href="https://www.pulumi.com/docs/concepts/inputs-outputs/apply/"&gt;&lt;code&gt;apply(...)&lt;/code&gt;&lt;/a&gt; or &lt;a href="https://www.pulumi.com/docs/concepts/inputs-outputs/all/"&gt;&lt;code&gt;all(..)&lt;/code&gt;&lt;/a&gt; block to the code, and place the breakpoint on the materialized value within that block. This follows all the same rules as accessing those variables in code in a Pulumi program.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// NOTE: The `debugger` keyword automatically sets a breakpoint here
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// so you don&amp;#39;t need to set it via the IDE.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;debugger&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Limited integration with VS Code:&lt;/strong&gt; Unfortunately our technique of running Pulumi in wrapper script as a backgrounded pre-launch task in VS Code leaves some things to be desired. It is different enough from the use case that VS Code had in mind for these features (e.g. interacting with a long-running &lt;code&gt;tsc-watch&lt;/code&gt; or similar task) that making things &amp;ldquo;just work&amp;rdquo; is a little difficult. For example, we can&amp;rsquo;t easily report on errors in the &amp;ldquo;Problems&amp;rdquo; tab, and VS Code complains that a problem matcher is missing the first time you run it. VS Code can&amp;rsquo;t tell that the program finished and so you&amp;rsquo;ll have to manually stop the debugging session after Pulumi has completed (or wait for the retry/timeout to expire).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Despite these limitations, Pulumi with VS Code as your IDE provides a rich experience compared to trawlling through unstructured logs, or adding in &lt;code&gt;console.log(...)&lt;/code&gt; calls to echo out ad-hoc debugging information (aka. &lt;a href="https://www.cs.colostate.edu/~fsieker/misc/debug/DEBUG.html"&gt;&lt;code&gt;printf&lt;/code&gt; debugging&lt;/a&gt;). Also, you can enable this for any language that Pulumi supports, and most popular IDEs support breakpoint debugging (e.g. Visual Studio, Webstorm, neovim, etc). Python, Go, and C# all have popular debuggers and IDEs that can be used in the same manner. Whatever your preferred IDE or language is, you can use their full range of breakpoint debugging features for your Pulumi programs.&lt;/p&gt;
&lt;p&gt;Pulumi also offers detailed logging which can be used to look into the other aspects that breakpoint debugging doesn&amp;rsquo;t cover. In an upcoming article we&amp;rsquo;ll show how to use these tools as well. Until then, have fun &lt;a href="https://queue.acm.org/detail.cfm?id=945136"&gt;spelunking&lt;/a&gt; through your code with your favorite IDE!&lt;/p&gt;
&lt;h2 id="next-steps"&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;If you haven&amp;rsquo;t already, &lt;a href="https://www.pulumi.com/docs/install/"&gt;install Pulumi&lt;/a&gt; today, and follow our self-directed &lt;a href="https://www.pulumi.com/start"&gt;Getting Started guides&lt;/a&gt; to learn more about making the most of Pulumi&amp;rsquo;s next-level infrastructure management features at your organization.&lt;/p&gt;
&lt;p&gt;To learn more, you can watch the following video which provides a high level overview of how Pulumi works:&lt;/p&gt;
&lt;div class="rounded-md shadow border border-gray-300 w-3/4 mx-auto my-4" style="position: relative; padding-bottom: 40.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe
src="//www.youtube.com/embed/Q8tw6YTD3ac?rel=0"
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;"
allowfullscreen=""
title="Introduction to Pulumi in Three Minutes"
srcdoc="&lt;style&gt;*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img{position:absolute;width:100%;top:0;bottom:0;margin:auto}&lt;/style&gt;&lt;a href=https://www.youtube.com/embed/Q8tw6YTD3ac?autoplay=1&gt;&lt;img src='https://www.pulumi.com/images/home/youtube-getting-started.png' alt='Introduction to Pulumi in Three Minutes'&gt;&lt;/a&gt;"&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;h2 id="pulumi-cloud"&gt;Pulumi Cloud&lt;/h2&gt;
&lt;p&gt;The Pulumi Cloud is a fully managed service that helps you adopt Pulumi’s open source SDK with ease. It provides built-in state and secrets management, integrates with source control and CI/CD, and offers a web console and API that make it easier to visualize and manage infrastructure. It is free for individual use, with features available for teams.&lt;/p&gt;
&lt;p&gt;&lt;a class="btn btn-secondary" href="https://app.pulumi.com/signup" target="_blank"&gt;Create an Account&lt;/a&gt;&lt;/p&gt;</description><author>Troy Howard</author><category>next-level-iac</category><category>debugging</category><category>vscode</category><category>typescript</category><category>nodejs</category><category>ide</category></item></channel></rss>