<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0"><channel><title>Pulumi Blog: Self service</title><link>https://www.pulumi.com/blog/tag/self-service/</link><description>Pulumi blog posts: Self service.</description><language>en-us</language><pubDate>Tue, 30 Sep 2025 00:00:00 +0000</pubDate><item><title>How to Implement Robust Security Guardrails Using Policy as Code</title><link>https://www.pulumi.com/blog/deployment-guardrails-with-policy-as-code/</link><pubDate>Tue, 30 Sep 2025 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/deployment-guardrails-with-policy-as-code/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/deployment-guardrails-with-policy-as-code/index.png" /&gt;
&lt;p&gt;Welcome to the third post in our &lt;strong&gt;IDP Best Practices&lt;/strong&gt; series, where we explore how to implement &lt;strong&gt;policy as code&lt;/strong&gt; with &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard"&gt;Pulumi CrossGuard&lt;/a&gt; to create deployment guardrails that make self-service infrastructure both powerful and safe.&lt;/p&gt;
&lt;p&gt;Platform engineering presents a fundamental tension: we want to enable developer velocity while maintaining security and compliance. Every platform team faces the same question: how do you give teams the freedom to deploy infrastructure quickly without compromising on safety, security, or organizational standards? The answer isn&amp;rsquo;t to choose between speed and safety, but rather to embrace &lt;strong&gt;automated guardrails&lt;/strong&gt; powered by policy as code that make both possible simultaneously.&lt;/p&gt;
&lt;div class="note note-tip"&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.4a9ac1016b9d8a688a5e7e867f96bdf80115a0739af8c688ba04791e15f64461.svg#p-lightbulb-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;&lt;strong&gt;Want hands-on experience?&lt;/strong&gt; Access the &lt;a href="https://github.com/pulumi/workshops/tree/main/idp-component-policies"&gt;complete demo code&lt;/a&gt; and &lt;a href="https://github.com/pulumi/workshops/tree/main/idp-component-policies/demo-policies"&gt;policy examples&lt;/a&gt; from this workshop.&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="the-platform-engineering-challenge-speed-vs-safety"&gt;The Platform Engineering Challenge: Speed vs. Safety&lt;/h2&gt;
&lt;p&gt;Let me tell you a story that perfectly captures the platform engineering dilemma. Statsig, a fast-growing feature flag platform processing an incredible 2 trillion events daily, had one infrastructure engineer named Jason who handled all infrastructure requests. Everything worked smoothly until Jason went on parental leave. Suddenly, the entire engineering organization ground to a halt. Infrastructure requests piled up, deployments slowed to a crawl, and the team faced a stark realization: their entire infrastructure capability depended on a single person.&lt;/p&gt;
&lt;p&gt;This crisis forced them to confront a fundamental question that every growing engineering team eventually faces: How do you enable self-service infrastructure without sacrificing security, compliance, or operational stability? The answer wasn&amp;rsquo;t to hire more Jasons or to lock down infrastructure even tighter. Instead, they discovered that deployment guardrails with policy as code could transform their infrastructure conversation from &amp;ldquo;talk to the infrastructure person&amp;rdquo; to &amp;ldquo;ship with confidence, knowing guardrails will catch any issues.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Think of it like building a system of roads with guardrails. When you create well-designed infrastructure components with proper safety barriers, teams can drive fast and confidently, knowing they&amp;rsquo;re protected from going off the cliff. The guardrails don&amp;rsquo;t slow them down; they enable speed by removing fear.&lt;/p&gt;
&lt;h2 id="understanding-platform-engineering-layers"&gt;Understanding Platform Engineering Layers&lt;/h2&gt;
&lt;p&gt;Before we dive into implementing guardrails, we need to understand the architecture of a modern platform and where policies fit within it. Think of your platform as having three distinct layers, each with different security and access requirements.&lt;/p&gt;
&lt;p&gt;At the foundation, you have your &lt;strong&gt;Layer 1: Foundational Infrastructure&lt;/strong&gt;, which includes security controls, shared networking, and identity management systems like OIDC and IAM. Platform teams typically manage this layer with strict access controls because it forms the security backbone of your entire infrastructure.&lt;/p&gt;
&lt;p&gt;Building on that foundation is &lt;strong&gt;Layer 2: Shared Infrastructure&lt;/strong&gt;, which encompasses VPCs, compute platforms, and load balancers. These are standardized components that teams can use but with some room for customization based on specific needs.&lt;/p&gt;
&lt;p&gt;The most dynamic layer is &lt;strong&gt;Layer 3: The Workloads Layer&lt;/strong&gt;, where deployable artifacts, pipelines, and operability tools live. This is where the rubber meets the road, where most self-service activity happens and, consequently, where guardrails become absolutely critical. Developers need maximum freedom at this layer to innovate and ship quickly, but this freedom also introduces the most risk. It&amp;rsquo;s precisely here that policy-driven guardrails prove their worth, enabling that freedom while automatically preventing dangerous configurations.&lt;/p&gt;
&lt;h2 id="what-are-deployment-guardrails"&gt;What Are Deployment Guardrails?&lt;/h2&gt;
&lt;p&gt;Deployment guardrails are automated policies that act as your infrastructure&amp;rsquo;s safety net. Rather than relying on manual reviews or hoping developers remember all the security requirements, guardrails automatically prevent misconfigurations before they reach production. They enforce security standards without human intervention, guide developers toward best practices through immediate feedback, and enable safe self-service by catching issues at the earliest possible moment.&lt;/p&gt;
&lt;p&gt;A helpful analogy is to think of guardrails like type checking in programming languages. Just as TypeScript doesn&amp;rsquo;t restrict your ability to write JavaScript but rather catches type errors before runtime, deployment guardrails don&amp;rsquo;t limit your infrastructure creativity. They simply ensure you&amp;rsquo;re following secure patterns and catch potentially dangerous configurations before they cause problems in production.&lt;/p&gt;
&lt;h2 id="introducing-pulumi-crossguard-policy-as-code"&gt;Introducing Pulumi CrossGuard: Policy as Code&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard"&gt;Pulumi CrossGuard&lt;/a&gt; is Pulumi&amp;rsquo;s policy as code framework that brings the same engineering rigor to compliance and security that you apply to your application code. Instead of maintaining policy documents in wikis or relying on manual reviews, you can write policies in familiar programming languages like &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/get-started#writing-policies-in-python"&gt;Python&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/get-started#writing-policies-in-typescript"&gt;TypeScript&lt;/a&gt;, or Go. These policies then enforce themselves across all your cloud resources and providers, running at different stages of the deployment lifecycle and integrating seamlessly with your CI/CD pipelines for automated enforcement.&lt;/p&gt;
&lt;h3 id="key-policy-types"&gt;Key Policy Types&lt;/h3&gt;
&lt;p&gt;CrossGuard supports two fundamental types of policies, each serving different validation needs:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/core-concepts#resource-validation"&gt;Resource Policies&lt;/a&gt;&lt;/strong&gt;: Validate individual resources&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;restrict_dangerous_ports&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ResourceValidationArgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;report_violation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ReportViolation&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resource_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;aws:lb/targetGroup:TargetGroup&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="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;port&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="n"&gt;dangerous_ports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;22&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;23&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;3389&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="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;dangerous_ports&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="n"&gt;report_violation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Dangerous port detected. Avoid using SSH, Telnet, or RDP ports.&amp;#34;&lt;/span&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;&lt;strong&gt;&lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/core-concepts#stack-validation"&gt;Stack Policies&lt;/a&gt;&lt;/strong&gt;: Validate relationships across resources&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate_microservice_encryption&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;StackValidationArgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;report_violation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ReportViolation&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="n"&gt;microservice_components&lt;/span&gt; &lt;span class="o"&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="n"&gt;s3_buckets&lt;/span&gt; &lt;span class="o"&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resources&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resource_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;custom:infrastructure:Microservice&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="n"&gt;microservice_components&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&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="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resource_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;aws:s3/bucket:Bucket&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="n"&gt;s3_buckets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;microservice_components&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;s3_buckets&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;s3_buckets&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="n"&gt;encryption&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;serverSideEncryptionConfiguration&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="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;encryption&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="n"&gt;report_violation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;S3 bucket must have encryption enabled when used with microservice components.&amp;#34;&lt;/span&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;h2 id="building-practical-guardrails-real-world-examples"&gt;Building Practical Guardrails: Real-World Examples&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s walk through building guardrails for a microservice platform, starting with the component from our &lt;a href="https://www.pulumi.com/blog/golden-paths-infrastructure-components-and-templates/"&gt;previous workshop&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="example-1-port-security-policy"&gt;Example 1: Port Security Policy&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Developers might accidentally expose services on dangerous ports like SSH (22) or RDP (3389).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: A policy that blocks dangerous port configurations.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pulumi_policy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;policy&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;restrict_dangerous_ports_validation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;report_violation&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;#34;&amp;#34;Prevent services from running on dangerous ports.&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resource_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;aws:lb/targetGroup:TargetGroup&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="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;port&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="n"&gt;dangerous_ports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;22&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;23&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;3389&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;5432&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;3306&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="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;dangerous_ports&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="n"&gt;report_violation&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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Port &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; is not allowed. This port is commonly used for &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;administrative services and should not be exposed via load balancer.&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;restrict_dangerous_ports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResourceValidationPolicy&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="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;restrict-dangerous-ports&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="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Prevent services from using dangerous ports&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="n"&gt;validate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;restrict_dangerous_ports_validation&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="n"&gt;enforcement_level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EnforcementLevel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MANDATORY&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;h3 id="example-2-resource-limits-policy"&gt;Example 2: Resource Limits Policy&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Teams might request oversized resources, leading to cost overruns.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: A policy that enforces reasonable resource limits with advisory warnings.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;limit_memory_validation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;report_violation&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;#34;&amp;#34;Limit memory allocation for microservices.&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resource_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;custom:infrastructure:Microservice&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="c1"&gt;# Extract memory from component tags or properties&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;memory_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;memory&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;512Mi&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;# Parse memory value (assuming format like &amp;#34;2Gi&amp;#34;, &amp;#34;1024Mi&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;memory_str&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;endswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Gi&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="n"&gt;memory_gb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;memory_str&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;memory_gb&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&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="n"&gt;report_violation&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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Memory allocation of &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;memory_str&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; exceeds recommended limit of 1Gi &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;for microservices. Consider optimizing your application or &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;contact the platform team for exceptions.&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;limit_memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResourceValidationPolicy&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="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;limit-microservice-memory&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="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Enforce reasonable memory limits for microservices&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="n"&gt;validate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;limit_memory_validation&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="n"&gt;enforcement_level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EnforcementLevel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ADVISORY&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;h3 id="example-3-cross-resource-security-policy"&gt;Example 3: Cross-Resource Security Policy&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: When microservices use S3 buckets, encryption should be mandatory.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: A stack policy that validates encryption across related resources.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;microservice_s3_encryption_validation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;report_violation&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;#34;&amp;#34;Ensure S3 buckets used with microservices have encryption enabled.&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;microservice_resources&lt;/span&gt; &lt;span class="o"&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="n"&gt;s3_buckets&lt;/span&gt; &lt;span class="o"&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Collect relevant resources&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resources&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resource_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;custom:infrastructure:Microservice&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="n"&gt;microservice_resources&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&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="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resource_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;aws:s3/bucket:Bucket&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="n"&gt;s3_buckets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&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;# If we have both microservices and S3 buckets, check encryption&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;microservice_resources&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;s3_buckets&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;s3_buckets&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="n"&gt;sse_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;serverSideEncryptionConfiguration&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="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;sse_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="n"&gt;report_violation&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="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;S3 bucket &amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39; must have server-side encryption &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;enabled when used with microservice components.&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;microservice_s3_encryption&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StackValidationPolicy&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="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;microservice-s3-encryption&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="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Ensure S3 buckets used with microservices are encrypted&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="n"&gt;validate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;microservice_s3_encryption_validation&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="n"&gt;enforcement_level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EnforcementLevel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MANDATORY&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;h2 id="policy-enforcement-models"&gt;Policy Enforcement Models&lt;/h2&gt;
&lt;p&gt;Pulumi CrossGuard supports multiple &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/core-concepts#enforcement-levels"&gt;enforcement models&lt;/a&gt; to fit different workflows, and understanding when to use each model is crucial for effective policy implementation.&lt;/p&gt;
&lt;h3 id="the-preventative-model"&gt;The Preventative Model&lt;/h3&gt;
&lt;p&gt;The most common approach is the preventative model, where policies run before resources are created. This gives you fast feedback and prevents bad deployments from ever reaching the cloud. When you run &lt;code&gt;pulumi preview&lt;/code&gt;, policies are evaluated immediately, and if violations are found during &lt;code&gt;pulumi up&lt;/code&gt;, the deployment is blocked. This model works particularly well for validating port configurations, resource limits, and other settings that you can check without needing to see the actual deployed resource.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Policies run automatically during preview and deployment&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pulumi preview &lt;span class="c1"&gt;# Policies evaluated here&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pulumi up &lt;span class="c1"&gt;# Policies block deployment if violations found&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="the-detective-model"&gt;The Detective Model&lt;/h3&gt;
&lt;p&gt;Sometimes you need to validate the actual cloud state, including auto-generated values like ARNs or IP addresses. That&amp;rsquo;s where the detective model comes in. These policies run after resources are created, making them perfect for compliance scanning and drift detection. While they can&amp;rsquo;t prevent initial deployment of non-compliant resources, they excel at catching configuration drift and validating properties that only exist after deployment.&lt;/p&gt;
&lt;h3 id="cicd-integration"&gt;CI/CD Integration&lt;/h3&gt;
&lt;p&gt;The third model integrates policies directly into your deployment pipeline. This ensures consistent enforcement across all teams and creates natural deployment gates. For example, you might configure &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/continuous-delivery/github-actions"&gt;GitHub Actions&lt;/a&gt; to run policy validation on every pull request, blocking merges if violations are found. This approach combines the best of both worlds: early feedback during development and guaranteed enforcement before production.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# GitHub Actions example&lt;/span&gt;&lt;span class="w"&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Run Policy Validation&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&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="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; pulumi preview --policy-pack ./policies
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; if [ $? -ne 0 ]; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; echo &amp;#34;Policy violations found. Deployment blocked.&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; exit 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; fi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="policy-remediation-beyond-detection"&gt;Policy Remediation: Beyond Detection&lt;/h2&gt;
&lt;p&gt;Modern policy frameworks don&amp;rsquo;t just detect violations; they can &lt;strong&gt;&lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/core-concepts#remediation-policies"&gt;automatically fix&lt;/a&gt;&lt;/strong&gt; them:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;auto_tag_resources&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;report_violation&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;#34;&amp;#34;Automatically add required tags to resources.&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resource_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;aws:s3/bucket:Bucket&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="n"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;tags&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&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Department&amp;#34;&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tags&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;# Instead of just reporting, fix the issue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;hasattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;tags&amp;#39;&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="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;tags&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&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="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;tags&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Department&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;Engineering&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;props&lt;/span&gt; &lt;span class="c1"&gt;# Return modified properties&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="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt; &lt;span class="c1"&gt;# No changes needed&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="n"&gt;auto_tag_policy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResourceValidationPolicy&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="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;auto-tag-resources&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="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Automatically add required tags&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="n"&gt;validate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;auto_tag_resources&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="n"&gt;enforcement_level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EnforcementLevel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;REMEDIATE&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;h2 id="server-side-policy-enforcement"&gt;Server-Side Policy Enforcement&lt;/h2&gt;
&lt;p&gt;For enterprise deployments, Pulumi provides &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/get-started#enforcing-a-policy-pack"&gt;server-side policy enforcement&lt;/a&gt; that ensures policies can&amp;rsquo;t be bypassed. The process starts by publishing your policies to your Pulumi organization with &lt;code&gt;pulumi policy publish ./my-policies&lt;/code&gt;. Once published, you can &lt;a href="https://www.pulumi.com/docs/iac/crossguard/configuration/#using-pulumi-cloud"&gt;create policy groups&lt;/a&gt; that combine multiple policies with specific enforcement levels, targeting particular stacks or environments while configuring exceptions for special cases. The beauty of this approach is that policies run automatically without requiring CLI flags, providing consistent governance across your entire organization without relying on developers to remember to include policy packs in their commands.&lt;/p&gt;
&lt;h2 id="compliance-ready-policies"&gt;Compliance-Ready Policies&lt;/h2&gt;
&lt;p&gt;While custom policies address your specific organizational needs, compliance requirements often follow industry standards. Pulumi provides hundreds of &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/compliance-ready-policies"&gt;pre-built policies&lt;/a&gt; for common compliance frameworks:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PolicyManager&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/policy&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;policyManager&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/compliance-ready-policies/policy-manager&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="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;PolicyPack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;aws-compliance-ready-policies-typescript&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="nx"&gt;policies&lt;/span&gt;&lt;span class="o"&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 class="nx"&gt;policyManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;selectPolicies&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="nx"&gt;vendors&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;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="nx"&gt;services&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ec2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;s3&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="nx"&gt;severities&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;medium&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;high&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;critical&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="nx"&gt;topics&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;encryption&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="nx"&gt;frameworks&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pcidss&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="p"&gt;},&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;mandatory&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="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 automatically includes policies for major compliance frameworks like &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/compliance-ready-policies#frameworks"&gt;PCI DSS&lt;/a&gt; for payment card industry standards, &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/compliance-ready-policies#frameworks"&gt;SOC 2&lt;/a&gt; for security and compliance controls, &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/compliance-ready-policies#frameworks"&gt;ISO 27001&lt;/a&gt; for information security management, and &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/compliance-ready-policies#frameworks"&gt;CIS Benchmarks&lt;/a&gt; for security configuration standards.&lt;/p&gt;
&lt;div class="rounded-lg bg-violet-50 p-6 my-8"&gt;
&lt;p class="heading-4 m-0 mb-3 flex items-center gap-1.5"&gt;Add guardrails with policy as code&lt;/p&gt;
&lt;div class="body-base m-0 text-gray-950"&gt;Write policies in Python or TypeScript, enforce them across every deployment, and give teams self-service infrastructure that stays secure and compliant.&lt;/div&gt;
&lt;a href="https://www.pulumi.com/docs/insights/policy/" data-track="blog-body-cta" class="btn btn-primary mt-4"&gt;
Get started
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--regular size-4" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.4a9ac1016b9d8a688a5e7e867f96bdf80115a0739af8c688ba04791e15f64461.svg#p-arrow-right-regular"/&gt;&lt;/svg&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;h2 id="best-practices-for-policy-implementation"&gt;Best Practices for Policy Implementation&lt;/h2&gt;
&lt;p&gt;After implementing policies at dozens of organizations, we&amp;rsquo;ve learned that successful policy adoption follows predictable patterns. The key is to adopt a product mindset: think of your policies as a product serving your development teams, not as bureaucratic rules imposed from above. Start small and iterate based on real feedback rather than trying to implement a comprehensive policy framework from day one.&lt;/p&gt;
&lt;h3 id="start-small-and-iterate"&gt;Start Small and Iterate&lt;/h3&gt;
&lt;p&gt;Begin with just two or three critical policies that address your most pressing risks. Use &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/core-concepts#enforcement-levels"&gt;advisory enforcement&lt;/a&gt; initially, which warns developers about violations but doesn&amp;rsquo;t block deployments. This gives your team time to understand and adapt to the policies. Only after gathering feedback and refining the policies should you graduate to mandatory enforcement.&lt;/p&gt;
&lt;h3 id="provide-clear-actionable-error-messages"&gt;Provide Clear, Actionable Error Messages&lt;/h3&gt;
&lt;p&gt;Nothing frustrates developers more than cryptic policy violations. Your error messages should explain not just what&amp;rsquo;s wrong, but how to fix it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;good_error_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;report_violation&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;violation_detected&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="n"&gt;report_violation&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;S3 bucket encryption is required for compliance. &amp;#34;&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;Add serverSideEncryptionConfiguration to fix this. &amp;#34;&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;See: https://docs.company.com/s3-encryption&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="embrace-progressive-enforcement"&gt;Embrace Progressive Enforcement&lt;/h3&gt;
&lt;p&gt;Think of enforcement levels as a dial, not a switch. Start with &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/core-concepts#advisory"&gt;advisory&lt;/a&gt; mode to warn about issues, move to &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/core-concepts#mandatory"&gt;mandatory&lt;/a&gt; to block deployments, and eventually implement &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/core-concepts#remediation-policies"&gt;remediation&lt;/a&gt; to automatically fix common issues. This progression gives teams time to adapt while gradually raising the security bar.&lt;/p&gt;
&lt;h3 id="test-your-policies-thoroughly"&gt;Test Your Policies Thoroughly&lt;/h3&gt;
&lt;p&gt;Policies are code, and like any code, they need testing. Write unit tests for your policies to ensure they catch violations correctly and don&amp;rsquo;t produce false positives:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Test policies with unit tests&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_dangerous_port_policy&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;# Mock resource with port 22&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_mock_args&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;aws:lb/targetGroup:TargetGroup&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;port&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;22&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="n"&gt;violations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;run_policy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;restrict_dangerous_ports&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&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="k"&gt;assert&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;violations&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;dangerous port&amp;#34;&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;violations&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&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;lower&lt;/span&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;h3 id="document-escape-hatches"&gt;Document Escape Hatches&lt;/h3&gt;
&lt;p&gt;No matter how well-designed your policies are, there will always be edge cases. Rather than forcing teams to work around policies in dangerous ways, provide clear, documented escape hatches. Create processes for requesting exceptions, handling emergency exemptions, and appealing for policy changes. As one platform engineer put it, you need &amp;ldquo;guardrails outside the guardrails&amp;rdquo; because platform adoption will never be 100%, and that&amp;rsquo;s okay. This transparency builds trust and ensures policies remain effective enablers rather than bureaucratic obstacles to circumvent.&lt;/p&gt;
&lt;h2 id="real-world-success-statsigs-transformation"&gt;Real-World Success: Statsig&amp;rsquo;s Transformation&lt;/h2&gt;
&lt;p&gt;Remember Statsig&amp;rsquo;s infrastructure crisis when Jason went on parental leave? Let&amp;rsquo;s look at how they transformed their platform using the guardrails approach we&amp;rsquo;ve been discussing. After implementing policy-driven guardrails, their infrastructure story completely changed.&lt;/p&gt;
&lt;p&gt;As Tyrone Wong, Infrastructure Engineer at Statsig, explains: &amp;ldquo;We had a single infra owner. Parental leave forced us to build self-service, and that&amp;rsquo;s when everything clicked. Developers open a PR, Pulumi previews the change right in the PR, and CI blocks risky changes. That&amp;rsquo;s how you move fast safely. The magic was turning &amp;rsquo;talk to the infra person&amp;rsquo; into &amp;lsquo;ship with guardrails.&amp;rsquo;&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The results speak for themselves. Deployment times dropped from 1.5 weeks to mere minutes. The infrastructure ticket queue that once haunted their Slack channels disappeared entirely. Security actually improved through automated policy enforcement, eliminating the human error factor. Most importantly, developer satisfaction soared as teams gained the autonomy to ship infrastructure changes without friction or fear.&lt;/p&gt;
&lt;p&gt;When asked if developers were actually using the self-service platform, Tyrone&amp;rsquo;s response was telling: &amp;ldquo;Yeah, people are actually using it because there&amp;rsquo;s changes they wanted to get done. Previously it became this giant effort with lots of meetings, people being concerned, and Google docs about what the changes would be. Now people can just put together a PR, we have our discussions there, see if anything gets flagged, and move forward.&amp;rdquo;&lt;/p&gt;
&lt;h2 id="building-your-policy-strategy"&gt;Building Your Policy Strategy&lt;/h2&gt;
&lt;p&gt;Implementing deployment guardrails isn&amp;rsquo;t a big-bang transformation; it&amp;rsquo;s a journey that unfolds in phases. Based on patterns we&amp;rsquo;ve seen across successful implementations, the first week or two should focus on assessment. Start by understanding your current state, auditing existing infrastructure patterns to identify what teams are actually deploying. Look for common misconfigurations that have caused incidents or near-misses, and document your security and compliance requirements as specific, enforceable rules. Most importantly, survey your developers to understand their pain points with the current infrastructure process, as this assessment forms the foundation for policies that solve real problems rather than creating new ones.&lt;/p&gt;
&lt;p&gt;In weeks three and four, build your foundation by implementing three to five core policies that address your most critical risks. Set up &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/continuous-delivery"&gt;CI/CD integration&lt;/a&gt; so policies run automatically on every pull request, starting with advisory enforcement to gather feedback without blocking deployments. Create clear documentation and runbooks that explain not just what the policies do, but why they exist and how to work with them.&lt;/p&gt;
&lt;p&gt;By the second month, you&amp;rsquo;re ready to expand. Add &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/compliance-ready-policies"&gt;compliance-specific policies&lt;/a&gt; for regulatory requirements and implement &lt;a href="https://www.pulumi.com/docs/iac/crossguard/get-started/#enforcing-a-policy-pack"&gt;server-side enforcement&lt;/a&gt; to ensure policies can&amp;rsquo;t be bypassed. Create formal processes for policy exemptions and exceptions, and begin measuring policy effectiveness through metrics like violation rates and remediation times.&lt;/p&gt;
&lt;p&gt;Remember that policy implementation is never &amp;ldquo;done.&amp;rdquo; Continuously monitor violation patterns to identify areas where policies might be too strict or too lenient. Refine policies based on developer feedback and incident data, add &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/core-concepts#remediation-policies"&gt;automated remediation&lt;/a&gt; for common violations to reduce manual fixes, and gradually expand coverage to new services and teams using lessons learned from early adopters.&lt;/p&gt;
&lt;h2 id="measuring-policy-success"&gt;Measuring Policy Success&lt;/h2&gt;
&lt;p&gt;You can&amp;rsquo;t improve what you don&amp;rsquo;t measure, and policy effectiveness is no exception. Successful teams track metrics across three critical dimensions to validate their policy strategy.&lt;/p&gt;
&lt;p&gt;From a security perspective, start by monitoring your policy violation rate: the percentage of deployments that trigger policy warnings or blocks. This tells you whether your policies are catching real issues or creating unnecessary friction. Track time to remediation to understand how quickly teams fix violations when they occur. Most importantly, measure the reduction in security incidents caused by misconfigurations. If your policies aren&amp;rsquo;t reducing incidents, they&amp;rsquo;re not addressing the right risks.&lt;/p&gt;
&lt;p&gt;Security is only half the equation, though. The developer experience dimension is equally important. Monitor deployment velocity to ensure policies aren&amp;rsquo;t slowing teams down. Regular developer satisfaction surveys reveal whether teams see policies as helpful guardrails or annoying obstacles. Track support ticket volume; successful policy implementation should reduce infrastructure-related requests as teams become more self-sufficient.&lt;/p&gt;
&lt;p&gt;Finally, don&amp;rsquo;t forget to measure the operational health of your policy system itself. Policy coverage shows what percentage of your resources are protected by policies, while the exemption rate reveals whether policies are practical or if teams constantly need exceptions. Track remediation automation to see how many violations are fixed automatically versus requiring manual intervention. Together, these metrics paint a complete picture of your policy program&amp;rsquo;s health and help you continuously improve your approach.&lt;/p&gt;
&lt;h2 id="common-pitfalls-and-how-to-avoid-them"&gt;Common Pitfalls and How to Avoid Them&lt;/h2&gt;
&lt;p&gt;Even with the best intentions, policy implementations can go wrong. Through years of helping organizations implement policy as code, we&amp;rsquo;ve identified four critical pitfalls that can derail your efforts.&lt;/p&gt;
&lt;p&gt;The first and most common trap is over-engineering policies. It&amp;rsquo;s tempting to create sophisticated policies that handle every edge case, but overly complex policies are hard to understand and maintain. Teams won&amp;rsquo;t trust what they don&amp;rsquo;t understand. Instead, start with simple, clear policies that address specific risks. Use descriptive naming and provide examples of both compliant and non-compliant configurations. Remember, a simple policy that everyone follows is better than a perfect policy that everyone circumvents.&lt;/p&gt;
&lt;p&gt;Equally dangerous is falling into &amp;ldquo;policy theater&amp;rdquo;: implementing policies because you think you should, not because they address real risks. This creates friction without improving security. Every policy should trace back to an actual incident, security requirement, or compliance need. If you can&amp;rsquo;t explain why a policy exists with a concrete example, it probably shouldn&amp;rsquo;t exist.&lt;/p&gt;
&lt;p&gt;Poor developer experience is another common failure point. Nothing kills policy adoption faster than cryptic error messages and unclear remediation steps. When a developer hits a policy violation at 5 PM on a Friday, they need clear guidance on how to fix it. Invest heavily in documentation, helpful error messages, and examples. Consider your policies&amp;rsquo; error messages as part of your product&amp;rsquo;s user experience.&lt;/p&gt;
&lt;p&gt;Finally, inadequate testing can erode trust quickly. Policies that break legitimate use cases will be worked around or disabled. Before enforcing any policy, test it thoroughly with real scenarios from your production workloads. Run policies in advisory mode first to catch false positives, and have teams attempt real deployments with policies enabled to ensure they don&amp;rsquo;t block valid configurations.&lt;/p&gt;
&lt;h2 id="the-future-of-policy-as-code"&gt;The Future of Policy as Code&lt;/h2&gt;
&lt;p&gt;As infrastructure becomes increasingly complex and distributed, policy as code is evolving beyond simple rule enforcement to become an intelligent layer that understands context and intent. Three major trends are shaping this evolution.&lt;/p&gt;
&lt;p&gt;First, we&amp;rsquo;re seeing the emergence of AI-enhanced policies with smart detection systems that use machine learning to identify anomalies that rule-based policies might miss. These systems learn from your infrastructure patterns and can provide contextual recommendations that adapt based on actual usage. Even more exciting is predictive enforcement: imagine policies that can identify risky patterns before they become violations, guiding developers away from problems they haven&amp;rsquo;t encountered yet.&lt;/p&gt;
&lt;p&gt;Second, the multi-cloud reality is driving the need for universal governance. Organizations need policies that work seamlessly across &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/compliance-ready-policies-aws"&gt;AWS&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/compliance-ready-policies-azure"&gt;Azure&lt;/a&gt;, and &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/compliance-ready-policies-gcp"&gt;GCP&lt;/a&gt;, with federated enforcement that maintains consistency across multiple cloud accounts and regions. Compliance automation is also maturing, with systems that automatically collect evidence for audits and generate compliance reports without manual intervention.&lt;/p&gt;
&lt;p&gt;Finally, policy enforcement is moving closer to where developers actually work. IDE integration will soon provide real-time policy feedback as you write infrastructure code, catching issues before you even attempt to deploy. Self-service exemption workflows will let developers request and receive policy exceptions through automated approval processes. Perhaps most intriguingly, we&amp;rsquo;re seeing the development of learning policies: systems that improve and adapt based on developer feedback and usage patterns, becoming more helpful over time rather than more restrictive.&lt;/p&gt;
&lt;h2 id="conclusion-enabling-safe-self-service-at-scale"&gt;Conclusion: Enabling Safe Self-Service at Scale&lt;/h2&gt;
&lt;p&gt;We started this post with a fundamental tension in platform engineering: the need for both speed and safety. Through the lens of Statsig&amp;rsquo;s transformation and the technical deep-dive into Pulumi CrossGuard, we&amp;rsquo;ve seen that this isn&amp;rsquo;t actually a tension that needs resolving. It&amp;rsquo;s a false dichotomy that policy as code eliminates entirely.&lt;/p&gt;
&lt;p&gt;The key insight from successful platform teams like Statsig is that guardrails don&amp;rsquo;t restrict freedom; they enable it. When developers know that automated policies will catch dangerous configurations, they gain the confidence to move fast and experiment. When platform teams know that policies automatically enforce security and compliance standards, they can focus on building better platforms instead of reviewing every change. This is the magic of policy as code: it transforms infrastructure governance from a bottleneck into an accelerator.&lt;/p&gt;
&lt;p&gt;But perhaps the most important lesson is that policy as code isn&amp;rsquo;t about saying &amp;ldquo;no&amp;rdquo; to developers. It&amp;rsquo;s about intelligent automation that makes the secure path the path of least resistance. It&amp;rsquo;s about catching mistakes before they become incidents. It&amp;rsquo;s about encoding your organization&amp;rsquo;s hard-won knowledge into systems that help every developer benefit from that experience.&lt;/p&gt;
&lt;p&gt;As you embark on your own journey to implement deployment guardrails, remember that perfection isn&amp;rsquo;t the goal; progress is. Start small, iterate based on feedback, and gradually expand your coverage. Your developers will thank you for the clarity and confidence that comes with well-designed guardrails, and your security team will sleep better knowing that policies are enforced automatically and consistently.&lt;/p&gt;
&lt;p&gt;The path from manual reviews to automated guardrails is well-traveled and well-documented. Our &lt;a href="https://github.com/pulumi/workshops/tree/main/idp-component-policies/demo-policies"&gt;complete policy examples&lt;/a&gt; provide real-world implementations you can adapt to your needs, while the &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard"&gt;CrossGuard documentation&lt;/a&gt; offers deep technical details for advanced use cases. If you&amp;rsquo;re on AWS, &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/awsguard"&gt;AWSGuard&amp;rsquo;s pre-built policies&lt;/a&gt; offer immediate value, and our &lt;a href="https://www.pulumi.com/docs/iac/packages-and-automation/crossguard/compliance-ready-policies"&gt;compliance-ready policy catalog&lt;/a&gt; addresses specific regulatory requirements.&lt;/p&gt;
&lt;p&gt;The future of infrastructure management isn&amp;rsquo;t about choosing between developer autonomy and operational control. It&amp;rsquo;s about using policy as code to achieve both, creating platforms that are simultaneously powerful and safe, flexible and compliant, fast and secure.&lt;/p&gt;
&lt;p&gt;In our next post, we&amp;rsquo;ll explore Day 2 Platform Operations, diving into how to maintain infrastructure compliance after deployment and automatically remediate configuration drift. Because getting to production is just the beginning; keeping your infrastructure secure and compliant over time is where the real challenge lies.&lt;/p&gt;
&lt;section class="my-16"&gt;
&lt;div class="container mx-auto max-w-5xl md:flex my-8 align-top justify-center text-center"&gt;
&lt;div class="md:w3-/12 mr-4"&gt;
&lt;h2 class="no-anchor"&gt;Get Started with Pulumi&lt;/h2&gt;
&lt;p class="text-gray-700 dark:text-gray-300 text-sm"&gt;Use Pulumi's open-source SDK to create, deploy, and manage infrastructure on any cloud.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="mx-auto max-w-4xl"&gt;
&lt;div class="tiles flex-wrap mt-4"&gt;
&lt;div class="pb-4 md:pr-4 md:w-1/2"&gt;
&lt;a class="tile p-8" href="https://www.pulumi.com/docs/iac/get-started/aws/"&gt;
&lt;img class="h-10 mx-auto" src="https://www.pulumi.com/logos/tech/aws.svg" alt="AWS" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;div class="pb-4 md:w-1/2"&gt;
&lt;a class="tile p-8" href="https://www.pulumi.com/docs/iac/get-started/azure/"&gt;
&lt;img class="h-10 mx-auto" src="https://www.pulumi.com/logos/tech/azure.svg" alt="Azure" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;div class="pb-4 md:pr-4 md:w-1/2"&gt;
&lt;a class="tile p-8" href="https://www.pulumi.com/docs/iac/get-started/gcp/"&gt;
&lt;img class="h-10 mx-auto" src="https://www.pulumi.com/logos/tech/gcp.svg" alt="Google Cloud" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;div class="pb-4 md:w-1/2"&gt;
&lt;a class="tile p-8" href="https://www.pulumi.com/docs/iac/get-started/kubernetes/"&gt;
&lt;img class="h-10 mx-auto" src="https://www.pulumi.com/logos/tech/k8s.svg" alt="Kubernetes" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;</description><author>Adam Gordon Bell</author><category>internal-developer-platform</category><category>platform-engineering</category><category>policy-as-code</category><category>crossguard</category><category>compliance</category><category>security</category><category>self-service</category><category>guardrails</category></item><item><title>How to Build an Internal Developer Platform: Strategy, Best Practices, and Self-Service Infrastructure</title><link>https://www.pulumi.com/blog/idp-strategy-planning-self-service-infrastructure-that-balances-developer-autonomy-with-operational-control/</link><pubDate>Thu, 14 Aug 2025 05:13:02 +0200</pubDate><guid>https://www.pulumi.com/blog/idp-strategy-planning-self-service-infrastructure-that-balances-developer-autonomy-with-operational-control/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/idp-strategy-planning-self-service-infrastructure-that-balances-developer-autonomy-with-operational-control/index.png" /&gt;
&lt;p&gt;Welcome to the first post in our &lt;strong&gt;IDP Best Practices&lt;/strong&gt; series. In this guide, we’ll walk through the strategic foundations for designing an Internal Developer Platform that empowers developers without sacrificing governance, security, or operational control.&lt;/p&gt;
&lt;p&gt;At Pulumi, we’ve worked with hundreds of teams facing the same core challenge: &lt;strong&gt;How do you give developers the infrastructure access they need, while maintaining the governance and security your organization requires?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;That tension is at the heart of every IDP conversation. Teams want to &lt;strong&gt;move faster and innovate&lt;/strong&gt;, but also need to stay compliant, control costs, and maintain operational stability.&lt;/p&gt;
&lt;p&gt;The good news? You can do both, with a clear strategy and the right approach. This series shares &lt;strong&gt;proven best practices&lt;/strong&gt; for designing, building, and scaling IDPs using Pulumi.&lt;/p&gt;
&lt;p&gt;These lessons come from real-world implementations across industries and company sizes—and are built to grow with you.&lt;/p&gt;
&lt;h2 id="understanding-the-platform-engineering-layers-in-your-internal-developer-platform"&gt;Understanding the Platform Engineering Layers in Your Internal Developer Platform&lt;/h2&gt;
&lt;p&gt;&lt;img src="internal-developer-platform-key-layers.png" alt="internal-developer-platform-key-layers.png"&gt;&lt;/p&gt;
&lt;p&gt;When we work with customers on their platform strategy, we often start by referring to the &amp;ldquo;platform engineering layer cake.&amp;rdquo;
Here is a quick walkthrough of each layer and how Pulumi IDP constructs fit this layer cake approach:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Layer 1: Infrastructure Layer&lt;/strong&gt; - This is your raw cloud resources: VMs, databases, networks, storage.
These are the fundamental building blocks that exist in AWS, Azure, GCP, and other cloud providers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Layer 2: Platform Layer&lt;/strong&gt; - This is where &lt;a href="https://www.pulumi.com/docs/iac/concepts/resources/components/"&gt;Pulumi Components&lt;/a&gt; live.
Components take those raw infrastructure resources and package them into higher-level abstractions that encapsulate best practices, security policies, and organizational standards.
For example, instead of manually configuring 15 different AWS resources to create a secure web application, you create a component that handles all that complexity and exposes just the configuration options that matter to your developers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Layer 3: Developer Experience Layer&lt;/strong&gt; - This is where &lt;a href="https://www.pulumi.com/templates/"&gt;Pulumi Templates&lt;/a&gt; and the &lt;a href="https://www.pulumi.com/docs/idp/get-started/private-registry/"&gt;Private Registry&lt;/a&gt; come into play.
Templates provide ready-to-deploy patterns that developers can customize, while the private registry makes everything discoverable and manageable at scale.&lt;/p&gt;
&lt;p&gt;In our workshop, we focused specifically on those top two layers because that&amp;rsquo;s where the transformation happens. This is where you turn raw infrastructure into something developers can actually use productively without becoming infrastructure experts themselves.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how this maps to what you&amp;rsquo;re actually building:&lt;/p&gt;
&lt;h3 id="infrastructure-layer--raw-cloud-resources"&gt;Infrastructure Layer → Raw Cloud Resources&lt;/h3&gt;
&lt;p&gt;Your foundation is still the same: AWS EC2 instances, Azure Virtual Networks, GCP Cloud Functions.
Pulumi&amp;rsquo;s providers give you access to these resources using real programming languages instead of YAML or proprietary DSLs.&lt;/p&gt;
&lt;h3 id="platform-layer--pulumi-components"&gt;Platform Layer → Pulumi Components&lt;/h3&gt;
&lt;p&gt;This is where you create your reusable building blocks. A component might encapsulate:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A complete microservice infrastructure pattern (load balancer, auto-scaling group, database, monitoring)&lt;/li&gt;
&lt;li&gt;A secure data pipeline (storage, processing, access controls, encryption)&lt;/li&gt;
&lt;li&gt;A standardized Kubernetes application deployment (ingress, service, deployment, secrets management)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Components are written once in any supported language (TypeScript, Python, Go, .NET, Java) but can be consumed by teams using any of these languages.
This is crucial. Your platform team might write components in Go, but your application teams can consume them in Python or TypeScript.&lt;/p&gt;
&lt;h3 id="developer-experience-layer--templates--private-registry"&gt;Developer Experience Layer → Templates + Private Registry&lt;/h3&gt;
&lt;p&gt;Templates are complete, deployable projects that use your components. They provide:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Getting started patterns: &amp;ldquo;Deploy a new microservice&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Reference architectures: &amp;ldquo;Deploy a three-tier web application&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Environment patterns: &amp;ldquo;Set up a complete dev/staging/prod pipeline&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Private Registry is your distribution mechanism.
It&amp;rsquo;s where components and templates become discoverable, versioned, and manageable.
Developers don&amp;rsquo;t need to hunt through Git repositories or Slack channels to find the right building blocks. Everything is catalogued, documented, and accessible through familiar package management workflows.&lt;/p&gt;
&lt;h2 id="idp-example-building-a-web-application-platform-step-by-step"&gt;IDP Example: Building a Web Application Platform Step-by-Step&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s make this concrete with an example from our workshops.
Say you want to enable teams to deploy secure web applications:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Infrastructure Layer:&lt;/strong&gt; You need an Application Load Balancer, EC2 Auto Scaling Group, RDS database, VPC with proper subnets, Security Groups, IAM roles, CloudWatch monitoring, and S3 bucket for static assets.
That&amp;rsquo;s about 20+ individual AWS resources that need to be configured correctly and securely.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Platform Layer (Components):&lt;/strong&gt; You create a &lt;code&gt;WebApplication&lt;/code&gt; component that encapsulates all this complexity.
Your component exposes simple configuration options like:&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;const&lt;/span&gt; &lt;span class="nx"&gt;app&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;WebApplication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;my-app&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="nx"&gt;instanceType&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;t3.medium&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="nx"&gt;minSize&lt;/span&gt;: &lt;span class="kt"&gt;2&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="nx"&gt;maxSize&lt;/span&gt;: &lt;span class="kt"&gt;10&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="nx"&gt;databaseSize&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;small&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="nx"&gt;environment&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;production&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Behind the scenes, your component handles all the security configurations, networking setup, monitoring, and best practices.
You publish this component to your private registry.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Developer Experience Layer (Templates):&lt;/strong&gt; You create templates like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;web-app-starter&lt;/code&gt;: A simple web application using your &lt;code&gt;WebApplication&lt;/code&gt; component&lt;/li&gt;
&lt;li&gt;&lt;code&gt;microservice-template&lt;/code&gt;: API service with database and monitoring&lt;/li&gt;
&lt;li&gt;&lt;code&gt;full-stack-template&lt;/code&gt;: Frontend, backend, and database in a complete environment&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Developers can now run &lt;code&gt;pulumi new web-app-starter&lt;/code&gt; and get a production-ready, secure web application in minutes instead of weeks.
The template uses your component, which handles all the underlying infrastructure complexity.&lt;/p&gt;
&lt;p&gt;This layered approach solves the core challenge we see every platform team struggling with: how do you provide developers with the infrastructure they need without creating operational bottlenecks or compromising security standards.&lt;/p&gt;
&lt;h2 id="why-internal-developer-platforms-matter-in-2025-and-beyond"&gt;Why Internal Developer Platforms Matter in 2025 and Beyond&lt;/h2&gt;
&lt;p&gt;While DevOps brought us incredible advances in how we ship and maintain software, we&amp;rsquo;ve watched many organizations struggle with the unintended consequences: tool sprawl, Day 2 operational pain, and developers who are drowning in infrastructure complexity.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s why platform teams have emerged.
You exist to solve these challenges by building tools and workflows that enable your internal customers (the developers) to provision infrastructure and deploy software without getting blocked.
But here&amp;rsquo;s the thing I&amp;rsquo;ve learned from working with hundreds of platform teams: success isn&amp;rsquo;t just about the tools you choose.
It&amp;rsquo;s about the strategy behind how you implement them.&lt;/p&gt;
&lt;h2 id="5-core-components-of-a-successful-internal-developer-platform"&gt;5 Core Components of a Successful Internal Developer Platform&lt;/h2&gt;
&lt;p&gt;Through years of working with platform teams and analyzing what separates successful IDPs from those that struggle to gain adoption, we&amp;rsquo;ve identified five essential components that every platform strategy needs.
These aren&amp;rsquo;t theoretical concepts. They&amp;rsquo;re battle-tested patterns that work across organizations of all sizes and industries.&lt;/p&gt;
&lt;h3 id="1-abstractions"&gt;1. Abstractions&lt;/h3&gt;
&lt;p&gt;Let me be clear about something: abstractions aren&amp;rsquo;t about dumbing down infrastructure for developers.
The abstraction is really where you&amp;rsquo;re hiding the complexity of the underlying infrastructure from your end users, but you&amp;rsquo;re doing it intentionally to provide appropriate interfaces for different personas in your organization.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ve seen too many platform teams get this wrong by either over-abstracting (creating black boxes that developers can&amp;rsquo;t customize) or under-abstracting (exposing too much complexity).
The sweet spot is creating &lt;a href="https://www.pulumi.com/docs/iac/concepts/resources/components/"&gt;component resources&lt;/a&gt; that encapsulate your infrastructure patterns and best practices into reusable building blocks that can be consumed across different programming languages and deployment scenarios, while still providing escape hatches when needed.&lt;/p&gt;
&lt;h3 id="2-blueprints"&gt;2. Blueprints&lt;/h3&gt;
&lt;p&gt;Blueprints are your templatized, well-architected patterns that developers can use to bootstrap their infrastructure.
But here&amp;rsquo;s what I want you to understand about blueprints: they&amp;rsquo;re not just starting points that you throw over the wall to developers.
They&amp;rsquo;re carefully designed patterns that embody your organizational best practices and architectural decisions.&lt;/p&gt;
&lt;p&gt;When we see successful platform teams, their templates serve as both accelerators and guardrails.
They give developers a fast path to production-ready infrastructure while ensuring that everything they deploy follows your organization&amp;rsquo;s standards.
That&amp;rsquo;s the power of good blueprint design: speed and compliance working together, not against each other.&lt;/p&gt;
&lt;h3 id="3-workflows"&gt;3. Workflows&lt;/h3&gt;
&lt;p&gt;Here&amp;rsquo;s where many platform teams get trapped: they try to build one workflow to rule them all.
But in our experience working with organizations across every industry, you need to support multiple consumption patterns because you have multiple types of users.
You need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No-code workflows&lt;/strong&gt; for users who want point-and-click deployment (think product managers or junior developers who just need to spin up a database)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Low-code workflows&lt;/strong&gt; using tools like &lt;a href="https://www.pulumi.com/docs/iac/languages-sdks/yaml/"&gt;Pulumi YAML&lt;/a&gt; for configuration-driven infrastructure (perfect for developers who understand infrastructure but don&amp;rsquo;t want to write Go or TypeScript)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Full-code workflows&lt;/strong&gt; for developers who need maximum flexibility and want to leverage the full power of general-purpose programming languages&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The key insight? These aren&amp;rsquo;t three different platforms.
They&amp;rsquo;re three different interfaces to the same underlying components and templates.&lt;/p&gt;
&lt;h3 id="4-security-guardrails"&gt;4. Security guardrails&lt;/h3&gt;
&lt;p&gt;This is probably the most important distinction we can share with you: you want to have guardrails, not gates.
Too many platform teams create approval processes and manual checkpoints that completely undermine the self-service promise they&amp;rsquo;re trying to deliver.&lt;/p&gt;
&lt;p&gt;Guardrails are different.
They start with the best practices and security built into the reusable abstractions. But even the most secure solutions need a safety net.
This safety net is policy-as-code that runs automatically, preventing violations before deployment happens.
When we work with customers on implementing &lt;a href="https://www.pulumi.com/crossguard/"&gt;Pulumi CrossGuard&lt;/a&gt;, we&amp;rsquo;re not creating new friction. We&amp;rsquo;re embedding security, compliance, and cost controls directly into the deployment process.
The developer gets immediate feedback, and you get the assurance that nothing goes to production without meeting your standards.&lt;/p&gt;
&lt;h3 id="5-self-service"&gt;5. Self-service&lt;/h3&gt;
&lt;p&gt;Everything we&amp;rsquo;ve talked about so far builds toward this moment: enabling developers to provision and manage infrastructure independently.
But self-service isn&amp;rsquo;t just about providing a UI. It&amp;rsquo;s about carefully orchestrating all the other components to create experiences that are both powerful and intuitive.&lt;/p&gt;
&lt;p&gt;When we walked through the demo in our workshop, what you saw was the culmination of thoughtful platform design.
Developers can discover available services, deploy infrastructure through whatever interface makes sense for them, and manage their resources over time, all without requiring tickets or manual intervention from platform teams.
That&amp;rsquo;s the promise of a well-designed IDP: developer autonomy without operational chaos.&lt;/p&gt;
&lt;div class="rounded-lg bg-violet-50 p-6 my-8"&gt;
&lt;p class="heading-4 m-0 mb-3 flex items-center gap-1.5"&gt;Put your IDP strategy into practice&lt;/p&gt;
&lt;div class="body-base m-0 text-gray-950"&gt;Build reusable components, golden paths, and self-service workflows on Pulumi, and give developers autonomy while you keep governance and costs in check.&lt;/div&gt;
&lt;a href="https://app.pulumi.com/signup" data-track="blog-body-cta" class="btn btn-primary mt-4"&gt;
Get started
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--regular size-4" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.4a9ac1016b9d8a688a5e7e867f96bdf80115a0739af8c688ba04791e15f64461.svg#p-arrow-right-regular"/&gt;&lt;/svg&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;h2 id="how-to-implement-your-idp-strategy"&gt;How to Implement Your IDP Strategy&lt;/h2&gt;
&lt;h3 id="supporting-different-personas-in-your-internal-developer-platform-design"&gt;Supporting Different Personas in Your Internal Developer Platform Design&lt;/h3&gt;
&lt;p&gt;One of the biggest mistakes we see platform teams make: they try to build for their most sophisticated users first.
But here&amp;rsquo;s what I&amp;rsquo;ve learned from working with hundreds of organizations: you need to think about all your personas from day one.&lt;/p&gt;
&lt;p&gt;In most organizations, you&amp;rsquo;re serving:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Infrastructure engineers&lt;/strong&gt; who want full control and flexibility (they&amp;rsquo;ll use the full-code workflows)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Application developers&lt;/strong&gt; who need infrastructure but prefer higher-level abstractions (perfect for low-code approaches)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Non-technical users&lt;/strong&gt; who want simple, point-and-click deployment (your no-code users)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The breakthrough insight that separates successful platform teams from struggling ones is this: all these personas can be served by the same underlying components and templates, just consumed through different interfaces.
You don&amp;rsquo;t need to build three different platforms—you need to build one platform with three different consumption models.&lt;/p&gt;
&lt;h3 id="why-a-private-registry-is-key-to-idp-adoption"&gt;Why a Private Registry Is Key to IDP Adoption&lt;/h3&gt;
&lt;p&gt;Here&amp;rsquo;s something we always tell platform teams: if you don&amp;rsquo;t solve the discoverability problem, your beautiful components and templates will sit unused in Git repositories where no one can find them.
That&amp;rsquo;s why the private registry isn&amp;rsquo;t just a nice-to-have. It&amp;rsquo;s the foundation that makes everything else work.&lt;/p&gt;
&lt;p&gt;When you establish a private registry as your source of truth for components, templates, providers, and policies, you&amp;rsquo;re solving two critical problems at once.
First, discoverability: developers can actually find and explore what&amp;rsquo;s available.
Second, lifecycle management: you can see where each package is being used, track version drift, and understand the impact of changes before you make them.&lt;/p&gt;
&lt;p&gt;The workflow is beautifully simple: you publish standardized building blocks with a single &lt;code&gt;pulumi publish&lt;/code&gt; command, and developers discover and consume these assets through familiar package management workflows they already know.&lt;/p&gt;
&lt;h3 id="aligning-your-idp-to-organizational-context-and-services"&gt;Aligning Your IDP to Organizational Context and Services&lt;/h3&gt;
&lt;p&gt;One pattern we see in every successful IDP implementation is that the platform reflects how the organization actually works.
Your developers don&amp;rsquo;t think in terms of individual stacks or resources. They think in terms of services, applications, and business functionality.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s why we built &lt;a href="https://www.pulumi.com/docs/idp/get-started/services/"&gt;Pulumi Services&lt;/a&gt; - to let teams logically group stacks and ESC environments in ways that make sense to your organization.
Pulumi Services improve organization by helping your team model infrastructure in a way that&amp;rsquo;s familiar - simplifying Day 2 operations by providing additional context like links to relevant dashboards, Slack channels and more.
When something breaks at 2 AM, your on-call engineer needs to understand dependencies, track usage, and manage infrastructure in the context of the business services that are actually impacted.&lt;/p&gt;
&lt;h2 id="how-to-measure-the-success-of-your-internal-developer-platform"&gt;How to Measure the Success of Your Internal Developer Platform&lt;/h2&gt;
&lt;p&gt;Here&amp;rsquo;s something that might surprise you: the most successful platform teams we work with don&amp;rsquo;t measure their success by how many cool features they&amp;rsquo;ve built.
They measure success by the business outcomes they&amp;rsquo;re driving:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Reduced time-to-market&lt;/strong&gt; through faster infrastructure provisioning (because at the end of the day, your platform exists to help the business move faster)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Improved developer productivity&lt;/strong&gt; by eliminating infrastructure bottlenecks (happy developers ship more features)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enhanced security posture&lt;/strong&gt; through consistent policy enforcement (security that doesn&amp;rsquo;t slow people down is security that actually gets used)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lower operational overhead&lt;/strong&gt; through standardization and automation (because your platform team&amp;rsquo;s time is better spent on innovation than toil)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The numbers speak for themselves.
We&amp;rsquo;ve worked with customers like Snowflake who reduced deployment times from one and a half weeks to less than a day.
Starburst Data cut their infrastructure deployments from two weeks to just three hours.
These aren&amp;rsquo;t vanity metrics. They&amp;rsquo;re business transformations.&lt;/p&gt;
&lt;h2 id="idp-strategy-5-key-steps-to-build-a-strong-foundation"&gt;IDP Strategy: 5 Key Steps to Build a Strong Foundation&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;re just starting your IDP journey, here&amp;rsquo;s the roadmap we give to every platform team we work with:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Start with user research:&lt;/strong&gt; Before you write a single line of code, go talk to your developers.
Understand your different personas and their actual needs, not what you think they need. Do your users like to work from the command line? Do they prefer interacting with a UI?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Identify common patterns:&lt;/strong&gt; Look for infrastructure patterns that get repeated across teams.
These are your goldmine—the patterns that, once abstracted and templatized, will provide immediate value.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Begin with components:&lt;/strong&gt; Build reusable infrastructure building blocks before you worry about fancy UIs or workflow orchestration.
You need solid foundations before you can build the house.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Implement progressive disclosure:&lt;/strong&gt; Give people simple interfaces for common use cases, but always provide escape hatches for complex scenarios.
The moment your abstraction becomes a prison, developers will route around it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Measure and iterate:&lt;/strong&gt; Track adoption and gather feedback religiously.
Your platform is only as good as its adoption rate, and adoption only happens when you&amp;rsquo;re solving real problems for real people.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="the-future-of-idps-and-platform-engineering"&gt;The Future of IDPs and Platform Engineering&lt;/h2&gt;
&lt;p&gt;Trends come and go, but platform engineering is here to stay.
It&amp;rsquo;s not just another tool or methodology. This is how modern organizations scale infrastructure to match the speed of innovation. The companies that win are the ones that treat their &lt;strong&gt;Internal Developer Platform (IDP)&lt;/strong&gt; as a strategic foundation, not just a tool.&lt;/p&gt;
&lt;p&gt;Your job isn’t just to manage infrastructure and choose the right tools - it&amp;rsquo;s to enable developers to move faster while keeping governance, security, and costs under control. Get that balance right, and your platform becomes a force multiplier across your entire engineering department.&lt;/p&gt;
&lt;p&gt;The fastest way to get there? Focus on these five essential components:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Abstractions&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Blueprints&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Workflows&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security guardrails&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Self-service&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Together, they turn your IDP into more than just infrastructure automation, they create a platform that developers trust and your business relies on.&lt;/p&gt;
&lt;h3 id="ready-to-build-a-successful-idp-that-scales"&gt;Ready to Build a Successful IDP that Scales?&lt;/h3&gt;
&lt;p&gt;Pulumi makes it easy to go from static IaC to dynamic, self-service infrastructure with real programming languages and built-in guardrails.&lt;/p&gt;
&lt;p&gt;Explore &lt;a href="https://www.pulumi.com/product/internal-developer-platforms/"&gt;Pulumi IDP&lt;/a&gt; or &lt;a href="https://app.pulumi.com/signup"&gt;sign up for free&lt;/a&gt; to get started today.&lt;/p&gt;</description><author>Mitch Gerdisch</author><author>Engin Diri</author><category>internal-developer-platform</category><category>platform-engineering</category><category>developer-experience</category><category>self-service</category><category>governance</category><category>components</category><category>templates</category></item></channel></rss>