<?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>DEV Community: Manu Muraleedharan</title>
    <description>The latest articles on DEV Community by Manu Muraleedharan (@manumaan).</description>
    <link>https://dev.to/manumaan</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%2F1060158%2Fa9062491-c06e-4f08-bcf3-b4cf9c359306.png</url>
      <title>DEV Community: Manu Muraleedharan</title>
      <link>https://dev.to/manumaan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/manumaan"/>
    <language>en</language>
    <item>
      <title>Durable Functions in Lambda</title>
      <dc:creator>Manu Muraleedharan</dc:creator>
      <pubDate>Thu, 15 Jan 2026 09:22:03 +0000</pubDate>
      <link>https://dev.to/manumaan/durable-functions-in-lambda-4bna</link>
      <guid>https://dev.to/manumaan/durable-functions-in-lambda-4bna</guid>
      <description>&lt;p&gt;What if - &lt;/p&gt;

&lt;p&gt;You could build multi-step applications and workflows - directly in Lambda? &lt;/p&gt;

&lt;p&gt;Pause your app and continue based on callbacks? &lt;/p&gt;

&lt;p&gt;All this, with the tried and tested AWS Lambda platform? &lt;/p&gt;

&lt;p&gt;All this and more are possible with the new Durable Function Lambda announced during Reinvent 2025. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are Durable Functions?&lt;/strong&gt;&lt;br&gt;
Lambda Durable Functions let you build resilient multi-step applications and workflows that can run up to a year, while preserving progress state across interruptions. Each run is called a Durable Execution. Each time checkpoints record the state so system can automatically recover from failures by replaying the execution - starting from the beginning but skipping any work that has already been completed. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How Does it Work?&lt;/strong&gt;&lt;br&gt;
Behind the scenes, durable functions use Lambda functions that use a checkpoint-and-replay mechanism. This tracks and supports long-running executions. When a durable function resumes from a wait state (suspension) or does a retry, your code runs from the beginning but checks what has already been completed by using checkpoints. Then it skips the steps that has been completed. It will just reuse the results of the completed checkpoints. This replay mechanism preserves the consistency. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Cases for Durable Functions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many applications that you might have used, such as services like Step Functions or Orchestrated microservices, could be done using Lambda Durable Function. &lt;/p&gt;

&lt;p&gt;For example, an order processing system might have these steps: reserve inventory, process payment, and create shipment. &lt;/p&gt;

&lt;p&gt;Previously, if you reserve your inventory and then fail in one of the next steps, on potential retries you had to make sure to not reserve the item again, this required custom code to be written or other scaffolding. Now in Durable functions, these will be three separate steps. On retry, Lambda sees the checkpoint for reserving, and does not reserve again, automatically without you doing anything. &lt;/p&gt;

&lt;p&gt;Payment processing could be an external api that requires you to implement retries, exponential backoff etc according to the API contract. These are handled natively by Durable Functions and are just parameters for the step. &lt;/p&gt;

&lt;p&gt;Maybe the reserving happens in an external ERP system, and it is async. Earlier, your lambda or custom code has to wait (expensive waste) or poll status. Now, with durable functions, it can just wait and use a callback from the ERP system without spending any money for the wait. &lt;/p&gt;

&lt;p&gt;Maybe you need a human to approve before creating the shipment. Durable functions can wait for human intervention before proceeding. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to create Durable Functions&lt;/strong&gt;&lt;br&gt;
We create Durable Functions just like any Lambda, using the Lambda console or other IaC. Currently, it is available for NodeJS and Python, and in select regions only. (Ohio only as of now) &lt;/p&gt;

&lt;p&gt;We use decorators in Python to designate parts of code as Durable Steps and Durable Execution. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Durable Step&lt;/em&gt;&lt;br&gt;
Executes business logic with automatic checkpointing and retry. Use steps for operations that call external services, perform calculations, or execute any logic that should be checkpointed. The SDK creates a checkpoint before and after the step, storing the result for replay.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Durable Execution&lt;/em&gt;&lt;br&gt;
How the Steps are run, where waits will happen or callbacks. &lt;/p&gt;

&lt;p&gt;Sample Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from aws_durable_execution_sdk_python import (
    DurableContext,
    durable_execution,
    durable_step,
)
from aws_durable_execution_sdk_python.config import Duration

@durable_step
def validate_order(step_context, order_id):
    step_context.logger.info(f"Validating order {order_id}")
    return {"orderId": order_id, "status": "validated"}

@durable_step
def process_payment(step_context, order_id):
    step_context.logger.info(f"Processing payment for order {order_id}")
    return {"orderId": order_id, "status": "paid", "amount": 99.99}

@durable_step
def confirm_order(step_context, order_id):
    step_context.logger.info(f"Confirming order {order_id}")
    return {"orderId": order_id, "status": "confirmed"}

