<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ana Carmiña Mendoza</title>
    <description>The latest articles on Forem by Ana Carmiña Mendoza (@anacarminamg).</description>
    <link>https://forem.com/anacarminamg</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1067367%2Fb44b0ec9-907f-4158-be53-21f2493903c1.png</url>
      <title>Forem: Ana Carmiña Mendoza</title>
      <link>https://forem.com/anacarminamg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/anacarminamg"/>
    <language>en</language>
    <item>
      <title>Build your self-destructing architecture in AWS</title>
      <dc:creator>Ana Carmiña Mendoza</dc:creator>
      <pubDate>Sun, 23 Apr 2023 21:51:18 +0000</pubDate>
      <link>https://forem.com/aws-builders/build-your-self-destructing-architecture-in-aws-1448</link>
      <guid>https://forem.com/aws-builders/build-your-self-destructing-architecture-in-aws-1448</guid>
      <description>&lt;p&gt;How amazing would be to provision an application that whenever it is no longer in use, it will destroy itself automatically?! 🤯&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AVSOAzKGb24wT3NgXCUivPw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AVSOAzKGb24wT3NgXCUivPw.gif" alt="A great scene from The Mandalorian"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Si prefieres leer este artículo en español, &lt;a href="https://dev.to/aws-builders/construye-una-arquitectura-en-aws-que-se-autodestruye-sola-2m44"&gt;¡haz click aquí!&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;In this post, I will go through some use cases, the architecture diagram and every service needed for a self-destructing infrastructure in AWS. The fun part is that you can add any additional resource you need to the architecture! &lt;/p&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;Sometimes, developers would provision a lot of services to test their applications and then forget to delete them, incurring extra expenses. &lt;/p&gt;

&lt;p&gt;In an internal initiative along with a great colleague, I was asked by my managers to find a creative solution this problem. So my peer focused on configuring the application automatically on an EC2 Instance, while I was working on building an infrastructure that could delete itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  In which scenarios would I need this?
&lt;/h2&gt;

&lt;p&gt;Lets say you want to create a development environment to test new code. With this architecture you can create and delete environments on demand, &lt;strong&gt;reducing costs&lt;/strong&gt; and even &lt;strong&gt;increasing efficiency&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Another example would be to use it on event-based workloads, such as conferences or workshops. To host these events you might need servers and storage, but for a very short time. By using a self-destructive architecture you could easily delete everything after the event, &lt;strong&gt;reducing complexity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;What about an application for &lt;strong&gt;disaster recovery&lt;/strong&gt;? In the event of an outage you could transfer your traffic to this infrastructure. Once the original is restored and you route the traffic back, this environment would be automatically deleted.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it work?
&lt;/h2&gt;

&lt;p&gt;This architecture is provisioned with &lt;a href="https://aws.amazon.com/cloudformation/" rel="noopener noreferrer"&gt;AWS CloudFormation&lt;/a&gt;, a tool to provision workloads using infrastructure as code. The great thing about this, is that by having all resources and dependencies defined on a &lt;em&gt;template&lt;/em&gt; and deployed in a &lt;em&gt;stack&lt;/em&gt;, it becomes really easy to delete all of them, as a single unit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture diagram
&lt;/h2&gt;

&lt;p&gt;Lets focus on the &lt;strong&gt;main components of the architecture&lt;/strong&gt;: EC2 Instance, the CloudWatch alarm, EventBridge Rule, the Lambda Function and the respective IAM Role, IAM Policy and Lambda Permission. There are other trivial resources needed like a security group, instance role and instance profile. These are not going to be covered here.&lt;/p&gt;

&lt;p&gt;The CloudFormation stack will create the following architecture:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AWyMOQoauj9ts9wgLb4sy-Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AWyMOQoauj9ts9wgLb4sy-Q.png" alt="Self-destructing Architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the architecture in motion:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AVOOSEh8POResrwr8RES9wA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AVOOSEh8POResrwr8RES9wA.png" alt="Self-destructing Architecture once the application is not longer in use"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Now, lets dive deep into each one of the elements of the architecture! 🤓&lt;/p&gt;

&lt;h2&gt;
  
  
  WebServer Instance
&lt;/h2&gt;

&lt;p&gt;First and foremost, we need an application. This will be provisioned on an EC2 Instance. You can configure this as you want. In my case, I configure the application using the &lt;em&gt;UserData&lt;/em&gt; section.&lt;/p&gt;

