<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Cloudy Mountains</title><link>https://cloudymountains.cloud/</link><description>Recent content on Cloudy Mountains</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Tue, 22 Sep 2026 10:00:00 +0100</lastBuildDate><atom:link href="https://cloudymountains.cloud/index.xml" rel="self" type="application/rss+xml"/><item><title>Your AI Agent Is a Contractor. Treat It Like One.</title><link>https://cloudymountains.cloud/projects/platform-engineering/agents-are-contractors/</link><pubDate>Tue, 22 Sep 2026 10:00:00 +0100</pubDate><guid>https://cloudymountains.cloud/projects/platform-engineering/agents-are-contractors/</guid><description>&lt;p>For a big part of my career I was the contractor. Consultancy after consultancy, client after client. And one thing kept surprising me: the team that was supposed to help us was often the least helpful group in the building.&lt;/p>
&lt;p>Access requests took weeks. Questions got one-line answers, if any. In meetings we were the outsiders who didn&amp;rsquo;t know how things worked here, the ones who would break something, the expensive people who needed everything explained twice. Sometimes it was subtle. Sometimes it was not subtle at all.&lt;/p></description></item><item><title>The AI-Native Internal Developer Platform</title><link>https://cloudymountains.cloud/projects/platform-engineering/ai-native-idp/</link><pubDate>Tue, 26 May 2026 10:00:00 +0100</pubDate><guid>https://cloudymountains.cloud/projects/platform-engineering/ai-native-idp/</guid><description>&lt;p>Internal Developer Platforms have a well-known dirty secret: most developers do not use them. The platform team builds something genuinely useful — curated pipelines, Terraform modules, Helm charts, GitOps patterns, cost guardrails — wraps it in a service catalogue, adds a web portal, writes runbooks, and waits. Adoption trickles in, usually driven by mandate rather than enthusiasm.&lt;/p>
&lt;p>This is not a technology problem. It is a distribution problem. The platform team solved the right problem and delivered it to the wrong address.&lt;/p></description></item><item><title>Centralized AWS Observability with OAM and Terraform (Part 2)</title><link>https://cloudymountains.cloud/projects/observability/aws-observability-part-two/</link><pubDate>Mon, 30 Mar 2026 13:00:44 +0100</pubDate><guid>https://cloudymountains.cloud/projects/observability/aws-observability-part-two/</guid><description>&lt;p>In &lt;a href="https://cloudymountains.cloud/projects/observability/aws-observability-part-one/">part one&lt;/a> we covered the architecture and design behind the centralized observability solution. In this post, we walk through the practical configuration and provide code snippets to build the first part of the solution: &lt;strong>metrics&lt;/strong> centralization.&lt;/p>
&lt;p>&lt;a href="https://docs.aws.amazon.com/OAM/latest/APIReference/Welcome.html">CloudWatch cross-account observability&lt;/a> (OAM) requires you to designate a &lt;strong>monitoring account&lt;/strong> (or create one). AWS recommends a dedicated monitoring account. In our case, we used the existing &lt;strong>Shared Services&lt;/strong> account where we already run shared services, so we did not use a separate account.&lt;/p></description></item><item><title>Centralized AWS Observability: theoretical justification (part 1)</title><link>https://cloudymountains.cloud/projects/observability/aws-observability-part-one/</link><pubDate>Sun, 25 Jan 2026 13:00:44 +0100</pubDate><guid>https://cloudymountains.cloud/projects/observability/aws-observability-part-one/</guid><description>&lt;p>In this series of blog posts I will describe the journey (or one of the possible ways) of building a comprehensive observability solution for AWS and on-prem workloads. I will provide a step by step guide and how the decisions were made for choosing or not the particular technologies (observability stacks or whatever you call it). I will try to provide as much as possible examples and code snippets. So lets start. First let say a few words about the initial state and the goals that I have to achieve with this solution.&lt;/p></description></item><item><title>Enforcing AWS AMI images with OPA</title><link>https://cloudymountains.cloud/projects/policy-as-code/allowed-amis-opa/</link><pubDate>Mon, 23 Jun 2025 13:00:44 +0100</pubDate><guid>https://cloudymountains.cloud/projects/policy-as-code/allowed-amis-opa/</guid><description>&lt;p>In the &lt;a href="https://cloudymountains.cloud/projects/policy-as-code/enforce-aws-tags-opa/">part 2&lt;/a>, we provided examples of how you can enforce AWS tags to ensure compliance and governance within your organization. In this post, we will extend those concepts by demonstrating how you can enforce specific AMI IDs using OPA policies, helping you maintain control over the AMI images used in your infrastructure.&lt;/p>
&lt;p>It is critical for all organizations to establish a robust AMI building process to ensure that operating systems are consistently patched for security vulnerabilities. By maintaining control over the AMI lifecycle, organizations can enforce compliance, reduce exposure to risks, and ensure that their infrastructure remains secure and up-to-date. This process not only helps in mitigating potential threats but also aligns with best practices for infrastructure management and governance. This process is typically managed by the Security team, who are responsible for building and maintaining approved AMIs. The &amp;ldquo;customers&amp;rdquo; of these AMIs are other teams within the organization, such as Development, Operations, or QA, who rely on these pre-approved images to ensure their workloads meet security and compliance standards.&lt;/p></description></item><item><title>Enforcing AWS Resource Tags with OPA</title><link>https://cloudymountains.cloud/projects/policy-as-code/enforce-aws-tags-opa/</link><pubDate>Fri, 13 Jun 2025 13:00:44 +0100</pubDate><guid>https://cloudymountains.cloud/projects/policy-as-code/enforce-aws-tags-opa/</guid><description>&lt;p>In &lt;a href="https://cloudymountains.cloud/projects/policy-as-code/start-small-opa-terraform/">Part 1&lt;/a> of this series, we covered the basics of Policy as Code and how the shift-left approach helps catch infrastructure mistakes early. In this post, we’re putting theory into practice—specifically, how to enforce AWS tagging strategy using Open Policy Agent (OPA) during Terraform plan phase/stage.&lt;/p>
&lt;p>This isn’t just about tagging hygiene. Good tagging is foundational for tracking cloud costs, understanding ownership, and avoiding dangerous or expensive mistakes.&lt;/p>
&lt;h2 id="why-tags-matter">Why Tags Matter&lt;/h2>
&lt;p>Tags seem trivial—until you’re staring at a $1M AWS bill and have no idea where it came from.&lt;/p></description></item><item><title>Static site with S3 and CloudFront</title><link>https://cloudymountains.cloud/projects/static-site-s3-cloudfront/</link><pubDate>Fri, 06 Jun 2025 12:20:44 +0100</pubDate><guid>https://cloudymountains.cloud/projects/static-site-s3-cloudfront/</guid><description>&lt;p>When I decided to build my own site, I knew I wanted something fast, scalable, and modern — not just in terms of the tech stack, but also in the way it’s managed and deployed. This post walks you through exactly how my site (Cloudy Mountains) is deployed using &lt;strong>Hugo&lt;/strong>, &lt;strong>AWS (S3 + CloudFront)&lt;/strong>, &lt;strong>Terraform&lt;/strong>, &lt;strong>GitHub Actions&lt;/strong>, and &lt;strong>OIDC&lt;/strong> authentication. I’ll show you the challenges that I had and how to solve them properly.&lt;/p></description></item><item><title>First policy as code using OPA</title><link>https://cloudymountains.cloud/projects/policy-as-code/policy-as-code-opa-terraform/</link><pubDate>Thu, 15 May 2025 23:58:44 +0100</pubDate><guid>https://cloudymountains.cloud/projects/policy-as-code/policy-as-code-opa-terraform/</guid><description>&lt;p>As I mentioned in my &lt;a href="https://cloudymountains.cloud/projects/policy-as-code/intro-opa-terraform/">previous blog post&lt;/a>, my first OPA policy was just to catch one simple parameter, if we have in the S3 Terrafom module set the &lt;code>force_destroy = true&lt;/code>.&lt;/p>
&lt;p>Here&amp;rsquo;s a simple OPA policy that will catch this dangerous configuration:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-rego" data-lang="rego">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">package&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nx">terraform&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="nx">plan&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="n">deny&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">msg&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c"># Find all resources in the plan&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nx">resource&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">:=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nx">input&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="nx">resource_changes&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">_&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> 
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c"># Check if it&amp;#39;s an S3 bucket&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nx">resource&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="nx">type&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">==&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;aws_s3_bucket&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> 
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c"># Look for force_destroy in the configuration&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nx">resource&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="nx">change&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="nx">after&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="nx">force_destroy&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">==&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> 
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nx">msg&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">:=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">sprintf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;S3 bucket &amp;#39;%s&amp;#39; has force_destroy set to true. This is dangerous as it allows bucket deletion even when not empty.&amp;#34;&lt;/span>&lt;span class="o">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">resource&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="nx">address&lt;/span>&lt;span class="p">])&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This policy works by:&lt;/p></description></item><item><title>How I Learned the Hard Way That Terraform Needs Policy as Code</title><link>https://cloudymountains.cloud/projects/policy-as-code/intro-opa-terraform/</link><pubDate>Sun, 30 Mar 2025 13:00:44 +0100</pubDate><guid>https://cloudymountains.cloud/projects/policy-as-code/intro-opa-terraform/</guid><description>&lt;p>&lt;strong>At a glance&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Context:&lt;/strong> a cloud consultancy engagement, bootstrapping 15 new AWS accounts for a client with Terraform 0.11/0.12.&lt;/li>
&lt;li>&lt;strong>Incident:&lt;/strong> I accidentally deleted the S3 bucket that held the Terraform state for all 15 accounts.&lt;/li>
&lt;li>&lt;strong>Cost:&lt;/strong> all 15 accounts were recreated and provisioned again from scratch. Because everything was code, that took less than two days. The real cost was our reputation with the client.&lt;/li>
&lt;li>&lt;strong>Fix:&lt;/strong> policy as code. OPA policies evaluated against every &lt;code>terraform plan&lt;/code> in CI, failing the pipeline before a dangerous change reaches &lt;code>apply&lt;/code>.&lt;/li>
&lt;li>&lt;strong>Outcome:&lt;/strong> 15 workload pipelines gated, and every pipeline created after them inherited the same checks.&lt;/li>
&lt;/ul>
&lt;h2 id="what-went-wrong">What went wrong?&lt;/h2>
&lt;p>A few years ago, while working for a cloud consultancy company, I made a mistake that I will never forget. I accidentally deleted a Terraform state bucket: the S3 bucket that stored the state for bootstrapping 15 AWS accounts, each packed with resources. To make things worse, it belonged to a very tough client.&lt;/p></description></item><item><title>Using Shift Left paradigm to manage cloud cost</title><link>https://cloudymountains.cloud/projects/policy-as-code/shift-left-opa-terracost/</link><pubDate>Fri, 31 May 2024 13:00:44 +0100</pubDate><guid>https://cloudymountains.cloud/projects/policy-as-code/shift-left-opa-terracost/</guid><description>&lt;h2 id="introduction">Introduction&lt;/h2>
&lt;p>In the fast-evolving world of cloud computing, managing costs effectively has become a crucial aspect of maintaining a sustainable and profitable business. The &amp;ldquo;Shift left&amp;rdquo; paradigm, originally a concept in software development, emphasizes the importance of addressing potential issues early in the development process. When applied to AWS cost optimization and management, this approach ensures that cost considerations are integrated into the earliest stages of the development lifecycle.&lt;/p>
&lt;p>By shifting cost management left, organizations can avoid unexpected expenses and optimize their cloud spending proactively. This blog post explores the application of the &amp;ldquo;Shift left&amp;rdquo; paradigm to AWS cost optimization, focusing on tools like Open Policy Agent (OPA) policies, Infracost, and Terracost. We will delve into how these tools can help estimate and control costs efficiently, ensuring that your AWS resources are both cost-effective and aligned with your financial goals.&lt;/p></description></item><item><title>CV</title><link>https://cloudymountains.cloud/cv/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://cloudymountains.cloud/cv/</guid><description>Experienced DevOps and Cloud Engineer with over 15 years of experience designing, implementing, and managing scalable, secure, and automated cloud infrastructures. Specialized in AWS architecture, Infrastructure as Code, CI/CD, and container orchestration. Passionate about building resilient systems through automation, GitOps, and modern DevOps practices.</description></item></channel></rss>