@durable_execution
def lambda_handler(event, context: DurableContext):
    order_id = event['orderId']

    # Step 1: Validate order
    validation_result = context.step(validate_order(order_id))

    # Step 2: Process payment
    payment_result = context.step(process_payment(order_id))

    # Wait for 10 seconds to simulate external confirmation
    context.wait(Duration.from_seconds(10))

    # Step 3: Confirm order
    confirmation_result = context.step(confirm_order(order_id))

    return {
        "orderId": order_id,
        "status": "completed",
        "steps": [validation_result, payment_result, confirmation_result]
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you run the Durable Function, you can see them in the new Durable Executions tab in Lambda console. Durable operations show the steps in the Durable Execution. It shows all the executions of this Durable Function. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F19tf0t1ocjtzvmfc631x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F19tf0t1ocjtzvmfc631x.png" alt="DurableExecution" width="800" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can go to Durable Operations. Here you can see the inputs, outputs, logs, etc. from the individual steps. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8wysf6wk1uh13mfodqkb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8wysf6wk1uh13mfodqkb.png" alt="DurableOperations" width="800" height="231"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Event History shows the events during the Durable Execution. If you had a wait, etc., it will show here. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmu8lwo0nfq1l0g7m7gxr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmu8lwo0nfq1l0g7m7gxr.png" alt="EventHistory" width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If these Durable Function screens are looking like the Step Function screens, you are not mistaken. They overlap in use cases, but they differ in how you model workflows, how observable they are, and where they work best.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Durable Fn&lt;/th&gt;
&lt;th&gt;Step Fn&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Development&lt;/td&gt;
&lt;td&gt;Imperative&lt;/td&gt;
&lt;td&gt;Declarative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best For&lt;/td&gt;
&lt;td&gt;Orchestrate with one Function&lt;/td&gt;
&lt;td&gt;Orchestrate among AWS services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Observability&lt;/td&gt;
&lt;td&gt;CloudWatch&lt;/td&gt;
&lt;td&gt;Visual Graphs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Here is a general guideline on when to use what&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prefer Lambda Durable Functions when:​

    Workflow is primarily Lambda-based business logic.
    Team wants a code-first model and strong unit-testability.
    You need long-running, pause/resume behavior without building a full state machine.
    You do not require a visual workflow designer or many direct service integrations.

Prefer Step Functions when:​

    Workflow orchestrates many AWS services and external systems.
    Visual observability and low-code configuration are important to the team.
    You have complex branching, human-in-the-loop, or very high-fanout orchestration.
    You want a clear separation between orchestration (state machine) and implementation (Lambdas/other services).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;More Durable Function Samples showing advanced features: &lt;a href="https://github.com/manumaan/durable-functions-lambda" rel="noopener noreferrer"&gt;https://github.com/manumaan/durable-functions-lambda&lt;/a&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>aws</category>
      <category>news</category>
      <category>serverless</category>
    </item>
    <item>
      <title>Recreating a Nostalgic Game with Q CLI</title>
      <dc:creator>Manu Muraleedharan</dc:creator>
      <pubDate>Wed, 28 May 2025 08:27:43 +0000</pubDate>
      <link>https://dev.to/aws-builders/recreating-a-nostalgic-game-with-q-cli-pygame-3n8c</link>
      <guid>https://dev.to/aws-builders/recreating-a-nostalgic-game-with-q-cli-pygame-3n8c</guid>
      <description>&lt;p&gt;Back when I was studying at the College of Engineering, Trivandrum (Any CETians here?), during my MCA days, we had tons of fun in our hostel rooms. Only one of us had a UPS for his computer, so whenever there was a power cut, we all gathered in his room. His screen was the only one lit up, and we’d play a Flash game called Hangaroo—a Hangman clone where you had to guess the word before the kangaroo met its fate! Those memories still bring a smile to my face.&lt;/p&gt;

&lt;p&gt;When I came to know about the Q CLI Game Challenge, I immediately knew what I was going to build - a recreation of dear old Hangaroo! &lt;/p&gt;

&lt;p&gt;Q CLI is a wonderful coding assistant that natively works in your terminal. I was able to build 90% of the functionality with just one prompt. Then I spent a couple of hours tweaking the looks and gameplay to suit what I had in mind. &lt;/p&gt;

&lt;p&gt;Why would you use Q CLI, when many other coding assistants exist? Let me list the superpowers: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Natively list and describe AWS resources &lt;/li&gt;
&lt;li&gt;Multi-turn conversations &lt;/li&gt;
&lt;li&gt;Can connect to MCP servers and use tools on them &lt;/li&gt;
&lt;li&gt;Finds and uses your file system, Git, and OS tools. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do you also want to create an app using Q CLI? Below are the steps:&lt;/p&gt;

&lt;p&gt;Install Q CLI:&lt;br&gt;
&lt;a href="https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line-installing.html" rel="noopener noreferrer"&gt;Q CLI Setup&lt;/a&gt; This should take care of most of the usual usecases. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/aws/the-essential-guide-to-installing-amazon-q-developer-cli-on-linux-headless-and-desktop-3bo7"&gt;Special situations&lt;/a&gt;&lt;br&gt;
Wonderful article from Ricardo, if the usual cases did not apply to you.  &lt;/p&gt;

&lt;p&gt;Use the command q chat to start conversing with the Q CLI Agent. I asked it to create a hangman-like game using pygame, and told the agent what I remembered about Hangaroo. &lt;/p&gt;

&lt;p&gt;In minutes I had a working game ready to play. Core functionality was up and running. Then I spent some time tweaking some of the looks and game play details, which I had forgot to give in the first go. I believe if you go with a plan, review, execute flow with Q you can probably achieve better results. I wanted to go raw at it and see how much the AI is able to achieve with the least amount of input, and I was impressed. &lt;/p&gt;

&lt;p&gt;Gameplay (See if you can guess the movie title before I do) :&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia2.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExNTJ2bHp2MTNhZ3l3ZHYyZWs4emRiZmwzcDduYzZpaWhmZzRydGtueiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2FSXiQOrR4OUOhsCqurF%2Fgiphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia2.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExNTJ2bHp2MTNhZ3l3ZHYyZWs4emRiZmwzcDduYzZpaWhmZzRydGtueiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2FSXiQOrR4OUOhsCqurF%2Fgiphy.gif" width="480" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I showed the game to my son who was hooked. Now he plans to make his own version of Amongus with Q.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>gamedev</category>
      <category>pygame</category>
      <category>awschallenge</category>
    </item>
    <item>
      <title>Voice to Voice AI with Amazon Nova Sonic</title>
      <dc:creator>Manu Muraleedharan</dc:creator>
      <pubDate>Fri, 16 May 2025 18:19:59 +0000</pubDate>
      <link>https://dev.to/aws-builders/voice-to-voice-ai-with-amazon-nova-sonic-1nb5</link>
      <guid>https://dev.to/aws-builders/voice-to-voice-ai-with-amazon-nova-sonic-1nb5</guid>
      <description>&lt;p&gt;Amazon Nova Sonic is a state-of-the-art speech-to-speech model that delivers real-time, human-like voice conversations with industry-leading price performance and low latency. Available with a bidirectional streaming API on Bedrock, Nova Sonic can enable developers to create truly natural, human-like AI agents that do not require users to type in their requests. What excites me most is that this capability opens AI access to many people who otherwise might struggle to use it. &lt;/p&gt;

&lt;p&gt;Nova Sonic has both masculine-sounding and feminine-sounding voices, and can produce American and British English accents. &lt;/p&gt;

&lt;p&gt;Nova Sonic can be used in Agentic workflows. It can consult knowledge bases using RAG and ground the information it gives to the user. It can do function calling, also called tool use. Since tools are supported, we are just a step away from utilising MCP servers with Nova Sonic. &lt;/p&gt;

&lt;p&gt;Amazon Nova Sonic uses a persistent bidirectional connection that allows simultaneous event streaming in both directions.We use WebSockets in the demo below. This means that the conversation can flow very naturally, we can continuously stream the audio, and input can be processed while output is being generated. Just like humans, Nova Sonic can even respond without needing to wait for complete utterances from the user. &lt;/p&gt;

&lt;p&gt;Nova Sonic is event-driven.  client and model exchange structured JSON events and those events control the session lifecycle, audio streaming, text responses, and tool interactions. &lt;/p&gt;

&lt;p&gt;How to use Nova Sonic? AWS SDKs in several languages, including Java, JavaScript, C++, Kotlin, and Swift, support the new bidirectional InvokeModelWithBidirectionalStream API. Python SDK, which uses async features to do this, is an experimental one, but it covers the basics well. &lt;/p&gt;

&lt;p&gt;You will do the following (Python example, but same applies elsewhere) &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a Sonic client. &lt;/li&gt;
&lt;li&gt;Create function(s) that define how you will handle each event like ContentStart, ContentEnd etc. &lt;/li&gt;
&lt;li&gt;Start a session with the client &lt;/li&gt;
&lt;li&gt;Call the Invoke api above with await (in experimental Python SDK) &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Demo Video Snippet:&lt;br&gt;
&lt;a href="https://youtu.be/ObiFCrq2juk" rel="noopener noreferrer"&gt;Amazon Nova Sonic Demo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also get started with this Nova Workshop codebase: &lt;br&gt;
&lt;a href="https://github.com/aws-samples/amazon-nova-samples" rel="noopener noreferrer"&gt;Nova Sample code&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ai</category>
      <category>amazon</category>
      <category>voice</category>
    </item>
    <item>
      <title>Amazon Inspector</title>
      <dc:creator>Manu Muraleedharan</dc:creator>
      <pubDate>Wed, 05 Jun 2024 08:52:30 +0000</pubDate>
      <link>https://dev.to/aws-builders/amazon-inspector-4fk4</link>
      <guid>https://dev.to/aws-builders/amazon-inspector-4fk4</guid>
      <description>&lt;p&gt;Inspector is a Vulnerability scanning tool for AWS workloads. &lt;br&gt;
Here is an over view from AWS: &lt;a href="https://www.youtube.com/watch?v=viAn4E7uwRU" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=viAn4E7uwRU&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Personal note&lt;/em&gt;: In the context of other law-enforcement terms used to name AWS Security services(Detective, Guard etc), Inspector is a bit different. In my country, a police inspector (the inspector that comes to my mind when I hear the title) is a law enforcement officer, who conducts investigations. I would say AWS Inspector is more like the vehicle inspector, who would verify if your vehicle is configured fine and is not causing pollution. &lt;/p&gt;

&lt;p&gt;For an instance to be scanned by Inspector, it needs to be a managed instance in SSM, and the below prerequisites need to be met: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SSM Agent is installed on EC2 and it is running &lt;/li&gt;
&lt;li&gt;The instance has an IAM role with the required permissions to talk to SSM. &lt;/li&gt;
&lt;li&gt;443 port is open outbound from EC2 instance so it can talk to SSM service. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Steps to follow if your EC2 is not coming as SSM Managed instance: &lt;a href="https://repost.aws/knowledge-center/systems-manager-ec2-instance-not-appear" rel="noopener noreferrer"&gt;https://repost.aws/knowledge-center/systems-manager-ec2-instance-not-appear&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Types of scanning&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EC2 scanning - An agent would be installed on the EC2 (SSM Agent) which would scan the EC2 for any vulnerability. &lt;/li&gt;
&lt;li&gt;ECR Scanning - Scan images in ECR &lt;/li&gt;
&lt;li&gt;Lambda scanning - Scan packages used in lambda&lt;/li&gt;
&lt;li&gt;Lambda code scanning - scan code in lambda &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the vulnerabilities found, it will give relevant details like remediation steps, CVSS (Common Vulnerability Scoring System) Score, Inspector score etc which shows how critical this vulnerability is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Suppression Rules&lt;/strong&gt;&lt;br&gt;
Say you have a web server. Then port 80, 443 being open is expected and you dont want to see warnings for that. &lt;br&gt;
You can create suppression rules to avoid seeing specific vulnerabilities reported. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vulnerability Database Search&lt;/strong&gt;&lt;br&gt;
Search CVE ID in vulnerability databases to get more info on the reported vulnerability. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deep scan of EC2&lt;/strong&gt;&lt;br&gt;
In addition to OS packages, application packages would be inspected for vulnerabilities. You can specify which paths you need to be scanned. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Center of Internet Security (CIS) Benchmark assessments&lt;/strong&gt;&lt;br&gt;
Center of Internet Security, offers a suite of security benchmarks that serve as authoritative guidelines for securing IT systems, which are utilized extensively in the industry. On-demand/Scheduled scans can be run with CIS benchmark for specific operating systems. This will select resources based on the tags you specify. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Export Software BOMS&lt;/strong&gt;&lt;br&gt;
Export the Bill of Materials in the software packages analysed by inspector into industry standard formats. These BOMs contain a hierarchical list of all the individual components in a package. This functionality helps to check for vulnerabilities in a system not reachable from AWS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inspector Demo&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EC2 scanning&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create an EC2 instance with an older version of Debian (version 10) from the marketplace. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/marketplace/pp/prodview-vh2uh3o4pdfow#pdp-overview" rel="noopener noreferrer"&gt;https://aws.amazon.com/marketplace/pp/prodview-vh2uh3o4pdfow#pdp-overview&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(This AMI is free to use)&lt;/p&gt;

&lt;p&gt;Create a security group allowing traffic from anywhere(0.0.0.0/0) to 22. Attach this security group to the EC2. &lt;/p&gt;

&lt;p&gt;SSH into the EC2, then install and start the SSM Agent. &lt;br&gt;
Steps for this: &lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/manually-install-ssm-agent-linux.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/systems-manager/latest/userguide/manually-install-ssm-agent-linux.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the vulnerabilities from this EC2 would be detected by Inspector and shown in the console. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feqb4qaiiywptw68xun5v.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feqb4qaiiywptw68xun5v.png" alt="EC2scan" width="800" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Security group with SSH from anywhere will also be detected as a vulnerability. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Container scanning&lt;/strong&gt;&lt;br&gt;
Pull a Debian 10 image from dockerhub and push it to the Amazon ECR.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker pull debian:10.0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;How to push to ECR: &lt;a href="https://docs.aws.amazon.com/AmazonECR/latest/userguide/docker-push-ecr-image.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/AmazonECR/latest/userguide/docker-push-ecr-image.html&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Now vulnerabilities from this docker image would be detected by Inspector and shown in the console. You can look at vulnerability per container repo or by container image. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fposlwz09pn0yc68nod98.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fposlwz09pn0yc68nod98.png" alt="Containerscan" width="800" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lambda scanning&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a lambda with some vulnerabilities. For example, lambda below updates a reserved variable and has an insecure socket connection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import os
import json
import socket

def lambda_handler(event, context):

    # print("Scenario 1");
    os.environ['_HANDLER'] = 'hello'
    # print("Scenario 1 ends")
    # print("Scenario 2");
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(('',0))
    # print("Scenario 2 ends")

    return {
        'statusCode': 200,
        'body': json.dumps("Inspector Code Scanning", default=str)
    } 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Code needs to use runtimes supported by Inspector to be able to scan them. Many times this is not the latest, but the -1 version. For python, it is 3.11 as of writing this article, whereas latest version for lambda is 3.12.&lt;/p&gt;

&lt;p&gt;You can check the supported versions here:&lt;br&gt;
&lt;a href="https://docs.aws.amazon.com/inspector/latest/user/supported.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/inspector/latest/user/supported.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the vulnerabilities from the lambda code can be seen in the console. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiy0u8wq5w76eqh498wqr.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiy0u8wq5w76eqh498wqr.png" alt="Lambda" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>security</category>
      <category>vulnerabilities</category>
    </item>
    <item>
      <title>AWS Detective</title>
      <dc:creator>Manu Muraleedharan</dc:creator>
      <pubDate>Mon, 29 Apr 2024 06:13:34 +0000</pubDate>
      <link>https://dev.to/aws-builders/aws-detective-3p1p</link>
      <guid>https://dev.to/aws-builders/aws-detective-3p1p</guid>
      <description>&lt;p&gt;AWS Detective service helps to analyze security issues.&lt;/p&gt;

&lt;p&gt;It automatically collects and analyzes security logs like VPC flow log, Cloudtrail and guard duty results and utilizes machine learning, graph theory and visualization to help in RCA. &lt;/p&gt;

&lt;p&gt;You can answer questions like &lt;br&gt;
1) How did this security incident happen? &lt;br&gt;
2) Where was the first intrusion &lt;br&gt;
3) How to prevent such incidents. &lt;/p&gt;