&lt;p&gt;This is the definition of the resource:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"WebServerInstance": {
      "Type" : "AWS::EC2::Instance",
      "Properties": {
        "ImageId"            : "ami-0ab4d1e9cf9a1215a",
        "InstanceType"       : "t3.small",
        "KeyName"            : "YOUR_KEY_PAIR",
        "IamInstanceProfile" : "YOUR_INSTANCE_PROFILE",
        "BlockDeviceMappings" : [
          {
            "DeviceName" : "/dev/xvda",
            "Ebs" : {
              "VolumeType"           : "gp2",
              "VolumeSize"           : "25",
              "Encrypted"            : "true",
              "KmsKeyId"             : "YOUR_KMS_KEY",
              "DeleteOnTermination"  : "true"
            }
          }],

        "NetworkInterfaces" : [{
            "AssociatePublicIpAddress"  : "true",
            "DeleteOnTermination"       : "true",
            "SubnetId"                  : "YOUR_SUBNET_ID",
            "GroupSet"                  :  ["YOUR_SECURITY_GROUP"],
            "DeviceIndex"               : 0
          }],

         "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
            "#!/bin/bash\n",
            "SOME_CONFIGURATION_FOR_YOUR_APP"
            ]]}}
      }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Inactivity Alarm
&lt;/h2&gt;

&lt;p&gt;Based on the &lt;strong&gt;CPU utilization metric&lt;/strong&gt;, we can know if the application is still being used.&lt;/p&gt;

