<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Krishnadutt Panchagnula Blog</title>
        <link>https://krishnaduttpanchagnula.github.io/posts</link>
        <description>Krishnadutt Panchagnula Blog</description>
        <lastBuildDate>Tue, 07 Apr 2026 11:52:29 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Engineering Resilience: A Deep Dive into Chaos Engineering in Distributed Systems]]></title>
            <link>https://krishnaduttpanchagnula.github.io/posts/engineering-resilience-a-deep-dive-into-chaos-engineering-in-distributed-systems</link>
            <guid>https://krishnaduttpanchagnula.github.io/posts/engineering-resilience-a-deep-dive-into-chaos-engineering-in-distributed-systems</guid>
            <pubDate>Tue, 07 Apr 2026 11:52:29 GMT</pubDate>
            <description><![CDATA[Originally published at HackerNoon]]></description>
            <content:encoded><![CDATA[<p><em>Originally published at <a href="https://hackernoon.com/engineering-resilience-a-deep-dive-into-chaos-engineering-in-distributed-systems?source=rss" target="_blank" rel="noopener noreferrer" class="">HackerNoon</a></em></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Kill Heroes, Build Systems and Processes]]></title>
            <link>https://krishnaduttpanchagnula.github.io/posts/kill-heroes-build-systems-and-processes</link>
            <guid>https://krishnaduttpanchagnula.github.io/posts/kill-heroes-build-systems-and-processes</guid>
            <pubDate>Mon, 09 Mar 2026 08:36:59 GMT</pubDate>
            <description><![CDATA[Originally published at HackerNoon]]></description>
            <content:encoded><![CDATA[<p><em>Originally published at <a href="https://hackernoon.com/kill-heroes-build-systems-and-processes?source=rss" target="_blank" rel="noopener noreferrer" class="">HackerNoon</a></em></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Stop Throwing AI at Broken Systems: Fix Your Engineering Culture First]]></title>
            <link>https://krishnaduttpanchagnula.github.io/posts/stop-throwing-ai-at-broken-systems-fix-your-engineering-culture-first</link>
            <guid>https://krishnaduttpanchagnula.github.io/posts/stop-throwing-ai-at-broken-systems-fix-your-engineering-culture-first</guid>
            <pubDate>Fri, 20 Feb 2026 01:34:18 GMT</pubDate>
            <description><![CDATA[Originally published at HackerNoon]]></description>
            <content:encoded><![CDATA[<p><em>Originally published at <a href="https://hackernoon.com/stop-throwing-ai-at-broken-systems-fix-your-engineering-culture-first?source=rss" target="_blank" rel="noopener noreferrer" class="">HackerNoon</a></em></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Use the 4-C Framework to Build Observability in Cloud Native Environments]]></title>
            <link>https://krishnaduttpanchagnula.github.io/posts/use-the-4-c-framework-to-build-observability-in-cloud-native-environments</link>
            <guid>https://krishnaduttpanchagnula.github.io/posts/use-the-4-c-framework-to-build-observability-in-cloud-native-environments</guid>
            <pubDate>Wed, 22 Jan 2025 11:49:18 GMT</pubDate>
            <description><![CDATA[Originally published at HackerNoon]]></description>
            <content:encoded><![CDATA[<p><em>Originally published at <a href="https://hackernoon.com/use-the-4-c-framework-to-build-observability-in-cloud-native-environments?source=rss" target="_blank" rel="noopener noreferrer" class="">HackerNoon</a></em></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Accelerating cloud migration from console to IAC tools using “Terraform Import”]]></title>
            <link>https://krishnaduttpanchagnula.github.io/posts/accelerating-cloud-migration</link>
            <guid>https://krishnaduttpanchagnula.github.io/posts/accelerating-cloud-migration</guid>
            <pubDate>Fri, 12 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[With the advantages such as reduced upfront cost, little to no maintenance costs, organizations both large and small are moving to cloud, for their storage, compute and sometimes their complete end-to end business operations.]]></description>
            <content:encoded><![CDATA[<p>With the advantages such as reduced upfront cost, little to no maintenance costs, organizations both large and small are moving to cloud, for their storage, compute and sometimes their complete end-to end business operations.</p>
<p>hese different stages are based upon the Cloud maturity of the organization, which is divided into 5 progressive cloud maturity stages ( Although stage 4 is quite new). To simplify,</p>
<p><strong>Stage 0</strong> — When all the data storage, web/data hosting and operations are done entirely done in the legacy/local systems</p>
<p><strong>Stage 1</strong> — When the company has all the data storage, web/data hosting, and most of the operations are in legacy and only a few costly operations are moved to the cloud.</p>
<p><strong>Stage 2</strong> — When the company chooses to migrate certain part, which might be operations or storage or compute needs to the cloud and the rest are provided from legacy back-end systems.</p>
<p><strong>Stage 3</strong> — When the company has completed its migration and have its entire business in the cloud</p>
<p><strong>Stage 4</strong> — When the company has created multi-cloud deployment either in active-active or active-passive implementation mode.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-is-infrastructure-as-codeiac">What is Infrastructure as Code(IAC)<a href="https://krishnaduttpanchagnula.github.io/posts/accelerating-cloud-migration#what-is-infrastructure-as-codeiac" class="hash-link" aria-label="Direct link to What is Infrastructure as Code(IAC)" title="Direct link to What is Infrastructure as Code(IAC)" translate="no">​</a></h2>
<p>When the company is in the initial stages of cloud, like stage 1 and stage 2, the development of cloud infrastructure can be done entirely from console. But as our infrastructure scales, in stage 3 and stage 4, we can no longer do it from the console, as the infrastructure we have to manage, maintain and update is in a very large scale. Creating and maintaining it at that large scale is quite difficult. To reduce this problem, we have “Infrastructure as Code (IAC) “ tools such as Terraform, Ansible etc. (The Terraform is better suited for infrastructure provisioning while the Ansible is better suited for Configuring provisioned infrastructure / Configuration Management).</p>
<p>The Infrastructure as Code is a concept in which the process of provisioning, maintaining, and managing infrastructure(networks, virtual machines, load balancers, and connection topology), is done through machine-readable definition files (usually written in YAML or JSON), rather than physical hardware configuration or interactive configuration tools.</p>
<p>Implementing IAC tools within the existing development environment sometimes can be daunting as their resources and knowledge to implement, would be, at the moment quite scarce. To overcome this problem, we are going to talk about a certain method, which would ease your Terraforming journey. The tool is a command within the terraform environment called <code>terraform import</code>. In this post, for the sake of demonstration, we are will be using AWS ( as it takes the largest share among cloud providers).</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-is-terraform-import-and-how-it-can-help-us">What is Terraform import and how it can help us?<a href="https://krishnaduttpanchagnula.github.io/posts/accelerating-cloud-migration#what-is-terraform-import-and-how-it-can-help-us" class="hash-link" aria-label="Direct link to What is Terraform import and how it can help us?" title="Direct link to What is Terraform import and how it can help us?" translate="no">​</a></h2>
<p>Before we explore the implementation, let's try to understand what this command is and what it does.</p>
<p>Terraform import is one of the commands within the terraform environment, which would help us import the configuration settings, preferred storage selections, security configuration of our already created resources into the terraform state file(The terraform state file is like a treasurer of the terraform environment, who keeps track of what resources are up and running and what are destroyed)</p>
<p>Importing the state file helps us understand:</p>
<ol>
<li class="">How our preferences in the console can be translated to the commands within the terraform syntax</li>
<li class="">To understand which roles or policies a resource needs for its successful working.</li>
<li class="">How can I create multiple resources, given that we are able to leverage the existing roles and policies, within the cloud environment?</li>
</ol>
<p>To understand this better, Lets implement an example in AWS environment.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="terraform-import-implementation-in-aws">Terraform import implementation in AWS<a href="https://krishnaduttpanchagnula.github.io/posts/accelerating-cloud-migration#terraform-import-implementation-in-aws" class="hash-link" aria-label="Direct link to Terraform import implementation in AWS" title="Direct link to Terraform import implementation in AWS" translate="no">​</a></h2>
<p>For the example, let us create an EC2 with t2.micro instance :</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ec2-instance">EC2 instance:<a href="https://krishnaduttpanchagnula.github.io/posts/accelerating-cloud-migration#ec2-instance" class="hash-link" aria-label="Direct link to EC2 instance:" title="Direct link to EC2 instance:" translate="no">​</a></h2>
<p>Lets first create a EC2 in the console and later use terraform import to import resource state into terraform state-file.</p>
<p><strong>Launching EC2 from console:</strong></p>
<ol>
<li class="">
<p>First log into terraform console and type EC2 in the search bar</p>
</li>
<li class="">
<p>Create EC2 instance with t2.micro and Ubuntu image.
3  After couple of minutes the EC2 is created along with its IAM role, and EC2 status is changed into running.</p>
</li>
<li class="">
<p>Now, in-order to import , lets open our favorite IDE (which in my case is VS code).</p>
</li>
<li class="">
<p>Before we can use terraform in AWS , we need to configure AWS CLI and terraform CLI (Please refer this link, to do it : <a href="https://alexander.holbreich.org/2019-terraforming-aws/" target="_blank" rel="noopener noreferrer" class="">https://alexander.holbreich.org/2019-terraforming-aws/</a>)</p>
</li>
<li class="">
<p>Once AWS and terraform are configured, create a empty resource as shown below in VS Code.</p>
</li>
<li class="">
<p>Initialize the terraform within the directory, within the directory using <strong>terraform init</strong></p>
</li>
<li class="">
<p>Then type <strong>terraform import aws_instance.test i-0cc2507156b9510c1</strong>( The general form is “terraform import aws_instance.<name of="" the="" resource="" in="" terraform="" file=""> <id of="" ec2="" in="" aws="">”) and press enter. You will get the following message, once the resource has been imported.</id></name></p>
</li>
</ol>
<p>9. You can view your resources in your local terraform statefile using terraform state show aws_instance.web ( form is “terraform import aws_instance.<name of="" the="" resource="" in="" terraform="" file=""> <id of="" ec2="" in="" aws="">)</id></name></p>
<p><strong>Hope this tip accelerates your AWS journey and help you build amazing infrastructure. Happy Building !</strong></p>
<p>If you would like to connect with me, you can follow my <a href="https://medium.com/@krishnaduttpanchagnula" target="_blank" rel="noopener noreferrer" class="">blog here</a> or on <a href="https://www.linkedin.com/in/krishnadutt/" target="_blank" rel="noopener noreferrer" class="">linked-in</a> or on <a href="https://github.com/krishnaduttPanchagnula" target="_blank" rel="noopener noreferrer" class="">Git-hub</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Product-Management in Agile Projects: Addressing Technical Debt in DevOps Projects]]></title>
            <link>https://krishnaduttpanchagnula.github.io/posts/addressing-technical-debt</link>
            <guid>https://krishnaduttpanchagnula.github.io/posts/addressing-technical-debt</guid>
            <pubDate>Fri, 12 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[While developing products in DevOps teams, we take decisions on which features to develop, how to ship them quite quickly, in order to meet the customer requirements. Often these decisions causes more problems in the long run. These kind of decisions lead to “Technical Debt”.]]></description>
            <content:encoded><![CDATA[<p>While developing products in DevOps teams, we take decisions on which features to develop, how to ship them quite quickly, in order to meet the customer requirements. Often these decisions causes more problems in the long run. These kind of decisions lead to “Technical Debt”.</p>
<p>Tech debt is phenomenon which happens when we prioritise the speed of delivery now, by forgoing everything like code-quality or maintainability. Although the agility of delivery of products is key to stay relevent in this agile world, but we have to make decisions also that the changes are sustainable.</p>
<p>In this article, we’ll talk about what technical debt is, how to handle quick decisions during development, and give examples to help you understand how to avoid future issues.</p>
<p>Tech debt is the extra work we has to be done later because of the technical decisions that we make now. Although it was coined by software developer Ward Cunningham in 1992, but it’s still holds relevance .</p>
<p>Usually, Technical debt occurs when teams rush to push new features within deadlines, by writing write code, without thinking about other considerations such as security, extensibility etc. Over the time the tech debt increases and becomes difficult to manage. The only way to deal with tit then becomes to overhaul the entire system and rewrite everything from scratch. To prevent this scenario we need to continuously groom the tech debt and to that we need to understand the type of tech debt we are dealing with.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="causes-of-tech-debts">Causes of Tech Debts:<a href="https://krishnaduttpanchagnula.github.io/posts/addressing-technical-debt#causes-of-tech-debts" class="hash-link" aria-label="Direct link to Causes of Tech Debts:" title="Direct link to Causes of Tech Debts:" translate="no">​</a></h2>
<p><strong>Prudent and deliberate</strong>: Opting for swift shipping and deferring consequences signifies deliberate debt. This approach is favoured when the product’s significance is relatively low, and the benefits of quick delivery outweigh potential risks.</p>
<p><strong>Reckless and deliberate:</strong> Despite knowing how to craft superior code, prioritising rapid delivery over quality leads to reckless and deliberate debt.</p>
<p><strong>Prudent and inadvertent:</strong> Prudent and inadvertent debt occurs when there’s a commitment to producing top-tier code, but a superior solution is discovered post-implementation.</p>
<p><strong>Reckless and inadvertent:</strong> Reckless and inadvertent debt arises when a team strives for excellence in code without possessing the necessary expertise. Often, the team remains unaware of the mistakes they’re making.</p>
<p>Given these different causes for tech debts, lets try to understand the types of tech debts. These can be broadly categorised under three main heads</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="types-of-tech-debts">Types of Tech Debts:<a href="https://krishnaduttpanchagnula.github.io/posts/addressing-technical-debt#types-of-tech-debts" class="hash-link" aria-label="Direct link to Types of Tech Debts:" title="Direct link to Types of Tech Debts:" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="code-related-debts">Code Related Debts:<a href="https://krishnaduttpanchagnula.github.io/posts/addressing-technical-debt#code-related-debts" class="hash-link" aria-label="Direct link to Code Related Debts:" title="Direct link to Code Related Debts:" translate="no">​</a></h3>
<ul>
<li class=""><strong>Code Debt:</strong> When we talk about talk debt, code debt is the first thing that comes to the mind. It is due to bad coding practices, not following proper coding standards , insufficinet code documentation etc. This type of causes problem in terms of maintainability, extensibility, security etc.</li>
<li class=""><strong>Testing Debt:</strong> This occurs when the entire testing strategy is inadequate , which includes the absence of unit tests, integration tests, and adequate test coverage. This kind of debt causes us to loose confidence pushing new code changes and increases the risk of defects and bugs surfacing in production, potentially leading to system failures and customer dissatisfaction.</li>
<li class=""><strong>Documentation Debt:</strong> This manifests when documentation is either insufficient or outdated. It poses challenges for both new and existing team members in comprehending the system and the rationale behind certain decisions, thereby impeding efficiency in maintenance and development efforts.</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="architecture-debt">Architecture Debt:<a href="https://krishnaduttpanchagnula.github.io/posts/addressing-technical-debt#architecture-debt" class="hash-link" aria-label="Direct link to Architecture Debt:" title="Direct link to Architecture Debt:" translate="no">​</a></h3>
<ul>
<li class=""><strong>Design Debt:</strong> This results from flawed or outdated software architecture or design choices. It includes overly complex designs, improper use of patterns, and a lack of modularity. Design debt creates obstacles to scalability and the smooth incorporation of new features.</li>
<li class=""><strong>Infrastructure Debt:</strong> This is linked to the operational environment of the software, encompassing issues such as outdated servers, inadequate deployment practices, or the absence of comprehensive disaster recovery plans. Infrastructure debt can result in performance bottlenecks and increased periods of downtime.</li>
<li class=""><strong>Dependency Debt</strong>: This arises from reliance on outdated or unsupported third-party libraries, frameworks, or tools. Such dependency exposes the software to potential security vulnerabilities and integration complexities.</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="peoplemanagement-debt">People/Management Debt:<a href="https://krishnaduttpanchagnula.github.io/posts/addressing-technical-debt#peoplemanagement-debt" class="hash-link" aria-label="Direct link to People/Management Debt:" title="Direct link to People/Management Debt:" translate="no">​</a></h3>
<ul>
<li class=""><strong>Process Debt</strong>: This relates to inefficient or outdated development processes and methodologies. It includes poor communication practices, a lack of adoption of agile methodologies, and a lack of robust collaboration tools. Additionally, not automating the process can greatly affect the software delivery’s agility.</li>
<li class=""><strong>People/Technical Skills Debt</strong>: This occurs when the team lacks essential skills or knowledge, resulting in the implementation of sub-optimal solutions. Investing in training and development initiatives can help reduce this type of debt.</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="managing-and-prioritising-tech-debt">Managing and Prioritising Tech Debt<a href="https://krishnaduttpanchagnula.github.io/posts/addressing-technical-debt#managing-and-prioritising-tech-debt" class="hash-link" aria-label="Direct link to Managing and Prioritising Tech Debt" title="Direct link to Managing and Prioritising Tech Debt" translate="no">​</a></h3>
<p>Technical debt is something that happens when teams are developing products in aglie way. It’s like borrowing against the future by taking shortcuts now. But if the team knows about this debt and has a plan to deal with it later, it can actually help prioritise tasks. Whether the debt was intentional or not, it is crucial that the team grooms the technical debt during a backlog refinement session.</p>
<p>Value to customer vs Cost of solving it</p>
<ol>
<li class=""><strong>Do It Right Away</strong>: These tasks are crucial for the product’s smooth operation.</li>
<li class=""><strong>A Worthy Investment</strong>: These tasks contribute to the product’s long-term health, such as upgrading outdated systems.</li>
<li class=""><strong>Quick and Easy Wins</strong>: These are minor tasks that can be fixed easily. They’re great for familiarising new team members with the product.</li>
<li class=""><strong>Not Worth Considering</strong>: Sometimes, the problem might solve itself or it might not be worth the time and effort to fix, especially if a system upgrade or retirement is planned.</li>
</ol>
<p>While facing deadlines and working on new products, it’s easy to overlook accumulating technical debts. But if left unchecked, these debts can cause long-term problems. It’s key to balance the need for quick solutions with the importance of long-term stability.</p>
<p>While fast delivery and continuous improvement are central to agile development, it’s important to be mindful of accruing technical debts. Effectively managing technical debt can help ensure your projects’ long-term success.</p>
<p>Liked my content ? Feel free to reach out to my <a href="https://www.linkedin.com/in/krishnadutt/" target="_blank" rel="noopener noreferrer" class="">LinkedIn</a> for interesting content and productive discussions.</p>]]></content:encoded>
            <category>Devops</category>
            <category>Agile</category>
            <category>Tech debt</category>
            <category>Product-Management</category>
        </item>
        <item>
            <title><![CDATA[Developing Real-time log monitoring and email — alerting with Server-less Architecture using Terraform]]></title>
            <link>https://krishnaduttpanchagnula.github.io/posts/alerting-with-server-less-architecture</link>
            <guid>https://krishnaduttpanchagnula.github.io/posts/alerting-with-server-less-architecture</guid>
            <pubDate>Fri, 12 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Why Log Monitoring ?]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-log-monitoring-">Why Log Monitoring ?<a href="https://krishnaduttpanchagnula.github.io/posts/alerting-with-server-less-architecture#why-log-monitoring-" class="hash-link" aria-label="Direct link to Why Log Monitoring ?" title="Direct link to Why Log Monitoring ?" translate="no">​</a></h2>