&lt;p&gt;Amazon Detective requires that you have Amazon GuardDuty enabled on your accounts for at least 48 hours before you enable Detective on those accounts. Findings are sent from GuardDuty to Detective every 6 hrs by default, this can be changed to be as fast as every 15 minutes. It takes 2 weeks of data to build a historical baseline. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Finding Groups&lt;/strong&gt;&lt;br&gt;
It groups findings from various services together based on incidents, so you can see the related findings in one place. It shows severity, entity affected, MITRE tactic used etc. The group is constructed as a graph that allows you to see the relation between various incidents that occurred. By default, the graph visualization is force-directed. You can manipulate the graph to get more details or different visualizations. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feyt5wb5a28oj13k1vr2j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feyt5wb5a28oj13k1vr2j.png" alt="FindignGroup" width="800" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For principals, EC2 instances, and EKS clusters you can see the most number of API calls and success, and failure counts.&lt;br&gt;
Powerful search functionality allows you to search the incidents in the environment through various options. This lets you see if the failures are consistent or if is there a suspicious pattern. &lt;/p&gt;

&lt;p&gt;Inside the investigation, you can see a visualization of how different incidents and entities are related to each other. You can manipulate this graph, and research the information that Detective gathers to gain insight into the security incident.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1t54dboy2kro0iuahc8a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1t54dboy2kro0iuahc8a.png" alt="FindingGroup2" width="800" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Investigations&lt;/strong&gt;&lt;br&gt;
For findings in GuardDuty, you have the option to pivot to Detective and investigate the finding concerning the different entities involved (EC2 instance, IAM Role, Account, etc. ) &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdslmmds4i5assi3fbcn5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdslmmds4i5assi3fbcn5.png" alt="InvestigateFromGD" width="800" height="1004"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This runs an investigation of the findings in the data so far gathered and creates a report of all the related and relevant data. This can be used, then by the security analyst to find out details on how the attack occurred (eg: A day with many failed API calls with a bruteforce SSH), and what are remediation actions to be taken (isolate EC2, revoke sessions, rotate keys etc..)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgty43wjf4d8b78xf3c04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgty43wjf4d8b78xf3c04.png" alt="Investigate2" width="800" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Floo5r3q5sks4irik9jij.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Floo5r3q5sks4irik9jij.png" alt="Investigate3" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Analysts can find the details of the mappings to tactics, techniques, and procedures (TTP). All TTPs are classified according to their severity. The console shows the techniques and actions used. By selecting a specific TTP, they can see the details in the right pane. &lt;/p&gt;

&lt;p&gt;Once the analyst has enough information about the incident they can take remediation steps (isolate EC2, revoke sessions, rotate keys etc..)&lt;/p&gt;

&lt;p&gt;More information can be gained from this walkthrough of Detective (From AWS): &lt;a href="https://www.youtube.com/watch?v=Rz8MvzPfTZA"&gt;https://www.youtube.com/watch?v=Rz8MvzPfTZA&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>detective</category>
      <category>security</category>
    </item>
    <item>
      <title>AWS Guard Duty</title>
      <dc:creator>Manu Muraleedharan</dc:creator>
      <pubDate>Tue, 23 Apr 2024 13:51:20 +0000</pubDate>
      <link>https://dev.to/aws-builders/aws-guard-duty-1bkh</link>
      <guid>https://dev.to/aws-builders/aws-guard-duty-1bkh</guid>
      <description>&lt;p&gt;Guard Duty&lt;/p&gt;

&lt;p&gt;First off, a simple definition: &lt;br&gt;
GuardDuty is a guard that will stand in front of your workload and continuously let you know of any threats that are coming to your workload.&lt;/p&gt;