&lt;p&gt;The alarm is programmed for this: once the maximum CPU utilization of the instance is below 12% for 1 hour, the alarm will stop it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;✏️Note:&lt;/strong&gt; The threshold value for the CPU Utilization must be define according to your application. In my case, the application I deployed on the EC2 instance was a Splunk dashboard, so setting that threshold was my best option.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here’s the definition of the Alarm:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; "MyEC2Alarm": {
        "Type": "AWS::CloudWatch::Alarm",
        "Properties": {
          "AlarmDescription": "Alarm to stop Instance",
          "AlarmName": "Inactivity Alarm",
          "AlarmActions": 
            [ "arn:aws:automate:us-east-1:ec2:stop" ],
          "MetricName": "CPUUtilization",
          "Namespace": "AWS/EC2",
          "Statistic": "Maximum",
          "Period": "1800",
          "Threshold": "3",
          "ComparisonOperator": "LessThanOrEqualToThreshold",
          "EvaluationPeriods": "2",
          "Dimensions": [
            {
              "Name": "InstanceId",
              "Value": {  "Ref" :  "WebServerInstance" }
            }
          ]
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Event Rule
&lt;/h2&gt;

&lt;p&gt;The EventBridge Rule will be waiting for your application to stop, so it can then perform an action. The action will be to trigger a Lambda Function that contains the code to delete the CloudFormation Stack.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"EventRule": {
      "DependsOn": ["ADLambda", "WebServerInstance"],
      "Type": "AWS::Events::Rule",
      "Properties": {
        "Description": "EventRule for EC2 Stopping",
        "EventPattern": {
          "source": [
            "aws.ec2"
          ],
          "detail-type": [
            "EC2 Instance State-change Notification"
          ],
          "detail": {
            "state": [
              "stopped"
            ],
            "instance-id": [{
              "Ref": "WebServerInstance"
            }]
          }
        },
        "State": "ENABLED",
        "Targets": [{
          "Arn": {"Fn::GetAtt": ["ADLambda", "Arn"] },
          "Id": "ADLambda"
        }]
      }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Lambda Function
&lt;/h2&gt;

&lt;p&gt;Once the function is triggered by the event rule, it will run a python script to delete the CloudFormation stack that created everything… I mean, how awesome is that?! 🤯&lt;/p&gt;

&lt;p&gt;Here’s the definition of the Lambda:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"ADLambda": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Handler": "index.handler",
        "Role": {
          "Fn::GetAtt": [
              "LambdaExecutionRole",
              "Arn"
          ]
        },
        "Code": {
          "ZipFile": "import boto3 \nimport os \nimport json \nstack_name = os.environ['stackName'] \n\ndef delete_cfn(stack_name):\n  try:\n   cfn = boto3.resource('cloudformation')\n   stack = cfn.Stack(stack_name)\n   stack.delete()\n   return \"SUCCESS\"\n  except:\n   return \"ERROR\" \ndef handler(event, context):\n  print(\"Received event:\")\n  print(json.dumps(event))\n  return delete_cfn(stack_name)"
        },
        "Environment": {
          "Variables": {
            "stackName": {
              "Ref" : "AWS::StackName"
            }
          }
        },
        "Runtime": "python3.9"
      }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Python Code&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The one that’s on the “ZipFile” line on the previous section.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import boto3 
import os 
import json 
stack_name = os.environ['stackName']
def delete_cfn(stack_name):
 try:
 cfn = boto3.resource('cloudformation')
 stack = cfn.Stack(stack_name)
 stack.delete()
 return "SUCCESS"
 except:
 return "ERROR" 
def handler(event, context):
 print("Received event:")
 print(json.dumps(event))
 return delete_cfn(stack_name)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;For the Lambda Function to be able to work, we need a &lt;em&gt;role, policy&lt;/em&gt; and &lt;em&gt;permission&lt;/em&gt; resource. The IAM Role and Policy will allow the function to &lt;strong&gt;delete the stack&lt;/strong&gt;. On the other hand, the Lambda Permission will grant the EventBridge Rule to &lt;strong&gt;invoke the function&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lambda Execution Role
&lt;/h2&gt;

&lt;p&gt;The one that will perform and allow the Lambda Function to delete all resources from the stack, just as the policy states.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"LambdaExecutionRole": {&lt;br&gt;
      "Type": "AWS::IAM::Role",&lt;br&gt;
      "DeletionPolicy": "Retain",&lt;br&gt;
      "Properties": {&lt;br&gt;
        "AssumeRolePolicyDocument": {&lt;br&gt;
          "Version": "2012-10-17",&lt;br&gt;
          "Statement": [&lt;br&gt;
            {&lt;br&gt;
              "Effect": "Allow",&lt;br&gt;
              "Principal": {&lt;br&gt;
                "Service": ["lambda.amazonaws.com"]&lt;br&gt;
              },&lt;br&gt;
              "Action": ["sts:AssumeRole"]&lt;br&gt;
            }&lt;br&gt;
          ]&lt;br&gt;
        },&lt;br&gt;
        "Path": "/"&lt;br&gt;
      }&lt;br&gt;
    }&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Lambda Execution Policy&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;Here’s the policy with the permissions to delete every resource that the stack provisioned.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;✏️Note:&lt;/strong&gt; If you deploy any other resources within the stack, don’t forget to add the permissions to the policy. &lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"LambdaExecutionPolicy": {&lt;br&gt;
        "Type": "AWS::IAM::Policy",&lt;br&gt;
        "DeletionPolicy": "Retain",&lt;br&gt;
        "Properties": {&lt;br&gt;
            "PolicyName": "autodestruction-policy",&lt;br&gt;
            "PolicyDocument": {&lt;br&gt;
              "Version": "2012-10-17",&lt;br&gt;
              "Statement": [&lt;br&gt;
                  {&lt;br&gt;
                  "Effect": "Allow",&lt;br&gt;
                  "Action": ["logs:&lt;em&gt;"],&lt;br&gt;
                  "Resource": "arn:aws:logs:&lt;/em&gt;:&lt;em&gt;:&lt;/em&gt;"&lt;br&gt;
                  },&lt;br&gt;
                  {&lt;br&gt;
                  "Effect": "Allow",&lt;br&gt;
                  "Action": [  "cloudformation:DeleteStack" ],&lt;br&gt;
                  "Resource": {&lt;br&gt;
                      "Ref": "AWS::StackId"&lt;br&gt;
                  }},&lt;br&gt;
                  {&lt;br&gt;
                  "Effect": "Allow",&lt;br&gt;
                  "Action": [ "lambda:DeleteFunction" ],&lt;br&gt;
                  "Resource": "&lt;em&gt;"&lt;br&gt;
                  },&lt;br&gt;
                  {&lt;br&gt;
                  "Effect": "Allow",&lt;br&gt;
                  "Action": [  "events:RemoveTargets" ],&lt;br&gt;
                  "Resource": "&lt;/em&gt;"&lt;br&gt;
                  },&lt;br&gt;
                  {&lt;br&gt;
                  "Effect": "Allow",&lt;br&gt;
                  "Action": [ "events:DeleteRule" ],&lt;br&gt;
                  "Resource": "&lt;em&gt;"&lt;br&gt;
                  },&lt;br&gt;
                  {&lt;br&gt;
                  "Effect": "Allow",&lt;br&gt;
                  "Action": [ "lambda:RemovePermission" ],&lt;br&gt;
                  "Resource": "&lt;/em&gt;"&lt;br&gt;
                  },&lt;br&gt;
                  {&lt;br&gt;
                  "Effect": "Allow",&lt;br&gt;
                  "Action": ["iam:DeleteRolePolicy","iam:DeleteRole"],&lt;br&gt;
                  "Resource": "&lt;em&gt;"&lt;br&gt;
                  },&lt;br&gt;
                  {&lt;br&gt;
                    "Effect": "Allow",&lt;br&gt;
                    "Action": [  "ec2:TerminateInstances" ],&lt;br&gt;
                    "Resource": [{ "Fn::Join": ["", [&lt;br&gt;
                      "arn:aws:ec2:",{"Ref": "AWS::Region"},":",&lt;br&gt;
                      {"Ref": "AWS::AccountId"}, ":instance/",&lt;br&gt;
                      {"Ref": "WebServerInstance"}]]}]&lt;br&gt;
                  },&lt;br&gt;
                  {&lt;br&gt;
                   "Effect": "Allow",&lt;br&gt;
                   "Action": [  "iam:DeleteRolePolicy" ],&lt;br&gt;
                   "Resource": "&lt;/em&gt;"&lt;br&gt;
                  },&lt;br&gt;
                  {&lt;br&gt;
                    "Effect": "Allow",&lt;br&gt;
                    "Action": [  "cloudwatch:DeleteAlarms" ],&lt;br&gt;
                    "Resource": [{"Fn::GetAtt" : ["MyEC2Alarm","Arn"]}]&lt;br&gt;
                  }&lt;br&gt;
              ]&lt;br&gt;
            },&lt;br&gt;
            "Roles": [{&lt;br&gt;
              "Ref" : "LambdaExecutionRole"&lt;br&gt;
            }]&lt;br&gt;
        }&lt;br&gt;
    }&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Lambda Permission&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;The resource that will allow EventBridge rule to invoke the function. ⚡&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"PermissionForADLambda": {&lt;br&gt;
      "Type": "AWS::Lambda::Permission",&lt;br&gt;
      "Properties": {&lt;br&gt;
        "FunctionName": {&lt;br&gt;
          "Ref": "ADLambda"&lt;br&gt;
        },&lt;br&gt;
        "Action": "lambda:InvokeFunction",&lt;br&gt;
        "Principal": "events.amazonaws.com",&lt;br&gt;
        "SourceArn": {&lt;br&gt;
          "Fn::GetAtt": [&lt;br&gt;
            "EventRule",&lt;br&gt;
            "Arn"&lt;br&gt;
          ]&lt;br&gt;
        }&lt;br&gt;
      }&lt;br&gt;
    }&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Now here comes the interesting part…&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;The Lambda Function cannot delete the whole stack because it will be deleting the &lt;strong&gt;Lambda Policy&lt;/strong&gt; (contains the permissions of what can be deleted) and &lt;strong&gt;Lambda Role&lt;/strong&gt; (who is going to perform those policies). If we delete them both, then how could we even finish the task? It cannot delete itself and then continue doing a task that was told. &lt;/p&gt;

&lt;p&gt;Even if we set up some dependencies to alter the order of deletion, it still gets to a point where it should delete those resources before the complete stack. That is why these two special resources will be left out of the &lt;em&gt;destruction&lt;/em&gt; with a &lt;strong&gt;“Retain” Deletion Policy.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I know what you are thinking… &lt;em&gt;“Ana, this is no longer a self-destructive architecture 🤔”&lt;/em&gt;. Well this was the closest I could get! And the good thing about this, is that roles and policies &lt;strong&gt;do not incur costs&lt;/strong&gt;. So you’re still saving!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡Fun fact:&lt;/strong&gt; I was stuck for a while trying to figure this out, until I went to the AWS Summit Mexico City and I explained this architecture to an AWS Architect (on the Ask the Expert lounge). He was actually the one that enlightened me with the retention solution!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is how you should see your CloudFormation page once everything is created:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2006%2F1%2AcwbKWFz_PmWCCIgp4LyLsQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2006%2F1%2AcwbKWFz_PmWCCIgp4LyLsQ.png" alt="Creation of resources in CloudFormation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, the only thing left to do is to stop using the application and wait… ⏰&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2062%2F1%2Aj628wWrKw_WjnzWGtDjhAg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2062%2F1%2Aj628wWrKw_WjnzWGtDjhAg.png" alt="Deletion of resources in CloudFormation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So go ahead and provision your stack, open your application and then stop using it. The CPU utilization will drop and eventually start deleting itself. Believe me, it is a great feeling to see how it automatically gets deleted. 🥲&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Building an automatic self-destructive architecture its a solution that you can implement in your temporary projects to save costs, increase application efficiency, reduce complexity and even recover from disaster or outage. &lt;/p&gt;

&lt;p&gt;I invite you to test it out, break it and come with new solutions around it. I would love to hear any feedback or improvements you might find! 🔍&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👩‍💻Lets keep building!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>tutorial</category>
      <category>aws</category>
      <category>testing</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Construye una arquitectura en AWS que se autodestruye</title>
      <dc:creator>Ana Carmiña Mendoza</dc:creator>
      <pubDate>Sun, 23 Apr 2023 21:49:00 +0000</pubDate>
      <link>https://forem.com/aws-builders/construye-una-arquitectura-en-aws-que-se-autodestruye-sola-2m44</link>
      <guid>https://forem.com/aws-builders/construye-una-arquitectura-en-aws-que-se-autodestruye-sola-2m44</guid>
      <description>&lt;p&gt;¿Te imaginas qué increíble sería poder levantar una aplicación que, en cuanto deje de ser utilizada, se pueda autodestruir sola?! 🤯&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sXdp-1nk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AVSOAzKGb24wT3NgXCUivPw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sXdp-1nk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2AVSOAzKGb24wT3NgXCUivPw.gif" alt="Una gran escena de The Mandalorian" width="498" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you rather read this article in English, click here!&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;En este artículo voy a compartirles algunos casos de uso, el diagrama de arquitectura y la explicación de cada servicio que se utiliza en esta infraestructura de AWS. Lo padre de esta solución es que ¡puedes integrar cualquier otro servicio que necesites!&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivación
&lt;/h2&gt;

&lt;p&gt;Suele suceder que desarrolladores levantan muchos recursos para hacer pruebas en sus aplicaciones y después olvidan borrarlos, provocando gastos innecesarios. &lt;/p&gt;

&lt;p&gt;Trabajando en una inciativa interna junto con un gran compañero mío, se me solicitó encontrar una solución creativa para este tipo de problema. Fue entonces que mi compañero se enfocó en crear una configuración automática de  aplicación dentro de una instancia EC2, mientras que yo me encargué de construir una infraestructura que pudiera borrarse automáticamente. &lt;/p&gt;

&lt;h2&gt;
  
  
  ¿En qué tipo de escenarios necesito esta arquitectura?
&lt;/h2&gt;

&lt;p&gt;Imagina que quieres crear un ambiente de desarrollo para hacer pruebas de código. Con esta arquitectura tu puedes crear y borrar ambientes bajo demanda, &lt;strong&gt;reduciendo costos&lt;/strong&gt; e incluso &lt;strong&gt;incrementando la eficiencia&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Otro caso de uso sería en cargas de trabajo basada en eventos, como lo son conferencias o webinars. Para llevar a cabo estos eventos necesitas servidores y almacenamiento durante un periodo corto de tiempo. Al utilizar una arquitectura que se autodestruye, podrías facilmente eliminar todo después del evento, &lt;strong&gt;reduciendo así la complejidad&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Y ¿qué tal una aplicación para &lt;strong&gt;recuperación de desastre&lt;/strong&gt;? Si llega a existir una interrupción de servicio, podrías transferir el tráfico a esta infraestructura. Una vez que la original se restaure y regrese el tráfico, este ambiente puede eliminarse automáticamente.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Cómo funciona?
&lt;/h2&gt;

&lt;p&gt;Esta arquitectura es creada con &lt;a href="https://aws.amazon.com/es/cloudformation/?nc1=h_ls"&gt;AWS CloudFormation&lt;/a&gt;, un servicio de aprovisionamiento que utiliza infraestructura como código. La ventaja de esta herramienta es que todos los recursos y dependencias se definen en &lt;em&gt;plantillas&lt;/em&gt; y se despliegan en &lt;em&gt;pilas&lt;/em&gt;, lo cual hace que sea sencillo borrar todo como una sola unidad.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diagrama de arquitectura
&lt;/h2&gt;

&lt;p&gt;Vamos a enfocarnos en los &lt;strong&gt;componentes principales de la arquitectura&lt;/strong&gt;: Instancia EC2, la Alarma CloudWatch, Regla de EventBridge, la función Lambda y su respectivo IAM Rol, política y permiso. Hay otros recursos triviales que se necesitan como un grupo de seguridad, rol de instancia y perfil de instancia. Estos los vamos a omitir.&lt;/p&gt;

&lt;p&gt;La &lt;em&gt;pila&lt;/em&gt; de CloudFormation va a crear la siguiente arquitectura:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9HrDkzYv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2Avj8hzYhr720yd0PEmLRwag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9HrDkzYv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2Avj8hzYhr720yd0PEmLRwag.png" alt="Arquitectura autodestructiva" width="800" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esta es la arquitectura en acción:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--N7-UD08u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2ASs_itdMP5d4vjuxCJaaPxw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--N7-UD08u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/1%2ASs_itdMP5d4vjuxCJaaPxw.png" alt="Arquitectura autodestructiva una vez que el app no esta en uso" width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Ahora si, vamos a entrar de lleno a cada uno de estos elementos! 🤓&lt;/p&gt;

&lt;h2&gt;
  
  
  Instancia WebServer
&lt;/h2&gt;

&lt;p&gt;Antes que nada, necesitamos una aplicación. Esta será desplegada en una instancia EC2 y puedes configurarla como tu quieras. En este caso, yo la configuré dentro de la sección de &lt;em&gt;UserData&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Esta es la definición del recurso:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"WebServerInstance": {
      "Type" : "AWS::EC2::Instance",
      "Properties": {
        "ImageId"            : "ami-0ab4d1e9cf9a1215a",
        "InstanceType"       : "t3.small",
        "KeyName"            : "PAR_DE_LLAVES",
        "IamInstanceProfile" : "PERFIL_DE_INSTANCIA",
        "BlockDeviceMappings" : [
          {
            "DeviceName" : "/dev/xvda",
            "Ebs" : {
              "VolumeType"           : "gp2",
              "VolumeSize"           : "25",
              "Encrypted"            : "true",
              "KmsKeyId"             : "LLAVE_KMS",
              "DeleteOnTermination"  : "true"
            }
          }],

        "NetworkInterfaces" : [{
            "AssociatePublicIpAddress"  : "true",
            "DeleteOnTermination"       : "true",
            "SubnetId"                  : "ID_DE_SUBRED",
            "GroupSet"                  :  ["GRUPO_DE_SEGURIDAD"],
            "DeviceIndex"               : 0
          }],

         "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
            "#!/bin/bash\n",
            "CONFIGURACION_DE_APLICACION"
            ]]}}
      }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Alarma de inactividad