<p>Lets say that you have build a certain app ( Here we are building an app based on micro-service architecture) using containerized solution in EKS (Elastic Kubernetes Service) or running an standalone app in EC2 (Elastic Cloud Compute) instance. And to monitor this app, we are sending the application logs to cloud watch-logs. But having to keep a constant eye on the this resource log group is tiresome and sometimes technically challenging, as there are hundred other micro-services that send their own logs to their log groups. And as this app scales up, we need to invest more human resources to perform mundane tasks such as monitor these logs, which could be better utilized in developing new business frontiers.</p>
<p>What if we can build an automated solution, which scales efficiently in terms of cost and performance, help us with monitor and alert if there are any issues within the logs ? We can build this tool in one of the two architecture styles mentioned below :</p>
<ol>
<li class="">Using Server based architecture (or)</li>
<li class="">Server-less architecture.</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="server-centric-or-server-less-architecture">Server-Centric (or) Server-less Architecture?<a href="https://krishnaduttpanchagnula.github.io/posts/alerting-with-server-less-architecture#server-centric-or-server-less-architecture" class="hash-link" aria-label="Direct link to Server-Centric (or) Server-less Architecture?" title="Direct link to Server-Centric (or) Server-less Architecture?" translate="no">​</a></h2>
<p>With the advent of the cloud technologies, we have moved from server-centric to on demand servers to now the server-less. Before we choose server-centric, on-demand servers or server-less architecture, we must ask ourselves few questions:</p>
<ol>
<li class="">How am i going to serve the feature that i am developing? ( Is it extension of available Eco-system or a stand-alone feature?)</li>
<li class="">What should be its availability and Scalability? What is it runtime requirement?</li>
<li class="">Does the feature have stateful or stateless functionality?</li>
<li class="">What is my budget of running this feature?</li>
</ol>
<p>If the your answers to above questions are quite ambiguous, always remember one thing <strong>Prefer Server-less over Server-Centric,</strong> if your solution can be build as server-less ( Your Cloud Architect might help you with decision).</p>
<p>In my case, as my log-Monitoring system is</p>
<ol>
<li class="">A Standalone system</li>
<li class="">It is event-based ( the event here is log), which needs to be highly available and should be scalable for logs from different services.</li>
<li class="">The feature is Stateless.</li>
<li class="">Budget is Minimum.</li>
</ol>
<p>Given the above answers, i have chosen <strong>Server-less</strong> Architecture.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="case-example">Case Example<a href="https://krishnaduttpanchagnula.github.io/posts/alerting-with-server-less-architecture#case-example" class="hash-link" aria-label="Direct link to Case Example" title="Direct link to Case Example" translate="no">​</a></h2>
<p>This system can be better illustrated by an example. Let say that we have built our application in JAVA ( application is running in tomcat within a node in EKS) and this application in deployed within the EKS cluster.</p>
<blockquote>
<p>Example Log -1</p>
</blockquote>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">java.sql.SQLTransientConnectionException: HikariPool-1 — Connection is not available, request timed out after 30000ms.  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithin Transaction(TransactionAspectSupport.java:367)</span><br></div></code></pre></div></div>
<blockquote>
<p>Example Log -2</p>
</blockquote>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(Transaction Interceptor.java:118) </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)</span><br></div></code></pre></div></div>
<p>We would like to get notified every time the application log reads the keyword “<strong>ERROR</strong>” or “<strong>Connection Exception</strong>”, as seen in the log above.To achieve this, lets build our monitoring and alerting system.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="key-components-to-build-log-monitoring-and-alerting-system">Key components to build Log Monitoring and Alerting System<a href="https://krishnaduttpanchagnula.github.io/posts/alerting-with-server-less-architecture#key-components-to-build-log-monitoring-and-alerting-system" class="hash-link" aria-label="Direct link to Key components to build Log Monitoring and Alerting System" title="Direct link to Key components to build Log Monitoring and Alerting System" translate="no">​</a></h2>
<ol>
<li class="">AWS Cloud-watch Logs</li>
<li class="">AWS log filter pattern</li>
<li class="">AWS Lambda</li>
<li class="">Simple Notification Service (SNS)</li>
<li class="">Email Subscription</li>
</ol>
<p>We combine the above AWS resources, as shown in the architecture diagram above, to create a Real-time server-less log monitoring system.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="building-infrastructure-and-working-with-terraform">Building Infrastructure and Working with Terraform<a href="https://krishnaduttpanchagnula.github.io/posts/alerting-with-server-less-architecture#building-infrastructure-and-working-with-terraform" class="hash-link" aria-label="Direct link to Building Infrastructure and Working with Terraform" title="Direct link to Building Infrastructure and Working with Terraform" translate="no">​</a></h2>
<ol>
<li class="">Lets first create a log group, which would receive all the application logs</li>
</ol>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">terraform </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> required_providers </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  aws </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">   source </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"hashicorp/aws"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">   version </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"~&gt; 3.0"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"># Configure the AWS Provider</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">provider </span><span class="token string" style="color:rgb(255, 121, 198)">"aws"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> region </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">var</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">region</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"># Extract the current account details</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">data </span><span class="token string" style="color:rgb(255, 121, 198)">"aws_caller_identity"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"current"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">data </span><span class="token string" style="color:rgb(255, 121, 198)">"aws_region"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"current"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"># Create a Log group to send your application logs</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">resource </span><span class="token string" style="color:rgb(255, 121, 198)">"aws_cloudwatch_log_group"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"logs"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> name </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Feature_Logs"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></div></code></pre></div></div>
<p>Once this resource is created, we expose all our log traffic from application layer in EKS to this log group. As the application starts working, all its outputs and errors are sent as log stream to this log group.</p>
<ol start="2">
<li class="">
<p>After the above step, we start receiving the logs. Every time the application layer throws an <em>error</em> or <em>connection exception</em>, we would like to get notified, so our desired keywords are “<strong>Error</strong>” and “<strong>Connection Exception</strong>” within the log stream of the Cloud watch log group.</p>
</li>
<li class="">
<p>We can do this, using the <strong>cloud-watch log subscription filter</strong> which helps parse all those logs and find the logs which contain either the keyword “<strong>Error</strong>” or such keywords.</p>
</li>
</ol>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">resource </span><span class="token string" style="color:rgb(255, 121, 198)">"aws_cloudwatch_log_subscription_filter"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"logs_lambdafunction_logfilter"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> name </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"logs_lambdafunction_logfilter"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> # role_arn </span><span class="token operator">=</span><span class="token plain"> aws_iam_role</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">iam_for_moni_pre</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">arn</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> change_log_group_name </span><span class="token operator">=</span><span class="token plain"> aws_cloudwatch_log_group</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">logs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">name</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> filter_pattern </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"?SQLTransientConnectionException ?Error"</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// Change the error patterns here</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> destination_arn </span><span class="token operator">=</span><span class="token plain"> aws_lambda_function</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">logmonitoring_lambda</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">arn</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></div></code></pre></div></div>
<ol start="4">
<li class="">When the <strong>cloud-watch log subscription filter</strong> sends logs to any receiving service such as AWS lambda , they are base64 encoded and compressed with the gzip format. In order for us to unzip , decode the logs and send them to SNS, we need <strong>AWS Lambda service</strong>.</li>
</ol>
<p>We create this Lambda service, as a log based triggered event(Thanks to cloudwatch logs), which receives the log events from log group, <em>Unzips it</em>, <em>decodes it base 64,</em> and sends the log to the SNS topic, whose arn is passed as Environment variable to the lambda function.</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">resource </span><span class="token string" style="color:rgb(255, 121, 198)">"aws_lambda_function"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"logmonitoring_lambda"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> function_name </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"logmonitoring_lambda"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> filename   </span><span class="token operator">=</span><span class="token plain"> data</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">archive_file</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">Resource_monitoring_lambda</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">script</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">output_path</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> script     </span><span class="token operator">=</span><span class="token plain"> data</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">archive_file</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">Resource_monitoring_lambda</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">script</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> output_path  </span><span class="token operator">=</span><span class="token plain"> data</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">archive_file</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">Resource_monitoring_lambda</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">script</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">output_path</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> handler    </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"lambda_function.lambda_handler"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> package_type </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Zip"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> role      </span><span class="token operator">=</span><span class="token plain"> aws_iam_role</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">iam_for_moni_pre</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">arn</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> runtime    </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"python3.9"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> source_code_hash </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">filebase64sha256</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">archive_file</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">Resource_monitoring_lambda</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">script</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">output_path</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> timeouts </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> tracing_config </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  mode </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"PassThrough"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> environment </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  variables </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">   sns_arn </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"${aws_sns_topic.logsns.arn}"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">resource </span><span class="token string" style="color:rgb(255, 121, 198)">"aws_lambda_permission"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"allow_cloudwatch"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> statement_id </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"AllowExecutionFromCloudWatch"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> action    </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"lambda:InvokeFunction"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> function_name </span><span class="token operator">=</span><span class="token plain"> aws_lambda_function</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">logmonitoring_lambda</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">function_name</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> principal   </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"logs.${data.aws_region.current.name}.amazonaws.com"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> source_arn  </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"arn:aws:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:*"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></div></code></pre></div></div>
<ol start="5">
<li class="">Having received the decoded logs from lambda, the SNS (Simple Notification Service) topic sends this filtered log to its email subscription and the subscribed email owner gets the email about the filtered log.</li>
</ol>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">resource </span><span class="token string" style="color:rgb(255, 121, 198)">"aws_sns_topic"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"logsns"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> name </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"logsns"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">resource </span><span class="token string" style="color:rgb(255, 121, 198)">"aws_sns_topic_subscription"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"snstoemail_email_target"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> topic_arn </span><span class="token operator">=</span><span class="token plain"> aws_sns_topic</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">logsns</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">arn</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> protocol </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"email"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> endpoint </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">var</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">email</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></div></code></pre></div></div>
<p>The resources in this architecture, as it it is <strong>server-less</strong>, are only invoked when there there are such key words in the logs. Hence this method is <strong>cost optimized</strong>.</p>
<p>If you would like to connect with me , you can follow my <a href="https://medium.com/@krishnaduttpanchagnula" target="_blank" rel="noopener noreferrer" class="">blog here</a> (or) on <a href="https://www.linkedin.com/in/krishnadutt/" target="_blank" rel="noopener noreferrer" class="">linked-in</a> and you can find all the code in my <a href="https://github.com/krishnaduttPanchagnula" target="_blank" rel="noopener noreferrer" class="">Git-hub</a>.</p>
<blockquote>
<p>Here is the lambda python script:</p>
</blockquote>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> gzip</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> json</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> base64</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> boto3</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> os</span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">lambda_handler</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  log_data </span><span class="token operator">=</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">str</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">gzip</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">decompress</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">base64</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">b64decode</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"awslogs"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"data"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"utf-8"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  json_body </span><span class="token operator">=</span><span class="token plain"> json</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">loads</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">log_data</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">print</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">json_body</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  sns </span><span class="token operator">=</span><span class="token plain"> boto3</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">client</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">'sns'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">print</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">os</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">environ</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">'snsarn'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  response </span><span class="token operator">=</span><span class="token plain"> sns</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">publish</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    TopicArn</span><span class="token operator">=</span><span class="token builtin" style="color:rgb(189, 147, 249)">str</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">os</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">environ</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">'snsarn'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    Message</span><span class="token operator">=</span><span class="token builtin" style="color:rgb(189, 147, 249)">str</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">json_body</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">print</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">response</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><br></div></code></pre></div></div>]]></content:encoded>
            <category>Monitoring</category>
            <category>Observability</category>
            <category>Serverless</category>
            <category>Lambda</category>
            <category>SNS</category>
            <category>AWS</category>
            <category>Cloud</category>
            <category>Terraform</category>
        </item>
        <item>
            <title><![CDATA[How AWS CloudWatch Agent on Kubernetes Blew Our AWS Bill]]></title>
            <link>https://krishnaduttpanchagnula.github.io/posts/cloudwatch-agent-on-kubernetes</link>
            <guid>https://krishnaduttpanchagnula.github.io/posts/cloudwatch-agent-on-kubernetes</guid>
            <pubDate>Fri, 12 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[When running a microservice-based architecture, traffic flows from the front-end, passes through multiple microservices, and eventually receives the final response from the back-end. Kubernetes is a container orchestrating service that helps us run and manage these numerous microservices, including multiple copies of them if necessary.]]></description>
            <content:encoded><![CDATA[<p>When running a microservice-based architecture, traffic flows from the front-end, passes through multiple microservices, and eventually receives the final response from the back-end. Kubernetes is a container orchestrating service that helps us run and manage these numerous microservices, including multiple copies of them if necessary.</p>
<p>During the lifecycle of a request, if it fails at a specific microservice while moving from one service to another, pinpointing the exact point of failure becomes challenging. Observability is a paradigm that allows us to understand the system end-to-end. It provides insights into the “what,” “where,” and “why” of any event within the system, and how it may impact application performance.</p>
<p>There are various monitoring tools available for microservice setups in Kubernetes, both open-source (such as Prometheus and Grafana) and enterprise solutions (such as App Dynamics, DataDog, and AWS CloudWatch). Each tool may serve a specific purpose.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="story-time--how-we-built-our-kubernetes">Story Time — How we built our Kubernetes<a href="https://krishnaduttpanchagnula.github.io/posts/cloudwatch-agent-on-kubernetes#story-time--how-we-built-our-kubernetes" class="hash-link" aria-label="Direct link to Story Time — How we built our Kubernetes" title="Direct link to Story Time — How we built our Kubernetes" translate="no">​</a></h2>
<p>In one of our projects, we decided to build a lower environment on an AWS Kubernetes cluster using Amazon Elastic Kubernetes Service (EKS) on Amazon Elastic Compute Cloud (EC2). We had around 80+ microservices running on EKS, which were built and deployed into the Kubernetes cluster using GitLab pipelines. During the initial development phase, we had poorly developed Docker images that consumed a significant amount of disk space and included unnecessary components. Additionally, we were not utilizing multi-stage builds, further increasing the image size. For monitoring purposes, we deployed the AWS CloudWatch agent, which utilizes Fluentd to aggregate logs from all the nodes and sends them to CloudWatch Logs.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="setting-up-container-insights-on-amazon-eks-and-kubernetes">Setting up Container Insights on Amazon EKS and Kubernetes<a href="https://krishnaduttpanchagnula.github.io/posts/cloudwatch-agent-on-kubernetes#setting-up-container-insights-on-amazon-eks-and-kubernetes" class="hash-link" aria-label="Direct link to Setting up Container Insights on Amazon EKS and Kubernetes" title="Direct link to Setting up Container Insights on Amazon EKS and Kubernetes" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-to-install-and-set-up-cloudwatch-container-insights-on-amazon-eks-or-kubernetes">How to install and set up CloudWatch Container Insights on Amazon EKS or Kubernetes.<a href="https://krishnaduttpanchagnula.github.io/posts/cloudwatch-agent-on-kubernetes#how-to-install-and-set-up-cloudwatch-container-insights-on-amazon-eks-or-kubernetes" class="hash-link" aria-label="Direct link to How to install and set up CloudWatch Container Insights on Amazon EKS or Kubernetes." title="Direct link to How to install and set up CloudWatch Container Insights on Amazon EKS or Kubernetes." translate="no">​</a></h3>
<p>During a routine cost check, we made a startling discovery. The billing for AWS CloudWatch Logs (where the CloudWatch agent sends logs) in our setup was typically around 20–30 dollars per day, but it had spiked to 700–900 dollars per day. This had been going on for five days, resulting in a bill of 4500 dollars solely for the CloudWatch Logs and NAT gateway (used for sending logs to CloudWatch via public HTTPS). As an initial response, we stopped the CloudWatch agent daemon set and refreshed the entire EKS setup with new nodes.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-went-wrong">What went wrong<a href="https://krishnaduttpanchagnula.github.io/posts/cloudwatch-agent-on-kubernetes#what-went-wrong" class="hash-link" aria-label="Direct link to What went wrong" title="Direct link to What went wrong" translate="no">​</a></h3>
<p>As a temporary fix, we halted the CloudWatch agent running as a daemon set in our cluster to prevent further billing. Upon investigation, we discovered that a large number of pods were in an evicted state. The new pods attempting to start (as Kubernetes tries to match the desired state specified in manifests/Helm charts) were also going into the evicted state. This led to a high volume of logs, which were then sent to CloudWatch Logs via the CloudWatch agent. Since log billing is based on ingestion and storage, it significantly contributed to our AWS bill. This eviction was caused by a condition called “<strong>node disk pressure</strong>.” The node disk pressure occurred due to the following reasons:</p>
<ul>
<li class="">The existing pod had generated a large number of logs, occupying significant disk space.</li>
<li class="">When a new version of the app was deployed in the cluster, the new container (approximately 3 GB in size) could not start due to insufficient available space.</li>
<li class="">After multiple attempts to start the pod, it went into an evicted state.</li>
<li class="">As the current pod was evicted, the deployment controller deployed another pod to match the desired state specified in the deployment.</li>
<li class="">These events generated more logs, further consuming available disk space.</li>
<li class="">This cycle continued for five days, exacerbating the situation.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-we-resolved-it">How we resolved it<a href="https://krishnaduttpanchagnula.github.io/posts/cloudwatch-agent-on-kubernetes#how-we-resolved-it" class="hash-link" aria-label="Direct link to How we resolved it" title="Direct link to How we resolved it" translate="no">​</a></h2>
<p>To address the problem, we implemented the following solutions:</p>
<ul>
<li class="">Once we identified the issue, we refreshed Kubernetes by replacing the existing nodes with a new set. This action cleared up all the disk space on the nodes, and since all our logs are stored in CloudWatch Logs, we resolved the log-related concerns.</li>
<li class="">Additionally, we implemented multi-stage builds, which reduced the overall image size for deployment.</li>
<li class="">Lastly, we set up CloudWatch alarms to trigger when the disk usage percentage exceeds a certain threshold.</li>
</ul>]]></content:encoded>
            <category>Cloud</category>
            <category>AWS</category>
            <category>CloudWatch</category>
            <category>Kubernetes</category>
        </item>
        <item>
            <title><![CDATA[Deploy and Run Hashicorp Vault With TLS Security in AWS Cloud]]></title>
            <link>https://krishnaduttpanchagnula.github.io/posts/deploy-and-run-hashicorp-vault</link>
            <guid>https://krishnaduttpanchagnula.github.io/posts/deploy-and-run-hashicorp-vault</guid>
            <pubDate>Fri, 12 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Often in software engineering, when we are developing new features, it is quite a common feature that we would encode certain sensitive information, such as passwords, secret keys, or tokens, for our code to do its intended functionality. Different professionals within the IT realm use it in different ways, such as the following:]]></description>
            <content:encoded><![CDATA[<p>Often in software engineering, when we are developing new features, it is quite a common feature that we would encode certain sensitive information, such as passwords, secret keys, or tokens, for our code to do its intended functionality. Different professionals within the IT realm use it in different ways, such as the following:</p>
<ul>
<li class="">Developers use secrets from API tokens, Database credentials, or other sensitive information within the code.</li>
<li class="">Dev-ops engineers might have to export certain values as environment variables and write the values in the YAML file for CI/CD pipeline to run efficiently.</li>
<li class="">The cloud engineers might have to pass the credentials, secret tokens, and other secret information for them to access their respective cloud (In the case of AWS, even if we save these in a <code>.credentials</code> file, we still have to pass the filename in terraform block, which would indicate that the credentials are available locally within the computer.)</li>
<li class="">The system administrators might have to send different logins and passwords to the people for the employees to access different services</li>
</ul>
<p>But writing it in plain text or sharing it in plain text is quite a security problem, as anyone logging in to the code-base might access the secret or pull up a Man-in-the-Middle attack. To counter this, in the developing world, we have different options like Importing secrets from another file ( YAML, .py, etc.) or exporting them as an environment variable. But both of these still have a problem: a person having access to a singular config file or the machine can echo out the password ( read print). Given these problems, it would be very useful if we could deploy a single solution that would provide solutions to all the IT professionals mentioned above and more. This is the ideal place for introducing Vault.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="hashicorp-vault--an-introduction">HashiCorp Vault — an Introduction<a href="https://krishnaduttpanchagnula.github.io/posts/deploy-and-run-hashicorp-vault#hashicorp-vault--an-introduction" class="hash-link" aria-label="Direct link to HashiCorp Vault — an Introduction" title="Direct link to HashiCorp Vault — an Introduction" translate="no">​</a></h2>
<p>HashiCorp Vault is a secrets and encryption management system based on user identity. If we have to compare it with AWS, it is like an IAM user-based resource (read Vault here) management system which secures your sensitive information. This sensitive information can be API encryption keys, passwords, and certificates.</p>
<p>Its workflow can be visualized as follows:</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="hosting-cost-of-vault">Hosting Cost of Vault<a href="https://krishnaduttpanchagnula.github.io/posts/deploy-and-run-hashicorp-vault#hosting-cost-of-vault" class="hash-link" aria-label="Direct link to Hosting Cost of Vault" title="Direct link to Hosting Cost of Vault" translate="no">​</a></h2>
<ul>
<li class="">Local hosting: This method is usually done if the secrets are to be accessed only by the local users or during the development phase. This method has to be shunned if these secret engines have to be shared with other people. As it is within the local development environment, there is no additional investment for deployment. This can be hosted directly in <a href="https://www.vaultproject.io/downloads" target="_blank" rel="noopener noreferrer" class="">a local machine</a> or by its <a href="https://hub.docker.com/_/vault/" target="_blank" rel="noopener noreferrer" class="">official docker image</a></li>
<li class="">Public Cloud Hosting ( EC2 in AWS/Virtual Machine in Azure): If the idea is to set up Vault to share with people across different regions, hosting it on Public cloud is a good idea. Although we can achieve the same with the on-prem servers, upfront costs and scalability is quite a hassle. In the case of AWS, we can easily secure the endpoint by hosting Vault in the EC2 instance and creating a Security group on which IPs can access the EC2. If you feel more adventurous, you can map this to a domain name and route from Route 53 so the vault is accessible on a domain as a service to the end users. In the case of EC2 hosting with an AWS-defined domain, the cost is $0.0116/hr.</li>
<li class="">Vault cloud Hosting (HashiCorp Cloud Platform): If you don’t want to set up infrastructure in the Public Cloud Environments, there is an option of choosing the cloud hosted by vault. We can think of it as a SaaS-based cloud platform that enables us to use the Vault as a service on a subscription basis. Since hashicorp itself manages the cloud, we can expect a consistent user experience. For the cost, it has three production grade <a href="https://cloud.hashicorp.com/products/vault/pricing" target="_blank" rel="noopener noreferrer" class="">options</a>: Starter at $ 0.50/hr, Standard at $1.58/hr, and Plus at $1.84/hr (as seen in July 2022).</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="example-of-self-hosting-in-aws-cloud">Example of Self-Hosting in AWS Cloud<a href="https://krishnaduttpanchagnula.github.io/posts/deploy-and-run-hashicorp-vault#example-of-self-hosting-in-aws-cloud" class="hash-link" aria-label="Direct link to Example of Self-Hosting in AWS Cloud" title="Direct link to Example of Self-Hosting in AWS Cloud" translate="no">​</a></h2>
<p>Our goal in this Project is to create a Vault instance in EC2 and store static secrets in the Key—Value secrets engine. These secrets are later retrieved into the terraform script, which, when applied, would pull the secrets from the Vault Secrets Engine and use them to create infrastructure in AWS.</p>
<p>To create a ready-to-use Vault, we are going to follow these steps:</p>
<ol>
<li class="">Create an EC2 Linux instance with ssh keys to access it.</li>
<li class="">SSH into the instance and install the Vault to get it up and running</li>
<li class="">Configure the Valve Secrets Manager</li>
</ol>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-1-create-an-ec2-linux-instance-with-ssh-keys-to-access-it">Step 1: Create an EC2 Linux instance with ssh keys to access it<a href="https://krishnaduttpanchagnula.github.io/posts/deploy-and-run-hashicorp-vault#step-1-create-an-ec2-linux-instance-with-ssh-keys-to-access-it" class="hash-link" aria-label="Direct link to Step 1: Create an EC2 Linux instance with ssh keys to access it" title="Direct link to Step 1: Create an EC2 Linux instance with ssh keys to access it" translate="no">​</a></h3>
<p>To create an EC2 instance and access it remotely via SSH, we need to create the Key pair. First, let's create an SSH key via the AWS console.</p>
<p>Once the Keys have been created and downloaded into the local workbench, we create an EC2 (t2.micro) Linux instance and associate it with the above keys. The size of the EC2 can be selected based on your requirements, but usually, a t2.micro is more than enough.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-2-ssh-into-the-instance-and-install-the-secrets-to-get-it-up-and-running">Step 2: SSH into the instance and install the secrets to get it up and running<a href="https://krishnaduttpanchagnula.github.io/posts/deploy-and-run-hashicorp-vault#step-2-ssh-into-the-instance-and-install-the-secrets-to-get-it-up-and-running" class="hash-link" aria-label="Direct link to Step 2: SSH into the instance and install the secrets to get it up and running" title="Direct link to Step 2: SSH into the instance and install the secrets to get it up and running" translate="no">​</a></h3>
<p>Once the status of the EC2 changes to running, open the directory in which you have saved the SSH(.pem) key. Open a terminal and type <code>ssh -i &lt;keyname.pem&gt; ec2-user @&lt;publicdns IP4&gt;</code> . Once we have established a successful SSH session into our Ec2 instance, we can install the Vault using the following commands:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">wget -O- &lt;https://apt.releases.hashicorp.com/gpg&gt; | gpg — dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">echo "deb \[signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg\] &lt;https://apt.releases.hashicorp.com&gt; $(lsb\release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">sudo apt update &amp;&amp; sudo apt install vault</span><br></div></code></pre></div></div>
<p>The above command would install the vault in the EC2 environment. Sometimes the second command is known to throw some errors. In case of an error, replace <code>$(lsb_release -cs)</code> with “<code>jammy</code>”. [This entire process can be automated by copying the above commands to EC2 user data while creating an EC2 instance].</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-3-configure-the-hashicorp-valve">Step 3: Configure the Hashicorp valve<a href="https://krishnaduttpanchagnula.github.io/posts/deploy-and-run-hashicorp-vault#step-3-configure-the-hashicorp-valve" class="hash-link" aria-label="Direct link to Step 3: Configure the Hashicorp valve" title="Direct link to Step 3: Configure the Hashicorp valve" translate="no">​</a></h3>
<p>Before initializing the vault, let's ensure it is properly installed by following the command:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">vault</span><br></div></code></pre></div></div>
<p>Let's make sure there is no environment variable called <code>VAULT_TOKEN</code>. To do this, use the following command:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">$ unset VAULT_TOKEN</span><br></div></code></pre></div></div>
<p>Once we have installed the Vault, we need to configure the Vault, which is done using HCL files. These HCL files contain data such as backed, listeners, cluster address, UI settings, etc. As we have discussed in the Vault’s Architecture, the back end on which the data is stored is very different from the vault engine, which is to be persisted even when the vault is locked (Stateful resource). In addition to that, we need to specify the following details:</p>
<ul>
<li class="">Listener Ports: the port/s on which the Vault listens for API requests.</li>
<li class="">API address: Specifies the address to advertise to route client requests.</li>
<li class="">Cluster address: Indicates the address and port to be used for communication between the Vault nodes in a cluster. To secure it much further, we can use TLS-based communication. This step is optional and can only be tried if you want to secure your environment further. The TLS Certificate can be generated using openssl in Linux.</li>
</ul>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain"># Installs openssl  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">sudo apt install openssl  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">#Generates TLS Certificate and Private Key  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">openssl req -newkey rsa:4096 -x509 -sha512 -days 365 -nodes -out certificate.pem -keyout privatekey.pem </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></div></code></pre></div></div>
<p>Insert the TLS Certificate and Private Key file paths in their respective arguments in the listener “tcp” block.</p>
<ul>
<li class=""><code>tls_cert_file</code>: Specifies the path to the certificate for TLS in PEM encoded file format.</li>
<li class=""><code>tls_key_file</code>: Specifies the path to the private key for the certificate in PEM-encoded file format.</li>
</ul>
<div class="language-hcl codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-hcl codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">#Configuration in config.hcl file  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">storage "raft" {   </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">path = "./vault/data"   </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">node\id = "node1"   </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">}  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">listener "tcp" {  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> address = "127.0.0.1:8200"   </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">tls\disable = "true"  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">tls\cert\file = certificate.pem  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">tls\key\file = privatekey.pem  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">}  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">disable\mlock = true  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">api_addr = "http://127.0.0.1:8200"   </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">cluster_addr = "https://127.0.0.1:8201"  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> ui = true</span><br></div></code></pre></div></div>
<p>Once these are created, we create the folder where our backend will rest: vault/data.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">mkdir -p ./vault/data</span><br></div></code></pre></div></div>
<p>Once done, we can start the vault server using the following command:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">vault server -config=config.hcl</span><br></div></code></pre></div></div>
<p>Once done, we can start our Vault instance with the backend mentioned in the config file and all its settings.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">export VAULT_ADDR='http://127.0.0.1:8200'  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">vault operator init</span><br></div></code></pre></div></div>
<p>After it is initialized, it creates five Unseal keys called shamir keys (out of which three are used to unseal the Vault by default settings) and an Initial root token. This is the only time ever that all of this data is known by Vault, and these details are to be saved securely to unseal the vault. In reality, these shamir keys are to be distributed among key stakeholders in the project, and the Key threshold should be set in such a fashion that Vault can be unsealed when the majority are in consensus to do so.</p>
<p>Once we have created these Keys and the initial token, we need to unseal the vault:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">vault operator unseal</span><br></div></code></pre></div></div>
<p>Here we need to supply the threshold number of keys to unseal. Once we supply that, the sealed status changes to false.</p>
<p>Then we log in to the Vault using the Initial root token.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">vault login</span><br></div></code></pre></div></div>
<p>Once authenticated successfully, you can easily explore different encryption engines, such as Transit secrets Engine. This helps encrypt the data in transit, such as the Key-Value Store, which is used to securely store Key-value pairs such as passwords, credentials, etc.</p>
<p>As seen from the process, Vault is pretty robust in terms of encryption, and as long as the shamir keys and initial token are handled in a sensitive way, we can ensure the security and integrity</p>
<p>And you have a pretty secure Vault engine (protected by its own shamir keys) running on a free AWS EC2 instance (which is, in turn, guarded by the security groups)!</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">**Want to Connect?**  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">If you want to connect with me, you can do so on [LinkedIn](https://www.linkedin.com/in/krishnadutt/).</span><br></div></code></pre></div></div>]]></content:encoded>
            <category>Hashicorp Vault</category>
            <category>Agile</category>
            <category>Security</category>
            <category>Hashicorp</category>
        </item>
        <item>
            <title><![CDATA[Optimizing Golang Docker images with multi-stage build]]></title>
            <link>https://krishnaduttpanchagnula.github.io/posts/docker-images-with-multi-stage-builds</link>
            <guid>https://krishnaduttpanchagnula.github.io/posts/docker-images-with-multi-stage-builds</guid>
            <pubDate>Fri, 12 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[With the increasing scale of development required to build an product, a large number of developers are required to develop, share and maintain the code. And as each of the developer’s environment are different from one another, it becomes quite a hassle to create similar environments with similar library versions. To solve this issue we use Docker, which creates similar environment experience for all the developers. When using docker, often we face problem of creating a large docker images sometimes racking up to some GBs of space. This idea very much defeats the idea that Docker has evolved beyond the classic VMs — “To create light weight and resource-light images that the developers can work easily ”]]></description>
            <content:encoded><![CDATA[<p>With the increasing scale of development required to build an product, a large number of developers are required to develop, share and maintain the code. And as each of the developer’s environment are different from one another, it becomes quite a hassle to create similar environments with similar library versions. To solve this issue we use Docker, which creates similar environment experience for all the developers. When using docker, often we face problem of creating a large docker images sometimes racking up to some GBs of space. This idea very much defeats the idea that Docker has evolved beyond the classic VMs — “To create light weight and resource-light images that the developers can work easily ”</p>
<p>To solve this problem of docker image bloating, we have several solutions such as using dockerignore to not add unnecessary files, using distroless/minimal base images or Minimizing the number of layers. But when we are building an application, we would different tools which would rule out the possibility of using distroless images. And when building we would be dealing with several steps so there is so much availability to reduce the layers within the dockerfile.</p>
<p>The tools that we use to build the application are often not used when running application. So what if we can somehow separate/remove these build tools and have only the tools which will run the application? Enter the <em>Multi-stage</em> builds in docker.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="docker--multi-stage-builds">Docker : Multi-Stage Builds<a href="https://krishnaduttpanchagnula.github.io/posts/docker-images-with-multi-stage-builds#docker--multi-stage-builds" class="hash-link" aria-label="Direct link to Docker : Multi-Stage Builds" title="Direct link to Docker : Multi-Stage Builds" translate="no">​</a></h2>
<p>Multi-stage builds is an implementation of Builder Pattern in a Dockerfile which helps in minimizing the size of the final container, improving run time performance, allowing for better organization of Docker commands. A multi-stage build is done by breaking the single-stage dockerfile into different sections (You can think them as different jobs like build, stage etc) within the same dockerfile, thereby creating separation of environments. As each of this step would use base image that is only useful to that step while passing its outputs to next step, we can keep the docker image lean. This can also be done using different dockerfiles in a CI (Continuous Integration pipeline), by passing the output of one stage to another. But the Multi-stage feature from docker remove the need to create all these steps with our pipeline and helps keep it clean.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="creating-the-multi-stage-docker-file">Creating the Multi-Stage Docker file<a href="https://krishnaduttpanchagnula.github.io/posts/docker-images-with-multi-stage-builds#creating-the-multi-stage-docker-file" class="hash-link" aria-label="Direct link to Creating the Multi-Stage Docker file" title="Direct link to Creating the Multi-Stage Docker file" translate="no">​</a></h2>
<p>For explaining this, we will be building and running a Movie application written in Golang, which performs basic crud operations. The code for the app can be found <a href="https://github.com/krishnaduttPanchagnula/Golang_projects/tree/main/CRUD_api_GO" target="_blank" rel="noopener noreferrer" class="">here</a>.</p>
<p>As we know in Go, in order for the app to run we need to compile it. On compilation it will create a executable ( pertaining to that OS) and only this executable is required to run the application. To illustrate the power of multi-stage build let’s first build it as a single stage Docker file.</p>
<p>Once we run docker build on the above file, we get the following executable which is around 350 MB.</p>
<p>Now lets separate build stage and execution stage into two different environments. For build-stage environment, lets use the Golang image based on alpine which comes loaded with all the tools required to run, test, build and validate the Golang. We build our application using the tools using this environment tools. Once this is done we pass the executable to environment which is execution/production environment which will run the executable.</p>
<p>Since the executable is created, we would not require much of the previous environment tools and can work with a base alpine image. Once we run docker build on this file, we observe that size of the file is around 13 MB ( named <strong>crud_multistage</strong> in the below picture) compared to 350 MB (named <strong>crud</strong> in the below picture) from single-stage Dockerfile. This multi-stage build offered around 95% reduction in total sie of the docker image</p>
<p>Since this image is very small, it easier for portability and can be easily to deploy in production. Although the multi-stage build sounds like a fantastic idea, there are certain scenarios when this should be used and certain scenarios when this should be avoided.</p>
<p><strong>When not to use Multi-stage build:</strong></p>
<ul>
<li class="">When the language you are writing completely packages requirements into a single file ( like in case of GO etc) or at-least as a group of file ( in case of JavaScript etc).</li>
<li class="">If you are not planning to run docker exec commands on final artifact to explore the application code.</li>
<li class="">If you don’t require the tools and files used in build stage, further down the line to debug the final artifact.</li>
</ul>
<p><strong>When to use Multi-stage build:</strong></p>
<ul>
<li class="">When you want to minimize the total size of the final Docker image that you deploy into production.</li>
<li class="">When you want to speed up your CI/CD processes by running steps/stages in the Docker file in parallel.</li>
<li class="">When different layers in Your Docker file are straight-forward and standardized.</li>
<li class="">When you are fine with loosing the build intermediaries and only want the final docker artifact.</li>
</ul>]]></content:encoded>
            <category>Go</category>
            <category>Golang</category>
            <category>CI/CD</category>
            <category>Docker</category>
            <category>Dockerfile</category>
            <category>Multi-stage</category>
            <category>Kuberentes</category>
        </item>
        <item>
            <title><![CDATA[InfraSecOps : Enable Monitoring and automated continuous Compliance of Security Groups using Cloud-watch and Lambda]]></title>
            <link>https://krishnaduttpanchagnula.github.io/posts/infrasecops-enable-monitoring</link>
            <guid>https://krishnaduttpanchagnula.github.io/posts/infrasecops-enable-monitoring</guid>
            <pubDate>Fri, 12 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[As a Dev-ops engineer, we use different compute resources in our cloud, to make sure that different workloads are working efficiently. And in order to restrict the traffic accessing our compute resources ( EC2/ECS/EKS instance in case of AWS) , we create stateful firewalls ( like Security groups in AWS). And as a lead engineer, we often describe the best practices for configuring the Security groups.But when we have large organization working on cloud, monitoring and ensuring each team follows these best practices is quite a tedious task and often eats up lot of productive hours. And it is not as if we can ignore this, this causes security compliance issues.]]></description>
            <content:encoded><![CDATA[<p>As a Dev-ops engineer, we use different compute resources in our cloud, to make sure that different workloads are working efficiently. And in order to restrict the traffic accessing our compute resources ( EC2/ECS/EKS instance in case of AWS) , we create stateful firewalls ( like Security groups in AWS). And as a lead engineer, we often describe the best practices for configuring the Security groups.But when we have large organization working on cloud, monitoring and ensuring each team follows these best practices is quite a tedious task and often eats up lot of productive hours. And it is not as if we can ignore this, this causes security compliance issues.</p>
<p>For example, the Security group might be configured with following configuration by a new developer ( or some rogue engineer). If we observe the below , security group which is supposed to restrict the traffic to different AWS resources is configured to allow all kinds of traffic on all protocols from the entire internet. This beats the logic of configuring the securing the resource with security group and might as well remove it.</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">"version"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"0"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">"detail-type"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"AWS API Call via CloudTrail"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"responseElements"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token property">"securityGroupRuleSet"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token property">"items"</span><span class="token operator">:</span><span class="token plain"> \</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token property">"groupOwnerId"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"XXXXXXXXXXXXX"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token property">"groupId"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"sg-0d5808ef8c4eh8bf5a"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token property">"securityGroupRuleId"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"sgr-035hm856ly1e097d5"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token property">"isEgress"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token property">"ipProtocol"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"-1"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  --&gt; It allows traffic from all protocols  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token property">"fromPort"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token number">-1</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> --&gt; to all the ports  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token property">"toPort"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token number">-1</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token property">"cidrIpv4"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"0.0.0.0/0"</span><span class="token plain"> --&gt; from entire internet</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> which is a bad practice.  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          \</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></div></code></pre></div></div>
<p>This kind of mistake can be done while building a Proof Of Concept or While testing a feature, which would cost us lot in terms of security. And Monitoring these kind of things by Cloud Engineers takes a toll and consumes a lot of time.What if we can automate this monitoring and create a self-healing mechanism, which would detect the deviations from best practices and remediate them?</p>
<p>The present solution that i have built in AWS, watches the each Security group ingress rule ( can be extended to even egress rules too) the ports that it is allowing, the protocol its using and the IP range that it communicating with. These security group rules are compared with the baseline rules that we define for our security compliance, and any deviations are automatically removed. These base-rules are configured in the python code( which can be modified to our liking, based on the requirement).</p>
<h1>Components used to build this system</h1>
<ol>
<li class="">
<p>AWS Cloud trail</p>
</li>
<li class="">
<p>AWS event bridge rule</p>
</li>
<li class="">
<p>AWS lambda</p>
</li>
<li class="">
<p>AWS SNS</p>
</li>
<li class="">
<p>S3 Bucket</p>
</li>
<li class="">
<p>Whenever a new activity ( either creation/modification/deletion of rule) is performed in the security group, its event log not sent as event log to cloud watch ,but as api call to cloud trail. So to monitor these events, we need to first enable cloud trail. This cloud trail will monitor all the api cloud trails from EC2 source and save them in a log file in S3 bucket.</p>
</li>
<li class="">
<p>Once these api calls are being recorded, we need to filter only those which are related to the Security group api calls. This can be done by directly sending all the api call to another lambda or via AWS event bridge rule. The former solution using lambda is costly as each api call will invoke lambda, so we create a event bridge rule to only cater the api calls from ec2 instance.</p>
</li>
</ol>
<p>3. These filtered API events are sent to the lambda, which will check for the port, protocol and traffic we have previously configured in the python code( In this example, i am checking for wildcard IP — which is entire internet, all the ports on ingress rule. You can also filter with with the protocol that you don't want to allow. Refer the <a href="https://github.com/krishnaduttPanchagnula/AWS_Terraform_scripts/blob/master/Auto%20Delete%20insecure%20securitygroup%20ingress%20rules/lambda_function.py" target="_blank" rel="noopener noreferrer" class="">code</a> for details)</p>
<p>4. This python code will filter all the security groups and find the security group rules, which violate them and delete them.</p>
<p>Creating a rouge security group ruleThe lambda taking action and deleting the rouge rule</p>
<p>5. Once these are deleted, SNS is used to send email event details such as arn of security group rule, the role arn of the person creating this rule, the violations that the rule group has done in reference to baseline security compliance. This email altering can help us to understand the actors causing these deviations and give proper training on the security compliance. The details are also logged in the cloud-watch log groups created in the present architecture.</p>
<p>For entire python code along with terraform code, please refer the following <a href="https://github.com/krishnaduttPanchagnula/AWS_Terraform_scripts/tree/master/Auto%20Delete%20insecure%20securitygroup%20ingress%20rules" target="_blank" rel="noopener noreferrer" class="">Github repo</a>. To replicate this system in your environment, change the base security rules that you want to monitor for in python and type <strong><em>terraform apply</em></strong> in the terminal. Sit back and have a cup of coffee, while the terraform builds this system in your AWS account.</p>
<p>Liked my content ? Feel free to reach out to my <a href="https://www.linkedin.com/in/krishnadutt/" target="_blank" rel="noopener noreferrer" class="">LinkedIn</a> for interesting content and productive discussions.</p>]]></content:encoded>
            <category>Cloud</category>
            <category>AWS</category>
            <category>CloudWatch</category>
            <category>Serverless</category>
            <category>Lambda</category>
            <category>Devsecops</category>
            <category>Monitoring</category>
            <category>Observability</category>
            <category>Cloud</category>
        </item>
        <item>
            <title><![CDATA[Exploring an Object-Oriented Jenkins Pipeline for Terraform:A novel architecture design in Jenkin's multi-stage Terraform CD pipeline to improve CI/CD granularity]]></title>
            <link>https://krishnaduttpanchagnula.github.io/posts/object-oriented-jenkins-pipeline</link>
            <guid>https://krishnaduttpanchagnula.github.io/posts/object-oriented-jenkins-pipeline</guid>
            <pubDate>Fri, 12 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Usually, when we perform terraform plan, terraform destroy, or terraform apply, we apply these actions to all the resources in our target files, often main.tf (you can use any name for the file, but this name is just used as a convention).]]></description>
            <content:encoded><![CDATA[<p>Usually, when we perform <code>terraform plan</code>, <code>terraform destroy</code>, or <code>terraform apply</code>, we apply these actions to all the resources in our target files, often <code>main.tf</code> (you can use any name for the file, but this name is just used as a convention).</p>
<p>In the age of CI/CD, when we have everything as pipelines right from data, and application code to infrastructure code, it is usually difficult to this granularity. Usually, at least in Terraform, to achieve these three different actions, we have three different pipelines to perform <code>terraform plan</code>: <code>terraform apply</code> and <code>terraform destroy</code>. And when we select a certain action (let's say <code>terraform plan</code>), this action is performed on all the stages and on all resources within the pipeline.</p>
<p>But when we observe all these pipelines, there is a commonality that can be abstracted out to create a generality, on which the dynamic nature can be inherited. Just as we create a class, using different objects with different attribute values can be built, is it possible to create a similar base class (read pipelines) which when instantiated can create different pipeline objects?</p>
<blockquote>
<p>###One Pipeline to create them all###</p>
</blockquote>
<p>##The Modular Infrastructure</p>
<p>In order to build this class-based pipeline, we first need to create a terraform script. This script developed should be loosely coupled and should be modular in nature. For this, we have created this modular script, which has three modules named “Networking,” “Compute,” and “Notifications.” The components that each of these modules create is as follows:</p>
<ol>
<li class="">Networking: 1 VPC and 1 subnet</li>
<li class="">Compute : 1 IAM role, 1 Lambda, 1 EC2 t2.micro instance</li>
<li class="">Notifications: 1 SNS topic and 1 email subscription</li>
</ol>
<p>And the file structure is as follows:</p>
<p>Once we have this ready, let’s create a groovy script in declarative style in a Jenkins file.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="class-based-jenkins-pipeline">Class-Based Jenkins Pipeline<a href="https://krishnaduttpanchagnula.github.io/posts/object-oriented-jenkins-pipeline#class-based-jenkins-pipeline" class="hash-link" aria-label="Direct link to Class-Based Jenkins Pipeline" title="Direct link to Class-Based Jenkins Pipeline" translate="no">​</a></h2>
<p>To create this class-based architecture style to flexibly create pipeline objects at the action and resource level, we are going to utilize a feature called “parameters” in Jenkins. This feature helps us create multiple objects using a single base class Jenkins pipeline. In this example, let’s create three actions namely:</p>
<ul>
<li class=""><code>terraform plan</code>: This creates and prints out a plan of the resources that we are going to create in the respective provider ( can be AWS, Kubernetes, GCP, Azure, etc.)</li>
<li class=""><code>terraform apply</code>: This command creates the resources in the respective provider and creates a state-file that saves the current state of resources in it.</li>
<li class=""><code>terraform destroy</code>: This removes all the resources that are listed within the state-file.</li>
</ul>
<p>These actions are performed on three modules/resources namely “Networking,” “Compute,” and “Notifications.”</p>
<p>The above parameters create a UI for the end user, as shown below, which would help the end user to create objects of the base pipeline on the fly.</p>
<p>Based on the actions selected and the resources on which these actions have to be done, Jenkins will create a dynamic pipeline according to your requirement. In the picture below, we see that we have applied terraform for the networking and compute resources in #24, and run <code>terraform apply</code> on networking and notification in run #25. To clean the infrastructure, we ran <code>terraform destroy</code> on run #26.</p>
<p>The present approach implemented is more in line with Continuous delivery principles than continuous deployment.</p>
<p>For the Jenkins file and Terraform code, refer to this <a href="https://github.com/krishnaduttPanchagnula/Multifunctional-terraform-Jenkins-pipeline" target="_blank" rel="noopener noreferrer" class="">link</a>.</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">**Want to Connect?**Feel free to reach out to my [LinkedIn](https://www.linkedin.com/in/krishnadutt/) for interesting content and productive discussions.</span><br></div></code></pre></div></div>]]></content:encoded>
            <category>Python</category>
            <category>Terraform</category>
            <category>CI/CD</category>
            <category>Github</category>
            <category>Devops</category>
            <category>Jenkins</category>
            <category>AWS</category>
            <category>Cloud</category>
            <category>IAC</category>
            <category>Infrastructure</category>
            <category>OOP</category>
        </item>
        <item>
            <title><![CDATA[DevOps Wizardry: Crafting Your Parlay GitHub Action  - Improve your Development Process with Personalized Custom Automation]]></title>
            <link>https://krishnaduttpanchagnula.github.io/posts/parlay-github-action</link>
            <guid>https://krishnaduttpanchagnula.github.io/posts/parlay-github-action</guid>
            <pubDate>Fri, 12 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Recently while trying to integrate a devsecops tool in my pipeline, i was trying to find the GitHub action which would simplify my workflow. Since i could not find it, i have to write the commands inline to run the command. Although it is not a hassle to write it within the script, it would be beneficial to have an action which we could directly call, pass parameters and run the action within the pipeline.]]></description>
            <content:encoded><![CDATA[<p>Recently while trying to integrate a devsecops tool in my pipeline, i was trying to find the GitHub action which would simplify my workflow. Since i could not find it, i have to write the commands inline to run the command. Although it is not a hassle to write it within the script, it would be beneficial to have an action which we could directly call, pass parameters and run the action within the pipeline.</p>
<p>In this blog, i will walk you through different steps on how you can create a custom GitHub actions which would satisfy your requirement. The blog will be of 2 parts:</p>
<ul>
<li class="">Understanding what the GitHub action are</li>
<li class="">Creating your custom GitHub actions</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="github-actions">GitHub actions:<a href="https://krishnaduttpanchagnula.github.io/posts/parlay-github-action#github-actions" class="hash-link" aria-label="Direct link to GitHub actions:" title="Direct link to GitHub actions:" translate="no">​</a></h2>
<p>Often when we write pipelines, we would have a set of actions which we would like to perform based on the type of application that we are developing. In order for us to run these actions across the repos in our organization, we would have to copy + paste this code across the repositories, which would make this process error prone and maintenance tussle. It would be better if we take DRY principle of software engineering and apply it to CI/CD world.</p>
<p>GitHub action is exactly this principle in practice. We create and host the required action in a certain GitHub public repository and this action is used across the pipeline to perform the action defined in the action. Now that we understand what GitHub action is, lets explore how we can build a custom GitHub action which can help automate set of actions. For this blog, i illustrate it with an example of SBOM enrichment tool Parlay, for which i have built a custom action.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="creating-custom-action--a-case-on-parlay">Creating Custom Action — A case on Parlay<a href="https://krishnaduttpanchagnula.github.io/posts/parlay-github-action#creating-custom-action--a-case-on-parlay" class="hash-link" aria-label="Direct link to Creating Custom Action — A case on Parlay" title="Direct link to Creating Custom Action — A case on Parlay" translate="no">​</a></h2>
<p>We will be creating our custom action in the following steps:</p>
<ul>
<li class="">Defining inputs and outputs in action.yml</li>
<li class="">Developing business logic in bash script</li>
<li class="">Dockerize the bash application</li>
<li class="">Test the action</li>
<li class="">Publish it in GitHub action Marketplace</li>
</ul>
<p>Defining inputs and outputs in action.yml</p>
<p>To start creating custom action create a custom git repository, clone that repo in your local system and open it up in your favourite code editor. We start by creation a file named actions.yml. This actions.yml defines the inputs that the action would take, the outputs that it would give and the environment it will run. For our use case we have 3 inputs and 1 output. The actions.yml should have following arguments:</p>
<ul>
<li class=""><strong>name</strong>: This would be the name of the action, which would be used to search in GitHub action marketplace. Since it would be published in marketplace, it’s name should be globally unique like s3 bucket.</li>
<li class=""><strong>description</strong>: This describes what your action would do. This would be helpful to identify which action would be the right fit for our use case.</li>
<li class=""><strong>inputs</strong>: Defines the list of options which would be used within the action. These can be compulsory or optional, which can be defined using “required” argument. In our current use case we are passing 3 arguments, input_file_name, enricher and output_file_name.</li>
<li class=""><strong>outputs</strong>: This enlists the list of outputs that the action gives.</li>
<li class=""><strong>runs</strong>: defines the environment in which action will execute , which in our case is docker</li>
</ul>
<p>The action.yml will look something like this:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">\</span><span class="token comment" style="color:rgb(98, 114, 164)"># action.yaml  </span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Parlay Github Action"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">description</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Runs Parlay on the given input file using the given enricher and outputs it in your given output file"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">branding</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">icon</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"shield"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">color</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"gray-dark"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">inputs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">input_file_name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">description</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Name of the input SBOM file to enrich"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">required</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token boolean important">true</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">enricher</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">description</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"The enricher used to enrich the parlay sbom. Currently parlay supports ecosystems, snyk, scorecard(openssf scorecard)"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">required</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token boolean important">true</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">default</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ecosystems  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">output_file_name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">description</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Name of the output file to save the SBOM enriched using the parlay's enricher"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">required</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token boolean important">true</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">outputs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">output_file_name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">description</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Prints the output file"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">runs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">using</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"docker"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Dockerfile"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">args</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> $</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> inputs.input_file_name </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> $</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> inputs.enricher </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> $</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> inputs.output_file_name </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="developing-business-logic-in-bash-script">Developing business logic in bash script<a href="https://krishnaduttpanchagnula.github.io/posts/parlay-github-action#developing-business-logic-in-bash-script" class="hash-link" aria-label="Direct link to Developing business logic in bash script" title="Direct link to Developing business logic in bash script" translate="no">​</a></h2>
<p>Once we have defined the inputs, outputs and environment that we are going to use, we would like to define what we are going to do with those inputs ( basically our logic) in a file. We can either define this in JavaScript or bash. For my current use case, i am using bash.</p>
<p>In my current logic, i am going to check if all the inputs are first given, if not the action fails. Once i have these 3 arguments, i am going to construct the command to run the action and save the output in an output file. This file is printed in stdout and formatted using jq utility.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">#!/bin/bash  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">\# Check if all three arguments are provided  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">if [ "$#" -ne 3 ]; then  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    echo "Usage: $0 &lt;input&gt; &lt;input_file_name&gt; &lt;output_file_name&gt;"  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    exit 1  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">fi  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">\# Extract arguments  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">INPUT_INPUT_FILE_NAME=$1  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">INPUT_ENRICHER=$2  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">INPUT_OUTPUT_FILE_NAME=$3  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">\# Construct command  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">full_command="parlay $INPUT_ENRICHER enrich $INPUT_INPUT_FILE_NAME &gt; $INPUT_OUTPUT_FILE_NAME"  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">eval "$full_command"  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">\# Check if the command was successful  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">if [ $? -eq 0 ]; then  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    echo "Command executed successfully: $full_command"  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    cat $INPUT_OUTPUT_FILE_NAME | jq .  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">else  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    echo "Error executing command: $full_command"  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">fi</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="dockerize-the-bash-application">Dockerize the bash application<a href="https://krishnaduttpanchagnula.github.io/posts/parlay-github-action#dockerize-the-bash-application" class="hash-link" aria-label="Direct link to Dockerize the bash application" title="Direct link to Dockerize the bash application" translate="no">​</a></h2>
<p>Once we have the bash script ready, we will be dockerizing it using the following script. Whenever we invoke the action, this action which is defined in the bash script runs in an isolated docker container. In addition to the bash script in entrypoint.sh, we would also be adding the the required libraries such as wget, jq and installing parlay binary.</p>
<div class="language-dockerfile codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-dockerfile codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">\# Base image  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">FROM --platform=linux/amd64 alpine:latest  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">\# installes required packages for our script  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">RUN apk add --no-cache bash wget jq  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">\# Install parlay  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">RUN wget &lt;https://github.com/snyk/parlay/releases/download/v0.1.4/parlay_Linux_x86_64.tar.gz&gt;   </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">RUN tar -xvf parlay_Linux_x86_64.tar.gz   </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">RUN mv parlay /usr/bin/parlay  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">RUN ls /usr/bin | grep parlay  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">RUN parlay  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">\# Copies your code file  repository to the filesystem  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">COPY . .  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">\# change permission to execute the script and  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">RUN chmod +x /entrypoint.sh  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">\# file to execute when the docker container starts up  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">ENTRYPOINT ["/entrypoint.sh"]</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="test-the-action">Test the action<a href="https://krishnaduttpanchagnula.github.io/posts/parlay-github-action#test-the-action" class="hash-link" aria-label="Direct link to Test the action" title="Direct link to Test the action" translate="no">​</a></h2>
<p>No amount of software is good without running some tests on it. To test the action, lets first push the code to GitHub. Once pushed, lets define the pipeline in pipeline.yaml file in .github/workflows folder. For the sake of input file, i am using a sample sbom <a href="https://github.com/krishnaduttPanchagnula/parlayaction/blob/main/cyclonedx.json" target="_blank" rel="noopener noreferrer" class="">file</a> in cyclonedx format and have pushed it to GitHub. In my pipeline.yaml file, i am cloning the GitHub repo and using my action called krishnaduttPanchagnula/parlayaction@main on cyclonedx.json.</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token key atrule">on</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain">push</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">jobs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">custom_test</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">runs-on</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ubuntu</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">latest  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> We test it locally with act  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">steps</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Checkout git branch  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">uses</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> actions/checkout@v1  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Run Parlay locally and get result  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">uses</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> krishnaduttPanchagnula/parlayaction@main  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">id</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> parlay  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">with</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">input_file_name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ./cyclonedx.json  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">enricher</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ecosystems  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token key atrule">output_file_name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> enriched_cyclonedx.json</span><br></div></code></pre></div></div>
<p>Once the pipeline runs, this should give output in the std-out in pipeline console as follows.</p>
<p>Parlay Github action Output</p>
<p>Publish it in GitHub action Marketplace</p>
<p>Once we have tested the action and that is running fine, we are going to publish it GitHub actions market place. TO do so, our custom app should have globally unique name. To make it more unique we can add icon with our custom <a href="https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#branding" target="_blank" rel="noopener noreferrer" class="">symbol and colour</a> to uniquely identify the action in marketplace.</p>
<p>Once that is done you would see the button, “Draft a Release”. Ensure that your action.yml file has Name, description, Icon and color.</p>
<p>Once you have tick marks, you would be guided to release page where you can mention the title and version of the release. After that, click on “publish release” and you should be able to see your action in GitHub Actions marketplace.</p>
<p>Liked my content ? Feel free to reach out to my <a href="https://www.linkedin.com/in/krishnadutt/" target="_blank" rel="noopener noreferrer" class="">LinkedIn</a> for interesting content and productive discussions.</p>]]></content:encoded>
            <category>Python</category>
            <category>Diagrams as Code</category>
            <category>CI/CD</category>
            <category>Github</category>
            <category>Devops</category>
            <category>Security</category>
            <category>AWS</category>
            <category>Cloud</category>
            <category>IAC</category>
            <category>Infrastructure</category>
        </item>
        <item>
            <title><![CDATA[Secure your data and internet traffic with your Personalized VPN in AWS]]></title>
            <link>https://krishnaduttpanchagnula.github.io/posts/personalized-vpn-in-aws</link>
            <guid>https://krishnaduttpanchagnula.github.io/posts/personalized-vpn-in-aws</guid>
            <pubDate>Fri, 12 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Introduction]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="introduction">Introduction<a href="https://krishnaduttpanchagnula.github.io/posts/personalized-vpn-in-aws#introduction" class="hash-link" aria-label="Direct link to Introduction" title="Direct link to Introduction" translate="no">​</a></h2>
<p>In today’s era, the internet has become embedded into the very fabric of our lives. It has revolutionized the way we communicate, work, shop, and entertain ourselves. With the increasing amount of personal information that we share online, data security has become a major concern. Cyber-criminals are constantly on the lookout for sensitive data such as credit card information, social security numbers, and login credentials to use it for identity theft, fraud, or other malicious activities.</p>
<p>Moreover, governments and companies also collect large amounts of data on individuals, including browsing history, location, and personal preferences, to model the behavior of the users using deep-learning clustering models. This data can be used to coerce users psychologically to buy their products or form an opinion that they want us to form.</p>
<p>To overcome this issue, we can use a VPN which can be used to mask the user’s identity and route our traffic through a remote server. In addition, we can bypass internet censorship and access content that may be restricted in our region, which enables us to access our freedom to consume the data we want rather than what the governments/legal entities want us to consume. The VPNs we will discuss are of two types: Public VPNs such as Nord VPN, Proton VPN, etc., and private VPNs. Let’s try to understand the differences amongst them.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="private-vs-public-vpn">Private vs Public VPN<a href="https://krishnaduttpanchagnula.github.io/posts/personalized-vpn-in-aws#private-vs-public-vpn" class="hash-link" aria-label="Direct link to Private vs Public VPN" title="Direct link to Private vs Public VPN" translate="no">​</a></h2>
<p>Public VPNs are VPN services that are available to the general public for a fee or for free. These services typically have servers located all around the world, and users can connect to any of these servers to access the internet.</p>
<p>Private VPNs, on the other hand, are VPNs that are created and managed by individuals or organizations for their own use. Private VPNs are typically used by businesses to allow remote employees to securely access company resources, or by individuals to protect their online privacy and security.</p>
<p>Not all VPNs are created equal, and there are risks associated with using public VPN services over private VPN as follows:</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="risks-of-using-private-vpns">Risks of Using Private VPNs<a href="https://krishnaduttpanchagnula.github.io/posts/personalized-vpn-in-aws#risks-of-using-private-vpns" class="hash-link" aria-label="Direct link to Risks of Using Private VPNs" title="Direct link to Risks of Using Private VPNs" translate="no">​</a></h2>
<ol>
<li class="">Trustworthiness of the VPN Provider</li>
</ol>
<p>When using a private VPN, you are essentially entrusting your online security to the VPN provider. If the provider is untrustworthy or has a history of privacy breaches, your data could be compromised. Unfortunately, many private VPN providers have been caught logging user data or even selling it to third-party companies for profit.</p>
<ol start="2">
<li class="">Potential for Malware or Adware</li>
</ol>
<p>Some private VPNs have been found to include malware or adware in their software. This can be particularly dangerous, as malware can be used to steal sensitive information, while adware can slow down your computer and make browsing the web more difficult.</p>
<ol start="3">
<li class="">Unreliable Security of your Data</li>
</ol>
<p>Private VPNs may not always provide reliable security. As the service is managed by the third-party service, it is difficult to understand how their system is working behind the closed doors. There may be logging data which can be easily used to identify the user, which would straight away remove the idea of anonymity of use.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="benefits-of-creating-your-own-personal-vpn">Benefits of Creating Your Own Personal VPN<a href="https://krishnaduttpanchagnula.github.io/posts/personalized-vpn-in-aws#benefits-of-creating-your-own-personal-vpn" class="hash-link" aria-label="Direct link to Benefits of Creating Your Own Personal VPN" title="Direct link to Benefits of Creating Your Own Personal VPN" translate="no">​</a></h2>
<ol>
<li class="">Complete Control Over Your Online Security</li>
</ol>
<p>By creating your own personal VPN, you have complete control over your online security. You can choose the encryption protocol, server locations, and other security features, ensuring that your data is protected to the fullest extent possible.</p>
<ol start="2">
<li class="">No Third-Party Involvement</li>
</ol>
<p>When using a private VPN provider, you are relying on a third-party to protect your online security. By creating your own personal VPN, you eliminate this risk entirely, as there are no third parties involved in your online security.</p>
<ol start="3">
<li class="">Cost-Effective</li>
</ol>
<p>While some private VPN providers charge high monthly fees for their services, creating your own personal VPN can be a cost-effective solution. By using open-source software and free server software, you can create a VPN that is just as secure as a private VPN provider, but without worrying about your browsing history privacy or the excessive costs.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="setting-up-openvpn-in-aws">Setting up OpenVPN in AWS<a href="https://krishnaduttpanchagnula.github.io/posts/personalized-vpn-in-aws#setting-up-openvpn-in-aws" class="hash-link" aria-label="Direct link to Setting up OpenVPN in AWS" title="Direct link to Setting up OpenVPN in AWS" translate="no">​</a></h2>
<p><a href="https://openvpn.net/" target="_blank" rel="noopener noreferrer" class="">OpenVPN</a> is an open-source project that can be used to create your custom VPN using their community edition and setting things up on your VPN server. Once the VPN server is set up, we use the Open-VPN client to connect to our VPN server and tunnel our traffic through the instance. For setting up the Open-VPN server, we are going to need the following things:</p>
<ol>
<li class="">An AWS account</li>
<li class="">A little bit of curiosity..!</li>
</ol>
<p>We are going to set up the VPN server in an AWS EC2 instance, which would be used to connect with our Open-VPN client on all our devices.The Open-VPN company also provides a <a href="https://openvpn.net/index.php/access-server/on-amazon-cloud.html" target="_blank" rel="noopener noreferrer" class="">purpose-built OpenVPN Access Server as an EC2 AMI</a> which comes out of the box with AWS-friendly integration , which we are going to use in this blog.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="setup-open-vpn-server-in-aws">Setup Open-VPN server in AWS:<a href="https://krishnaduttpanchagnula.github.io/posts/personalized-vpn-in-aws#setup-open-vpn-server-in-aws" class="hash-link" aria-label="Direct link to Setup Open-VPN server in AWS:" title="Direct link to Setup Open-VPN server in AWS:" translate="no">​</a></h2>
<ol>
<li class="">
<p>Once you have setup the AWS, login to your AWS account and search for EC2.</p>
</li>
<li class="">
<p>Once you are in the AWS EC2 console, switch to the region you want you VPN to be in and then click “Launch instances” button on the right side of the screen.</p>
</li>
<li class="">
<p>In the Ec2 creation console, search for AMI named “openvpn”. You will see a lot of AMI images. Based on the number of VPN connections you require, select the AMI. For the Current demonstration, I am choosing AMI which serves two VPN connection.</p>
</li>
<li class="">
<p>Choosing the above VPN, sets the Security group by itself. Ensure that the Ec2 is publicly accessible ( Either with EIP or setting Ec2 in public-subset). Once done press “Launch Instance”.</p>
</li>
<li class="">
<p>When we connect to the Ec2 instance, we are greeted with the OpenVPN server agreement. Create the settings as shown below and at the end, create an password.</p>
</li>
<li class="">
<p>Once done, open https://<ec-2-instance-ip>:943/admin’ where you would see an login page. Enter your user name and login that you have set in the VPN server, which in my case, username is openvpn and enter your previously set password.</ec-2-instance-ip></p>
</li>
<li class="">
<p>You would enter the openVPN settings page. In configuration&gt;Vpn settings, scroll to the bottom and toggle “Have clients use specific DNS servers” to ON. In the primary DNS enter 1.1.1.1 and in secondary dns enter 8.8.8.8. After this, click save changes on the bottom of the screen.</p>
</li>
<li class="">
<p>If you scroll to the top you will see a banner with “Update Running Server”, click on it.</p>
</li>
<li class="">
<p>You are set on the Open-VPN server side !</p>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="connecting-to-open-vpn-server-from-our-device">Connecting to Open-VPN server from our device:<a href="https://krishnaduttpanchagnula.github.io/posts/personalized-vpn-in-aws#connecting-to-open-vpn-server-from-our-device" class="hash-link" aria-label="Direct link to Connecting to Open-VPN server from our device:" title="Direct link to Connecting to Open-VPN server from our device:" translate="no">​</a></h2>
<ol>
<li class="">Once the server is configured, we would require client to connect to out openVPN server. For that purpose we need to install “Open-VPN connect”</li>
</ol>
<ul>
<li class=""><strong>For Windows</strong> : Download and install the open-VPN connect from <a href="https://openvpn.net/client-connect-vpn-for-windows/" target="_blank" rel="noopener noreferrer" class="">here</a></li>
<li class=""><strong>For Mobile</strong> : Search for “openvpn connect” in the play-store (for Android) and in app-store(for apple)</li>
<li class=""><strong>For Linux</strong>:</li>
</ul>
<p>First ensure that your apt supports the HTTPS transport:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">apt install apt-transport-https</span><br></div></code></pre></div></div>
<p>Install the Open-VPN repository key used by the OpenVPN 3 Linux packages</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">curl -fsSL &lt;https://swupdate.openvpn.net/repos/openvpn-repo-pkg-key.pub&gt; | gpg --dearmor &gt; /etc/apt/trusted.gpg.d/openvpn-repo-pkg-keyring.gpg</span><br></div></code></pre></div></div>
<p>Then you need to install the proper repository. Replace $DISTRO with the release name depending on your Debian/Ubuntu distribution. For distro list, refer <a href="https://www.notion.so/Secure-your-data-and-internet-traffic-with-your-Personalized-VPN-in-AWS-3f5e619598664880bfe2b496eef98741" target="_blank" rel="noopener noreferrer" class="">here</a></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">curl -fsSL &lt;https://swupdate.openvpn.net/community/openvpn3/repos/openvpn3-$DISTRO.list&gt; &gt;/etc/apt/sources.list.d/openvpn3.list </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">apt update </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">apt install openvpn3</span><br></div></code></pre></div></div>
<ol>
<li class="">
<p>Once installed open “Open-VPN connect“ , we should see the something like below.</p>
</li>
<li class="">
<p>In the URL form, enter the IP of your EC2 instance and click NEXT. Accept the certificate pop-ups you would get during this process.</p>
</li>
<li class="">
<p>In the user name form, enter the username that you have set in the server and same for the password. Then click IMPORT.</p>
</li>
<li class="">
<p>Once imported, click on the radio button and enter your credentials again.</p>
</li>
<li class="">
<p>Once connected you should see the screen link this. Voila ! enjoy using your private VPN in EC2.</p>
</li>
</ol>
<p>Liked my content ? Feel free to reach out to my <a href="https://www.linkedin.com/in/krishnadutt/" target="_blank" rel="noopener noreferrer" class="">LinkedIn</a> for interesting content and productive discussions.</p>]]></content:encoded>
            <category>Monitoring</category>
            <category>Observability</category>
            <category>Serverless</category>
            <category>Lambda</category>
            <category>SNS</category>
            <category>AWS</category>
            <category>Cloud</category>
            <category>Terraform</category>
            <category>VPN</category>
            <category>Security</category>
            <category>OpenVPN</category>
        </item>
        <item>
            <title><![CDATA[Deploy and Run Hashicorp Vault With TLS Security in AWS Cloud]]></title>
            <link>https://krishnaduttpanchagnula.github.io/posts/post-standard</link>
            <guid>https://krishnaduttpanchagnula.github.io/posts/post-standard</guid>
            <pubDate>Fri, 12 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Often in software engineering, when we are developing new features, it is quite a common feature that we would encode certain sensitive information, such as passwords, secret keys, or tokens, for our code to do its intended functionality. Different professionals within the IT realm use it in different ways, such as the following:]]></description>
            <content:encoded><![CDATA[<p>Often in software engineering, when we are developing new features, it is quite a common feature that we would encode certain sensitive information, such as passwords, secret keys, or tokens, for our code to do its intended functionality. Different professionals within the IT realm use it in different ways, such as the following:</p>
<ul>
<li class="">Developers use secrets from API tokens, Database credentials, or other sensitive information within the code.</li>
<li class="">Dev-ops engineers might have to export certain values as environment variables and write the values in the YAML file for CI/CD pipeline to run efficiently.</li>
<li class="">The cloud engineers might have to pass the credentials, secret tokens, and other secret information for them to access their respective cloud (In the case of AWS, even if we save these in a <code>.credentials</code> file, we still have to pass the filename in terraform block, which would indicate that the credentials are available locally within the computer.)</li>
<li class="">The system administrators might have to send different logins and passwords to the people for the employees to access different services</li>
</ul>
<p>But writing it in plain text or sharing it in plain text is quite a security problem, as anyone logging in to the code-base might access the secret or pull up a Man-in-the-Middle attack. To counter this, in the developing world, we have different options like Importing secrets from another file ( YAML, .py, etc.) or exporting them as an environment variable. But both of these still have a problem: a person having access to a singular config file or the machine can echo out the password ( read print). Given these problems, it would be very useful if we could deploy a single solution that would provide solutions to all the IT professionals mentioned above and more. This is the ideal place for introducing Vault.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="hashicorp-vault--an-introduction">HashiCorp Vault — an Introduction<a href="https://krishnaduttpanchagnula.github.io/posts/post-standard#hashicorp-vault--an-introduction" class="hash-link" aria-label="Direct link to HashiCorp Vault — an Introduction" title="Direct link to HashiCorp Vault — an Introduction" translate="no">​</a></h2>
<p>HashiCorp Vault is a secrets and encryption management system based on user identity. If we have to compare it with AWS, it is like an IAM user-based resource (read Vault here) management system which secures your sensitive information. This sensitive information can be API encryption keys, passwords, and certificates.</p>
<p>Its workflow can be visualized as follows:</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="hosting-cost-of-vault">Hosting Cost of Vault<a href="https://krishnaduttpanchagnula.github.io/posts/post-standard#hosting-cost-of-vault" class="hash-link" aria-label="Direct link to Hosting Cost of Vault" title="Direct link to Hosting Cost of Vault" translate="no">​</a></h2>
<ul>
<li class="">Local hosting: This method is usually done if the secrets are to be accessed only by the local users or during the development phase. This method has to be shunned if these secret engines have to be shared with other people. As it is within the local development environment, there is no additional investment for deployment. This can be hosted directly in <a href="https://www.vaultproject.io/downloads" target="_blank" rel="noopener noreferrer" class="">a local machine</a> or by its <a href="https://hub.docker.com/_/vault/" target="_blank" rel="noopener noreferrer" class="">official docker image</a></li>
<li class="">Public Cloud Hosting ( EC2 in AWS/Virtual Machine in Azure): If the idea is to set up Vault to share with people across different regions, hosting it on Public cloud is a good idea. Although we can achieve the same with the on-prem servers, upfront costs and scalability is quite a hassle. In the case of AWS, we can easily secure the endpoint by hosting Vault in the EC2 instance and creating a Security group on which IPs can access the EC2. If you feel more adventurous, you can map this to a domain name and route from Route 53 so the vault is accessible on a domain as a service to the end users. In the case of EC2 hosting with an AWS-defined domain, the cost is $0.0116/hr.</li>
<li class="">Vault cloud Hosting (HashiCorp Cloud Platform): If you don’t want to set up infrastructure in the Public Cloud Environments, there is an option of choosing the cloud hosted by vault. We can think of it as a SaaS-based cloud platform that enables us to use the Vault as a service on a subscription basis. Since hashicorp itself manages the cloud, we can expect a consistent user experience. For the cost, it has three production grade <a href="https://cloud.hashicorp.com/products/vault/pricing" target="_blank" rel="noopener noreferrer" class="">options</a>: Starter at $ 0.50/hr, Standard at $1.58/hr, and Plus at $1.84/hr (as seen in July 2022).</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="example-of-self-hosting-in-aws-cloud">Example of Self-Hosting in AWS Cloud<a href="https://krishnaduttpanchagnula.github.io/posts/post-standard#example-of-self-hosting-in-aws-cloud" class="hash-link" aria-label="Direct link to Example of Self-Hosting in AWS Cloud" title="Direct link to Example of Self-Hosting in AWS Cloud" translate="no">​</a></h2>
<p>Our goal in this Project is to create a Vault instance in EC2 and store static secrets in the Key—Value secrets engine. These secrets are later retrieved into the terraform script, which, when applied, would pull the secrets from the Vault Secrets Engine and use them to create infrastructure in AWS.</p>
<p>To create a ready-to-use Vault, we are going to follow these steps:</p>
<ol>
<li class="">Create an EC2 Linux instance with ssh keys to access it.</li>
<li class="">SSH into the instance and install the Vault to get it up and running</li>
<li class="">Configure the Valve Secrets Manager</li>
</ol>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-1-create-an-ec2-linux-instance-with-ssh-keys-to-access-it">Step 1: Create an EC2 Linux instance with ssh keys to access it<a href="https://krishnaduttpanchagnula.github.io/posts/post-standard#step-1-create-an-ec2-linux-instance-with-ssh-keys-to-access-it" class="hash-link" aria-label="Direct link to Step 1: Create an EC2 Linux instance with ssh keys to access it" title="Direct link to Step 1: Create an EC2 Linux instance with ssh keys to access it" translate="no">​</a></h3>
<p>To create an EC2 instance and access it remotely via SSH, we need to create the Key pair. First, let's create an SSH key via the AWS console.</p>
<p>Once the Keys have been created and downloaded into the local workbench, we create an EC2 (t2.micro) Linux instance and associate it with the above keys. The size of the EC2 can be selected based on your requirements, but usually, a t2.micro is more than enough.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-2-ssh-into-the-instance-and-install-the-secrets-to-get-it-up-and-running">Step 2: SSH into the instance and install the secrets to get it up and running<a href="https://krishnaduttpanchagnula.github.io/posts/post-standard#step-2-ssh-into-the-instance-and-install-the-secrets-to-get-it-up-and-running" class="hash-link" aria-label="Direct link to Step 2: SSH into the instance and install the secrets to get it up and running" title="Direct link to Step 2: SSH into the instance and install the secrets to get it up and running" translate="no">​</a></h3>
<p>Once the status of the EC2 changes to running, open the directory in which you have saved the SSH(.pem) key. Open a terminal and type <code>ssh -i &lt;keyname.pem&gt; ec2-user @&lt;publicdns IP4&gt;</code> . Once we have established a successful SSH session into our Ec2 instance, we can install the Vault using the following commands:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">wget -O- &lt;https://apt.releases.hashicorp.com/gpg&gt; | gpg — dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">echo "deb \[signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg\] &lt;https://apt.releases.hashicorp.com&gt; $(lsb\release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">sudo apt update &amp;&amp; sudo apt install vault</span><br></div></code></pre></div></div>
<p>The above command would install the vault in the EC2 environment. Sometimes the second command is known to throw some errors. In case of an error, replace <code>$(lsb_release -cs)</code> with “<code>jammy</code>”. [This entire process can be automated by copying the above commands to EC2 user data while creating an EC2 instance].</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-3-configure-the-hashicorp-valve">Step 3: Configure the Hashicorp valve<a href="https://krishnaduttpanchagnula.github.io/posts/post-standard#step-3-configure-the-hashicorp-valve" class="hash-link" aria-label="Direct link to Step 3: Configure the Hashicorp valve" title="Direct link to Step 3: Configure the Hashicorp valve" translate="no">​</a></h3>
<p>Before initializing the vault, let's ensure it is properly installed by following the command:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">vault</span><br></div></code></pre></div></div>
<p>Let's make sure there is no environment variable called <code>VAULT_TOKEN</code>. To do this, use the following command:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">$ unset VAULT_TOKEN</span><br></div></code></pre></div></div>
<p>Once we have installed the Vault, we need to configure the Vault, which is done using HCL files. These HCL files contain data such as backed, listeners, cluster address, UI settings, etc. As we have discussed in the Vault’s Architecture, the back end on which the data is stored is very different from the vault engine, which is to be persisted even when the vault is locked (Stateful resource). In addition to that, we need to specify the following details:</p>
<ul>
<li class="">Listener Ports: the port/s on which the Vault listens for API requests.</li>
<li class="">API address: Specifies the address to advertise to route client requests.</li>
<li class="">Cluster address: Indicates the address and port to be used for communication between the Vault nodes in a cluster. To secure it much further, we can use TLS-based communication. This step is optional and can only be tried if you want to secure your environment further. The TLS Certificate can be generated using openssl in Linux.</li>
</ul>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain"># Installs openssl  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">sudo apt install openssl  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">#Generates TLS Certificate and Private Key  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">openssl req -newkey rsa:4096 -x509 -sha512 -days 365 -nodes -out certificate.pem -keyout privatekey.pem </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></div></code></pre></div></div>
<p>Insert the TLS Certificate and Private Key file paths in their respective arguments in the listener “tcp” block.</p>
<ul>
<li class=""><code>tls_cert_file</code>: Specifies the path to the certificate for TLS in PEM encoded file format.</li>
<li class=""><code>tls_key_file</code>: Specifies the path to the private key for the certificate in PEM-encoded file format.</li>
</ul>
<div class="language-hcl codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-hcl codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">#Configuration in config.hcl file  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">storage "raft" {   </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">path = "./vault/data"   </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">node\id = "node1"   </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">}  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">listener "tcp" {  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> address = "127.0.0.1:8200"   </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">tls\disable = "true"  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">tls\cert\file = certificate.pem  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">tls\key\file = privatekey.pem  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">}  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">disable\mlock = true  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">api_addr = "http://127.0.0.1:8200"   </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">cluster_addr = "https://127.0.0.1:8201"  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"> ui = true</span><br></div></code></pre></div></div>
<p>Once these are created, we create the folder where our backend will rest: vault/data.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">mkdir -p ./vault/data</span><br></div></code></pre></div></div>
<p>Once done, we can start the vault server using the following command:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">vault server -config=config.hcl</span><br></div></code></pre></div></div>
<p>Once done, we can start our Vault instance with the backend mentioned in the config file and all its settings.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">export VAULT_ADDR='http://127.0.0.1:8200'  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">vault operator init</span><br></div></code></pre></div></div>
<p>After it is initialized, it creates five Unseal keys called shamir keys (out of which three are used to unseal the Vault by default settings) and an Initial root token. This is the only time ever that all of this data is known by Vault, and these details are to be saved securely to unseal the vault. In reality, these shamir keys are to be distributed among key stakeholders in the project, and the Key threshold should be set in such a fashion that Vault can be unsealed when the majority are in consensus to do so.</p>
<p>Once we have created these Keys and the initial token, we need to unseal the vault:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">vault operator unseal</span><br></div></code></pre></div></div>
<p>Here we need to supply the threshold number of keys to unseal. Once we supply that, the sealed status changes to false.</p>
<p>Then we log in to the Vault using the Initial root token.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">vault login</span><br></div></code></pre></div></div>
<p>Once authenticated successfully, you can easily explore different encryption engines, such as Transit secrets Engine. This helps encrypt the data in transit, such as the Key-Value Store, which is used to securely store Key-value pairs such as passwords, credentials, etc.</p>
<p>As seen from the process, Vault is pretty robust in terms of encryption, and as long as the shamir keys and initial token are handled in a sensitive way, we can ensure the security and integrity</p>
<p>And you have a pretty secure Vault engine (protected by its own shamir keys) running on a free AWS EC2 instance (which is, in turn, guarded by the security groups)!</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">**Want to Connect?**  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">If you want to connect with me, you can do so on [LinkedIn](https://www.linkedin.com/in/krishnadutt/).</span><br></div></code></pre></div></div>]]></content:encoded>
            <category>Hashicorp Vault</category>
            <category>Agile</category>
            <category>Security</category>
            <category>Hashicorp</category>
        </item>
        <item>
            <title><![CDATA[Pushing Digital Transformation boundaries beyond Technology : A Radical Perspective]]></title>
            <link>https://krishnaduttpanchagnula.github.io/posts/pushing-digital-transformation</link>
            <guid>https://krishnaduttpanchagnula.github.io/posts/pushing-digital-transformation</guid>
            <pubDate>Fri, 12 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Digital transformation is a radical re-imagination of how an organization utilizes bleeding-edge technologies to fundamentally change their business models and performance. Implementing technology in both processes and products is key to digital transformation, as it is not just about implementing new technologies, but about fundamentally changing the way an organization functions.]]></description>
            <content:encoded><![CDATA[<p>Digital transformation is a radical re-imagination of how an organization utilizes bleeding-edge technologies to fundamentally change their business models and performance. Implementing technology in both processes and products is key to digital transformation, as it is not just about implementing new technologies, but about fundamentally changing the way an organization functions.</p>
<p>Digital transformation is both digital and cultural. On the digital side, it involves the implementation of new technologies and the optimization of processes and systems to take advantage of those technologies. This can include things like cloud computing, data analytics, automation, and other cutting-edge technologies.</p>
<p>However, digital transformation is not just about the technology. It also involves a cultural shift within the organization. This includes things like customer-centricity, agility, continuous learning, unbounded collaboration, and an appetite for risk. These cultural changes are necessary to enable the organization to stay competitive in an increasingly digital world.</p>
<p>Current Digital transformation is based on Digital — implementing new technologies but not on transformation — which is about how we function as individuals in a social setting. Lots of companies are implementing these cool ideas of DEVOPS while there is no change fundamentally in how they work/function.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-should-we-care-about-digital-transformation">Why should we care about Digital Transformation:<a href="https://krishnaduttpanchagnula.github.io/posts/pushing-digital-transformation#why-should-we-care-about-digital-transformation" class="hash-link" aria-label="Direct link to Why should we care about Digital Transformation:" title="Direct link to Why should we care about Digital Transformation:" translate="no">​</a></h2>
<p>As technology advances, it is essential to change the way we live, work, and do business. Organizations that fail to adapt to these changes will struggle to stay competitive and may eventually be left behind.</p>
<blockquote>
<p>Digital transformation is not just about implementing new technologies, but about fundamentally changing the way an organization functions.</p>
</blockquote>
<p>This includes optimizing processes, products, systems, and organizational structure to take advantage of the latest technologies. By embracing digital transformation, organizations can improve their business performance, reduce costs, and increase efficiency.</p>
<p>Digital transformation can also help organizations improve their customer experience. By using technology to collect and analyze data, organizations can better understand their customers and provide personalized, relevant products and services. This can lead to increased customer satisfaction and loyalty.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="characteristics-for-digital-transformation-culture">Characteristics for Digital transformation culture:<a href="https://krishnaduttpanchagnula.github.io/posts/pushing-digital-transformation#characteristics-for-digital-transformation-culture" class="hash-link" aria-label="Direct link to Characteristics for Digital transformation culture:" title="Direct link to Characteristics for Digital transformation culture:" translate="no">​</a></h2>
<ol>
<li class=""><strong>Customer - Centricity:</strong> In the past, organizations would implement the same transformation strategies for all of their customers. However, this one-size-fits-all approach is no longer effective. Today’s organizations must consider each customer’s unique vision and goals, and create personalized transformation strategies that align with those goals.</li>
<li class=""><strong>Agility</strong>: In a rapidly-changing world, organizations must be able to pivot quickly and adapt to new situations. Hierarchical structures, while useful for reliability, can be a hindrance to agility. As such, many organizations are adopting agile methodologies and flattening their hierarchies to enable faster decision-making and response times.</li>
<li class=""><strong>Continuous learning</strong> : As technology and the world around us change rapidly, organizations must be able to adapt and learn new skills and knowledge. This requires a culture of curiosity and a willingness to try new things. Organizations are hiring and working with individuals who are open to new ideas and ready to build new products and services.</li>
<li class=""><strong>Unbounded collaboration</strong>: In the past, teams within organizations would often work in silos, with limited communication and collaboration across teams. Today, organizations are fostering cultures that encourage and incentivize cross-team collaboration. This cross-functional knowledge sharing leads to more innovation and better results.</li>
<li class=""><strong>Appetite for risk</strong>: Many of the most exciting innovations are created at the edge of what is currently known. This requires organizations to venture into unknown territories, which can be risky. However, by fostering a culture of intelligent failure (failures that occur when trying to do new things) and minimizing preventable failures (failures due to sloppy work), organizations can improve their appetite for risk and drive innovation.</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="actions-to-imbibe-cultural-change-towards-digital-transformation">Actions to imbibe cultural change towards digital transformation:<a href="https://krishnaduttpanchagnula.github.io/posts/pushing-digital-transformation#actions-to-imbibe-cultural-change-towards-digital-transformation" class="hash-link" aria-label="Direct link to Actions to imbibe cultural change towards digital transformation:" title="Direct link to Actions to imbibe cultural change towards digital transformation:" translate="no">​</a></h2>
<ol>
<li class=""><strong>Communicate the importance and benefits of digital transformation</strong>: Employees may be resistant to change, especially if they do not understand why it is necessary. By communicating the importance and benefits of digital transformation, organizations can help employees understand why it is necessary and how it will benefit the organization and its customers.</li>
<li class=""><strong>Encourage and reward experimentation</strong>: Digital transformation requires a culture of continuous learning and experimentation. Organizations should encourage employees to try new things and should reward them for their efforts, even if those efforts don’t always lead to success.</li>
<li class=""><strong>Foster collaboration and knowledge sharing</strong>: Digital transformation often involves cross-functional collaboration and the sharing of knowledge and expertise across teams. Organizations should foster a culture that encourages and incentivizes collaboration and knowledge sharing.</li>
<li class=""><strong>Provide training and support</strong>: Digital transformation can be a daunting process, especially for employees who are not familiar with the latest technologies. Organizations should provide training and support to help employees learn new skills and adapt to the changes brought about by digital transformation.</li>
<li class=""><strong>Create a positive, inclusive culture:</strong> Digital transformation can be stressful and disruptive, especially for employees who may feel threatened by the changes it brings. Organizations should strive to create a positive, inclusive culture that supports and empowers employees during the transformation process.</li>
</ol>
<p>The future of digital transformation is uncertain, but it is likely that technology will continue to advance and play an increasingly important role in our lives and in business. Organizations must continue to embrace digital transformation in order to stay competitive and adapt to the changing digital landscape. By taking steps to improve the social culture around digital transformation, organizations can make it easier for employees to adapt to the changes brought about by digital transformation.</p>]]></content:encoded>
            <category>Digital Transformation</category>
            <category>Agile</category>
            <category>Devops</category>
            <category>Technology</category>
        </item>
        <item>
            <title><![CDATA[Developing Real-time resource monitoring via email on AWS using Terraform]]></title>
            <link>https://krishnaduttpanchagnula.github.io/posts/real-time-resource-monitoring</link>
            <guid>https://krishnaduttpanchagnula.github.io/posts/real-time-resource-monitoring</guid>
            <pubDate>Fri, 12 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[One of the main tasks as an SRE engineer is to maintain the infrastructure that is developed for the deployment of the application. As each of the service exposes the logs in different way, we need plethora of sns and lambdas to monitor the infrastructure. This increases the cost of monitoring, which would compel management to drop this monitoring system.]]></description>
            <content:encoded><![CDATA[<p>One of the main tasks as an SRE engineer is to maintain the infrastructure that is developed for the deployment of the application. As each of the service exposes the logs in different way, we need plethora of sns and lambdas to monitor the infrastructure. This increases the cost of monitoring, which would compel management to drop this monitoring system.</p>
<p>But what if i say that, we can develop this monitoring system for less than 24 cents ? And what if i say that you can deploy this entire monitoring system with just a single command “Terraform apply”? Sounds like something that you would like to know? Hop on the Terraform ride !</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="key-components-to-build-the-infrastructure">Key components to build the infrastructure<a href="https://krishnaduttpanchagnula.github.io/posts/real-time-resource-monitoring#key-components-to-build-the-infrastructure" class="hash-link" aria-label="Direct link to Key components to build the infrastructure" title="Direct link to Key components to build the infrastructure" translate="no">​</a></h2>
<p>In order to create an monitoring system to send email alerts, we need 3 components:</p>
<ol>
<li class="">Event Bridge</li>
<li class="">SNS</li>
<li class="">Email subscription</li>
</ol>
<p>We can build a rudimentary monitoring system, by combining all these components. But the logs we get as email, would be as following:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">"version"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"1.0"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">"timestamp"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"2022-02-01T12:58:45.181Z"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">"requestContext"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">"requestId"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"a4ac706f-1aea-4b1d-a6d2-5e6bb58c4f3e"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">"functionArn"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"arn:aws:lambda:ap-south-1:498830417177:function:gggg:$LATEST"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">"condition"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Success"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">"approximateInvokeCount"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token number">1</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">"requestPayload"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">"Records"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token property">"eventVersion"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"2.1"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token property">"eventSource"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"aws:s3"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token property">"awsRegion"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ap-south-1"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token property">"eventTime"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"2022-02-01T12:58:43.330Z"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token property">"eventName"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ObjectCreated:Put"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token property">"userIdentity"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token property">"principalId"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"A341B33DQLH0UH"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token property">"requestParameters"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token property">"sourceIPAddress"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"43.241.67.169"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token property">"responseElements"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token property">"x-amz-request-id"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"GX86AGXCNXB5ZYVQ"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token property">"x-amz-id-2"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"CPVpR8MNcPsNBzxcF8nOFqXbAIU60/zQlNC6njLp+wNFtC/ZnZF0SFhfMuhLOSpEqMFvvPqLA+tyvaXJSYMXAByR5EuDM0VF"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token property">"s3"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token property">"s3SchemaVersion"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"1.0"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token property">"configurationId"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"09dae0eb-9352-4d8a-964f-1026c76a5dcc"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token property">"bucket"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token property">"name"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"sddsdsbbb"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token property">"ownerIdentity"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token property">"principalId"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"A341B33DQLH0UH"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token property">"arn"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"arn:aws:s3:::sddsdsbbb"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token property">"object"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token property">"key"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"[variables.tf]"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token property">"size"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token number">402</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token property">"eTag"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"09ba37f25be43729dc12f2b01a32b8e8"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token property">"sequencer"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"0061F92E834A4ECD4B"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">"responseContext"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">"statusCode"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token number">200</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">"executedVersion"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"$LATEST"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">"responsePayload"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"binary/octet-stream"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></div></code></pre></div></div>
<p>Not so easy to read right ? What if we can improve it, making it legible for anyone to understand what is happening?</p>
<p>To make it easy to read, we use the feature in the Event bridge called <strong>input transformer</strong> and <strong>input template</strong>. This feature helps us in transforming the log in our desired format <strong>without</strong> using any <strong>lambda function.</strong></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="infrastructure-working">Infrastructure Working<a href="https://krishnaduttpanchagnula.github.io/posts/real-time-resource-monitoring#infrastructure-working" class="hash-link" aria-label="Direct link to Infrastructure Working" title="Direct link to Infrastructure Working" translate="no">​</a></h2>
<p>The way our infrastructure works is as follows:</p>
<ol>
<li class="">
<p>Our event bridge will collect all the logs from all the events from the AWS account, using event filter.</p>
</li>
<li class="">
<p>Once collected, these are sent to input transformer to parse and read our desired components.</p>
</li>
<li class="">
<p>After this, we use this parsed data to create our desired format using input template.</p>
</li>
</ol>
<p>Input transformer and input templete for event bridge rule</p>
<ol start="4">
<li class="">
<p>This transformed data is published to the SNS that we have created.</p>
</li>
<li class="">
<p>We create a subscription for this SNS, via email,SMS or HTTP.</p>
</li>
</ol>
<p>And Voila ! you have your infrastructure ready to update the changes…!</p>
<p>Here is the entire terraform code:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">terraform </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  required_providers </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    aws </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      source  </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"hashicorp/aws"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      version </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"~&gt; 3.0"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain">\# Configure the AWS Provider  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">provider </span><span class="token string" style="color:rgb(255, 121, 198)">"aws"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  region </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ap-south-1"</span><span class="token plain"> #insert your region code  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain">resource </span><span class="token string" style="color:rgb(255, 121, 198)">"aws_cloudwatch_event_rule"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"eventtosns"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  name </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"eventtosns"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  event_pattern </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">jsonencode</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      account </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">var</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">account</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">#insert  your account number  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">     </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain">resource </span><span class="token string" style="color:rgb(255, 121, 198)">"aws_cloudwatch_event_target"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"eventtosns"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">\# arn of the target and rule id of the eventrule  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  arn  </span><span class="token operator">=</span><span class="token plain"> aws_sns_topic</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">eventtosns</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">arn  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  rule </span><span class="token operator">=</span><span class="token plain"> aws_cloudwatch_event_rule</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">eventtosns</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">idinput_transformer </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    input_paths </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      Source      </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"$.source"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      detail</span><span class="token operator">-</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">type</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"$.detail-type"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      resources   </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"$.resources"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      state       </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"$.detail.state"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      status      </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"$.detail.status"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    input_template </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"\\"</span><span class="token plain">Resource name </span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token operator">&lt;</span><span class="token plain">Source</span><span class="token operator">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> Action name </span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token operator">&lt;</span><span class="token plain">detail</span><span class="token operator">-</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">type</span><span class="token operator">&gt;</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      details </span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token operator">&lt;</span><span class="token plain">status</span><span class="token operator">&gt;</span><span class="token plain"> </span><span class="token operator">&lt;</span><span class="token plain">state</span><span class="token operator">&gt;</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> Arn </span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token operator">&lt;</span><span class="token plain">resources</span><span class="token operator">&gt;</span><span class="token plain">\\""  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain">resource </span><span class="token string" style="color:rgb(255, 121, 198)">"aws_sns_topic"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"eventtosns"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  name </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"eventtosns"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain">resource </span><span class="token string" style="color:rgb(255, 121, 198)">"aws_sns_topic_subscription"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"snstoemail_email-target"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  topic_arn </span><span class="token operator">=</span><span class="token plain"> aws_sns_topic</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">eventtosns</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">arn  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  protocol  </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"email"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  endpoint  </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">var</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">email  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain">\# aws_sns_topic_policy</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">eventtosns</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">resource </span><span class="token string" style="color:rgb(255, 121, 198)">"aws_sns_topic_policy"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"eventtosns"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  arn </span><span class="token operator">=</span><span class="token plain"> aws_sns_topic</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">eventtosns</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">arnpolicy </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">jsonencode</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      Id </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"default_policy_ID"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      Statement </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          Action </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token string" style="color:rgb(255, 121, 198)">"SNS:GetTopicAttributes"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token string" style="color:rgb(255, 121, 198)">"SNS:SetTopicAttributes"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token string" style="color:rgb(255, 121, 198)">"SNS:AddPermission"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token string" style="color:rgb(255, 121, 198)">"SNS:RemovePermission"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token string" style="color:rgb(255, 121, 198)">"SNS:DeleteTopic"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token string" style="color:rgb(255, 121, 198)">"SNS:Subscribe"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token string" style="color:rgb(255, 121, 198)">"SNS:ListSubscriptionsByTopic"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token string" style="color:rgb(255, 121, 198)">"SNS:Publish"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token string" style="color:rgb(255, 121, 198)">"SNS:Receive"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">         </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          condition </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            test     </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"StringEquals"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            variable </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"AWS:SourceOwner"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            values </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">              </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">var</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">account</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">           </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain">Effect </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Allow"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          Principal </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            AWS </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"\*"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          Resource </span><span class="token operator">=</span><span class="token plain"> aws_sns_topic</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">eventtosns</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">arn  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          Sid      </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"__default_statement_ID"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          Action </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"sns:Publish"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          Effect </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Allow"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          Principal </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">            Service </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"events.amazonaws.com"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          Resource </span><span class="token operator">=</span><span class="token plain"> aws_sns_topic</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">eventtosns</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">arn  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">          Sid      </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"AWSEvents_lambdaless_Idcb618e86-b782-4e67-b507-8d10aaca5f09"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">     </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      Version </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"2008-10-17"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></div></code></pre></div></div>
<p>This entire infrastructure can be deployed using <em>Terraform apply</em> on above code.</p>
<p>Liked my content ? Feel free to reach out to my <a href="https://www.linkedin.com/in/krishnadutt/" target="_blank" rel="noopener noreferrer" class="">LinkedIn</a> for interesting content and productive discussions.</p>]]></content:encoded>
            <category>Hashicorp Terraform</category>
            <category>Terrraform</category>
            <category>Monitoring</category>
            <category>Observability</category>
            <category>Hashicorp</category>
            <category>Resource Monitoring</category>
            <category>AWS</category>
            <category>Cloud</category>
            <category>IAC</category>
            <category>Infrastructure</category>
        </item>
        <item>
            <title><![CDATA[Vulnerability Identification of Images and Files using SBOM with Trivy]]></title>
            <link>https://krishnaduttpanchagnula.github.io/posts/sbom-with-trivy</link>
            <guid>https://krishnaduttpanchagnula.github.io/posts/sbom-with-trivy</guid>
            <pubDate>Fri, 12 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[As we embrace digital progress and shift to using containers for our applications, we’re dealing with a variety of core images that form the basis of our apps. These images vary based on our app’s needs, given the different ways we build them. Unfortunately, in companies with a moderate level of DEVOPS experience (maturity levels 2 to 3), the focus often leans heavily towards getting new features out quickly, sometimes overlooking security.]]></description>
            <content:encoded><![CDATA[<p>As we embrace digital progress and shift to using containers for our applications, we’re dealing with a variety of core images that form the basis of our apps. These images vary based on our app’s needs, given the different ways we build them. Unfortunately, in companies with a moderate level of DEVOPS experience (maturity levels 2 to 3), the focus often leans heavily towards getting new features out quickly, sometimes overlooking security.</p>
<p>For us developers, the challenge is keeping up with the ever-changing world of software. This includes the extra pieces they need (dependencies), the building blocks (components), and the tools (libraries) that make them work together across our whole system. All these parts combined are what we call the Software Bill of Materials (SBOM). To tackle this, we need to understand the SBOM of each image before we use it as a foundation for our apps. But doing this manually is complex and time-consuming. Plus, every time we want to update to a newer image version, we have to go through the whole process again, slowing down our ability to deliver our products.</p>
<p>The solution? Automation. By using automation, we can navigate the intricate process of understanding the SBOM. It helps us make organized lists of all the parts, find any known problems, and suggest ways to fix them — all done with tools like Trivy. Before we dive into the detailed steps, let’s make sure we’re all on the same page about what the SBOM really means.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-is-sbom">What is SBoM?<a href="https://krishnaduttpanchagnula.github.io/posts/sbom-with-trivy#what-is-sbom" class="hash-link" aria-label="Direct link to What is SBoM?" title="Direct link to What is SBoM?" translate="no">​</a></h2>
<p>SBOM stands for Software Bill of Materials. Think of it like a detailed list of all the parts that make up our software. This list includes things like tools from other people, building blocks, and even the rules that guide how they’re used, all with exact version details.</p>
<p>SBOM is important because it gives us a big picture of all the different parts that come together to create a specific software. This helps our DevSecOps teams find out if there are any possible risks, understand how they could affect us, and take steps to fix them. All of this makes our software strong and secure.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-create-sbom">Why create SBOM?<a href="https://krishnaduttpanchagnula.github.io/posts/sbom-with-trivy#why-create-sbom" class="hash-link" aria-label="Direct link to Why create SBOM?" title="Direct link to Why create SBOM?" translate="no">​</a></h2>
<ol>
<li class="">Finding and Managing Outside Parts: SBOM helps us see all the software we use from others. It shows us different versions and even points out any possible security issues. With this info, we can make smart choices about what we use, especially when it comes to libraries and tools from other sources.</li>
<li class="">Making Our Supply Chain Secure: SBOM acts like a detailed map for our software. This map helps us make sure everything is safe and guards against any tricks or attacks on our software supply chain. We can even use SBOM to check if the people we get our software from follow good security rules.</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="sbom-format">SBOM format<a href="https://krishnaduttpanchagnula.github.io/posts/sbom-with-trivy#sbom-format" class="hash-link" aria-label="Direct link to SBOM format" title="Direct link to SBOM format" translate="no">​</a></h2>
<ul>
<li class=""><a href="https://spdx.github.io/spdx-spec/" target="_blank" rel="noopener noreferrer" class="">Software Package Data Exchange (SPDX)</a>: This open standard serves as a software bill of materials (SBOM), identifying and cataloging components, licenses, copyrights, security references, and other metadata related to software. While its primary purpose is to enhance license compliance, it also contributes to software supply-chain transparency and security improvement.</li>
<li class=""><a href="https://www.iso.org/standard/65666.html" target="_blank" rel="noopener noreferrer" class="">Software Identification Tags (SWID)</a>: These tags contain descriptive details about a specific software release, including its product and version. They also specify the organizations and individuals involved in producing and distributing the product. These tags establish a product’s lifecycle, from installation on an endpoint to deletion.</li>
<li class=""><a href="https://cyclonedx.org/docs/1.2/" target="_blank" rel="noopener noreferrer" class="">CycloneDX (CDX)</a>: The CycloneDX project establishes standards in XML, JSON, and protocol buffers. It offers an array of official and community-supported tools that either generate or work with this standard. While similar to SPDX, CycloneDX is a more lightweight alternative.</li>
</ul>
<p>In addition to creating SBOM, trivy has the capability to SCAN the SBOM generated either by trivy or other tools, to identify the severity of the problem. In addition to the vulnerability detection, it also suggests the possible fixes for the identified vulnerability.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="sbom-with-trivy">SBOM with TRIVY<a href="https://krishnaduttpanchagnula.github.io/posts/sbom-with-trivy#sbom-with-trivy" class="hash-link" aria-label="Direct link to SBOM with TRIVY" title="Direct link to SBOM with TRIVY" translate="no">​</a></h2>
<p>Trivy is a comprehensive security scanner, maintained and built by aqua security team. It is reliable, fast, and has several in-built scanners to scan for has different security issues, and different targets where it can find those issues. It can be used to scan following use cases:</p>
<ul>
<li class="">OS packages and software dependencies in use (SBOM)</li>
<li class="">Known vulnerabilities (CVEs)</li>
<li class="">IaC misconfigurations</li>
<li class="">Sensitive information and secrets</li>
</ul>
<p>Today we will be focusing on the SBOM scanning capabilities of the Trivy. In this tutorial, we would doing the following :</p>
<ul>
<li class="">First, Create the SBOM using trivy</li>
<li class="">Analyze the created SBOM to scan and find the vulnerabilites</li>
</ul>
<p>For the sake of the demo we will be using one of the most used docker images, NGINX, particularly nginx:1.21.5. We would using its Docker hub image and run scanner to generate the SBOM. Once the SBOM is generated, we would use this SBOM to get the list of Vulnerabilities and possible fixes for the same.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="generating-sbom">Generating SBOM<a href="https://krishnaduttpanchagnula.github.io/posts/sbom-with-trivy#generating-sbom" class="hash-link" aria-label="Direct link to Generating SBOM" title="Direct link to Generating SBOM" translate="no">​</a></h2>
<p>To generate the SBOM, make sure the trivy is first installed in you workbench. If not you can install using commands in this <a href="https://aquasecurity.github.io/trivy/v0.33/getting-started/installation/" target="_blank" rel="noopener noreferrer" class="">link</a>. In my case , my pc is debian based, so i installed using following command</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">sudo apt-get install wget apt-transport-https gnupg lsb-release  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">wget -qO - &lt;https://aquasecurity.github.io/trivy-repo/deb/public.key&gt; | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg &gt; /dev/null  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">echo "deb \[signed-by=/usr/share/keyrings/trivy.gpg\] &lt;https://aquasecurity.github.io/trivy-repo/deb&gt; $(lsb\_release -sc) main" | sudo tee -a /etc/apt/sources.list.d/trivy.list  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">sudo apt-get update  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">sudo apt-get install trivy</span><br></div></code></pre></div></div>
<p>If you are using any flavour of debian, you might face issue with “lsb_release -sc” in the command. To overcome the issue you can use one of the following values: wheezy, jessie, stretch, buster, trusty, xenial, bionic.</p>
<p>Once installed you should see the following, when you run</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">trivy --version</span><br></div></code></pre></div></div>
<p>Once the trivy is installed, we can scan the vulnerabilities in two ways, either for image, for the whole directory containing the files or an single file.</p>
<ul>
<li class="">For a folder containing group of language specific files</li>
</ul>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">trivy fs --format cyclonedx --output result.json /path/to/your\_project</span><br></div></code></pre></div></div>
<ul>
<li class="">For a specific file</li>
</ul>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">trivy fs --format cyclonedx --output result.json ./trivy-ci-test/Pipfile.lock</span><br></div></code></pre></div></div>
<ul>
<li class="">For a container image</li>
</ul>
<div class="language-basg codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-basg codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">trivy image --format spdx-json --output result.json nginx:1.21.5</span><br></div></code></pre></div></div>
<p>Once done, the scanner will scan the files/image and determine which language is the application written. Once determined, it will download the database pertaining to that specific language and get the list of libraries that are present in that language and check against which are being used in the current context.</p>
<p>These libraries are listed down along with OS level libraries in an SBOM in the format that we have requested in.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="listing-vulnerabilities-of-sbom">Listing Vulnerabilities of SBOM<a href="https://krishnaduttpanchagnula.github.io/posts/sbom-with-trivy#listing-vulnerabilities-of-sbom" class="hash-link" aria-label="Direct link to Listing Vulnerabilities of SBOM" title="Direct link to Listing Vulnerabilities of SBOM" translate="no">​</a></h2>
<p>Once the SBOM are generated, we can create the list of known vulnerabilities of the dependencies in the image/files such as libraries, OS packages etc. In addition to identifying these, trivy also suggests the version in which these vulnerabilities are fixed, making it not an effective tool to identify the vulnerabilities but also to resolve them.</p>
<p>In order for us to generate this list, we use the following command</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">trivy sbom results.json</span><br></div></code></pre></div></div>
<p>This will generate the following list</p>
<p>As you can observe, we get the name of the library, the CVE vulnerability Number, Its Severity (HIGH,MEDIUM,LOW), The status of Vulnerability fix( fixed, not fixed or will_not fix) , if its fixed then the fixed version and along with the details on the vulnerability.</p>
<p>Based on this information ,we can upgrade the fixed vulnerable libraries, understand the vulnerability level in not fixed libraries and remove them if they are not required. In-addition to that, we would have the opportunity to look into the alternatives to the vulnerable libraries.</p>
<p>For more information and documentation, visit this <a href="https://aquasecurity.github.io/trivy/v0.33/" target="_blank" rel="noopener noreferrer" class="">site</a>.</p>
<p>Liked my content ? Feel free to reach out to my <a href="https://www.linkedin.com/in/krishnadutt/" target="_blank" rel="noopener noreferrer" class="">LinkedIn</a> for interesting content and productive discussions.</p>]]></content:encoded>
            <category>Docker</category>
            <category>SBOM</category>
            <category>Aquasecurity</category>
            <category>CLI</category>
            <category>Trivy</category>
            <category>Kubernetes</category>
            <category>Devsecops</category>
            <category>Security</category>
            <category>Best Practices</category>
        </item>
        <item>
            <title><![CDATA[Deploy and Run Hashicorp Vault With TLS Security in AWS Cloud]]></title>
            <link>https://krishnaduttpanchagnula.github.io/posts/terraform-state-drift</link>
            <guid>https://krishnaduttpanchagnula.github.io/posts/terraform-state-drift</guid>
            <pubDate>Fri, 12 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[In an ideal IaC world, all our infrastructure implementation and updates are written and implemented by pushing the updated code to GitHub, which would trigger a CI/CD pipeline either in Jenkins or Circle-Ci, and changes are reflected in our favorite public cloud. But reality is far from this, even in companies in stage four of cloud maturity. It can be for a plethora of reasons, such as the following:]]></description>
            <content:encoded><![CDATA[<p>In an ideal IaC world, all our infrastructure implementation and updates are written and implemented by pushing the updated code to GitHub, which would trigger a CI/CD pipeline either in Jenkins or Circle-Ci, and changes are reflected in our favorite public cloud. But reality is far from this, even in companies in stage four of cloud maturity. It can be for a plethora of reasons, such as the following:</p>
<ul>
<li class="">The company is still in its initial stages of cloud automation</li>
<li class="">There are multiple stakeholders across different teams who are developing proofs-of-concept via console.</li>
<li class="">An ad-hoc manual hot-fix is introduced to stabilize the current production.</li>
<li class="">The user is not aware of IAC tools</li>
</ul>
<p>Given these reasons, different categories of drift are introduced into the system, each of which has its own remediation actions. This article explains terraform drift, its categories, remediation strategies, and tools to monitor terraform drift.</p>
<p>To understand these concepts better, let’s first explore what terraform drift is and how Terraform detects this drift.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-is-terraform-drift">What is Terraform Drift?<a href="https://krishnaduttpanchagnula.github.io/posts/terraform-state-drift#what-is-terraform-drift" class="hash-link" aria-label="Direct link to What is Terraform Drift?" title="Direct link to What is Terraform Drift?" translate="no">​</a></h2>
<p>When we create resources (i.e., <code>terraform apply</code>) using Terraform, it stores information about current infrastructure, either locally or remote backed in a file named <code>terraform.tfstate</code>. On subsequent <code>terraform apply</code>, this file gets updated with the current state of the infrastructure. But when we make manual changes via console or CLI, those changes are applied in the cloud environment but not seen in the state file.</p>
<blockquote>
<p>Terraform drift can be understood as a drift /difference that is observed from the actual state of infrastructure defined in our terraform to the state of infrastructure present in our cloud environment.</p>
</blockquote>
<p>In any of the above situations, having the infrastructure changes outside Terraform code causes our Terraform state file to have a very different state than the cloud environment. So when we apply the Terraform code next time, we would see a drift, which might cause the Terraform resources to either change or destroy the resources. So understanding how different kinds of drift creeps into our infrastructure helps us mitigate such risks.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="types-of-drifts">Types of Drifts<a href="https://krishnaduttpanchagnula.github.io/posts/terraform-state-drift#types-of-drifts" class="hash-link" aria-label="Direct link to Types of Drifts" title="Direct link to Types of Drifts" translate="no">​</a></h2>
<p>We can categorize the Terraform configuration drift into three categories:</p>
<ol>
<li class="">Emergent drift — Drift observed when infrastructure changes are made outside of the Terraform ecosystem, which was initially applied via Terraform (So their state is present in the Terraform state file).</li>
<li class="">Pseudo drift — “Changes” seen in the plan/apply cycle due to ordering items in the list and other provider idiosyncrasies.</li>
<li class="">Introduced drift — New infrastructure created outside of Terraform.</li>
</ol>
<p>Sometimes it is debated that introduced drift should not be considered as the infrastructure is entirely set up via the console. But the idea of using Terraform entirely automates infrastructure processes via code. So any manual/hybrid is considered as drift.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="managing-emergent-drift">Managing Emergent Drift<a href="https://krishnaduttpanchagnula.github.io/posts/terraform-state-drift#managing-emergent-drift" class="hash-link" aria-label="Direct link to Managing Emergent Drift" title="Direct link to Managing Emergent Drift" translate="no">​</a></h2>
<p>As mentioned, emergent drift is observed when infrastructure applied and managed by Terraform is modified outside of the Terraform ecosystem. This can be managed based on the state that we prefer :</p>
<ul>
<li class="">Infrastructure state preferred: If our preferred state is the state that is in the cloud, then we would make changes to our Terraform configuration figure ( usually <code>[main.tf](http://main.tf)</code> file ) and its dependent modules so that next time we run <code>terraform apply</code>, the state of the configuration file and Terraform state file are in sync.</li>
<li class="">Configuration state preferred: If our preferred state is the one in our configuration file, we just run <code>terraform apply</code> using our configuration file. This would negate all the changes in the cloud and apply the configuration in the Terraform configuration file.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="managing-pseudo-drift">Managing Pseudo Drift<a href="https://krishnaduttpanchagnula.github.io/posts/terraform-state-drift#managing-pseudo-drift" class="hash-link" aria-label="Direct link to Managing Pseudo Drift" title="Direct link to Managing Pseudo Drift" translate="no">​</a></h2>
<p>Pseudo drift can be observed when the ordering of certain resources or certain arguments for a resource is different in the configuration file from the state file. This drift is not so common but can seldom be observed with some providers. To understand this better, let’s take an example of creating a multi-availability zone RDS.</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">resource </span><span class="token string" style="color:rgb(255, 121, 198)">"aws\_db\_instance"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"default"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  allocated\_storage    </span><span class="token operator">=</span><span class="token plain"> </span><span class="token number">10</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  engine               </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"mysql"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  engine\_version       </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"5.7"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  instance\_class       </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"db.t3.micro"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">	availability\_zone    </span><span class="token operator">=</span><span class="token plain"> \</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"us-east-1b"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token string" style="color:rgb(255, 121, 198)">"us-east-1c"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token string" style="color:rgb(255, 121, 198)">"us-east-1a"</span><span class="token plain">\</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"># Us</span><span class="token operator">-</span><span class="token plain">east </span><span class="token operator">-</span><span class="token plain">1a was added later   </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  name                 </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"mydb"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  username             </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"foo"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  password             </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"foobarbaz"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  parameter\_group\_name </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"default.mysql5.7"</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  skip\_final\_snapshot  </span><span class="token operator">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></div></code></pre></div></div>
<p>Initially, we only wanted east-1b and 1c, but later added the 1a. When we applied this configuration, it ran successfully. Being careful SRE engineers that we are, we run a <code>terraform plan</code> to confirm that everything is the way we wanted. But to our surprise, we might see it adding this resource again with changes in the “availability zone” line. And when we apply this change again, this change log can be shown in the subsequent <code>terraform apply</code> lifecycles.</p>
<p>To manage this, we should run <code>terraform show</code> which will show us the current state file. Locate the availability zone argument and see the order in which these arguments are passed as a list. Copy these values to the Terraform configuration file, and you should be good to go.</p>
<p>Managing Introduced Drift</p>
<p>Introduced drift happens when new infrastructure is provisioned outside the Terraform ecosystem in the cloud. This is the most gruesome drift, which would require a conscientious effort from the engineer to detect and handle, as there is no track of these changes in the Terraform state file. Unless viewed via console by going through each resource, reading the cloud-watch logs, checking the billing console, or learning from the person who has done this change, it is quite difficult to detect this drift. This can also happen when we run <code>terraform destroy</code>, and some resources fail to destroy.</p>
<p>If we can identify the resource which is manually provisioned, there are two approaches based on which environment it is present:</p>
<ol>
<li class="">Provisioning anew: If the resource is not in a production-grade environment, it is recommended that we destroy that resource and then create a module for the same within our Terraform configuration file. This way, the infrastructure is logged, tracked, and monitored via Terraform state file, and all the resources are created via Terraform.</li>
<li class="">Terraform import: If the resource is present in the production-grade environment, it is difficult to create it anew. In this case, we import the resources using the “terraform import.” Terraform import helps us create Terraform HCL code for the resource in question. Once we get this resource, we can copy this code into the Terraform configuration file, which, when applied, would update the state file with the same configuration as the state present in the cloud.</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="drift-identification-and-monitoring">Drift Identification and Monitoring<a href="https://krishnaduttpanchagnula.github.io/posts/terraform-state-drift#drift-identification-and-monitoring" class="hash-link" aria-label="Direct link to Drift Identification and Monitoring" title="Direct link to Drift Identification and Monitoring" translate="no">​</a></h2>
<p>All this management of the drift can be done only when we can detect that there is a drift. In the case of emergent and pseudo drift, we can identify them using the “Terraform Plan” command, which would compare the current state file with resources in the cloud (previously created with Terraform). But this would fail in the case of introduced drift, as there is no state for the resource created outside the Terraform ecosystem. So it would serve us better if we can detect this kind of drift beforehand and automate it via IAC tools. This drift can be done using two tools:</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="cloudquery">CloudQuery<a href="https://krishnaduttpanchagnula.github.io/posts/terraform-state-drift#cloudquery" class="hash-link" aria-label="Direct link to CloudQuery" title="Direct link to CloudQuery" translate="no">​</a></h3>
<p>If you like to use a data-centric approach with visualization dashboard, this solution is for you. CloudQuery is an open source tool that compares the state file with the resources in our desired cloud provider, then formats and loads this data into a <a href="https://www.postgresql.org/" target="_blank" rel="noopener noreferrer" class="">PostgreSQL</a> database. As a drift detection command is created on top of PostgreSQL with a column as managed or unmanaged, we can use this flag as a filter to visualize in our favorite dashboard solution, such as Tableau or Power BI, to monitor infrastructure state drift. (For more information, refer to <a href="https://www.cloudquery.io/docs/cli/commands/cloudquery" target="_blank" rel="noopener noreferrer" class="">https://www.cloudquery.io/docs/cli/commands/cloudquery</a>.)</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token key atrule">providers</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)"># provider configurations  </span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> aws  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">configuration</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">       </span><span class="token key atrule">accounts</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">	      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">id</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> &lt;UNIQUE ACCOUNT IDENTIFIER</span><span class="token punctuation" style="color:rgb(248, 248, 242)">&gt;</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)"># Optional. Role ARN we want to assume when accessing this account  </span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)">#     role\_arn: &lt; YOUR\_ROLE\_ARN &gt;  </span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)"># Named profile in config or credential file from where CQ should grab credentials  </span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      local\_profile =  default  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)"># By default assumes all regions  </span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">	    </span><span class="token key atrule">regions</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">	      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> us</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">east</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token number">1</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">	      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> us</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">west</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token number">2</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)"># The maximum number of times that a request will be retried for failures.   </span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">	    </span><span class="token key atrule">max\_retries</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">5</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)"># The maximum back off delay between attempts. The backoff delays exponentially with a jitter based on the number of attempts. Defaults to 30 seconds.  </span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token key atrule">max\_backoff</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">20</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)">#    </span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)"># list of resources to fetch  </span><span class="token plain"></span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">	    </span><span class="token key atrule">resources</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">	      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"\*"</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="driftctl">Driftctl<a href="https://krishnaduttpanchagnula.github.io/posts/terraform-state-drift#driftctl" class="hash-link" aria-label="Direct link to Driftctl" title="Direct link to Driftctl" translate="no">​</a></h2>
<p>If you are more of a CLI kind of person who loves working with the terminal, this tool is for you. Driftctl helps us track and detect managed and unmanaged drifts that may happen with a single command.</p>
<p>Since this is a CLI-based tool, this can be easily integrated into the CI/CD pipeline written in the Jenkins pipeline, and the results can be pushed as output to the PR in GitHub. If that is not your cup of coffee, run this as a cron job within your system. Create a log group that would collect the logs and then use log monitoring solutions such as Fleuentd or Prometheus/graphana packages to visualize and create alerting solutions. For more information, read <a href="https://docs.driftctl.com/0.35.0/installation" target="_blank" rel="noopener noreferrer" class="">https://docs.driftctl.com/0.35.0/installation</a>.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">#to scan local filedriftctl scan# To scan backend in AWS </span><br></div><div class="token-line" style="color:#F8F8F2"><span class="token plain">S3driftctl scan --from tfstate+s3://my-bucket/path/to/state.tfstate</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusion">Conclusion<a href="https://krishnaduttpanchagnula.github.io/posts/terraform-state-drift#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>It always prevents the drift from creeping into our code rather than creating remediations after they have crept in. Finally, I would like to suggest that it is always better to write better code and coding practices.</p>
<ul>
<li class="">Always try to build automated infrastructure. Even if you perform manual steps, try to import them into Terraform script and then apply them.</li>
<li class="">Write and apply code incrementally.</li>
<li class="">Implement a drift-tracking system with a custom alerting system that would mail the SRE about the infra-drift observed.</li>
</ul>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#F8F8F2"><span class="token plain">**Liked my content?**Feel free to reach out to my [LinkedIn](https://www.linkedin.com/in/krishnadutt/) for interesting content and productive discussions.</span><br></div></code></pre></div></div>]]></content:encoded>
            <category>Hashicorp Terraform</category>
            <category>Terrraform</category>
            <category>Terraform State Drift</category>
            <category>Hashicorp</category>
            <category>AWS</category>
            <category>Cloud</category>
            <category>IAC</category>
            <category>Infrastructure</category>
        </item>
        <item>
            <title><![CDATA[Tfblueprintgen: A Tool to Simplify Terraform Folder Setup and Provide Base Resource Modules]]></title>
            <link>https://krishnaduttpanchagnula.github.io/posts/tfblueprintgen-a-tool-to-simplify-terraform</link>
            <guid>https://krishnaduttpanchagnula.github.io/posts/tfblueprintgen-a-tool-to-simplify-terraform</guid>
            <pubDate>Fri, 12 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Whether it’s a React front-end app, a Go CLI tool, or a UI design project, there is always initial toil to figure out the optimal folder structure. As this initial decision influences a lot of flexibility, extensibility, self-explanation, and easy maintenance in our projects, it is key decision to ensure a smooth developer experience.]]></description>
            <content:encoded><![CDATA[<p>Whether it’s a React front-end app, a Go CLI tool, or a UI design project, there is always initial toil to figure out the optimal folder structure. As this initial decision influences a lot of flexibility, extensibility, self-explanation, and easy maintenance in our projects, it is key decision to ensure a smooth developer experience.</p>
<p>When working with a new tool/technology/framework, our journey typically starts with reading official “getting started” handbook from their official website or even reading some articles on the same topic. We use these resources and start getting our hands dirty with hands-on experience, often using its structure as a foundation for more complex real-world projects. But these articles or tutorials are often serve us good in initial phases of the project, when the complexity is low. When we are solving complex problem involving multiple actors, the legibility and maintainability takes precedence. It becomes a daunting task to later refactor or sometimes rewrite everything from the scratch. To reduce this hassle and tackle this issue head on, I’ve distilled my Terraform experience into a CLI tool. This tool generates a battle-tested folder structure along with basic modules, allowing us to quickly hit the ground running.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="structuring-terraform-folders">Structuring Terraform Folders<a href="https://krishnaduttpanchagnula.github.io/posts/tfblueprintgen-a-tool-to-simplify-terraform#structuring-terraform-folders" class="hash-link" aria-label="Direct link to Structuring Terraform Folders" title="Direct link to Structuring Terraform Folders" translate="no">​</a></h2>
<p>Most companies and their ops teams find it cumbersome to manage multiple environments across multiple regions for their applications. We can structure our terraform folders as follows:</p>
<ul>
<li class="">Folder structure organized by Region</li>
<li class="">Folder structure by Resources ( like AWS EC2, or Azure Functions etc)</li>
<li class="">Folder structure on use case ( like front-end app, networking etc)</li>
<li class="">Folder structure organized by Account</li>
<li class="">Folder structure organized by environment and</li>
<li class="">A Hybrid of all the above</li>
</ul>
<p>Given the above options it quite becomes confusing to the teams starting with terraform to decide how to structure their projects. Based on my experience here are my 2 cents on how to structure a terraform project:</p>
<ul>
<li class="">Create a modular style code with each module containing all the resources required to create for each use-case. These modules would serve as base blueprints which can be utilized across different environments.</li>
<li class="">For ex: In case of AWS, The front-end module should consist of Cloud-front, S3 bucket, cloud-front origin access control, s3 policy bucket policy and s3 bucket public access block.</li>
<li class="">Create a folder structure for each of the environments that you are deploying. This statement would be true, if the architecture across all the environments doesn’t change and their deployment strategies does not change.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="tfblueprintgen-a-terraform-tool-to-generate-folder-structure-and-base-blueprints">Tfblueprintgen: A Terraform tool to generate folder structure and base blueprints<a href="https://krishnaduttpanchagnula.github.io/posts/tfblueprintgen-a-tool-to-simplify-terraform#tfblueprintgen-a-terraform-tool-to-generate-folder-structure-and-base-blueprints" class="hash-link" aria-label="Direct link to Tfblueprintgen: A Terraform tool to generate folder structure and base blueprints" title="Direct link to Tfblueprintgen: A Terraform tool to generate folder structure and base blueprints" translate="no">​</a></h2>
<p>Based on the above postulates, i have created a CLI tool called Tfblueprintgen, which generates the folder structure along with the modular working blocks to create AWS building blocks. In terms of folder structure, the structure will look something like below.</p>
<p>Image 1 : Generated Terraform folder structure with base modules</p>
<p>To run the tool download the both windows and Linux binaries from <a href="https://github.com/krishnaduttPanchagnula/Tfblueprintgen/releases/download/0.1/tfblueprintgen.exe?ref=hackernoon.com" target="_blank" rel="noopener noreferrer" class="">here</a> or you can build your own binary from <a href="https://github.com/krishnaduttPanchagnula/Tfblueprintgen/archive/refs/tags/0.1.zip?ref=hackernoon.com" target="_blank" rel="noopener noreferrer" class="">here</a>. Use the the binary ( if in Windows double-click to run Tfblueprintgen.exe or if it is Linux run the binary using ./Tfblueprintgen)</p>
<p>Image 2 : Running the tfblueprintgen tool</p>
<p>As described in the image 1, the tool generates two things:</p>
<ul>
<li class="">A Parent folder which contains all the main terraform files ( <a href="http://outputs.tf/?ref=hackernoon.com" target="_blank" rel="noopener noreferrer" class="">outputs.tf</a>, variables<a href="http://providers.tf/?ref=hackernoon.com" target="_blank" rel="noopener noreferrer" class="">.tf</a> and <a href="http://main.tf/?ref=hackernoon.com" target="_blank" rel="noopener noreferrer" class="">main.tf</a> )for each environment separated in their own folders.</li>
<li class="">A Module folder which contains all the different basic resources, segregated in their own separate folders.</li>
</ul>
<p>These modules can be leveraged within each of the environment folders, by calling those modules using module block and these can be applied using “terraform apply”</p>
<p>With this setup, you can hit the ground up and running in no time. Feel free to add more ideas as issues and Stay tuned to project.</p>
<p>Liked my content ? Feel free to reach out to my <a href="https://www.linkedin.com/in/krishnadutt/" target="_blank" rel="noopener noreferrer" class="">LinkedIn</a> for interesting content and productive discussions.</p>]]></content:encoded>
            <category>Golang</category>
            <category>Go</category>
            <category>IAC</category>
            <category>CLI</category>
            <category>AWS</category>
            <category>Cloud</category>
            <category>Terraform</category>
            <category>Automation</category>
            <category>Best Practices</category>
        </item>
    </channel>
</rss>