&lt;p&gt;Now the real definition:&lt;br&gt;
Amazon GuardDuty offers threat detection enabling you to continuously monitor and protect your AWS accounts, workloads, and data stored in Amazon Simple Storage Service (Amazon S3). GuardDuty analyzes continuous metadata streams generated from your account and network activity found in AWS CloudTrail Events, Amazon Virtual Private Cloud (VPC) Flow Logs, and domain name system (DNS) Logs. GuardDuty also uses integrated threat intelligence such as known malicious IP addresses, anomaly detection, and machine learning (ML) to more accurately identify threats.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features of Guard Duty&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fupatwnkilj8glyzzz0b6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fupatwnkilj8glyzzz0b6.png" alt="GDCONSOLE" width="800" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amazon S3 protection&lt;/strong&gt; - Monitor object-level suspicious activity &lt;br&gt;
&lt;strong&gt;EKS Protection&lt;/strong&gt; - Monitor suspicious activities on EKS clusters&lt;br&gt;
&lt;strong&gt;Runtime Monitoring&lt;/strong&gt; - Using an agent, monitor suspicious activities on ECS(Fargate), EKS, EC2&lt;br&gt;
&lt;strong&gt;Malware Protection&lt;/strong&gt; - Scan EBS volumes for malware&lt;br&gt;
&lt;strong&gt;RDS Protection&lt;/strong&gt; - scans login activity on Aurora RDS&lt;br&gt;
&lt;strong&gt;Lambda Protection&lt;/strong&gt; - scans network traffic from Lambda execution &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Suppression Rules&lt;/strong&gt; - Selectively suppress some findings to automatically archive findings which are low-value, false positive etc, to reduce the noise. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Threat list&lt;/strong&gt; - This is a list of known malicious IPs. This could be in many formats including industry-standard formats like STIX, OTX or even plaintext. Lists could be stored at an accessible internet URI, including your own S3 bucket. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trusted List&lt;/strong&gt; - stores known trusted IPs with the same storage and format characteristics &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Findings&lt;/strong&gt; - You can drill down into the findings, and get more information about the incident including the target of the attack, the actor of the attack etc. It also provides a link to pivot to detective and investigate this incident.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1.Malicious IP access &lt;/p&gt;

&lt;p&gt;We create a text file with a known IP in it, say 8.8.8.8 and upload it to an S3 bucket. Specify this file as a Threat List inside GuardDuty. &lt;/p&gt;

&lt;p&gt;From an EC2 inside your account, ping this IP. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;ping 8.8.8.8&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Soon, GuardDuty finds this and you can see it in the console.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft2yfu8mlhu874fwz6rmc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft2yfu8mlhu874fwz6rmc.png" alt="MALICIOUSIP" width="800" height="965"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2.Instance Credential Exfiltration&lt;/p&gt;

&lt;p&gt;We know an EC2 instance could have an IAM Role (Instance Profile) which gives it access to AWS API calls as per the role permissions. We can simulate the scenario where a hacker has got access to the EC2 and is using these credentials to call AWS APIs. &lt;/p&gt;

&lt;p&gt;Login to the EC2 and get the IAM credentials. &lt;br&gt;
This could depend on the Instance Metadata Service Version of the EC2. &lt;br&gt;
See this page for details: &lt;br&gt;
&lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#instance-metadata-security-credentials" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#instance-metadata-security-credentials&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For me, I am on v2. My Ec2-instance has the role ec2-admin&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \
&amp;amp;&amp;amp; curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/ec2-admin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the output of this command note the Access Key ID, Secret Access Key and Session Token. &lt;/p&gt;

&lt;p&gt;Now replicate same session in any other system terminal where you have AWS CLI installed. Below commands can be used for that. It creates a profile called badbob (BAD BOB!) who is the hacker.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
aws configure set profile.badbob.region us-east-1

aws configure set profile.badbob.aws_access_key_id &amp;lt;AccessKeyId&amp;gt;

aws configure set profile.badbob.aws_secret_access_key &amp;lt;SecretAccessKey&amp;gt;

aws configure set profile.badbob.aws_session_token &amp;lt;Token&amp;gt;

export AWS_DEFAULT_PROFILE=badbob

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now using the session, issue several AWS API Calls. An example is below. Remember the hacker does not know the permissions on the role, so he may try many commands across the spectrum, so try a whole lot of options. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;aws s3 ls --profile badbob&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can see GuardDuty finds this suspicious activity and reports it. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg45w4vhqtr2z2t0ehwoz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg45w4vhqtr2z2t0ehwoz.png" alt="EXFILTRATION" width="800" height="1004"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that in both cases, GuardDuty gives a whole lot of background information about the finding that helps the security team investigate this finding. &lt;/p&gt;

&lt;p&gt;This includes an overview, resources involved in the finding, IAM details, Network details, the action in the finding, actor involved in the finding etc. &lt;/p&gt;

&lt;p&gt;If you have enabled another AWS tool, AWS Detective at least 48 hours before you enabled GuardDuty, you would also see the option to investigate this finding in Detective. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm4me8ogs8oc0xt90r363.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm4me8ogs8oc0xt90r363.png" alt="DETECTIVE" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will continue this discussion with an article on &lt;a href="https://dev.to/manumaan/aws-detective-3p1p"&gt;AWS Detective. &lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ids</category>
      <category>security</category>
    </item>
    <item>
      <title>How do you manage IaC promotion?</title>
      <dc:creator>Manu Muraleedharan</dc:creator>
      <pubDate>Fri, 19 Apr 2024 13:26:45 +0000</pubDate>
      <link>https://dev.to/manumaan/how-do-you-manage-iac-promotion-2g1p</link>
      <guid>https://dev.to/manumaan/how-do-you-manage-iac-promotion-2g1p</guid>
      <description>&lt;p&gt;How do you manage the changes in Infrastructure as code, with respect to testing before putting into production? Production infra might differ a lot from the lower environments. Sometimes the infra component we are making a change to, may not even exist on a non-prod environment. &lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Chaos Engineering in AWS with FIS</title>
      <dc:creator>Manu Muraleedharan</dc:creator>
      <pubDate>Wed, 06 Mar 2024 09:59:33 +0000</pubDate>
      <link>https://dev.to/aws-builders/chaos-engineering-in-aws-with-fis-3h04</link>
      <guid>https://dev.to/aws-builders/chaos-engineering-in-aws-with-fis-3h04</guid>
      <description>&lt;p&gt;&lt;strong&gt;Chaos Engineering&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Chaos Engineering is the discipline of experimenting on a system in order to build confidence in the system’s capability to withstand turbulent conditions in production. It is not about creating chaos, it is about making the inherent chaos in real-world applications visible to you.&lt;/p&gt;

&lt;p&gt;One of the famous Chaos Engineering tools was Netflix Chaos Monkey, which would shut down random machines in the environment and check the effect on the availability. &lt;/p&gt;

&lt;p&gt;In the Well-Architected Framework, Chaos Engineering is a part of the Reliability pillar. &lt;/p&gt;

&lt;p&gt;Design Principles of Reliability say:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Automatically recover from failure&lt;/li&gt;
&lt;li&gt;Test recovery procedures&lt;/li&gt;
&lt;li&gt;Scale horizontally to increase aggregate workload availability&lt;/li&gt;
&lt;li&gt;Stop guessing capacity&lt;/li&gt;
&lt;li&gt;Manage change through automation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;AWS FIS (Fault Injection Simulator) corresponds directly to the 2nd principle and indirectly to the 1st principle. &lt;/p&gt;

&lt;p&gt;FIS allows you to create Chaos Experiments and test your workload to see if your workload is designed reliably. It shows whether your recovery procedures work, and whether you can automatically recover from failures. It also gives you an idea of downtime that can be expected in the particular DR strategy you have chosen.&lt;/p&gt;

&lt;p&gt;We recently had this question from a customer. They have only 2 AZ in their architecture, and they have a multi-AZ RDS database with a cross-region read replica. If one of the AZs goes down, will the CRR replica continue to function? Will it keep in sync with the DB after the multi-AZ failover happens? How much is the time, that we won't be able to access the RDS db, and the read replica? We want to optimistically answer with Yes for these questions and add "a very short time" to the last one. But how can we be sure? &lt;/p&gt;

&lt;p&gt;You create an FIS experiment and test it out. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features of AWS FIS&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Managed Chaos Experiments: AWS FIS provides templates for creating and managing chaos experiments, allowing teams to focus on results rather than the intricacies of setup and execution.

Broad Fault Injection Capabilities: Simulate a wide range of failures, including server outages, network latency, unavailability of EC2 resources, and throttled database access, to understand their impact on your application.

Integration with AWS Services: Seamlessly integrate with other AWS services such as Amazon EC2, Amazon RDS, Amazon ECS, AWS Lambda, VPC, etc, enabling a comprehensive testing environment.

