<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>nunogrl.com - infrastructure</title><link href="https://nunogrl.com/" rel="alternate"></link><link href="https://nunogrl.com/categories/infrastructure/atom.xml" rel="self"></link><id>https://nunogrl.com/</id><updated>2024-08-01T00:00:00+01:00</updated><entry><title>Homelab Network Overview</title><link href="https://nunogrl.com/articles/homelab-network-overview/" rel="alternate"></link><published>2024-08-01T00:00:00+01:00</published><updated>2024-08-01T00:00:00+01:00</updated><author><name>Nuno Leitao</name></author><id>tag:nunogrl.com,2024-08-01:/articles/homelab-network-overview/</id><summary type="html">&lt;p class="first last"&gt;A comprehensive guide to building a secure homelab network with VLANs, DNS, monitoring, and automation&lt;/p&gt;
</summary><content type="html">&lt;p&gt;My homelab network is designed to provide a &lt;strong&gt;secure, efficient, and self-hosted environment&lt;/strong&gt;
for various automation, development, and personal infrastructure needs.
This setup prioritizes &lt;strong&gt;network segmentation, security, and performance optimization&lt;/strong&gt;,
while being flexible enough to scale or adapt for experimentation.&lt;/p&gt;
&lt;div class="section" id="problem-solution"&gt;
&lt;h2&gt;Problem &amp;amp; Solution&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; I needed a reliable and secure environment for automation, CI/CD testing, Git hosting, and local infrastructure—
&lt;strong&gt;without relying on cloud platforms or exposing services to the internet&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Additionally, the solution had to run on &lt;strong&gt;low-powered, repurposed hardware&lt;/strong&gt; with minimal overhead
and support &lt;strong&gt;remote access&lt;/strong&gt;, &lt;strong&gt;internal DNS resolution&lt;/strong&gt;, and &lt;strong&gt;segmented security domains&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; I architected a network centered around an OpenWRT-based router with VLAN segmentation,
isolated zones for each function, and layered services:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;Tailscale&lt;/strong&gt; provides secure access to internal services, even when offsite.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cloudflare Tunnel&lt;/strong&gt; allows for secure access to internal services from the internet.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AdGuard Home&lt;/strong&gt; filters DNS-based ads and trackers at the router level.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TinyDNS + BIND&lt;/strong&gt; handle authoritative DNS within the homelab.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Traefik&lt;/strong&gt; serves as the reverse proxy using a wildcard cert via DNS verification.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prometheus + Grafana&lt;/strong&gt; provide observability for all infrastructure nodes.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;D-Link 3782 router&lt;/strong&gt; is used as a wireless bridge to isolate the IoT network.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The OpenWRT router also provides wireless access to mobile and personal devices,
which are segmented into their own VLAN. These include laptops, phones, and tablets
used for managing or testing infrastructure services.&lt;/p&gt;
&lt;p&gt;For mobile devices, &lt;strong&gt;Syncthing&lt;/strong&gt; is used to selectively back up content to the NAS.
While backups are not fully automated, this gives more control over what is stored.
I am considering adding a backup option to &lt;strong&gt;Dropbox&lt;/strong&gt; for external redundancy.&lt;/p&gt;
&lt;p&gt;The entire infrastructure is &lt;strong&gt;provisioned via Ansible playbooks&lt;/strong&gt;, which manage deployment
and configuration across the environment. These playbooks live on an internal Git server
and may be shared publicly in the future.&lt;/p&gt;
&lt;p&gt;The system emphasizes &lt;strong&gt;modularity&lt;/strong&gt;, &lt;strong&gt;resilience&lt;/strong&gt;, and &lt;strong&gt;observability&lt;/strong&gt;, ensuring that
each component is isolated but observable.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="full-network-topology-combined"&gt;
&lt;h2&gt;Full Network Topology (Combined)&lt;/h2&gt;
&lt;div class="mermaid" id="mermaid-diagram-3243488435404578603"&gt;
flowchart TD
    %% ingress egress
    Internet --&gt; Router
    Router --&gt;|VPN: Site2Site| VPNCloudflare
    Router --&gt;|VPN: host| VPNTailscale

    %% DNS
    Router -.-&gt; AdGuard
    AdGuard -.-&gt; BIND
    BIND -.-&gt; TinyDNS


    %%        Traefik --&gt; Router
    %%        Traefik --&gt; IoT_Bridge

    %%        Prometheus --&gt; NAS
    %%        Prometheus --&gt; Server1
    %%        Prometheus --&gt; CIService
    %%        Prometheus --&gt; Router
    %%        Grafana --&gt; Prometheus

    Router ==&gt;|VLAN: NAS| NAS
    Router ==&gt;|VLAN: Dev| Server1
    Router ==&gt;|VLAN: CI| Zeus
    Router ==&gt;|VLAN: IoT| IoT_Bridge
    Router ==&gt;|VLAN: WiFi| Wireless_Clients
    IoT_Bridge --&gt;|Wireless| IoT_Devices

    %%subgraph rproxy [reverse proxy]
    %%            Traefik --&gt; GitServer
    %%            Traefik --&gt; CIService
    %%            Traefik --&gt; Grafana
    %%            Traefik --&gt; Syncthing
    %%            Traefik --&gt; Portainer
    %%            Traefik --&gt; Prometheus
    %%            Traefik --&gt; NASUI
    %%            Traefik --&gt; binrepo
    %%        end




    %% description
    VPNCloudflare((VPN fa:fa-lock
                cloudflared
                tunnel))
    VPNTailscale((VPN fa:fa-lock
                tailscale
                server
                ))
    Router{{Router}}
    IoT_Bridge{{IoT Bridge}}
    Internet(((Internet
            fa:fa-cloud)))
    %% NASUI([homepage fab:fa-docker])
    %% GitServer([git fab:fa-docker])

    %% CIService([CIService fab:fa-docker])
    %% Grafana([grafana fab:fa-docker])
    %% Portainer([Portainer fab:fa-docker])
    %% Traefik([traefik fab:fa-docker])
    %% Syncthing([Syncthing fab:fa-docker])
    %% Prometheus([Prometheus fab:fa-docker])
    %% binrepo([Binary Repo fab:fa-docker])
    Server1[Raspberry Pi]


    %% styles
    classDef default fill:#f9f,stroke:#333,stroke-width:1px;
    classDef net fill:#fff;
    classDef hardware fill:#f96;
    classDef dns fill:#AFF;
    classDef container fill:#EF0;
    classDef vpn fill:#EF0;
    classDef network fill:#CCCCCC;

    Internet:::net

    VPNCloudflare:::vpn
    VPNTailscale:::vpn

    AdGuard:::dns
    BIND:::dns
    TinyDNS:::dns

    Router:::network
    IoT_Bridge:::network
    NAS:::hardware
    Server1:::hardware
    Zeus:::hardware

    Wireless_Clients:::hardware
    IoT_Devices:::hardware

    %% NASUI:::container
    %% GitServer:::container
    %% CIService:::container
    %% binrepo:::container
    %% Grafana:::container
    %% Portainer:::container
    %% Traefik:::container
    %% Syncthing:::container
    %% Prometheus:::container&lt;/div&gt;&lt;p&gt;This shows how DNS resolution, secure access, proxy routing, and monitoring interconnect.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="layered-views-progressive-breakdown"&gt;