&lt;/h2&gt;

&lt;p&gt;Basándose en la &lt;strong&gt;métrica de la utilización de CPU&lt;/strong&gt;, podemos saber si la aplicación sigue en uso.&lt;/p&gt;

&lt;p&gt;La alarma esta programada para lo siguiente: Una vez que la máxima utilización del CPU llega a estar por debajo del 12% durante 1 hora, la alarma va a detener la instancia.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;✏️Nota:&lt;/strong&gt; El límite establecido para la utilización del CPU debe ser definido acorde a tu aplicación. En mi caso, la aplicación era un dashboard de Splunk, por lo tanto ese límite era lo más adecuado.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Esta es la definición de la alarma:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"MyEC2Alarm": {
        "Type": "AWS::CloudWatch::Alarm",
        "Properties": {
          "AlarmDescription": "Alarm to stop Instance",
          "AlarmName": "Inactivity Alarm",
          "AlarmActions": 
            [ "arn:aws:automate:us-east-1:ec2:stop" ],
          "MetricName": "CPUUtilization",
          "Namespace": "AWS/EC2",
          "Statistic": "Maximum",
          "Period": "1800",
          "Threshold": "3",
          "ComparisonOperator": "LessThanOrEqualToThreshold",
          "EvaluationPeriods": "2",
          "Dimensions": [
            {
              "Name": "InstanceId",
              "Value": {  "Ref" :  "WebServerInstance" }
            }
          ]
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Regla de EventBridge
&lt;/h2&gt;

&lt;p&gt;La regla de EventBridge va a estar esperando que la aplicación se encuentre en estado &lt;em&gt;detenido&lt;/em&gt;, para entonces poder tomar acción. La acción será invocar la función Lambda que contiene el código que  eliminará la *pila *de CloudFormation.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"EventRule": {
      "DependsOn": ["ADLambda", "WebServerInstance"],
      "Type": "AWS::Events::Rule",
      "Properties": {
        "Description": "EventRule for EC2 Stopping",
        "EventPattern": {
          "source": [
            "aws.ec2"
          ],
          "detail-type": [
            "EC2 Instance State-change Notification"
          ],
          "detail": {
            "state": [
              "stopped"
            ],
            "instance-id": [{
              "Ref": "WebServerInstance"
            }]
          }
        },
        "State": "ENABLED",
        "Targets": [{
          "Arn": {"Fn::GetAtt": ["ADLambda", "Arn"] },
          "Id": "ADLambda"
        }]
      }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Función Lambda
&lt;/h2&gt;

&lt;p&gt;Una vez que la función sea invocada por la regla, ésta va a correr el código Python que eliminará la pila de CloudFormation... ¿Increíble, no? 🤯&lt;/p&gt;

&lt;p&gt;Aquí la definición de la Lambda:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"ADLambda": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Handler": "index.handler",
        "Role": {
          "Fn::GetAtt": [
              "LambdaExecutionRole",
              "Arn"
          ]
        },
        "Code": {
          "ZipFile": "import boto3 \nimport os \nimport json \nstack_name = os.environ['stackName'] \n\ndef delete_cfn(stack_name):\n  try:\n   cfn = boto3.resource('cloudformation')\n   stack = cfn.Stack(stack_name)\n   stack.delete()\n   return \"SUCCESS\"\n  except:\n   return \"ERROR\" \ndef handler(event, context):\n  print(\"Received event:\")\n  print(json.dumps(event))\n  return delete_cfn(stack_name)"
        },
        "Environment": {
          "Variables": {
            "stackName": {
              "Ref" : "AWS::StackName"
            }
          }
        },
        "Runtime": "python3.9"
      }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Código Python
&lt;/h3&gt;

&lt;p&gt;Este es el código que se encuentra en la línea “ZipFile” de la sección anterior.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import boto3 
import os 
import json 
stack_name = os.environ['stackName']
def delete_cfn(stack_name):
 try:
 cfn = boto3.resource('cloudformation')
 stack = cfn.Stack(stack_name)
 stack.delete()
 return "SUCCESS"
 except:
 return "ERROR" 
def handler(event, context):
 print("Received event:")
 print(json.dumps(event))
 return delete_cfn(stack_name)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Para que la función Lambda pueda funcionar, se necesita un rol, una política y un recurso de permiso. El IAM rol y la política van a permitir que la función pueda &lt;strong&gt;borrar la pila&lt;/strong&gt;. Por otra parte, el permiso de Lambda será el que permitirá que la regla EventBridge &lt;strong&gt;pueda invocarla&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rol de Lambda
&lt;/h2&gt;

&lt;p&gt;Aquel IAM rol que permitirá que la función borre los recursos de la pila, justo como lo establece la política.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"LambdaExecutionRole": {&lt;br&gt;
      "Type": "AWS::IAM::Role",&lt;br&gt;
      "DeletionPolicy": "Retain",&lt;br&gt;
      "Properties": {&lt;br&gt;
        "AssumeRolePolicyDocument": {&lt;br&gt;
          "Version": "2012-10-17",&lt;br&gt;
          "Statement": [&lt;br&gt;
            {&lt;br&gt;
              "Effect": "Allow",&lt;br&gt;
              "Principal": {&lt;br&gt;
                "Service": ["lambda.amazonaws.com"]&lt;br&gt;
              },&lt;br&gt;
              "Action": ["sts:AssumeRole"]&lt;br&gt;
            }&lt;br&gt;
          ]&lt;br&gt;
        },&lt;br&gt;
        "Path": "/"&lt;br&gt;
      }&lt;br&gt;
    }&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Política de Lambda&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;Esta es la política con los permisos para eliminar cada recurso que la pila aprovisionó. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;✏️Nota:&lt;/strong&gt; No olvides agregarle cualquier recurso extra que despliegues.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"LambdaExecutionPolicy": {&lt;br&gt;
        "Type": "AWS::IAM::Policy",&lt;br&gt;
        "DeletionPolicy": "Retain",&lt;br&gt;
        "Properties": {&lt;br&gt;
            "PolicyName": "autodestruction-policy",&lt;br&gt;
            "PolicyDocument": {&lt;br&gt;
              "Version": "2012-10-17",&lt;br&gt;
              "Statement": [&lt;br&gt;
                  {&lt;br&gt;
                  "Effect": "Allow",&lt;br&gt;
                  "Action": ["logs:&lt;em&gt;"],&lt;br&gt;
                  "Resource": "arn:aws:logs:&lt;/em&gt;:&lt;em&gt;:&lt;/em&gt;"&lt;br&gt;
                  },&lt;br&gt;
                  {&lt;br&gt;
                  "Effect": "Allow",&lt;br&gt;
                  "Action": [  "cloudformation:DeleteStack" ],&lt;br&gt;
                  "Resource": {&lt;br&gt;
                      "Ref": "AWS::StackId"&lt;br&gt;
                  }},&lt;br&gt;
                  {&lt;br&gt;
                  "Effect": "Allow",&lt;br&gt;
                  "Action": [ "lambda:DeleteFunction" ],&lt;br&gt;
                  "Resource": "&lt;em&gt;"&lt;br&gt;
                  },&lt;br&gt;
                  {&lt;br&gt;
                  "Effect": "Allow",&lt;br&gt;
                  "Action": [  "events:RemoveTargets" ],&lt;br&gt;
                  "Resource": "&lt;/em&gt;"&lt;br&gt;
                  },&lt;br&gt;
                  {&lt;br&gt;
                  "Effect": "Allow",&lt;br&gt;
                  "Action": [ "events:DeleteRule" ],&lt;br&gt;
                  "Resource": "&lt;em&gt;"&lt;br&gt;
                  },&lt;br&gt;
                  {&lt;br&gt;
                  "Effect": "Allow",&lt;br&gt;
                  "Action": [ "lambda:RemovePermission" ],&lt;br&gt;
                  "Resource": "&lt;/em&gt;"&lt;br&gt;
                  },&lt;br&gt;
                  {&lt;br&gt;
                  "Effect": "Allow",&lt;br&gt;
                  "Action": ["iam:DeleteRolePolicy","iam:DeleteRole"],&lt;br&gt;
                  "Resource": "&lt;em&gt;"&lt;br&gt;
                  },&lt;br&gt;
                  {&lt;br&gt;
                    "Effect": "Allow",&lt;br&gt;
                    "Action": [  "ec2:TerminateInstances" ],&lt;br&gt;
                    "Resource": [{ "Fn::Join": ["", [&lt;br&gt;
                      "arn:aws:ec2:",{"Ref": "AWS::Region"},":",&lt;br&gt;
                      {"Ref": "AWS::AccountId"}, ":instance/",&lt;br&gt;
                      {"Ref": "WebServerInstance"}]]}]&lt;br&gt;
                  },&lt;br&gt;
                  {&lt;br&gt;
                   "Effect": "Allow",&lt;br&gt;
                   "Action": [  "iam:DeleteRolePolicy" ],&lt;br&gt;
                   "Resource": "&lt;/em&gt;"&lt;br&gt;
                  },&lt;br&gt;
                  {&lt;br&gt;
                    "Effect": "Allow",&lt;br&gt;
                    "Action": [  "cloudwatch:DeleteAlarms" ],&lt;br&gt;
                    "Resource": [{"Fn::GetAtt" : ["MyEC2Alarm","Arn"]}]&lt;br&gt;
                  }&lt;br&gt;
              ]&lt;br&gt;
            },&lt;br&gt;
            "Roles": [{&lt;br&gt;
              "Ref" : "LambdaExecutionRole"&lt;br&gt;
            }]&lt;br&gt;
        }&lt;br&gt;
    }&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Permiso para Lambda&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;Es el recurso que le va a permitir a la regla EventBridge invocar la función.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"PermissionForADLambda": {&lt;br&gt;
      "Type": "AWS::Lambda::Permission",&lt;br&gt;
      "Properties": {&lt;br&gt;
        "FunctionName": {&lt;br&gt;
          "Ref": "ADLambda"&lt;br&gt;
        },&lt;br&gt;
        "Action": "lambda:InvokeFunction",&lt;br&gt;
        "Principal": "events.amazonaws.com",&lt;br&gt;
        "SourceArn": {&lt;br&gt;
          "Fn::GetAtt": [&lt;br&gt;
            "EventRule",&lt;br&gt;
            "Arn"&lt;br&gt;
          ]&lt;br&gt;
        }&lt;br&gt;
      }&lt;br&gt;
    }&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Ahora aquí viene lo interesante…&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;La función Lambda no puede eliminar toda la pila porque estaría borrando la &lt;strong&gt;política Lambda&lt;/strong&gt; (la que tiene los permisos para borrar) y el &lt;strong&gt;rol Lambda&lt;/strong&gt; (el que ejecuta esas política). Si los borramos, entonces ¿cómo se podría terminar la tarea? No puede auto eliminarse y seguir continuando con lo que le pidió. &lt;/p&gt;

&lt;p&gt;Incluso agregando dependencias para alterar el orden de eliminación, eventualmente se llega al punto en donde se tienen que eliminar ese rol y esa política. Es por eso que estos dos recursos se separan de la &lt;em&gt;destrucción&lt;/em&gt; con el parámetro de &lt;strong&gt;DeletionPolicy = Retain&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Se lo que están pensando… &lt;em&gt;“Ana, esto ya no es una arquitectura que se autodestruye por completo 🤔”&lt;/em&gt;. Bueno, ¡Esto es lo más cercano que pude llegar! Y la ventaja es que ese rol y esa política &lt;strong&gt;no generan costos&lt;/strong&gt;, asi que aún asi ¡estas ahorrando!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡Fun fact:&lt;/strong&gt; Estuve varias semanas tratando de encontrar una manera de que esta arquitectura funcionara, hasta que fui al AWS Summit Mexico City y le expliqué esto a un Arquitecto AWS (en la sala “Pregunta a los Expertos”). ¡El fue el que me iluminó con la idea de la retención de recursos!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Asi es como se debe de ver CloudFormation una vez que todo se ha creado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UhhC6N76--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2006/1%2AcwbKWFz_PmWCCIgp4LyLsQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UhhC6N76--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2006/1%2AcwbKWFz_PmWCCIgp4LyLsQ.png" alt="Creación de recursos en CloudFormation" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ahora lo único queda es dejar de utilizar esa aplicación y esperar…⏰&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--26kLJT65--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2062/1%2Aj628wWrKw_WjnzWGtDjhAg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--26kLJT65--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2062/1%2Aj628wWrKw_WjnzWGtDjhAg.png" alt="Eliminación de recrusos en CloudFormation" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Asi que anímate y despliega esta arquitectura, abre tu aplicación y luego deja de utilizarla por unas horas. La utilización del CPU bajará y eventualmente comenzará a eliminarse. Créame, es bellísimo ver como todo se va eliminando automáticamente.🥲&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;Crear una arquitectura que se destruye automáticamente al dejarla de utilizar, es una solución que puedes implementar en tus proyectos para ahorrar gastos, incrementar la eficiencia de la aplicación, reducir la complejidad e incluso recuperarte en el evento de un desastre.&lt;/p&gt;

&lt;p&gt;Te invito a probarla, romper esta arquitectura y regresar con nuevas soluciones. ¡Me encantaría escuchar tu retroalimentación o las mejoras que encuentres! 🔍&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👩‍💻¡Sigamos construyendo!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>tutorial</category>
      <category>aws</category>
      <category>cloud</category>
      <category>spanish</category>
    </item>
  </channel>
</rss>