Safety and Security: AWS FIS is built with safety in mind, offering mechanisms to limit the blast radius of experiments and ensure that your production environments remain secure.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Experiment:&lt;/strong&gt; An experiment in AWS Fault Injection Simulator (FIS) is a controlled procedure designed to assess the resilience of your AWS infrastructure by intentionally introducing faults or disruptions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Template:&lt;/strong&gt; This template defines the actions (faults) to be executed, the targets (AWS resources) those actions will affect, and any conditions or constraints. Templates ensure experiments are reproducible and standardized.&lt;br&gt;
An experiment is a template in action. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Actions:&lt;/strong&gt; Actions are the specific faults or disruptions you want to introduce. AWS FIS supports a variety of actions, such as stopping an EC2 instance, injecting latency into a network, and throttling database I/O operations, among others.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Targets:&lt;/strong&gt; Targets are the AWS resources upon which actions will be performed. Targets can be specified explicitly or selected dynamically based on tags or other identifiers, allowing for flexibility in defining the scope of the experiment. Eg: Which RDS to stop, Which subnet to have network disruption.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stop Conditions:&lt;/strong&gt; To ensure safety and prevent unintended consequences, experiments can include stop conditions. These are criteria that, when met, will automatically terminate the experiment. This can be defined as a CloudWatch Alarm. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating an Experiment Template&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Navigate to the AWS FIS console -&amp;gt; Experiment Template. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6qijv6x0wysa5kf42oj.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6qijv6x0wysa5kf42oj.png" alt="FIS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the account this experiment will run on&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F904slbid9w4tvqaggj1c.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F904slbid9w4tvqaggj1c.png" alt="fis account"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After giving a name and description, select the actions you want to include. I want to include a network disruption action that would disrupt all network connectivity in one AZ us-east-1a. &lt;/p&gt;

&lt;p&gt;Action Type: NETWORK, aws-network-disrupt-connectivity&lt;br&gt;
Target: (a target node is created automatically for the action which you will edit later)&lt;br&gt;
Duration: I will disrupt for 2 minutes&lt;br&gt;
Scope: (All all types of network connectivity will be disrupted including regional services like S3)&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3u44x60kou4p1k8hoxep.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3u44x60kou4p1k8hoxep.png" alt="fis network disrupt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now edit the Targets node. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flmppp41qu4owz7h1w6m9.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flmppp41qu4owz7h1w6m9.png" alt="fis target subnet"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can select targets using resource tags, filters or directly using resource IDs. I am selecting the subnet ID:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn0zc8ghvab83pwmaaiot.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn0zc8ghvab83pwmaaiot.png" alt="subnet-select"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, I create the action for DB instance going down:&lt;/p&gt;

&lt;p&gt;Action type: RDS aws:rds:reboot-db-instances&lt;br&gt;
Start-After: network-disruption (I want db to go down after the first action)&lt;br&gt;
Target: (a target node is created automatically for the action which you will edit later)&lt;br&gt;
Force failover: Yes (this will cause failover to the standby instance)&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhpn2doa8unlw6dy7o5v.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhpn2doa8unlw6dy7o5v.png" alt="fis actions db"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now edit the Targets node: (Select the DB instance I have) &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj97b8st19475400hptdo.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj97b8st19475400hptdo.png" alt="fis actions"&gt;&lt;/a&gt;&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fssw3efgcdbh8l4y72bt9.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fssw3efgcdbh8l4y72bt9.png" alt="selected db"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Actions are done, now specify the additional options:&lt;/p&gt;

&lt;p&gt;Empty target resolution mode: What if you gave some tags to find the targets by, and at runtime, no targets were found? I am specifying that I want the experiment to fail in that case. &lt;/p&gt;

&lt;p&gt;Service Access: What IAM Role would be used by the experiment? This needs to have access to CloudWatch if you want to log experiment logs to a CloudWatch log group. The default IAM role for FIS does not have CloudWatch access, edit the policy to add that. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsgsmwkepyjh56rb2eiyd.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsgsmwkepyjh56rb2eiyd.png" alt="fis options"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stop Condition: You wanted to bring down one AZ but ended up bringing down everything. Now you are panicking and want to stop the experiment. Specifying a CloudWatch Alarm will allow you to stop an experiment by putting the Alarm in Alarm State. &lt;br&gt;
For eg: This could be set so it goes into Alarm if there are more than X messages in a queue. &lt;/p&gt;

&lt;p&gt;You can also stop the experiment from the console by clicking "stop experiment" if you have access.&lt;/p&gt;

&lt;p&gt;Logs: You can send the logs of the experiment to an S3 bucket or a CloudWatch Log Group. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fziazl0e2sd7v8p43xhdz.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fziazl0e2sd7v8p43xhdz.png" alt="Logs_Stop"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Running the Experiment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now let's look at our steady state. I have a multi-AZ RDS MySQL DB instance. Currently primary is us-east-1a&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1g6jl3uckrmtssuweoim.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1g6jl3uckrmtssuweoim.png" alt="2az-db"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This DB sits over 2 AZs, evident from the Subnet Group for the DB, which includes us-east-1a and us-east-1b. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fht97i3vz1p15wq0jkvbq.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fht97i3vz1p15wq0jkvbq.png" alt="multiaz-db"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please note: Both subnets in the group must share the same network accessibility. This could be done by having them associate with the same route table. Otherwise, after failover, it may be stuck in a subnet with no access. &lt;/p&gt;

&lt;p&gt;At this point, both DB and the replica are in sync:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7owo2onawvj3wqli0qnr.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7owo2onawvj3wqli0qnr.png" alt="in-sync"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you save the experiment, start the experiment by clicking Start Experiment&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe2n6gef7mxzfwefpxiu7.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe2n6gef7mxzfwefpxiu7.png" alt="StartExp"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see the status changing in actions. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkrh8rsc627cubjsz2rha.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkrh8rsc627cubjsz2rha.png" alt="status"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In logs, you can see the targets that have been resolved. &lt;br&gt;
It has found the following subnets:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffovie4m8ctir4jumqz57.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffovie4m8ctir4jumqz57.png" alt="subnet"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It has found the DB:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqlk4evil9p4fdebnkwpc.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqlk4evil9p4fdebnkwpc.png" alt="db target"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the network disruption is under process, your MySQL connectivity will seem stuck. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fltd3f9w07wj3niosaf23.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fltd3f9w07wj3niosaf23.png" alt="mysqlstuck"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the DB action starts, you will see the DB instance rebooting. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fool5tpijvminmu2e5sut.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fool5tpijvminmu2e5sut.png" alt="reboot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While rebooting you won't be able to insert into the DB. &lt;/p&gt;

&lt;p&gt;When the console comes back to show DB as "Available" create a new connection to the DB. &lt;/p&gt;

&lt;p&gt;Note that the console may not yet show the AZ change. It takes some time for it to reflect. But DB has failed over to the other AZ when it says available. It is a DNS change behind the scenes.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzeatl1wznqq6aon4qyc7.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzeatl1wznqq6aon4qyc7.png" alt="Insert"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can also query from the replica and it is still in sync!&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2yl5vlot54ni0c666yk5.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2yl5vlot54ni0c666yk5.png" alt="replica"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We could notice a downtime of about 2 minutes for the RDS db to come back up, for our tiny db.t3.micro instance. More powerful instances take less time. &lt;/p&gt;

&lt;p&gt;After some minutes console shows the new AZ for primary: us-east-1b&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcx7u80wxy2ppildd60j4.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcx7u80wxy2ppildd60j4.png" alt="post-failover"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Actions should show as completed now. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1077icq316xr3o5ycml.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1077icq316xr3o5ycml.png" alt="completed1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The experiment is completed. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwdpzifaaloarkbgwo51f.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwdpzifaaloarkbgwo51f.png" alt="completed2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By using FIS, we can test the resiliency of our applications in AWS. In this demo, we saw how we tested the resilience of a multi-az db and read replica in the face of losing one of the 2 AZs. &lt;/p&gt;

&lt;p&gt;More info can be found here: &lt;a href="https://aws.amazon.com/fis/" rel="noopener noreferrer"&gt;https://aws.amazon.com/fis/&lt;/a&gt;&lt;br&gt;
Great demo at ReInvent: &lt;a href="https://www.youtube.com/watch?v=N0aZZVVZiUw" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=N0aZZVVZiUw&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope this was helpful!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Installing MySQL on Amazon Linux 2023</title>
      <dc:creator>Manu Muraleedharan</dc:creator>
      <pubDate>Thu, 15 Feb 2024 13:18:55 +0000</pubDate>
      <link>https://dev.to/aws-builders/installing-mysql-on-amazon-linux-2023-1512</link>
      <guid>https://dev.to/aws-builders/installing-mysql-on-amazon-linux-2023-1512</guid>
      <description>&lt;p&gt;MySQL does not come by default with Amazon Linux 2023. &lt;/p&gt;