&lt;h2&gt;Layered Views (Progressive Breakdown)&lt;/h2&gt;
&lt;div class="section" id="dns-resolution-flow"&gt;
&lt;h3&gt;DNS Resolution Flow&lt;/h3&gt;
&lt;div class="mermaid" id="mermaid-diagram-1749526783412610"&gt;
flowchart TD
    Client --&gt; AdGuard
    AdGuard --&gt; BIND
    BIND -.-&gt; I
    BIND -.-&gt; L
    BIND --&gt; TinyDNS
    BIND -.-&gt; LXC

L((Local network))
I((Internet))
LXC((LXC_Containers))&lt;/div&gt;&lt;/div&gt;
&lt;div class="section" id="traefik-reverse-proxy-flow"&gt;
&lt;h3&gt;Traefik Reverse Proxy Flow&lt;/h3&gt;
&lt;div class="mermaid" id="mermaid-diagram-1115101435375041153"&gt;
flowchart TD
    Internet --&gt;|DNS Challenge| Traefik
    Traefik --&gt; GitServer
    Traefik --&gt; Grafana
    Traefik --&gt; CIService
    Traefik --&gt; binRepo
    Traefik --&gt; Syncthing
    Traefik --&gt; Portainer
    Traefik --&gt; RouterUI
    Traefik --&gt; NASUI
    Traefik --&gt; IoT_Bridge&lt;/div&gt;&lt;/div&gt;
&lt;div class="section" id="prometheus-monitoring-flow"&gt;
&lt;h3&gt;Prometheus Monitoring Flow&lt;/h3&gt;
&lt;div class="mermaid" id="mermaid-diagram--5064678229061580148"&gt;
flowchart TD
    Prometheus --&gt; NAS
    Prometheus --&gt; Server1
    Prometheus --&gt; CIService
    Prometheus --&gt; Router
    Prometheus --&gt; IoT_Bridge
    Grafana --&gt; Prometheus&lt;/div&gt;&lt;p&gt;Each layer can be inspected individually or in combination via Grafana dashboards and log collectors.
