<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>nunogrl.com - iac</title><link href="https://nunogrl.com/" rel="alternate"></link><link href="https://nunogrl.com/categories/iac/atom.xml" rel="self"></link><id>https://nunogrl.com/</id><updated>2024-03-21T00:00:00+00:00</updated><entry><title>Automating Server Startups with CloudFormation &amp; Sceptre</title><link href="https://nunogrl.com/articles/automating-server-startups-cloudformation-sceptre/" 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/automating-server-startups-cloudformation-sceptre/</id><summary type="html">&lt;p class="first last"&gt;Learn how to automate EC2 instance scheduling using CloudFormation and Sceptre, with CloudWatch Events and Lambda for reliable execution&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;div class="section" id="context-backstory"&gt;
&lt;h3&gt;📌 &lt;strong&gt;Context / Backstory&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;We had a requirement to &lt;strong&gt;start a test EC2 instance automatically at 08:00&lt;/strong&gt; each morning. This server, called &lt;cite&gt;Tests01&lt;/cite&gt;, was only needed during working hours, and we wanted to avoid manual intervention or running it 24/7.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-problem"&gt;
&lt;h3&gt;⚠️ &lt;strong&gt;The Problem&lt;/strong&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Manual starts were unreliable and easy to forget.&lt;/li&gt;
&lt;li&gt;CloudFormation alone doesn't handle timed triggers.&lt;/li&gt;
&lt;li&gt;Lambda + CloudWatch Events provide scheduling, but managing them manually is messy.&lt;/li&gt;
&lt;li&gt;We needed this &lt;strong&gt;fully automated and reproducible&lt;/strong&gt;, ideally within infrastructure-as-code.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="the-solution"&gt;
&lt;h3&gt;💡 &lt;strong&gt;The Solution&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;We used &lt;strong&gt;Sceptre&lt;/strong&gt; to deploy a &lt;strong&gt;CloudFormation template&lt;/strong&gt; that provisions:
- A &lt;strong&gt;CloudWatch rule&lt;/strong&gt; triggered at 08:00
- A &lt;strong&gt;Lambda function&lt;/strong&gt; that starts the &lt;cite&gt;Tests01&lt;/cite&gt; instance
- All IAM roles and permissions necessary&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="who-this-helps"&gt;
&lt;h3&gt;👥 &lt;strong&gt;Who This Helps&lt;/strong&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;DevOps engineers using AWS automation&lt;/li&gt;
&lt;li&gt;Teams migrating from cron jobs to infrastructure-as-code&lt;/li&gt;
&lt;li&gt;Anyone needing &lt;strong&gt;scheduled resource management&lt;/strong&gt; in the cloud&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&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 automation flow:&lt;/p&gt;
&lt;div class="mermaid" id="mermaid-diagram-6439199693712232369"&gt;
flowchart LR
   CW[CloudWatch Event]
   L[Lambda Function]
   EC2[EC2 Instance]

   CW --&gt;|"Trigger (08:00)"| L
   L --&gt;|"StartInstances API"| EC2

   subgraph "AWS Infrastructure"
   CW
   L
   EC2
   end&lt;/div&gt;&lt;div class="section" id="sceptre-project-setup"&gt;
&lt;h3&gt;1️⃣ Sceptre Project Setup&lt;/h3&gt;
&lt;p&gt;Project layout:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;config/
  config.yaml
  dev/
    start-tests.yaml
templates/
  start-tests.yaml
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Global &lt;cite&gt;config/config.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;project_code&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;startup-project&lt;/span&gt;
&lt;span class="nt"&gt;region&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;eu-west-1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Stack config &lt;cite&gt;config/dev/start-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-tests.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;/div&gt;
&lt;div class="section" id="cloudformation-template"&gt;
&lt;h3&gt;2️⃣ CloudFormation Template&lt;/h3&gt;
&lt;p&gt;File: &lt;cite&gt;templates/start-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;AWSTemplateFormatVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#39;2010-09-09&amp;#39;&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="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;String&lt;/span&gt;
&lt;span class="nt"&gt;Resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;LambdaExecutionRole&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::IAM::Role&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;AssumeRolePolicyDocument&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;Version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#39;2012-10-17&amp;#39;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;Statement&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="nt"&gt;Effect&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;Allow&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;Principal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="nt"&gt;Service&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;lambda.amazonaws.com&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;Action&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;sts:AssumeRole&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;Policies&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="nt"&gt;PolicyName&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;StartInstance&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;PolicyDocument&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;Version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#39;2012-10-17&amp;#39;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nt"&gt;Statement&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="nt"&gt;Effect&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;Allow&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nt"&gt;Action&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;ec2:StartInstances&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nt"&gt;Resource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;*&amp;quot;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;StartInstanceLambda&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.start_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;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;StartEventRule&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::Events::Rule&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;ScheduleExpression&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;cron(0 8 * * ? *)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;Targets&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="nt"&gt;Arn&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;StartInstanceLambda.Arn&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;Id&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;TargetFunctionV1&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;PermissionForEventsToInvokeLambda&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::Permission&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;FunctionName&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;StartInstanceLambda&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;Action&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;lambda:InvokeFunction&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;Principal&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;events.amazonaws.com&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;SourceArn&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;StartEventRule.Arn&lt;/span&gt;
&lt;/pre&gt;&lt;/div&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;Ensure the Lambda role has permissions to &lt;cite&gt;ec2:StartInstances&lt;/cite&gt;.&lt;/li&gt;
&lt;li&gt;Use &lt;cite&gt;aws lambda invoke&lt;/cite&gt; to manually test the function.&lt;/li&gt;
&lt;li&gt;Logs appear in CloudWatch Logs; confirm the instance ID is correct.&lt;/li&gt;
&lt;li&gt;Validate your cron expression with AWS docs: &lt;cite&gt;cron(0 8 * * ? *)&lt;/cite&gt; runs at 08:00 UTC.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="optimizations-alternatives"&gt;
&lt;h2&gt;🔁 Optimizations &amp;amp; Alternatives&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;You can also add a second Lambda + CloudWatch rule to &lt;strong&gt;stop&lt;/strong&gt; the instance at 18:00.&lt;/li&gt;
&lt;li&gt;Consider replacing this with &lt;strong&gt;AWS Systems Manager Automation documents&lt;/strong&gt; if you're not using CloudFormation.&lt;/li&gt;
&lt;li&gt;If you're managing multiple instances, parameterize the instance list or use tags.&lt;/li&gt;
&lt;/ul&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;This setup gives you a &lt;strong&gt;reproducible, versioned, and automated method&lt;/strong&gt; for managing instance scheduling using CloudFormation and Sceptre. It's a clean way to handle what would otherwise be a manual or error-prone task—and it fits directly into a GitOps-style workflow.&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 automation patterns with CloudFormation? Share your experience or ask questions below!&lt;/p&gt;
&lt;/div&gt;
</content><category term="Cloud"></category><category term="aws"></category><category term="cloudformation"></category><category term="sceptre"></category><category term="automation"></category><category term="lambda"></category><category term="cloudwatch"></category><category term="iac"></category><category term="devops"></category></entry></feed>