&lt;p&gt;I ran into some challenges installing it, and had to consult multiple blogs for success. &lt;/p&gt;

&lt;p&gt;Follow these steps to install it. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download the RPM file
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo wget https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install RPM file
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo dnf install mysql80-community-release-el9-1.noarch.rpm -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;You need the public key of mysql to install the software.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;If you need to install mysql client:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo dnf install mysql-community-client -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo dnf install mysql-community-server -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Terragrunt with Terraform in AWS</title>
      <dc:creator>Manu Muraleedharan</dc:creator>
      <pubDate>Mon, 12 Feb 2024 08:13:02 +0000</pubDate>
      <link>https://dev.to/manumaan/terragrunt-with-terraform-in-aws-2n10</link>
      <guid>https://dev.to/manumaan/terragrunt-with-terraform-in-aws-2n10</guid>
      <description>&lt;p&gt;&lt;strong&gt;Intro&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Terragrunt is a utility that can be used along with Terraform, to alleviate some of the challenges that come with using Terraform at scale. Today we will see Terragrunt in action when using it to create infra on AWS. &lt;/p&gt;

&lt;p&gt;The main benefit of Terragrunt is to reduce the repetition in code and keep the code DRY (Don't Repeat Yourself principle). &lt;br&gt;
When you have just one instance or one account of AWS, this problem may not occur. But as soon as you start managing multiple accounts or environments of AWS, you start copying code from one place to another and there are chances of manual mistakes and redundant code. Terragrunt helps with this. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;br&gt;
To use Terragrunt with Terraform on AWS, you will need to install the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;AWS CLI&lt;/li&gt;
&lt;li&gt;Terraform&lt;/li&gt;
&lt;li&gt;Terragrunt &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To use other functionalities we will see, we need: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;TFlint (For before-hooks that run linting)&lt;br&gt;
&lt;a href="https://github.com/terraform-linters/tflint" rel="noopener noreferrer"&gt;tflint&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SSH - Add the SSH key to your GitHub account and make sure you can pull and push from GitHub using SSH.  (for pulling Terraform at run-time from a git repo) Also add github to the known hosts: &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

   (host=github.com; ssh-keyscan -H $host; for ip in $(dig @8.8.8.8 github.com +short); do ssh-keyscan -H $host,$ip; ssh-keyscan -H $ip; done) 2&amp;gt; /dev/null &amp;gt;&amp;gt; .ssh/known_hosts



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can use this git repo to go through the demo examples:&lt;br&gt;
&lt;a href="https://github.com/manumaan/my-terragrunt-demo" rel="noopener noreferrer"&gt;Terragrunt Demo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This code will create 2 EC2 instances, one using local code and one pulling the code from a remote git repo. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6frnv8j8ynk6qwf05if.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6frnv8j8ynk6qwf05if.png" alt="Ec2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Workflow of using Terragrunt&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install the prerequisites above. &lt;/li&gt;
&lt;li&gt;Create a file called terragrunt.hcl which holds the terragrunt configuration. &lt;/li&gt;
&lt;li&gt;Instead of terraform commands, run terragrunt commands:
terraform init --&amp;gt; terragrunt init&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;terraform plan --&amp;gt; terragrunt plan &lt;/p&gt;

&lt;p&gt;terraform apply --&amp;gt; terragrunt apply &lt;/p&gt;

&lt;p&gt;terraform destroy --&amp;gt; terragrunt destroy&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep your code DRY with Terragrunt&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Backend configuration&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Backend configuration in Terraform does not allow for variables. This means people copy the configuration from one environment and use it in another one and manually change something. Which can lead to errors. With terragrunt, we keep it parameterized. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#Keep your backend DRY
remote_state {
  backend = "s3"
  generate = {
    path      = "backend.tf"
    if_exists = "overwrite_terragrunt"
  }
  config = {
    bucket = "tf-state-manum-0202041706"
    key = "${path_relative_to_include()}/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "tf-lock-table"
  }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This above code goes in terragrunt.hcl, and means the state will be kept in different paths for each module. Please note that the key is a variable, changing for each module. &lt;/p&gt;

&lt;p&gt;Below image shows the bucket for the backend, where different module state is kept in different prefixes.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo13vfr8ayfgb3fcw0izv.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo13vfr8ayfgb3fcw0izv.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Keep provider configuration DRY&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Note the below code in terragrunt.hcl, It uses assume_role to assume a specific role in the AWS for terraform. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#Keep your provider DRY
generate "provider" {
  path = "provider.tf"
  if_exists = "overwrite_terragrunt"
  contents = &amp;lt;&amp;lt;EOF
provider "aws" {
  region = "us-east-1"
  profile = "admin"
  assume_role {
    role_arn = "arn:aws:iam::644107485976:role/github_actions_role"
  }
}
EOF
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Keep your CLI arguments dry&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In many cases, you have variables to be passed to Terraform which changes for each account and each environment. These may be kept in different files and passed to Terraform with the CLI argument &lt;code&gt;-var-file&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is cumbersome. Terragrunt avoids that and injects the variables using the below code in terragrunt.hcl &lt;br&gt;
Variables from account.tfvars and region.tfvars will be injected into the modules where you are running terragrunt and it will be made available to them with the syntax var.xyz&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


#Keep your CLI DRY
terraform {
  extra_arguments "common_vars" {
    commands = ["plan", "apply"]

    required_var_files = [
     "${get_parent_terragrunt_dir()}/account.tfvars",
     "${get_parent_terragrunt_dir()}/region.tfvars"
    ]
  }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Before, After, Error Hooks&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Terragrunt allows you to hook into the lifecycle of terraform runs, and you can run custom code either before, after, or in case of an error in terraform. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvzz1abtulgypsixi856.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvzz1abtulgypsixi856.png" alt="before-hook"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Below code will print "start Terraform" at the start of each module terraform using echo command, using before_hook. &lt;/p&gt;

&lt;p&gt;It will print "Finished running Terraform" using after_hook. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F03qmhffmfb8a00zoudjo.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F03qmhffmfb8a00zoudjo.png" alt="after-hook"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;error_hook will execute in case of an error. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


    before_hook "before_hook" {
    commands     = ["apply", "plan"]
    execute      = ["echo","Start Terraform"]
  }

  after_hook "after_hook" {
    commands     = ["apply", "plan"]
    execute      = ["echo", "Finished running Terraform"]
    run_on_error = true
  }
    error_hook "import_resource" {
    commands  = ["apply"]
    execute   = ["echo", "Error Hook executed"]
    on_errors = [
      ".*",
    ]
  }


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This brings up an interesting possibility. We could run some linters or other code validators using before_hook, like below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;before_hook "before_hook" {
commands     = ["apply", "plan"]
execute      = ["tflint"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;This will look for the .tflint.hcl within the path where you are running the code. &lt;/p&gt;

&lt;p&gt;Here's a minimal .tflint.hcl &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

config {
  module = true
}

// Plugin configuration
plugin "aws" {
  enabled = true
  version = "0.29.0"
  source  = "github.com/terraform-linters/tflint-ruleset-aws"
}

plugin "terraform" {
  enabled = true
  preset  = "recommended"
  version = "0.4.0"
  source  = "github.com/terraform-linters/tflint-ruleset-terraform"
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;RUN-ALL command&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Terragrunt brings run-all command to terraform. Say you have 100 modules in a folder and want to create all that infra. Either you have to run the terraform plan and apply repeatedly 100 times manually or through a script. With terragrunt you just do:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

terragrunt run-all plan 
terragrunt run-all apply


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fijqx5a946xvj6jxg5ne2.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fijqx5a946xvj6jxg5ne2.png" alt="Run-all command"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: you can use skip argument to skip some of the modules.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Different Versions of code in Different Environments&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One powerful feature of terragrunt is to pull versioned code out of code repositories and run that terraform code. Say you have production running on stable code, and on dev, you want to try out something. a 1.1 version. You can have that version of code tagged 1.1 on GitHub (or another repository) and then pull that code at the run time. This is done by code like below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

terraform {
  source = "git::git@github.com:manumaan/Terragrunt_Demo.git//compute?ref=v1.1.0"
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The above code will pull the code with the 1.1.0 tag from the GitHub repo &lt;a href="https://www.github.com/manumaan/Terragrunt_Demo" rel="noopener noreferrer"&gt;https://www.github.com/manumaan/Terragrunt_Demo&lt;/a&gt; and run that in that module. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Some Extra Features&lt;/em&gt;&lt;br&gt;
Terragrunt will automatically retry any transient errors. (What is transient is defined by terragrunt). It will automatically run init if init has not been done in that path. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Debugging Terragrunt&lt;/em&gt; &lt;br&gt;
You can specify log level during commands to get debug logs. Different levels are:&lt;/p&gt;

&lt;p&gt;panic&lt;br&gt;
fatal&lt;br&gt;
error&lt;br&gt;
warn&lt;br&gt;
info --&amp;gt; This is the default&lt;br&gt;
debug&lt;br&gt;
trace &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Terraform with Multiple Accounts/Environments&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Using Terraform with multiple accounts or environments brings its challenges. Some approaches seen are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use different git branches/repos&lt;/li&gt;
&lt;li&gt;Use Terraform Cloud&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Git branches/repos don't add to the cost or learning complexity but do not help with repetitive code that has to be managed. Variable management is also not available. &lt;/p&gt;

&lt;p&gt;Terraform Cloud provides all the features you want, but there is a cost. Integration with policy-as-code is a benefit. Instead of terragrunt.hcl files, here you will create workspaces and projects. Here's my article on Terraform Cloud that gives all the details: &lt;a href="https://dev.to/aws-builders/terraform-cloud-with-aws-o20"&gt;Terraform Cloud with AWS&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Terragrunt takes a middle path, where it provides some of the functionalities you need for this use case, for no cost, while keeping the code repetition-free. &lt;/p&gt;

&lt;p&gt;Below is a comparison of different approaches:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuj86zlk7r6idlpbptys1.jpg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuj86zlk7r6idlpbptys1.jpg" alt="Comparison"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope this was helpful!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>terraform</category>
      <category>devops</category>
    </item>
    <item>
      <title>Terraform Cloud with AWS</title>
      <dc:creator>Manu Muraleedharan</dc:creator>
      <pubDate>Sat, 13 Jan 2024 06:06:38 +0000</pubDate>
      <link>https://dev.to/aws-builders/terraform-cloud-with-aws-o20</link>
      <guid>https://dev.to/aws-builders/terraform-cloud-with-aws-o20</guid>
      <description>&lt;p&gt; &lt;br&gt;
&lt;strong&gt;TerraForm&lt;/strong&gt;&lt;br&gt;
Terraform is an infrastructure-as-code tool to provision and tear down infrastructure on cloud or on-premises&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Terraform Cloud&lt;/strong&gt;&lt;br&gt;
Terraform Cloud is a SaaS application that helps teams use Terraform together. It aims to solve many problems that arise when many developers are using Terraform in an organization. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It provides secure &amp;amp; easy access to shared state and secret data. No longer have to give out powerful credentials to everyone who needs to run Terraform. No need to have duplicated variable values. &lt;/li&gt;
&lt;li&gt;&lt;p&gt;It allows you to integrate with your version control repo and run terraform plans/runs when there is a state change on the repo, i.e. Pull-Request, Commit, etc. You can run a terraform plan on pull-request and see the speculated changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cost Estimation: Estimate the cost of cloud resources you are creating. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can apply policies to control what infrastructure changes are allowed, using policy-as-code tools like Sentinel or OPA. You can fail the terraform run if the cost is higher than $$$. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Get your own Free Terraform Cloud Account&lt;/strong&gt;&lt;br&gt;
You can sign up with your email ID and get a free Terraform cloud account from &lt;a href="https://www.hashicorp.com/products/terraform?product_intent=terraform" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Once your email is verified you are in Terraform Cloud. Click "Create New Organization"&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz1ocgi82obbkskjpnaz8.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz1ocgi82obbkskjpnaz8.png" alt="Create Org1"&gt;&lt;/a&gt;&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuqy0b1phntpw9qpk8is8.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuqy0b1phntpw9qpk8is8.png" alt="Create org1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create Workspace&lt;/strong&gt;&lt;br&gt;
One Github Repository corresponds to one workspace. All terraform runs from the repo will come inside this workspace.&lt;/p&gt;

&lt;p&gt;Terraform Cloud has 3 different workflow types:&lt;br&gt;
VCS - Connect to your GitHub and trigger runs manually or automatically on commit/pull-request&lt;/p&gt;

&lt;p&gt;CLI - Have the code on your local system and run from the terminal, but runs will still display on the portal. &lt;/p&gt;

&lt;p&gt;API - Run terraform using API. &lt;/p&gt;

&lt;p&gt;On the below screen select "Version Control Workflow"&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm8hssgqgcxfibn8anelp.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm8hssgqgcxfibn8anelp.png" alt="Create workspace"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select your Version Control System (Github in my case) then do the login into the version control system. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6l8wtmf4hoe2jmchd8as.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6l8wtmf4hoe2jmchd8as.png" alt="Select Repo1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once logged in, you will be asked to select the repository that will be tracked by this workspace. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6d6zamb42rm6rpd3avf4.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6d6zamb42rm6rpd3avf4.png" alt="Select Repo2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After this, enter the Workspace name,  and you are done. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Connecting Terraform Cloud to AWS&lt;/strong&gt; &lt;br&gt;
Unlike the Terraform CLI you use on the local system, you don't need to have your AWS credentials available to the Terraform locally in the cloud version. Terraform Cloud can save variables that should be available to all workspaces (or some of them) centrally. You can keep them secure. &lt;/p&gt;

&lt;p&gt;You create Variable Sets (that contain variables) and specify whether the variable set would be accessible to all workspaces or some of them. &lt;/p&gt;

&lt;p&gt;Navigate to Settings - Variable Sets and create a Variable Set. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvqivuxqqicno3gdjpy0z.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvqivuxqqicno3gdjpy0z.png" alt="Variable set"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Inside this create 2 variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. Set the value as the access key id and secret access key from AWS of an IAM user with the required permissions.&lt;/p&gt;

&lt;p&gt;Select the variable type as "environment". The other option is "Terraform Variables" which are variables of terraform type. &lt;br&gt;
Mark them as sensitive, and they are no longer visible to anyone. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1nma2ilo5p9sfctq93em.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1nma2ilo5p9sfctq93em.png" alt="Variable"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Workspace Variables &lt;/strong&gt;&lt;br&gt;
You can specify variables that are local to a specific repository in its Workspace variables. This also allows you to have variables with the same name in different workspaces. &lt;br&gt;
For eg: I have a Workspace with the below variables. These will be used by the terraform scripts in that workspace. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ukhc73x2suwu4eds5j6.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ukhc73x2suwu4eds5j6.png" alt="Workspace Variables"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In effect, any workspace will get the variables in the workspace, plus the variable sets defined as global or linked to that workspace. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now let's start Terraforming!&lt;/strong&gt;&lt;br&gt;
Add the code from the below repo into your Workspace repository.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/manumaangit" rel="noopener noreferrer"&gt;
        manumaangit
      &lt;/a&gt; / &lt;a href="https://github.com/manumaangit/terraformcloud_demo" rel="noopener noreferrer"&gt;
        terraformcloud_demo
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Demo Repo for Terraform Cloud
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;This repo is for demo of Terraform Cloud&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/manumaangit/terraformcloud_demo" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;The terraform does not run automatically the very first time, so trigger a run from the Workspace by going to it and clicking "New Run". You can trigger a run anytime manually using this button. In the below window, I have selected to do both terraform plan and terraform apply. You can choose to do only apply also.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffi1evd4rg6wx2u8ut78s.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffi1evd4rg6wx2u8ut78s.png" alt="New Run"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once it completes planning, just like CLI it will wait for approval to apply by default. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0vbu7vb2tlndovdy25dm.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0vbu7vb2tlndovdy25dm.png" alt="Complete Run"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to, you can set an option in Workspace settings to auto-apply.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9nvbriqxc8uhyi8glehu.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9nvbriqxc8uhyi8glehu.png" alt="Apply Default"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you don't want to apply, click "Discard Run".&lt;br&gt;
Now onwards, anytime you commit or pull-request on the repository, it will trigger an automatic run. The run on pull-request is only a speculative plan and you cannot apply it. Only changes that are committed to the repo can be applied. &lt;/p&gt;

&lt;p&gt;I make a small change in the main.tf file and raise a pull-request. Terraform Cloud will automatically run a plan from the changes. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpp2yiytyzh28vkrcapaz.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpp2yiytyzh28vkrcapaz.png" alt="PR Run"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I commit the changes. Another run happens which has the option to apply. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fboqievcyd0nangw56sw0.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fboqievcyd0nangw56sw0.png" alt="applyrun"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cost Estimation&lt;/strong&gt;&lt;br&gt;
You can enable cost estimation in the Terraform Cloud. Goto Organization Settings - Cost Estimation and enable it.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7n9f773mtn130hx95bt7.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7n9f773mtn130hx95bt7.png" alt="costestimation1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now if you change the ec2 type in the tf file and commit, you can see the cost estimation in the plan run. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftx6l2jzti3j3ivgf6pnf.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftx6l2jzti3j3ivgf6pnf.png" alt="costestimation2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Policies for Terraform&lt;/strong&gt;&lt;br&gt;
Policies-As-Code is a way to specify policies in the form of code, and there are multiple tools out there to do that. In Terraform Cloud 2 of the most popular ones are supported - Sentinel (by Hashicorp, makers of Terraform) and OPA. &lt;/p&gt;

&lt;p&gt;In the Free version of Terraform Cloud, there are a lot of limitations on how many policies you can have - You can have a total of 5 policies and one PolicySet as of this writing. (PolicySet is what links a policy to one or more Workspaces in the Terraform Cloud). Also, you cannot fetch policies from a version control system in a Free version. &lt;/p&gt;

&lt;p&gt;From Organization Settings - Policies you can create a Policy as given below. I have selected Sentinel type. &lt;/p&gt;

&lt;p&gt;Note that in the Free version, you can have a maximum of one soft/hard mandatory policy and multiple advisory policies. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Soft Mandatory - This is like a Warning, even if the code breaks the policy you can override it. &lt;/li&gt;
&lt;li&gt;Hard Mandatory - This is an Error. You cannot override if the code breaks the policy you can override it.&lt;/li&gt;
&lt;li&gt;Advisory - Will just print a message. More like INFO.
 
Below given Sentinel code checks if the change in infra will incur a cost of more than $100.

 &lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "tfrun"
import "decimal"
delta_monthly_cost = decimal.new(tfrun.cost_estimate.delta_monthly_cost)
main = rule {
 print("Cost change cannot be more than $ 100") and
 delta_monthly_cost.less_than(100)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the policy is saved, Navigate to Organization Settings - PolicySets and click on "Connect a New PolicySet"&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1e37uplfroygyreg933b.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1e37uplfroygyreg933b.png" alt="Policy1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then click the link that says "Create a PolicySet with individually managed policies"&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvq2syctu22ef3l9z25oy.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvq2syctu22ef3l9z25oy.png" alt="Policy2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Set what kind of policies are in the set (Sentinel). Select Policies enforced globally to apply to all Workspaces. At the bottom from the drop-down select the previously created Policy and add it to this PolicySet. Click "Connect PolicySet".&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F329rp6kfto5vtvuuhcym.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F329rp6kfto5vtvuuhcym.png" alt="Policyset"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's change the EC2 type to t2.2xlarge which will surely break this policy. &lt;/p&gt;

&lt;p&gt;The cost estimation is $276.97 which triggers the Policy to fail. Note that Apply is not an option anymore since we set it as "Hard Mandatory"&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0zkvzanj0gd1zsgetv6z.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0zkvzanj0gd1zsgetv6z.png" alt="Policyfail"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Try out the Terraform Cloud and take your Terraforming to the next level. &lt;/p&gt;

&lt;p&gt;Hope this was helpful!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>terraform</category>
    </item>
    <item>
      <title>Cool Announcements @ AWS ReInvent CEO KeyNote</title>
      <dc:creator>Manu Muraleedharan</dc:creator>
      <pubDate>Wed, 29 Nov 2023 08:01:31 +0000</pubDate>
      <link>https://dev.to/manumaan/cool-announcements-aws-reinvent-ceo-keynote-1bj9</link>
      <guid>https://dev.to/manumaan/cool-announcements-aws-reinvent-ceo-keynote-1bj9</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J45ZYWUf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p1qed37aszkp4t0afk8w.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J45ZYWUf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p1qed37aszkp4t0afk8w.jpg" alt="Image description" width="750" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;S3 Express One Zone&lt;/strong&gt;&lt;br&gt;
Highest performance lowest latency cloud storage&lt;br&gt;
50% less cost than S3 standard &lt;br&gt;
10 times faster than S3 standard&lt;br&gt;
Single-digit millisecond latency&lt;br&gt;
Millions of requests per second&lt;br&gt;
Co-locate storage and compute in the same AZ &lt;br&gt;
Pinterest has 10x faster write-speed and 40% less cost from S3 Express One Zone&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Graviton 4&lt;/strong&gt;&lt;br&gt;
30% faster than Graviton3&lt;br&gt;
Faster and more energy-efficient&lt;br&gt;
R8g Ec2 instance with Graviton4 in preview&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EC2 Ultra-clusters&lt;/strong&gt;&lt;br&gt;
20,000 GPUs, connected by EFA of 32000 GBPS &lt;br&gt;
Equal to a supercomputer = 20 Exaflops&lt;/p&gt;

&lt;p&gt;New GPU = GH200 which is 4 times faster with new LLM compilers&lt;br&gt;
Uses Grace Hopper technology to connect CPU and GPU at 1TBPS&lt;br&gt;
32 GH200 can connect via the NVLINK switch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NVIDIA DGX cloud is coming to AWS&lt;/strong&gt;&lt;br&gt;
This is NVIDIA's AI Factory, connecting 16,000+ GPUs together. &lt;br&gt;
65 Exaflops compute capacity and will make LLM learning 2x fast &lt;/p&gt;

&lt;p&gt;*&lt;em&gt;EC2 Capacity Blocks for ML *&lt;/em&gt;&lt;br&gt;
Reserve EC2 Ultra Clusters for short-term usage&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trainium 2&lt;/strong&gt;&lt;br&gt;
4x faster, second-gen specially designed chips for training models&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ML Customization in AWS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Fine-tuning available in:&lt;br&gt;
Titan Text Lite, Express, Cohere Command Lite, Meta Llama 2, and Anthropic Claude&lt;/p&gt;

&lt;p&gt;Retrieval-Augmented Generation with Knowledge Bases &lt;br&gt;
(Announced Sept 2023)&lt;/p&gt;

&lt;p&gt;Continued Pre-Training is available in AWS Bedrock. The technique involves using large amounts of unlabeled data before fine-tuning a model,&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Agents for Bedrock *&lt;/em&gt;&lt;br&gt;
Execute multi-step actions across company systems powered by ML&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Guardrails for Bedrock&lt;/strong&gt;&lt;br&gt;
Safeguard generative AI applications with responsible AI policies&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Education Commitment&lt;/strong&gt;&lt;br&gt;
AWS commits to training 29 million people in the cloud and 2 million in AI for free by 2025. &lt;/p&gt;

&lt;p&gt;*&lt;em&gt;AWS CodeWhisperer Customization Capability *&lt;/em&gt;&lt;br&gt;
Provide custom code suggestions using internal SDK, api, and code. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amazon Q (Some of the features in Preview)&lt;/strong&gt;&lt;br&gt;
This is the new service I am most excited for. &lt;br&gt;
AI assistant designed for the business world that understands your company information. &lt;br&gt;
Can chat with Q in AWS console, documentation, code whisperer, and chat apps like Slack.&lt;br&gt;
Q is already trained with all the AWS information, WAF principles, etc.&lt;br&gt;
Troubleshoot errors with Q when you get an error in the AWS console. &lt;br&gt;
Get recommendations and step-by-step information&lt;br&gt;
Feature Development: Develop a new feature in AWS using Q using prompts interactively and iteratively&lt;br&gt;
Code Transformation: Use Q to upgrade language versions in code eg: 1000 Java apps upgraded in 2 days&lt;br&gt;
Business expert: Connect to over 40 data sources and answer business questions, supports RBAC&lt;br&gt;
Amazon Q inside Quicksight: Create BI reports and visualizations using generative AI by Q&lt;br&gt;
Amazon Q inside Amazon Connect: AI Agent stays on-call, to help on-call agents with customer interaction&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zero-ETL integrations with Redshift in:&lt;/strong&gt;&lt;br&gt;
Aurora Postgres, RDS for MySQL, DynamoDB&lt;br&gt;
As soon as data is written into these databases, query and analyze in Redshift without ETL pipeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zero-ETL integration between DynamoDB and OpenSearch&lt;/strong&gt;&lt;br&gt;
Search DyanmoDB data through Opensearch without doing ETL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI recommendations for Amazon DataZone&lt;/strong&gt;&lt;br&gt;
Add business descriptions to data in DataZone using AI. &lt;/p&gt;

&lt;p&gt;Project Kuiper&lt;br&gt;
A constellation of low Earth orbit satellites that aims to provide fast, affordable, and reliable broadband to customers in areas without reliable internet connection. Private network connectivity is now available.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>reinvent</category>
    </item>
  </channel>
</rss>