This &lt;strong&gt;layered view mirrors how the infrastructure is designed, monitored, and interacted with.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="Infrastructure Automation"></category><category term="homelab"></category><category term="networking"></category><category term="infrastructure"></category><category term="openwrt"></category><category term="dns"></category><category term="monitoring"></category><category term="vlans"></category><category term="security"></category></entry><entry><title>Change Sets with Sceptre: Controlled AWS Changes in ITIL Environments</title><link href="https://nunogrl.com/articles/change-sets-sceptre-itil-environments/" rel="alternate"></link><published>2024-03-21T00:00:00+00:00</published><updated>2024-03-21T00:00:00+00:00</updated><author><name>Nuno Leitao</name></author><id>tag:nunogrl.com,2024-03-21:/articles/change-sets-sceptre-itil-environments/</id><summary type="html">&lt;p class="first last"&gt;Learn how to implement controlled AWS infrastructure changes in ITIL-governed environments using Sceptre and CloudFormation Change Sets&lt;/p&gt;
</summary><content type="html">&lt;div class="section" id="problem-solution"&gt;
&lt;h2&gt;🚀 Problem &amp;amp; Solution&lt;/h2&gt;
&lt;p&gt;📌 &lt;strong&gt;Context / Backstory&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We needed to &lt;strong&gt;add a stop-instance Lambda&lt;/strong&gt; to our existing AWS stack — but in a production environment governed by &lt;strong&gt;ITIL change control&lt;/strong&gt;. That meant:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;No untracked infrastructure changes&lt;/li&gt;
&lt;li&gt;No direct &amp;quot;deploy and hope&amp;quot; workflows&lt;/li&gt;
&lt;li&gt;Every change needed visibility, approval, and a rollback path&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;⚠️ &lt;strong&gt;The Problem&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;CloudFormation makes changes declarative — but deployments are immediate by default. In an ITIL environment, we needed:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;A &lt;strong&gt;way to preview the change&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;record of the proposed change&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;controlled execution&lt;/strong&gt;, ideally during a change window&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;💡 &lt;strong&gt;The Solution&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We used &lt;strong&gt;Sceptre's built-in support for CloudFormation Change Sets&lt;/strong&gt; to decouple &lt;strong&gt;proposing changes&lt;/strong&gt; from &lt;strong&gt;executing them&lt;/strong&gt;. This gave us:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Change Set visibility before applying&lt;/li&gt;
&lt;li&gt;A file-based workflow for review and audit&lt;/li&gt;
&lt;li&gt;Controlled deployments aligned with ITIL practices&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;👥 &lt;strong&gt;Who This Helps&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Engineers working in &lt;strong&gt;regulated environments&lt;/strong&gt; (finance, enterprise IT, healthcare)&lt;/li&gt;
&lt;li&gt;DevOps teams needing &lt;strong&gt;pre-deployment approvals&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Anyone trying to bridge &lt;strong&gt;automation with change control&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="technical-implementation"&gt;
&lt;h2&gt;⚙️ Technical Implementation&lt;/h2&gt;
&lt;p&gt;Let's visualize the change management workflow:&lt;/p&gt;
&lt;div class="mermaid" id="mermaid-diagram--1024360889188818916"&gt;
flowchart TD
   G[Git Repo] --&gt;|Template Changes| S[Sceptre]
   S --&gt;|Create| CS[Change Set]
   CS --&gt;|Review| A[Approval]
   A --&gt;|Execute| CF[CloudFormation]
   CF --&gt;|Update| I[Infrastructure]

   subgraph "Change Control Process"
   CS
   A
   end

   subgraph "AWS"
   CF
   I
   end&lt;/div&gt;&lt;div class="section" id="add-a-stop-lambda-to-your-cloudformation-template"&gt;
&lt;h3&gt;1️⃣ Add a Stop-Lambda to Your CloudFormation Template&lt;/h3&gt;
&lt;p&gt;For example, we extended our template with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;StopInstanceLambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;AWS::Lambda::Function&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;Properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;Handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;index.handler&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;!GetAtt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;LambdaExecutionRole.Arn&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;Runtime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;python3.9&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;Timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;30&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;ZipFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p p-Indicator"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="no"&gt;import boto3&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="no"&gt;import os&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="no"&gt;def handler(event, context):&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="no"&gt;ec2 = boto3.client(&amp;#39;ec2&amp;#39;)&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="no"&gt;ec2.stop_instances(InstanceIds=[os.environ[&amp;#39;INSTANCE_ID&amp;#39;]])&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;Variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;INSTANCE_ID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;!Ref&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;InstanceId&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We committed this change to Git but &lt;strong&gt;did not deploy yet&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="preview-with-sceptre-change-set"&gt;
&lt;h3&gt;2️⃣ Preview with Sceptre Change Set&lt;/h3&gt;
&lt;p&gt;In your Sceptre stack config (&lt;cite&gt;stop-tests.yaml&lt;/cite&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;template_path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;start-stop-template.yaml&lt;/span&gt;
&lt;span class="nt"&gt;stack_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;start-tests-scheduler&lt;/span&gt;
&lt;span class="nt"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;InstanceId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;i-0123456789abcdef0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then run:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sceptre&lt;span class="w"&gt; &lt;/span&gt;create-change-set&lt;span class="w"&gt; &lt;/span&gt;dev/stop-tests.yaml
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This creates a &lt;strong&gt;named Change Set&lt;/strong&gt; in CloudFormation.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="review-the-change-set"&gt;
&lt;h3&gt;3️⃣ Review the Change Set&lt;/h3&gt;
&lt;p&gt;You can now inspect the proposed changes via:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sceptre&lt;span class="w"&gt; &lt;/span&gt;describe-change-set&lt;span class="w"&gt; &lt;/span&gt;dev/stop-tests.yaml
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This outputs a diff-like summary of added/removed/modified resources.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="execute-the-change-set-in-a-controlled-window"&gt;
&lt;h3&gt;4️⃣ Execute the Change Set in a Controlled Window&lt;/h3&gt;
&lt;p&gt;Once approved:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sceptre&lt;span class="w"&gt; &lt;/span&gt;execute-change-set&lt;span class="w"&gt; &lt;/span&gt;dev/stop-tests.yaml
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This &lt;strong&gt;applies only what was reviewed and approved&lt;/strong&gt;, nothing more.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="troubleshooting-debugging"&gt;
&lt;h2&gt;🛠️ Troubleshooting &amp;amp; Debugging&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Change Sets fail if resources are renamed instead of replaced — use &lt;cite&gt;Retain&lt;/cite&gt; policies or snapshots carefully.&lt;/li&gt;
&lt;li&gt;If nothing appears in the Change Set, verify your stack is actually different from the current state.&lt;/li&gt;
&lt;li&gt;Include &lt;cite&gt;--no-execute-changeset&lt;/cite&gt; in manual &lt;cite&gt;aws cloudformation&lt;/cite&gt; calls if testing outside Sceptre.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="itil-alignment-best-practices"&gt;
&lt;h2&gt;🔁 ITIL Alignment &amp;amp; Best Practices&lt;/h2&gt;
&lt;p&gt;Why this works for &lt;strong&gt;change management&lt;/strong&gt;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;✅ &lt;strong&gt;Pre-approved changes&lt;/strong&gt;: Reviewable before execution&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Audit trail&lt;/strong&gt;: Change Set IDs + Git commits form a traceable chain&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Rollback-ready&lt;/strong&gt;: No impact until applied; easy to cancel&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Automatable&lt;/strong&gt;: Integrates with GitOps, CI/CD, and approval gates&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Compare to a traditional ITIL CAB process:
- Sceptre's Change Set becomes the &lt;strong&gt;RFC payload&lt;/strong&gt;
- Execution timing maps to &lt;strong&gt;change windows&lt;/strong&gt;
- Logs &amp;amp; ChangeSet name tie into &lt;strong&gt;CMDB or ticketing systems&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion-takeaways"&gt;
&lt;h2&gt;✅ Conclusion &amp;amp; Takeaways&lt;/h2&gt;
&lt;p&gt;By using Sceptre's Change Sets, we introduced &lt;strong&gt;governed change control&lt;/strong&gt; without sacrificing automation. It's a clean way to blend &lt;strong&gt;DevOps practices&lt;/strong&gt; with &lt;strong&gt;ITIL compliance&lt;/strong&gt; — reducing risk while maintaining velocity.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="comments-next-steps"&gt;
&lt;h2&gt;💬 Comments &amp;amp; Next Steps&lt;/h2&gt;
&lt;p&gt;Have you implemented similar change control processes in your AWS infrastructure? Share your experience or ask questions below!&lt;/p&gt;
&lt;/div&gt;
</content><category term="Cloud"></category><category term="aws"></category><category term="sceptre"></category><category term="itil"></category><category term="change-management"></category><category term="cloudformation"></category><category term="devops"></category><category term="compliance"></category><category term="infrastructure"></category></entry></feed>