<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>The Ops Community ⚙️: Jatin Mehrotra</title>
    <description>The latest articles on The Ops Community ⚙️ by Jatin Mehrotra (@jatin).</description>
    <link>https://community.ops.io/jatin</link>
    <image>
      <url>https://community.ops.io/images/-JLiHC_eqLdPNHiUstHH9xTX1OlhZqeHY6rtv97IOo8/rs:fill:90:90/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL3Vz/ZXIvcHJvZmlsZV9p/bWFnZS80OTIvZjUx/YjVkODktOTYxMi00/YjE3LWEzODQtNDdi/YjM1ZjQzODVhLmpw/ZWc</url>
      <title>The Ops Community ⚙️: Jatin Mehrotra</title>
      <link>https://community.ops.io/jatin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://community.ops.io/feed/jatin"/>
    <language>en</language>
    <item>
      <title>How to use AI for AWS CLI commands?</title>
      <dc:creator>Jatin Mehrotra</dc:creator>
      <pubDate>Tue, 21 Nov 2023 04:59:34 +0000</pubDate>
      <link>https://community.ops.io/jatin/how-to-use-ai-for-aws-cli-commands-jpn</link>
      <guid>https://community.ops.io/jatin/how-to-use-ai-for-aws-cli-commands-jpn</guid>
      <description>&lt;p&gt;&lt;em&gt;In this blog, I want to show how I was able to set up and use AWS CodeWhisperer for the command line and enhance my productivity.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Just before AWS Re:Invent 2023 there is an amazing update from AWS which allows to use of AI for the command line. Yes it's true that from today we can use AWS CodeWhisperer with AWS CLI with provides &lt;code&gt;CLI completion, inline documentation&lt;/code&gt; and &lt;code&gt;AI natural language -&amp;gt; to CLI command generation&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here is the link to the official announcement.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/about-aws/whats-new/2023/11/amazon-codewhisperer-command-line-preview/"&gt;https://aws.amazon.com/about-aws/whats-new/2023/11/amazon-codewhisperer-command-line-preview/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/vYiIkiS5KMqzqq9qwdG54Vxwk9d8LIrU2CRKtxAmozA/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL294YXl2/b3M5eXc0MzBkYmcx/ajRjLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/vYiIkiS5KMqzqq9qwdG54Vxwk9d8LIrU2CRKtxAmozA/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL294YXl2/b3M5eXc0MzBkYmcx/ajRjLnBuZw" alt="AWS annoucement" width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;em&gt;It's still in preview, so specifications about this blog may be subject to change in future.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  CodeWhisperer for command line setup
&lt;/h2&gt;

&lt;p&gt;At this moment codeWhisperer is available only on macOS as per official announcement&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;CodeWhisperer for command line is available on macOS for all major shells (bash, zsh, and fish) and major terminal emulators such as Terminal, iTerm2, Hyper, and the built-in terminals in Visual Studio Code and JetBrains.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Link to official Docs: &lt;a href="https://docs.aws.amazon.com/codewhisperer/latest/userguide/command-line-getting-started-installing.html"&gt;https://docs.aws.amazon.com/codewhisperer/latest/userguide/command-line-getting-started-installing.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download &lt;a href="https://desktop-release.codewhisperer.us-east-1.amazonaws.com/latest/CodeWhisperer.dmg"&gt;dmg file&lt;/a&gt; for CodeWhisperer for the command line dmg file from the docs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/dFTa5zhUQ6PD2CTWIeiD4jS29JjU04or0IT7kvd1H88/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzA3ZDcx/dWI4eTY4MXZjZm80/cWt4LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/dFTa5zhUQ6PD2CTWIeiD4jS29JjU04or0IT7kvd1H88/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzA3ZDcx/dWI4eTY4MXZjZm80/cWt4LnBuZw" alt="Codewhisperer DMG file installation" width="800" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Download DMG file and then move the file to Applications. (typical drag and drop for MacOS applications)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After installation, start the newly installed CodeWhisperer application&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/LAief4UuAs4Ya2NhHTMBLRkN8VNO2kTEM3dNwR_Q50I/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzB0cDFo/aWRpa2kwc2U5cDdz/cXZxLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/LAief4UuAs4Ya2NhHTMBLRkN8VNO2kTEM3dNwR_Q50I/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzB0cDFo/aWRpa2kwc2U5cDdz/cXZxLnBuZw" alt="CodeWhisperer startup" width="800" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install the shell integration hooks as the next step in the installation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/btRWxc_3jbG-QUeElGsFgIn7TLv0EnadEBG515QC_SU/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2Nhbzh2/Z2JkbWF6cmkydXJz/cWx4LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/btRWxc_3jbG-QUeElGsFgIn7TLv0EnadEBG515QC_SU/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2Nhbzh2/Z2JkbWF6cmkydXJz/cWx4LnBuZw" alt="Shell Integration" width="800" height="521"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As a next step we need to enable accessibility so that CodeWhisperer can write on insert CLI completions and insert commands in the shell. CodeWhisperer will not work if this is not enabled.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/JXBX3mI8bx4MsYNAbs1uhZtu3Sv1Q-mzFxjbDXnzXNw/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2ZxOHpp/N3cxdG5qOGRnZW50/MTMzLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/JXBX3mI8bx4MsYNAbs1uhZtu3Sv1Q-mzFxjbDXnzXNw/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2ZxOHpp/N3cxdG5qOGRnZW50/MTMzLnBuZw" alt="Enable accessibility option" width="800" height="1186"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Toggle the accessibility for CodeWhisperer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/FCbMsD-lREvv4cVCCnpgfBN0Hk292HaBG41ZT7mSPsA/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzIzZWUz/NHJjd2ptM3FmMHRi/ajFyLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/FCbMsD-lREvv4cVCCnpgfBN0Hk292HaBG41ZT7mSPsA/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzIzZWUz/NHJjd2ptM3FmMHRi/ajFyLnBuZw" alt="Enable accessibility toggle" width="800" height="596"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next step will ask to sign on. Upon clicking you will redirected to authorise CodeWhisperer for your AWS account.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/J4leAgFFsMiVAPEjgDDO5k9LVRsVuTcv94s-60qv05w/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzNjeGpk/bXZsajIxemIydjVj/ZnVzLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/J4leAgFFsMiVAPEjgDDO5k9LVRsVuTcv94s-60qv05w/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzNjeGpk/bXZsajIxemIydjVj/ZnVzLnBuZw" alt="Sign on option" width="800" height="570"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/EImokqUqWiE7v4C-vHU65p0g2NKVYDxm4SBmqyDFqkw/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzdvam54/eHVmN2YwbmlnNWVo/OGhsLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/EImokqUqWiE7v4C-vHU65p0g2NKVYDxm4SBmqyDFqkw/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzdvam54/eHVmN2YwbmlnNWVo/OGhsLnBuZw" alt="Authorization Screen" width="628" height="827"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You will need an AWS Builder ID. If you already have a Builder ID use your existing credentials otherwise create once as shown in image below. In my case I already have a Builder ID&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/QLo8wll77d1Cstk-ZixWgrVklCVlXiBcSM4itqc2C1c/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzFobmYw/dzM0czRvcTdsYW1v/anpiLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/QLo8wll77d1Cstk-ZixWgrVklCVlXiBcSM4itqc2C1c/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzFobmYw/dzM0czRvcTdsYW1v/anpiLnBuZw" alt="Builder ID prompt" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;As a last step, if you have setup everything correctly so far, you will see a prompt in which you allow COdewhisperer to access your data so that CodeWhisperer can do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable CodeWhisperer completions&lt;/li&gt;
&lt;li&gt;Enable CodeWhisperer analysis&lt;/li&gt;
&lt;li&gt;Access to IAM Identity centre accounts and permission sets.&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;&lt;a href="https://community.ops.io/images/ME3gq7rqYFp7rzvyo0xRPIW7wrTCGfYmCfIgeb9gTNE/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL25pemlu/cnZ1c20wODc1cDFi/eDBuLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/ME3gq7rqYFp7rzvyo0xRPIW7wrTCGfYmCfIgeb9gTNE/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL25pemlu/cnZ1c20wODc1cDFi/eDBuLnBuZw" alt="Allow code whisperer to access data" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's see CodeWhisperer in action for AWS CLI commands
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Once the setup is complete, you will see the code whisperer default window.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/XRL3_fQm8kSlN4JtK3LmHkIk9v3oA_Ne2DMLeSw-zcM/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzlibG91/cWF3c3g2bG0ybXhx/dG11LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/XRL3_fQm8kSlN4JtK3LmHkIk9v3oA_Ne2DMLeSw-zcM/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzlibG91/cWF3c3g2bG0ybXhx/dG11LnBuZw" alt="Start screen after installation" width="800" height="623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Generating Commands from text
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;With CodeWhisperer you can write natural language ( many languages are supported) instructions like &lt;code&gt;create s3 bucket&lt;/code&gt; or &lt;code&gt;create a lambda function&lt;/code&gt;. Codewhisperer will then convert this text to an instantly executable shell command. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can either use this feature in 2 ways:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
  cw ai CodeWhisperer completions
  &lt;span class="c"&gt;# CodeWhisperer completions // # is not the comment&lt;/span&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;I tried to create cloudfront distribution whose origin is s3 bucket using the following prompt
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
cw ai create cloudfront distribution named &lt;span class="nb"&gt;test &lt;/span&gt;whose origin is s3 bucket name &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="nt"&gt;-bucket&lt;/span&gt;


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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://community.ops.io/images/N6hh12COu8jPn3ERCdG7vsG4jq_K9PmeD2L3aKcmE0E/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL24xbjE3/ZDdpczZndnh4c2pl/b2p6LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/N6hh12COu8jPn3ERCdG7vsG4jq_K9PmeD2L3aKcmE0E/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL24xbjE3/ZDdpczZndnh4c2pl/b2p6LnBuZw" alt="create cloudfront distribution" width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Once you have found your command you either execute it, or choose to edit it or regenerate, ask another question or cancel it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can write the prompt using &lt;code&gt;# your prompt&lt;/code&gt;. In the following &lt;strong&gt;I tried to create a lambda in tokyo region&lt;/strong&gt; and it did pretty good job.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;# create cloudfront distribution named test whose origin is s3 bucket name test&lt;/span&gt;
&lt;span class="nt"&gt;-bucket&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://community.ops.io/images/XxUEM64KX1a9p8Bn7kjwy6m7wNKhpU5J7cJ57r20MNc/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzFzZmZj/MzZmZXM5MDQ1b3dx/MHliLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/XxUEM64KX1a9p8Bn7kjwy6m7wNKhpU5J7cJ57r20MNc/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzFzZmZj/MzZmZXM5MDQ1b3dx/MHliLnBuZw" alt="create lambda" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  CLI completion
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;It also does a great job when it comes to CLI completion in the way it adds *&lt;em&gt;typeahead code completions
*&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/WIh318j7_3wkUwwgH16hKmlcebLOgyCRfgCg5Ujzur0/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3Nqem5y/YTVsdTJlMnJzMHVr/bGtwLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/WIh318j7_3wkUwwgH16hKmlcebLOgyCRfgCg5Ujzur0/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3Nqem5y/YTVsdTJlMnJzMHVr/bGtwLnBuZw" alt="CLI completion" width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not only AWS CLI commands, code whisperer has support for docker, kubectl　（tested, git commands too.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/gG4iWVJP9YXAW-iVZn5LBEtRW4iATxYgmFKEC23umEI/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3NrcHg5/NTU5dzloZTA5dnFl/a25iLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/gG4iWVJP9YXAW-iVZn5LBEtRW4iATxYgmFKEC23umEI/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3NrcHg5/NTU5dzloZTA5dnFl/a25iLnBuZw" alt="docker command completion " width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/glboBkAgC2UD4ZvH-3N-lDDGlyVqW5nIQ5M3zK6wonA/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3ptbHln/bTdreWN4a2podnI5/Nml2LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/glboBkAgC2UD4ZvH-3N-lDDGlyVqW5nIQ5M3zK6wonA/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3ptbHln/bTdreWN4a2podnI5/Nml2LnBuZw" alt="Kubectl command completion" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/_Ywwe1X9eYUN8hJvqvapcx5hyRfc54JQLNod1gPDJh8/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2pjYnVv/dWNvMDdncmwxcmU5/bXRvLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/_Ywwe1X9eYUN8hJvqvapcx5hyRfc54JQLNod1gPDJh8/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2pjYnVv/dWNvMDdncmwxcmU5/bXRvLnBuZw" alt="aws command completion" width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: Customization of Codewhisperer for CLI
&lt;/h2&gt;

&lt;p&gt;You can always customise the behaviour of Codewhisperer from its dashboard which allows to &lt;strong&gt;change its theme&lt;/strong&gt;, &lt;strong&gt;disable code whisperer for certain commands&lt;/strong&gt;, instant &lt;strong&gt;execution of dangerous commands like bucket delete&lt;/strong&gt; etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/fF4Ye8rQ8zlW72UUUP2Y2VC59RSvm4r5PP2C7w9NRgo/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzc4bGMz/cGNoaXd6Y2N4OWxu/YTFhLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/fF4Ye8rQ8zlW72UUUP2Y2VC59RSvm4r5PP2C7w9NRgo/rt:fit/w:800/g:sm/q:0/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzc4bGMz/cGNoaXd6Y2N4OWxu/YTFhLnBuZw" alt="CodeWhisperer Dashboard" width="800" height="623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My thoughts
&lt;/h2&gt;

&lt;p&gt;As a DevOps engineer who has to run certain repeated commands every day for daily tasks, I think this update will definitely increase my productivity and make my life way easier with its code completion and text-to-command feature. &lt;/p&gt;

&lt;p&gt;As I said before it's in the preview stage, and cannot be used for production but it's going to get even better from this stage. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Connect with me over&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/jatinmehrotra/"&gt;Linkedin&lt;/a&gt; or &lt;a href="https://twitter.com/imjatinmehrotra"&gt;Twitter&lt;/a&gt; and share your thoughts about this blog.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>tutorials</category>
      <category>cloudops</category>
      <category>ai</category>
    </item>
    <item>
      <title>Send Custom Notification with AWS Chatbot</title>
      <dc:creator>Jatin Mehrotra</dc:creator>
      <pubDate>Wed, 13 Sep 2023 09:28:38 +0000</pubDate>
      <link>https://community.ops.io/jatin/send-custom-notification-with-aws-chatbot-5gkd</link>
      <guid>https://community.ops.io/jatin/send-custom-notification-with-aws-chatbot-5gkd</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;AWS Chatbot is ChatOps offering from AWS to monitor, troubleshoot, and operate your AWS environments natively from within your chat channels ( Teams, Slack channels etc)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Until now, there was a limitation that notifications from aws chatbot could not be customised, additional information in the notifications&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But with this &lt;a href="https://aws.amazon.com/about-aws/whats-new/2023/09/custom-notifications-aws-chatbot/"&gt;update&lt;/a&gt;, the aws chatbot just got new powers !!!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Outcome of the Blog
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/IbHdqrDCVcWEU0e_0f8AaUDoDgU1aLicXy_eBjkWPGg/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2UyYTV2/dTMwMDlxaXNpNXB2/N3poLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/IbHdqrDCVcWEU0e_0f8AaUDoDgU1aLicXy_eBjkWPGg/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2UyYTV2/dTMwMDlxaXNpNXB2/N3poLnBuZw" alt="Slack Notification" width="800" height="90"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;By the end of this blog, you will know: &lt;/li&gt;
&lt;li&gt;How to send custom notifications using chatbot using lambda.&lt;/li&gt;
&lt;li&gt;Why this update will help users to understand and respond quickly to events.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  About this Update [ 12/09/2023 ]
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/SnsNrGqISyVp1ZsNKOpZ8Cgnh4w4BHrBRlgHP4lYpJ0/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzFzajJ4/MnNocTJ6Y3U0Y2Nv/ZW44LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/SnsNrGqISyVp1ZsNKOpZ8Cgnh4w4BHrBRlgHP4lYpJ0/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzFzajJ4/MnNocTJ6Y3U0Y2Nv/ZW44LnBuZw" alt="Chatbot feature Update" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;This update will help users to understand more insights about the notification and which will help them to respond quicker.&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;You can add specific details, tag team members, and include remediation steps. It's upto your creativity now that how insightful and information you can make your custom notifications.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;There are no additional costs to use custom notifications.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites for sending custom notifications using chatbot?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Custom notifications &lt;strong&gt;must use the following event format&lt;/strong&gt; as mentioned in the &lt;a href="https://docs.aws.amazon.com/chatbot/latest/adminguide/custom-notifs.html#event-schema"&gt;docs&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Take a note about the &lt;strong&gt;parameters which are required&lt;/strong&gt; and which are optional in the given table in Parameters table&lt;/em&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;version&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;source&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;textType&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nextSteps&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt; 
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keywords&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; 
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;metadata&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                     
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;threadId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;summary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eventType&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;relatedResources&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;additionalContext&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;customerProvidedKey1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;customerProvidedKey2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;
                &lt;span class="p"&gt;...&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use client specific syntax&lt;/strong&gt;: If messages are being sent to slack then slack markdown format should be used within custom notification and vice-versa for Teams.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;From the &lt;a href="https://docs.aws.amazon.com/chatbot/latest/adminguide/custom-notifs.html#custom-content"&gt;docs &lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can add chat platform compatible emojis in your custom notifications. You can also tag team members using @mentions in your custom notifications for Slack. Tagged team members are notified when the custom notification is delivered to the chat channel. To tag a team member in Slack, use their user ID. For example, @userID. Tagging team members in Microsoft Teams isn't currently supported.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Architecture Pattern for using custom Notifications
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/tDHyHA9F8U5UFK6FtIyC3XjOaTB1IO1fKyNqkmJJStk/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3FjYnJu/dTNnbG5sNzc1MXBu/cjJjLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/tDHyHA9F8U5UFK6FtIyC3XjOaTB1IO1fKyNqkmJJStk/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3FjYnJu/dTNnbG5sNzc1MXBu/cjJjLnBuZw" alt="architecture of blog" width="800" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There will be a source which will emit the events with all the details. &lt;/li&gt;
&lt;li&gt;Either source will &lt;strong&gt;generate event (using Lambda)&lt;/strong&gt; with all the custom information or &lt;strong&gt;use EventBridge Input Transformers&lt;/strong&gt; to add custom information to the original event.&lt;/li&gt;
&lt;li&gt;Final notifications will be sent to SNS topic. &lt;/li&gt;
&lt;li&gt;Chatbot will continuously monitor that sns topic and send notification to slack channel.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Let's create a custom notification using aws Lambda.
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;As we saw in architecture pattern we need 3 things to implement and test out custom notification: AWS Lambda, sns topic and chatbot configured for the slack channel&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: &lt;strong&gt;For visual simplicity and understanding, I will be using AWS console for this blog but the same thing can be achieved using AWS CDK.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create SNS topic
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create SNS topic and note its arn.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/J-ADxwwY01JlrNooBv_csZRzsdm2ZXj9EWq5Hp8SVPI/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzB1ZHJi/aTJkczRoY2ZnbnRv/ZWo5LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/J-ADxwwY01JlrNooBv_csZRzsdm2ZXj9EWq5Hp8SVPI/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzB1ZHJi/aTJkczRoY2ZnbnRv/ZWo5LnBuZw" alt="sns topic" width="800" height="224"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a Lambda
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We will create a AWS Lambda Function with nodejs runtime and we will expose &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-urls.html"&gt;lambda using function Urls&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Code for Lambda&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;EventBridgeClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;PutEventsCommand&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@aws-sdk/client-eventbridge&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SNSClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PublishCommand&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@aws-sdk/client-sns&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;snsClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;SNSClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AWS_REGION&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;snsTopicARN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SNS_TOPIC_ARN&lt;/span&gt;


&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;


    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;publishNotificationToSlack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Successful lambda invocation&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
        &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;publishNotificationToSlack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;



 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;slackFormatEvent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;version&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;source&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;custom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;:fire: Your &amp;lt;https://www.linkedin.com/posts/jatinmehrotra_custom-notifications-are-now-available-for-activity-7107541447716814848-dAAv?utm_source=share&amp;amp;utm_medium=member_desktop|post&amp;gt; is gaining traction!!! :fire:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;:linkedin: Check Linkedin &amp;lt;@YOURSLACKID|YOURNAME&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;snsClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;PublishCommand&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slackFormatEvent&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="na"&gt;TopicArn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;snsTopicARN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;I have attached permissions of full access sns to lambda role so that lambda can send notifications to sns topic directly. &lt;strong&gt;From a security point of view you should limit access to only required SNS topic.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/QTL0EdvXV8LN340zTqXpbfPz-7ZwLPqoF8sJTnPvoCI/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3MwNHJs/dGZrM20xb2U3OG56/ZnpoLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/QTL0EdvXV8LN340zTqXpbfPz-7ZwLPqoF8sJTnPvoCI/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3MwNHJs/dGZrM20xb2U3OG56/ZnpoLnBuZw" alt="Lambda image role" width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add environment variable to lambda configuration as &lt;code&gt;SNS_TOPIC_ARN: arn of the SNS topic&lt;/code&gt; noted earlier&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configure AWS Chatbot client and Slack Channel
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;In order to set up AWS chatbot client for Slack and slack channel, follow the steps mentioned here in &lt;a href="https://docs.aws.amazon.com/chatbot/latest/adminguide/slack-setup.html"&gt;docs&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/wR-S3qM-c6q1YvvHLwpk22wZzFtJoSrHhkSuRoAq58k/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3cyZmJk/Y3NzaTdlemxuYXVj/Yjc4LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/wR-S3qM-c6q1YvvHLwpk22wZzFtJoSrHhkSuRoAq58k/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3cyZmJk/Y3NzaTdlemxuYXVj/Yjc4LnBuZw" alt="Chatbot slack channel configuration" width="800" height="864"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/p5szBuDZwxpx4qQ-tJhdneJ8Ql5BSH1uXrrbtpLGXSs/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2I3dDhn/ejUwdW9wYWxvNzJl/OHpxLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/p5szBuDZwxpx4qQ-tJhdneJ8Ql5BSH1uXrrbtpLGXSs/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2I3dDhn/ejUwdW9wYWxvNzJl/OHpxLnBuZw" alt="chatbot client" width="637" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Note: While configuring the Slack channel, add the SNS topic created earlier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/29Ic-2fi7quV-i7ok1Ln0-uEc2AoCEHqNY2NNiKpbpc/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzNuenRi/eGd5d3puYTl5MDg5/MmdwLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/29Ic-2fi7quV-i7ok1Ln0-uEc2AoCEHqNY2NNiKpbpc/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzNuenRi/eGd5d3puYTl5MDg5/MmdwLnBuZw" alt="sns topic for chatbot config" width="800" height="512"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Test out the Lambda function
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/x-XW3By7vj8MNugrajLGILfvZtX77z0G7LA9Hcmg-PE/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2E4cmJh/N3luNGtnZnZqNWU3/eGhwLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/x-XW3By7vj8MNugrajLGILfvZtX77z0G7LA9Hcmg-PE/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2E4cmJh/N3luNGtnZnZqNWU3/eGhwLnBuZw" alt="lambda function URL" width="800" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visit the function URL of the lambda function &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/6JgKcVSK3CM9JtdHSoW7kjenxY3LgZu5Dhv5_-KanaA/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzIxM3Rl/aWpxOHdmeXV6MHZh/ZmMxLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/6JgKcVSK3CM9JtdHSoW7kjenxY3LgZu5Dhv5_-KanaA/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzIxM3Rl/aWpxOHdmeXV6MHZh/ZmMxLnBuZw" alt="Lambda invoke" width="800" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/uRH3V6W67hXwNzUQupHBZ2A2KqXk2qDFV1jrh-LPJGg/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzdvOGN1/a3dlMDlxYnQyeTVo/cHJiLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/uRH3V6W67hXwNzUQupHBZ2A2KqXk2qDFV1jrh-LPJGg/rt:fit/w:800/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzdvOGN1/a3dlMDlxYnQyeTVo/cHJiLnBuZw" alt="slack image" width="800" height="90"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  From the DevOps perspective
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This update enables DevOps teams to improve their observability.&lt;/li&gt;
&lt;li&gt;Allows the team to understand more insights about the notifications as it allows to define and add more information to your notifications.&lt;/li&gt;
&lt;li&gt;With the support of custom notifications and native client support like slack mentions, it definitely allows the team to respond even more quickly at the time of critical events. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Connect with me over&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/jatinmehrotra/"&gt;Linkedin&lt;/a&gt; or &lt;a href="https://twitter.com/imjatinmehrotra"&gt;Twitter&lt;/a&gt; and share your thoughts about this blog.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>chatbot</category>
      <category>cloudops</category>
    </item>
    <item>
      <title>Saving cost with AWS Lambda recursion control !!!</title>
      <dc:creator>Jatin Mehrotra</dc:creator>
      <pubDate>Tue, 11 Jul 2023 11:12:21 +0000</pubDate>
      <link>https://community.ops.io/jatin/saving-cost-with-aws-lambda-recursion-control--20m9</link>
      <guid>https://community.ops.io/jatin/saving-cost-with-aws-lambda-recursion-control--20m9</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;AWS lambda has a new feature of recursion control which stops lambda functions execution during infinite or recursive loops.&lt;/p&gt;

&lt;p&gt;There is an &lt;a href="https://aws.amazon.com/blogs/compute/detecting-and-stopping-recursive-loops-in-aws-lambda-functions/"&gt;amazing blog&lt;/a&gt; on this from AWS team which test this feature with &lt;strong&gt;AWS SQS, Java lambda function and AWS SAM&lt;/strong&gt;. Please check it out for more details.&lt;/p&gt;

&lt;p&gt;However I took a different approach to test this feature using &lt;em&gt;&lt;strong&gt;CDK, SNS topic, and typescript lambda function&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Understanding how aws lambda is invoked and works.&lt;/li&gt;
&lt;li&gt;Understanding of event-driven architecture which involves an event source and destination where lambda outputs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Let's test it first
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;To test this feature we will be setting up &lt;strong&gt;sns topic, lambda (which publish message back to source sns topic)&lt;/strong&gt; this creates a recursive loop. &lt;/li&gt;
&lt;li&gt;&lt;p&gt;The infrastructure for this test will be provisioned using AWS CDK.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/jatinmehrotra/aws-lambda-recursion"&gt;Github repo for CDK code&lt;/a&gt;. In order to test this code, please enter your &lt;a href="https://github.com/jatinmehrotra/aws-lambda-recursion/blob/7b1430ab77f1e7381ac21deb37e7094217e3b907/lib/cdk-recursion-lambda-stack.ts#L15C4-L15C92"&gt;email address in the cdk code&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;// to deploy 

cdk deploy &lt;span class="nt"&gt;--all&lt;/span&gt; 

// to destroy 

cdk destroy &lt;span class="nt"&gt;--all&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Architecture Diagram
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/TDVpMTCCDsnxXBIDEXFS9Jh2M31lh9_ZgJ94uWAkHQo/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzVxN2Ns/bWxybHJ6ems5bW43/aDQwLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/TDVpMTCCDsnxXBIDEXFS9Jh2M31lh9_ZgJ94uWAkHQo/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzVxN2Ns/bWxybHJ6ems5bW43/aDQwLnBuZw" alt="Architecture diagram" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Recursive loop in Lambda function?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;AWS services &lt;strong&gt;(source)&lt;/strong&gt;  generate events that invoke Lambda functions, and Lambda functions then send messages to other AWS Services &lt;strong&gt;(destination)&lt;/strong&gt;. &lt;/li&gt;
&lt;li&gt;Usually in event-driven architectures source and destination cannot be the same. &lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Due to misconfiguration or coding bugs, the lambda function sends the processed event to the same AWS Service (source)  that invokes the Lambda function, causing a recursive loop.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;When this recursive loop occurs the lambda function is also executed for infinite times as long as the loop occurs thus adding up to the usage bill for the aws account.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is a Recursive control in Lambda?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;According to this new feature[&lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/invocation-recursion.html"&gt;aws docs&lt;/a&gt;] it will detect and automatically break this loop or say stop lambda execution if it is invoked &lt;strong&gt;for more than 16+ times&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Behind the scenes, Recursion control uses X-Ray. Lambda uses AWS X-Ray tracing headers. When AWS services that support recursive loop detection send events to Lambda, those events are automatically annotated with metadata. &lt;/li&gt;
&lt;li&gt;The updated metadata includes a count of the number of times that the event has invoked the function. That is how lambda detect recursion loop.&lt;/li&gt;
&lt;li&gt;You don't need to enable X-Ray active tracing for this feature to work.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Note: Some important points about this feature
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Same chain of requests&lt;/strong&gt;: &lt;em&gt;A chain of requests is a sequence of Lambda invocations caused by the same triggering event.&lt;/em&gt; for example &lt;code&gt;SNS → Lambda → SNS = recursive loop&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;If your function is invoked more than 16 times in the same chain of requests, then Lambda automatically stops the next function invocation in that request chain and notifies you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lambda stops only invocations that are part of the same chain of requests&lt;/strong&gt;. For example, if your function is configured with multiple triggers, then invocations from other triggers aren't affected.&lt;/li&gt;
&lt;li&gt;This feature is free to use.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Supported AWS Services and SDK
&lt;/h2&gt;

&lt;h3&gt;
  
  
  AWS Services
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;At this moment lambda recursion control is supported between &lt;strong&gt;AWS SQS and AWS SNS&lt;/strong&gt; event.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS SDKs
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Node.js
2.1147.0 &lt;span class="o"&gt;(&lt;/span&gt;SDK version 2&lt;span class="o"&gt;)&lt;/span&gt;
3.105.0 &lt;span class="o"&gt;(&lt;/span&gt;SDK version 3&lt;span class="o"&gt;)&lt;/span&gt;

Python
1.24.46 &lt;span class="o"&gt;(&lt;/span&gt;boto3&lt;span class="o"&gt;)&lt;/span&gt;
1.27.46 &lt;span class="o"&gt;(&lt;/span&gt;botocore&lt;span class="o"&gt;)&lt;/span&gt;

Java 8 and Java 11
1.12.200 &lt;span class="o"&gt;(&lt;/span&gt;SDK version 1&lt;span class="o"&gt;)&lt;/span&gt;
2.17.135 &lt;span class="o"&gt;(&lt;/span&gt;SDK version 2&lt;span class="o"&gt;)&lt;/span&gt;

Java 17
2.20.81

.NET
3.7.293.0

Ruby
3.134.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Types of notifications for Recursive loop
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Email&lt;/strong&gt; - An single email (once in 24 hours)  will be sent to AWS account's primary account contact and alternate operations contact.

&lt;ul&gt;
&lt;li&gt;I am using AWS organisations and iam role so it wasn't sent to my account email adress, it was my org account manager address.&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;&lt;a href="https://community.ops.io/images/qO3Sm0VbT6eaqXY8ZDnZOseN8deP8N0b9YdEPE6x2fM/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2duY2N6/aHRqZ3NnMTQ2Y3F1/eHZ6LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/qO3Sm0VbT6eaqXY8ZDnZOseN8deP8N0b9YdEPE6x2fM/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2duY2N6/aHRqZ3NnMTQ2Y3F1/eHZ6LnBuZw" alt="health dashboard email" width="800" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AWS Health Dashboard&lt;/strong&gt;- This will be inside your aws account. A notification under the&lt;code&gt;other notifications&lt;/code&gt; section with details and link to lambda function.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/1Amo1AHvN173y889qKpNVP4JRBN6THBordd-AiKFbu4/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzJ6NTN3/OG56eDYwZHl4ODl6/a3QxLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/1Amo1AHvN173y889qKpNVP4JRBN6THBordd-AiKFbu4/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzJ6NTN3/OG56eDYwZHl4ODl6/a3QxLnBuZw" alt="health dashboard" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/pCrrecZ4phkz1p9EAgwh9BUt9Ev6VdRr-aEHNqsFx08/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3l5MmMz/Y3VmYWN3NDllNm5j/djVlLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/pCrrecZ4phkz1p9EAgwh9BUt9Ev6VdRr-aEHNqsFx08/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3l5MmMz/Y3VmYWN3NDllNm5j/djVlLnBuZw" alt="email dashboard link" width="800" height="253"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: For both email and health dashboard, notifications will take around 3 hours to arrive.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Cloudwatch alarms&lt;/strong&gt; - In order to set the alarm we need to check the &lt;code&gt;RecursiveInvocationsDropped&lt;/code&gt; metric. We can always set an alarm if this metric count is more than 0.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I haven't set up alarms personally for this test, so feel free to post about this in the comments. Would love to hear.&lt;/li&gt;
&lt;/ul&gt;


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

&lt;h2&gt;
  
  
  How to fix this recursion loop?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Remove or disable the trigger which invokes lambda function. &lt;a href="https://github.com/jatinmehrotra/aws-lambda-recursion/blob/7b1430ab77f1e7381ac21deb37e7094217e3b907/lib/cdk-recursion-lambda-stack.ts#L34"&gt;In our case sns  topic trigger&lt;/a&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addSubscription&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;aws_sns_subscriptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LambdaSubscription&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;//remove this trigger&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Identify and fix code which may be cause the loop. in our case I am sending the message from lamba to the same sns topic &lt;a href="https://github.com/jatinmehrotra/aws-lambda-recursion/blob/7b1430ab77f1e7381ac21deb37e7094217e3b907/lambda/send-message.ts#L8"&gt;which is the source&lt;/a&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SNSClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PublishCommand&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@aws-sdk/client-sns&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;SNSClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AWS_Region&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// PublishInput&lt;/span&gt;
      &lt;span class="na"&gt;TopicArn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TOPIC_ARN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// fix this&lt;/span&gt;
      &lt;span class="na"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This is a message from lambda&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;PublishCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Setting concurrency to 0. It basically acts like disabling lambda or like how aws says off switch for lambda.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If sqs is the source set up &lt;a href="https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-dead-letter-queue.html"&gt;DLQ&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If sns is the source set up &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html#invocation-async-destinations"&gt;on failure destination&lt;/a&gt; for lambda.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to turn off this feature?
&lt;/h2&gt;

&lt;p&gt;By default this feature is turned on for supported AWS Services and sdk's. If your usecases uses recursive patterns, then you can request to turn off Lambda recursive loop detection. To request this change, &lt;a href="https://repost.aws/knowledge-center/aws-phone-support"&gt;contact AWS Support&lt;/a&gt;.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Recursion loop is not so often scenario but if its happens can cost a lot of money for your account and it can happen anyway due to misconfiguration or ignorance when writing lambda code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Right now this feature is not supported for other services like Dynamodb and s3 events. In case of dynamodb and s3, the only way to detect recursive loop is using cloudwatch alarms. Please make a note of this.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I really hope in the future this feature is supported in &lt;a href="https://aws.amazon.com/devops-guru/"&gt;DevOps Guru &lt;/a&gt;so that is very easy to find out the cause of this loop.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>lambda</category>
      <category>sns</category>
      <category>finops</category>
    </item>
    <item>
      <title>DevOps: Understanding Build and Package Manager Tools</title>
      <dc:creator>Jatin Mehrotra</dc:creator>
      <pubDate>Sun, 15 Jan 2023 06:52:53 +0000</pubDate>
      <link>https://community.ops.io/jatin/devops-understanding-build-and-package-manager-tools-27am</link>
      <guid>https://community.ops.io/jatin/devops-understanding-build-and-package-manager-tools-27am</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This blog talks about why an understanding of build tools, and package management tools is important for DevOps Engineers.&lt;/p&gt;

&lt;p&gt;In this blog we are going to build our knowledge of build tools and based on that we will establish how docker helps us with building code.&lt;/p&gt;

&lt;p&gt;This is a beginner-friendly blog that assumes you do not know anything about building code, artifacts or package management tools.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Outcome of the Blog
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/dYYszTQQkF4zSSCwO69Z1UtXbDClWDwmwteBW41dzdY/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3F4NmRw/ZjZ3eTh5N2Y3bnVh/ODlhLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/dYYszTQQkF4zSSCwO69Z1UtXbDClWDwmwteBW41dzdY/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3F4NmRw/ZjZ3eTh5N2Y3bnVh/ODlhLnBuZw" alt="Outcome" width="721" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By the end of this blog, you will know: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is Maven and grade, their difference and how does it help to build code for JAVA-based applications&lt;/li&gt;
&lt;li&gt;What is artifact and it's types and what is artifact repository&lt;/li&gt;
&lt;li&gt;How build tools and Docker are related&lt;/li&gt;
&lt;li&gt;The role of DevOps Engineers in this Building code phase&lt;/li&gt;
&lt;/ul&gt;

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


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://www.techworld-with-nana.com/devops-bootcamp" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://community.ops.io/images/EghRhhzjfZoe-WRqlC_6zuKEUmcXn0oAiXmCwsyFZfQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9zdGF0/aWMud2l4c3RhdGlj/LmNvbS9tZWRpYS9l/NzE4MmZfZmI5Mjk3/N2JhZTY5NDA3NGJl/YTAwMzk2YjFjZjg5/NDZ-bXYyLnBuZy92/MS9maWxsL3dfMTIw/MCxoXzYzMCxhbF9j/L2U3MTgyZl9mYjky/OTc3YmFlNjk0MDc0/YmVhMDAzOTZiMWNm/ODk0Nn5tdjIucG5n" height="462" class="m-0" width="880"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://www.techworld-with-nana.com/devops-bootcamp" rel="noopener noreferrer" class="c-link"&gt;
          DevOps Bootcamp | Techworld with Nana
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          6-month program to start your career as DevOps engineer
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://community.ops.io/images/pUJ_M-ZFFTixqyoGn39gLAPqXpRzPegDOHddl9SLk44/w:880/mb:500000/ar:1/aHR0cHM6Ly9zdGF0/aWMud2l4c3RhdGlj/LmNvbS9tZWRpYS9l/NzE4MmZfZDExMDc3/MjQ5MDE0NGViMjhh/YzFhMDdlOTVlZDk5/NzIlN0VtdjIucG5n/L3YxL2ZpbGwvd18z/MiUyQ2hfMzIlMkNs/Z18xJTJDdXNtXzAu/NjZfMS4wMF8wLjAx/L2U3MTgyZl9kMTEw/NzcyNDkwMTQ0ZWIy/OGFjMWEwN2U5NWVk/OTk3MiU3RW12Mi5w/bmc" width="32" height="32"&gt;
        techworld-with-nana.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: &lt;em&gt;I am not selling anything to you, just my personal views.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The idea for this blog comes from the Bootcamp I am currently undergoing to understand and acquire the niche skills of a DevOps Engineer by &lt;a href="https://www.linkedin.com/in/nana-janashia/"&gt;Nana Janashia&lt;/a&gt;. This Bootcamp can really help you to learn those skills needed for DevOps engineers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prequisites
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;I did mention earlier that it is a beginner-friendly blog, but there are a few tools which are needed to follow along.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;&lt;strong&gt;(Don't worry if you don't know I will post relevant links to brush up wherever needed :D)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;IntelliJ IDEA&lt;/li&gt;
&lt;li&gt;Maven &lt;/li&gt;
&lt;li&gt;Gradle&lt;/li&gt;
&lt;li&gt;Nodejs&lt;/li&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Why build the code?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;When you developed an application,&lt;em&gt;&lt;strong&gt;(for our understanding,lets stick our discussion to java based application)&lt;/strong&gt;&lt;/em&gt; it needs to be deployed on the production server so that people can consume/use it.&lt;/li&gt;
&lt;li&gt;Usually, any application will also have dependencies too, so how to move code from the local machine to the production server with dependencies?&lt;strong&gt;(Entire application ( main code + dependencies) will be big in size)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;To deploy the file, it is packed into a single movable file also called a package.&lt;/li&gt;
&lt;li&gt;This single package file is called an artifact.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The process of packaging multiple files into one ( compressed form) is called building the code, tools which help us to build code are called build tools.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;For java based applications the popular ones are maven, gradle.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What kind of file is the artifact?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Artifacts generated from maven or gradle are JAR or WAR file.&lt;/li&gt;
&lt;li&gt;Strictly Speaking of maven and Gradle based artifacts includes the application code + dependencies too but in the case of nodejs-based application tools package management tools not build tools ( will be discussed later) only contains the application code, not dependencies.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What is artifact repository?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Artifact repository is place where artifacts are stored&lt;/li&gt;
&lt;li&gt;It keeps artifact storage and makes it convenient to deploy it multiple times, have backup etc&lt;/li&gt;
&lt;li&gt;Build tools have commands for publishing to artifact repository and then you van download from anywhere on server using wget or curl.&lt;/li&gt;
&lt;li&gt;Artifact repository - nexus, jfrog for java-based application artifact.&lt;/li&gt;
&lt;li&gt;Later in the blog we will see how docker helps us to use a single repository for artifacts.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Similarities Between Maven and Gradle and other tools.
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;All are command line tools which have the options to run the code, test the code, build the code/zip, and publish to artifact repository.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can configure all these build tools like their build target directory, which files to include etc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  How build tool manages development and management dependencies?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;We need to use build tools &lt;strong&gt;locally when we are developing applications in order to test and run locally.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Build too also helps us to manage dependencies by automatically installing them.&lt;/li&gt;
&lt;li&gt;Maven dependencies are stored in pom.xml, for gradle build.gradle. ( Will be discussed later how they manage dependencies)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Let's Build some JAVA Code
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;For this blog, use this GitLab repository which has a sample JAVA maven application, JAVA Gradle Application and React Node and &lt;a href="https://docs.gitlab.com/ee/gitlab-basics/start-using-git.html#clone-a-repository"&gt;clone it to your local environment&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I would recommend using IntelliJ IDE as it will simplify the configuration process of JAVA for the project to a great extent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://gitlab.com/nanuchi/java-maven-app"&gt;JAVA Maven application&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://gitlab.com/nanuchi/java-app"&gt;JAVA Gradle application&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/nanuchi/react-nodejs-example"&gt;React-Node applicatoion&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Building JAVA app using maven
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;maven requires us to configure how build will take place.&lt;/li&gt;
&lt;li&gt;In our repository since it is an application which is using Sprint framework we will need to configure maven to build the code for spring boot by adding a plugin in pom.xml ( dependency resolution file for java apps)
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt; &lt;span class="nt"&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-maven-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.3.5.RELEASE&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;repackage&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;To build, you can write the commands in the integrated terminal of IntelliJ.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvc &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://community.ops.io/images/MnHC-9ZvXzYs09l7HJGZxqUPUnsE-wlGPozryoCZZ9c/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3VqZzRm/eGpibDdoMXRkYjA0/cXU1LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/MnHC-9ZvXzYs09l7HJGZxqUPUnsE-wlGPozryoCZZ9c/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3VqZzRm/eGpibDdoMXRkYjA0/cXU1LnBuZw" alt="maven build result" width="880" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After the build is complete, maven places the jar file inside the target folder.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/r57nuQ7lOzQyTvZXQtTPG7j5barNyHXlyt_VZQueJnw/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3M0MG90/bmdrNXEwdjdwZWZ6/MHZ3LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/r57nuQ7lOzQyTvZXQtTPG7j5barNyHXlyt_VZQueJnw/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3M0MG90/bmdrNXEwdjdwZWZ6/MHZ3LnBuZw" alt="JAR file form maven" width="880" height="149"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Building JAVA app using gradle
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Gradle does not require any kind of configuration. Dependency resolution file for gradle is build.gradle. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To build using gradle&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./gradlew build    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://community.ops.io/images/eEPWq1IO15euTJf5my7qa0QsFFk_tnh8GdX9dqSXd1A/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3ZnNDcz/MmY3NzB0ZmtkbDM4/NDIxLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/eEPWq1IO15euTJf5my7qa0QsFFk_tnh8GdX9dqSXd1A/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3ZnNDcz/MmY3NzB0ZmtkbDM4/NDIxLnBuZw" alt="gradle build" width="880" height="197"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gradles places the JAR file under build directory instead opf target directory unlike maven.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/ElANWP8lK49-lRgB-R4agzPYquuI-MfBc2l2NbLOIww/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2Z0Mnp6/d3h0M2ZtdmZ6M3p2/ZTNpLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/ElANWP8lK49-lRgB-R4agzPYquuI-MfBc2l2NbLOIww/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2Z0Mnp6/d3h0M2ZtdmZ6M3p2/ZTNpLnBuZw" alt="Gradle JAR file" width="716" height="280"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  How to run the artifact
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Now we know we need to build the artifact and move it to server but how to run the artifact?
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java &lt;span class="nt"&gt;-jar&lt;/span&gt; &amp;lt;name of the file&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Let's Manage NodeJS application
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;NodeJs based application usually doe not have artifact type &lt;/li&gt;
&lt;li&gt;In fact, nodejs based application have &lt;strong&gt;NPM or YARN as their package management tool, they dont build anything.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;They don't have a structure or standard way to do it, unlike maven or Gradle.&lt;/li&gt;
&lt;li&gt;JS artifact are zip or TAR files.&lt;/li&gt;
&lt;li&gt;zip/tar file only contains application and not dependencies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In order to run JS application on production server these are the steps&lt;/p&gt;

&lt;p&gt;1) Copy artifact ( zip file) and package.json file to production server&lt;br&gt;
2) install dependencies &lt;br&gt;
3) unpack zip/tar artifact&lt;br&gt;
4) run the App&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm pack &lt;span class="nb"&gt;command&lt;/span&gt; &lt;span class="c"&gt;# create tgz file containing package.json file too along with source code.&lt;/span&gt;
npm test. &lt;span class="c"&gt;# for testing&lt;/span&gt;
npm publish &lt;span class="c"&gt;# for publish to artifact repository&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to manage Building for frontend and backend
&lt;/h2&gt;

&lt;p&gt;Usually, frontend and backend of an application are seperate. Common pattern include like using React for front end with backend based out of nodejs or JAVA.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In any case either a separate artifact can be produced or common artifact can also be the option, which means seperate package.json for the former if backend is also based out of nodejs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; React code needs to be bundled, transpilled, and compressed. A tool called &lt;a href="https://webpack.js.org/"&gt;webpack&lt;/a&gt;which produces &lt;strong&gt;server.bundle.js&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;webpack also has a command line interface &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To use webpack, use these commands&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;api 
npm &lt;span class="nb"&gt;install&lt;/span&gt; // &lt;span class="k"&gt;for &lt;/span&gt;downloading webpack dependency
npm run build

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://community.ops.io/images/inV6gJZDEZ58Z5w822H1vTyH-Hmv5kdSJuiXhOhxTL8/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2ZvYWF2/YTA5b3l4a2Voczk3/NGhhLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/inV6gJZDEZ58Z5w822H1vTyH-Hmv5kdSJuiXhOhxTL8/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2ZvYWF2/YTA5b3l4a2Voczk3/NGhhLnBuZw" alt="webpack command" width="880" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Webpack produces a minified version of the entire react code &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/EFZ64hpl0jNrSEc_iG91kswQc_9sx1QODJaGjQ9au98/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3Q5dDlh/OTkyYmljY2ZzcmY4/ZXA0LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/EFZ64hpl0jNrSEc_iG91kswQc_9sx1QODJaGjQ9au98/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3Q5dDlh/OTkyYmljY2ZzcmY4/ZXA0LnBuZw" alt="Webpack bundle" width="880" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Relation between Build tools and Docker
&lt;/h2&gt;

&lt;p&gt;Modern architecture involves micro services sometimes inside a single project one microservice can be JAVA based and another can be nodejs or python based. Does that mean we need to handle different artifact types?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/b-Kh5qeP2wd-dY7ULrqlBRiVxinZJJF-id1ZgYAFOkM/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzk5MjN6/OWVnZDZjZjFwMXYy/a3lhLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/b-Kh5qeP2wd-dY7ULrqlBRiVxinZJJF-id1ZgYAFOkM/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzk5MjN6/OWVnZDZjZjFwMXYy/a3lhLnBuZw" alt="WHy we need docker" width="721" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;With docker, we don't need to build and move different artifact types. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;There is just one artifact type - Docker images&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Now, we build Docker images from the application and we don't need a repository for each file type, no need to move multiple files to the server like package.json, no need to zip, just copy everything into the docker filesystem and run it from docker image.&lt;/li&gt;
&lt;li&gt;Docker image is also an artifact&lt;/li&gt;
&lt;li&gt;In order to start the application you don't need npm or java on the server, execute everything ( command to run the JAR or node application) inside the docker image.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note - we don't have to create zip or tar files anymore because we can copy JS files into a docker image. But we still need to build apps outside the docker image and then copy it inside the docker image. For eg webpack or in the case of JAVA create a JAR file , then copy JAR file or bundle.js will create a docker image.&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;// for gradle app 

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; openjdk:8-jre-alpine&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8080&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./build/libs/java-app-1.0-SNAPSHOT.jar /usr/app/&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/app&lt;/span&gt;

&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["java", "-jar", "java-app-1.0-SNAPSHOT.jar"]&lt;/span&gt;


// for nodejs ap


&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;ui-build&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/src/app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; my-app/ ./my-app/&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;my-app &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run build

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;server-build&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /root/&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=ui-build /usr/src/app/my-app/build ./my-app/build&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; api/package*.json ./api/&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;api &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; api/server.js ./api/&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3080&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["node", "./api/server.js"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Our role as DevOps Engineers
&lt;/h2&gt;

&lt;p&gt;Now it's interesting to know where our knowledge as a DevOps engineers will come into the picture.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developers uses these tools locally and configure the tools to run application and test. We don't have much to do in this step.&lt;/li&gt;
&lt;li&gt;We come into the picture for building the artifact, because we know where and how it will run.&lt;/li&gt;
&lt;li&gt;Developers don't build the app locally, building the artifact -&amp;gt; docker image -&amp;gt; push to repo and run on the server is the responsibility of DevOps in build automation tools like Jenkins.&lt;/li&gt;
&lt;li&gt;Our job is to configure the CICD pipeline and build automation which includes, install dependencies -&amp;gt; run tests -&amp;gt; build app -&amp;gt; push to repo as a docker image.&lt;/li&gt;
&lt;li&gt;execute tests on build servers like mvn test or npm test, build and package into the docker image.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Till then, Happy Learning !!!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Feel Free to post any comments or questions.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Connect with me over&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/jatinmehrotra/"&gt;Linkedin&lt;/a&gt; or &lt;a href="https://twitter.com/imjatinmehrotra"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>tutorials</category>
      <category>buildtool</category>
      <category>docker</category>
    </item>
    <item>
      <title>AWS CodePipeline: Build &amp; Test with CodeBuild</title>
      <dc:creator>Jatin Mehrotra</dc:creator>
      <pubDate>Fri, 06 Jan 2023 11:02:11 +0000</pubDate>
      <link>https://community.ops.io/jatin/aws-codepipeline-build-test-with-codebuild-1bdh</link>
      <guid>https://community.ops.io/jatin/aws-codepipeline-build-test-with-codebuild-1bdh</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;In this series of &lt;code&gt;Build Better CI CD Pipelines&lt;/code&gt;, we will understand concepts around CI CD and build pipelines by actually making them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/4xvRBc311wGNz_sp2aMcwvrLufcA-pVC3_2kI_-SxDE/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL29ndGdv/ZWhub2Zscmc3N3Jy/NGV6LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/4xvRBc311wGNz_sp2aMcwvrLufcA-pVC3_2kI_-SxDE/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL29ndGdv/ZWhub2Zscmc3N3Jy/NGV6LnBuZw" alt="CI CD image" width="880" height="461"&gt;&lt;/a&gt;&lt;br&gt;
In this continuous series I will add blogs with different CI CD tools and deploy various AWS services using the pipeline. &lt;/p&gt;

&lt;p&gt;This is the second blog in the series. &lt;strong&gt;In this blog, we are going to trigger our pipeline with a commit in the CodeCommit repository followed by a building code and running test actions before deploying it to s3 as a static website.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Basic knowledge of AWS fundamental services like s3, ec2, and cloud formation.&lt;/li&gt;
&lt;li&gt;Working with git and CodeCommit.&lt;/li&gt;
&lt;li&gt;Basic knowledge of dockers.&lt;/li&gt;
&lt;li&gt;Fundamental knowledge of CI-CD concepts. You can read my previous blogs where I have covered &lt;a href="https://community.ops.io/jatin/ci-cd-101-with-gitlab-4pol"&gt;CI CD 101 with GitLab&lt;/a&gt;, &lt;a href="https://community.ops.io/jatin/aws-codepipeline-cd-pipeline-with-s3-57m7"&gt;CD pipeline with S3&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

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


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://www.udemy.com/course/aws-codepipeline-step-by-step/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://community.ops.io/images/83NV9WYteLQx-eMmLFJINo6uSJKLBOafff4-C1MoZqA/w:880/mb:500000/ar:1/aHR0cHM6Ly9pbWct/Yy51ZGVteWNkbi5j/b20vY291cnNlLzQ4/MHgyNzAvMjcxMzEz/Nl85ODk0XzguanBn" height="270" class="m-0" width="480"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://www.udemy.com/course/aws-codepipeline-step-by-step/" rel="noopener noreferrer" class="c-link"&gt;
          AWS CodePipeline Step by Step | Udemy
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Learn AWS CodePipeline with CodeCommit, CodeBuild &amp;amp; CodeDeploy, DevOps CI/CD on AWS from an AWS certified expert!
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://community.ops.io/images/6TO32ujff-z4szIcnkJtvTub8JlqUzri7j-BNJTMDQ8/w:880/mb:500000/ar:1/aHR0cHM6Ly93d3cu/dWRlbXkuY29tL3N0/YXRpY3gvdWRlbXkv/aW1hZ2VzL3Y4L2Zh/dmljb24tMzJ4MzIu/cG5n" width="32" height="32"&gt;
        udemy.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;The idea for this blog comes from one of the &lt;a href="https://www.udemy.com/course/aws-codepipeline-step-by-step/"&gt;amazing udemy courses&lt;/a&gt; by &lt;a href="https://www.linkedin.com/in/emre-yilmaz-shikisoft/"&gt;Emre Yilmaz&lt;/a&gt;. This course is a great course not only for beginners but also for experienced DevOps Engineers.&lt;/p&gt;

&lt;p&gt;Emre Yilmaz covers all the important concepts around CI CD AWS services at the most 101 level with advanced concepts along with hands-on which reinforces the concepts.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is CodeBuild?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;In the simplest terms, &lt;strong&gt;AWS CodeBuild allows you to run commands on your project. It acts as a command line in your pipelines.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Its serverless, scalable and fully managed service.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How does CodeBuild execute commands?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CodeBuild uses the Docker container for the build environments. Inside these containers, you can execute commands desired for building or testing code.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Commands are mentioned in a YAML file usually called buildspec.yml(default name), if the user defines a custom name they need to mention it so that CodeBuild can find the YAML file.&lt;/li&gt;
&lt;li&gt;We can use docker images provided by AWS or public images on the docker hub or custom images uploaded to ECR.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:-&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We can use a standalone codebuild project and trigger than console, sdk or cli.&lt;/li&gt;
&lt;li&gt;We can also schedule codebuild projects using cloudwatch events&lt;/li&gt;
&lt;li&gt;Uses IAM service roles to execute codebuild project&lt;/li&gt;
&lt;li&gt;Data in transit is encrypted and at rest using CMK managed by AWS KMS. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Let's Build the Pipeline
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Create a CodeCommit Repository
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create a CodeCommit repository and push the sample angular application to this repository.&lt;/li&gt;
&lt;li&gt;You can find the angular code &lt;a href="https://github.com/jatinmehrotra/codebuild-blog-angular"&gt;in this repository&lt;/a&gt;. All thanks to Emre Yilmaz.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/K8BR5mZ29HISoya7vGYeuuitQuI6y1PMDi1c7pLsGSg/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL283NGt2/cmdlbGh3MDdqYmw4/NjAxLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/K8BR5mZ29HISoya7vGYeuuitQuI6y1PMDi1c7pLsGSg/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL283NGt2/cmdlbGh3MDdqYmw4/NjAxLnBuZw" alt="CodeCommit Angular code" width="880" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Create the Pipeline for build and unit testing
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Configuring Source for the Pipeline
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Under the same pane select codepipeline and add name and role name for the pipeline.&lt;/li&gt;
&lt;li&gt;Moving forward, we need to select the source which will trigger the pipeline, this will be our code commit repository created in the previous step. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;For trigger we are choosing the recommended option of using Cloudwatch Events.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Configuring Build Provider for the Pipeline
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;For the Build Provider we will use AWS CodeBuild.&lt;/li&gt;
&lt;li&gt;Here we will create a new CodeBuild Project for &lt;strong&gt;building the angular application&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/d_ydggUQhxTe3PWBLGoHTR1uvY0OBLOyaa-5oxJmvO8/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2NldGt6/Y3EweWc1bGR6YzB2/eGhnLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/d_ydggUQhxTe3PWBLGoHTR1uvY0OBLOyaa-5oxJmvO8/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2NldGt6/Y3EweWc1bGR6YzB2/eGhnLnBuZw" alt="CodeBuild build stage" width="802" height="612"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Under the new window, we will configure our codebuild project settings like docker image, OS, IAM Role, and Buildspec.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/VErcd1Fs1QKy40jUpca4k5iOkx1ogNC205svuFXBWR4/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzM1eXMz/emJ4eXd0cWJoZjJs/dGh6LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/VErcd1Fs1QKy40jUpca4k5iOkx1ogNC205svuFXBWR4/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzM1eXMz/emJ4eXd0cWJoZjJs/dGh6LnBuZw" alt="codebuild project for build information" width="641" height="1023"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Here we are choosing Amazon managed image. provided by AWS with ubuntu as the operating system. For the Building project, we are specified to use a &lt;a href="https://github.com/jatinmehrotra/codebuild-blog-angular/blob/main/buildspec.yml"&gt;buildspec file&lt;/a&gt; which will be found by codebuild if the name is buildspec.yml by default. &lt;strong&gt;The structure of buildspec file is explained later.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Deploy the build app to s3
&lt;/h4&gt;

&lt;p&gt;Just like the previous blog, &lt;a href="https://community.ops.io/jatin/aws-codepipeline-cd-pipeline-with-s3-57m7"&gt;create a production s3 bucket&lt;/a&gt;, we will create a bucket, enable static website hosting and configure it in the Deploy stage of CodePipeline.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/itteGXSIjoCwMpAtOoZAW7xFgFseMUChrYt7PjiVA30/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3IzZ200/NXl4ZXY1NmViZnFw/NWt3LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/itteGXSIjoCwMpAtOoZAW7xFgFseMUChrYt7PjiVA30/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3IzZ200/NXl4ZXY1NmViZnFw/NWt3LnBuZw" alt="Deploy Stage" width="725" height="758"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Understanding Buildspec structure + unit testing
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Before creating the pipeline, it is very important to understand how codebuild will use buildspec.yml file to build the code which means how to write the buildspec.yml file.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  buildspec.yml for building angular code
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;A YAML file containing your commands and runtime env settings.&lt;/li&gt;
&lt;li&gt;Can be a separate file in the source code or we can mention commands in the console.&lt;/li&gt;
&lt;li&gt;Commands can be defined and executed in phases like &lt;strong&gt;install, pre_build, build, post_build&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Can define multiple runtimes for commands like nodejs, ruby or python or 2.0 for amazon Linux. If you don't define runtime it will use the default runtime of the image.&lt;/li&gt;
&lt;li&gt;Artifact configuration can also be defined in buildspec which tells which files and directories will be included in artifact.&lt;/li&gt;
&lt;li&gt;Environment variables can also be defined as key-value pairs, but can also be referenced using the Ec2 parameter store or secrets manager.&lt;/li&gt;
&lt;li&gt;Environment variables can be set outside buildspec for the entire project and use in your commands, which helps in reusing buildspec files across different codebuild projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;[Imp] We can also use different buildspec files in the source code repository for different code build projects&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.2&lt;/span&gt;

&lt;span class="na"&gt;phases&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;install&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runtime-versions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;nodejs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm install -g @angular/cli@9.0.6&lt;/span&gt;
  &lt;span class="na"&gt;pre_build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm install&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ng build --prod&lt;/span&gt;
    &lt;span class="na"&gt;finally&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo final block echo&lt;/span&gt;

&lt;span class="na"&gt;artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;base-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dist/my-angular-project&lt;/span&gt;
  &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;**/*'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Buildspec Phases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Commands executed for installing packages in build env&lt;/li&gt;
&lt;li&gt;During installation&lt;/li&gt;
&lt;li&gt;Best Practice: runtime version are also defined in this phase&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Prebuild
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Commands run before the build&lt;/li&gt;
&lt;li&gt;Use for installing dependencies, signing into ECR, docker hub etc.&lt;/li&gt;
&lt;li&gt;If you are building Docker Images, use this phase for signing into ECR.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Build
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use for running builds and tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  PostBuild
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Command after build.&lt;/li&gt;
&lt;li&gt; For example: sending SNS notifications using aws cli.&lt;/li&gt;
&lt;li&gt; Pushing images to the docker repository after building it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  artifacts
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This section tells codebuild where to find the artifact created by build command and use as &lt;strong&gt;build artifact&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;We are using wildcards to &lt;strong&gt;recursively include all directories&lt;/strong&gt; and their files for the build base directory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Phases are optional but one must be defined in buidspec&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding Unit Testing to Pipeline Using CodeBuild
&lt;/h2&gt;

&lt;h3&gt;
  
  
  why do we need to add tests to pipelines?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Because we can break the logic and bad logic can ship to the product.&lt;/li&gt;
&lt;li&gt;So ideally &lt;strong&gt;we should run unit tests in our code and then run the build command after them.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  How to add tests in the CodePipeline
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;either add unit test command either in the build phase in the buildpec.yml OR &lt;strong&gt;the preferred way&lt;/strong&gt; by separating unit test with build process by adding another buildspec.yml file as another codeBuild Project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Since we want testing to take place before building we will add the action just before the build action group in the CodePipeline ( this logic has been explained in the previous blog) &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/eNI4sXtn6Wn2LIkqpxDB53SaC_kGegouFey4TqYIkYw/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzhoeXk0/NDg1aG5hbzhoanhh/ZzdjLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/eNI4sXtn6Wn2LIkqpxDB53SaC_kGegouFey4TqYIkYw/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzhoeXk0/NDg1aG5hbzhoanhh/ZzdjLnBuZw" alt="adding test project" width="697" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Note: For testing, we are creating a separate CodeBuild Project with a different buildspec.yml file dedicated to testing, hence we need to specify the name of the buildspec file during project creation &lt;a href="https://github.com/jatinmehrotra/codebuild-blog-angular/blob/main/unit-test-buildspec.yml"&gt;unit-test-buildspec.yml&lt;/a&gt;. Here we are using Managed docker image from aws but the version is 5.0 not 6.0 as earlier.**&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/eHtU88gFjLOA1mnlBoXLKvGbikIOUD64__lxMX-MpzI/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3RoZWZj/MDA3YWZzYXg3N2Zv/NDhtLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/eHtU88gFjLOA1mnlBoXLKvGbikIOUD64__lxMX-MpzI/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3RoZWZj/MDA3YWZzYXg3N2Zv/NDhtLnBuZw" alt="codebuild test project for testing" width="644" height="909"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unit Testing Buildspec.yml
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.2&lt;/span&gt;

&lt;span class="na"&gt;phases&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;install&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runtime-versions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;nodejs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm install -g @angular/cli@9.0.6&lt;/span&gt;
  &lt;span class="na"&gt;pre_build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;npm install&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ng test --no-watch --no-progress --browsers=ChromeHeadlessCI&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Interesting things about buildspec.yml
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How to simulate a failure in build
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Sometimes we need to simulate a failure in our builds for that we can simply return a non zero value before build command&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;If the error happens before the build phase the execution switches to the final phase. If execution happens in the build phase it continues to the remaining phase.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt; &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;exit &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ng build --prod&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run command irrespective of whether pipeline fails or passes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt; &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ng build --prod&lt;/span&gt;
    &lt;span class="na"&gt;finally&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo final block echo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Testing Pipeline
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Upload the code to CodeCommit Repository. The pipeline will run.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/NG-Av9QSux4r7mjOR1FOm9b2gy1RIkLzV2ZcR6OpETQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2dseno4/ZDlwc2x5a3V4ODJn/dGw5LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/NG-Av9QSux4r7mjOR1FOm9b2gy1RIkLzV2ZcR6OpETQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2dseno4/ZDlwc2x5a3V4ODJn/dGw5LnBuZw" alt="How pipeline Works" width="880" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Finally, verify Deployment by going to the s3 website URL.
&lt;img src="https://community.ops.io/images/FEqmDUpgWkDqWkjD8PR1XIBCfaNsmj08QvU8wQ7Evj0/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL20zdnNo/djIydzh3MXFmbmtp/a2NzLnBuZw" alt="codepipeline deployment" width="880" height="222"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  From DevOps Perspective.
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;In this Blog, we understood how CodeBuild works and uses docker containers to act as a command line for our code when running in CodePipeline.&lt;/li&gt;
&lt;li&gt;We understand how we can add testing to Codepipeline &lt;/li&gt;
&lt;li&gt;We understood how to write buildspec.yml and its various syntax.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the next blog, we are going to learn CodeDeploy to deploy the code to ec2 instances and add further automation. &lt;/p&gt;

&lt;p&gt;Till then, Happy Learning !!!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Feel Free to post any comments or questions.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Connect with me over&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/jatinmehrotra/"&gt;Linkedin&lt;/a&gt; or &lt;a href="https://twitter.com/imjatinmehrotra"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>codebuild</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Using AWS CodeCatalyst: I Created and Deployed a React SPA #reinvent</title>
      <dc:creator>Jatin Mehrotra</dc:creator>
      <pubDate>Fri, 02 Dec 2022 00:30:55 +0000</pubDate>
      <link>https://community.ops.io/jatin/using-aws-codecatalyst-i-created-and-deployed-a-react-spa-reinvent-1lo9</link>
      <guid>https://community.ops.io/jatin/using-aws-codecatalyst-i-created-and-deployed-a-react-spa-reinvent-1lo9</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;In this blog I am going to introduce &lt;strong&gt;AWS CodeCatalyst&lt;/strong&gt; a new service that AWS announced at re:Invent 2022. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;It is a Unified software development service to quickly build and deliver applications on AWS.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;CodeCatalyst project consists of blueprints which setup new software development projects without any human effort, including CI/CD, deployable code, issue tracking, and AWS services (IAM roles and policies) configured according to best practices.&lt;/p&gt;

&lt;p&gt;You can know more about &lt;a href="https://codecatalyst.aws/explore"&gt;CodeCatalyst on their website &lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Features of CodeCatalyst
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dev Environments:&lt;/strong&gt; CodeCatalyst Dev Environments are automatically created with pre-installed dependencies and language-specific packages with integrated IDE.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Built-In Issue Tracking:&lt;/strong&gt; It allows to create issues, add custom labels, and feedback on issues.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Customize pipelines:&lt;/strong&gt; Create and customize automated workflows by configuring pre-defined actions using the desired IDE or directly editing the underlying YAML configuration. We can also use any GitHub Action in your workflows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Built-in Code coverage, test support:&lt;/strong&gt; built-in support for code coverage, software composition analysis, and unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Easy Deployment to AWS:&lt;/strong&gt;  Deploy applications to AWS services such as S3 or Cloudfront using CDK across accounts or regions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Better Collaboration:&lt;/strong&gt;  Track project activity such as deployments, accepted pull requests through CodeCatalyst’s notifications and personalized activity feed. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You need to create AWS Builder ID ( &lt;a href="https://docs.aws.amazon.com/general/latest/gr/aws_builder_id.html"&gt;to know more about it&lt;/a&gt; )&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/j8SI-a39yXVZcFKtHEKM3m-S5P0un45BzGaLVobvFhs/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3llMnZq/ZDkwZDBuOGliY252/MHlvLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/j8SI-a39yXVZcFKtHEKM3m-S5P0un45BzGaLVobvFhs/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3llMnZq/ZDkwZDBuOGliY252/MHlvLnBuZw" alt="codebuilder Image" width="880" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At this moment, &lt;strong&gt;this service is in preview mode and only available in Oregon Region&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to access CodeCatalyst?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CodeCatlyst can access from &lt;a href="https://codecatalyst.aws/explore"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set up an alias for CodeCatalyst. This is a unique identifier in CodeCatalyst. People will use this alias to mention in comments and pull requests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a Space: Space is where you collaborate with others on your software projects, verify your space and create it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/Jj4TWSsMl1k7ZC9mnhWW1wiqD0F3QWSrJNg694wALRk/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzdiM3d5/ZzJiMzQ4bXoxcGM0/cG9lLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/Jj4TWSsMl1k7ZC9mnhWW1wiqD0F3QWSrJNg694wALRk/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzdiM3d5/ZzJiMzQ4bXoxcGM0/cG9lLnBuZw" alt="alias and space" width="880" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's see CodeCatalyst in action.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create a project
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt; Can be either with a blueprint or from scratch. For this blog, we will use a &lt;strong&gt;Single-page application blueprint.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/SJv_xxUsh4x8pLgfX55gLVLyfZv2KqWGTyQ-RDVEN08/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2VkeHp0/cGt4Ynptb3plOHl6/ODVmLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/SJv_xxUsh4x8pLgfX55gLVLyfZv2KqWGTyQ-RDVEN08/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2VkeHp0/cGt4Ynptb3plOHl6/ODVmLnBuZw" alt="project" width="880" height="237"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/kcitQYyOwx-6dsGmDlvOZzrMO7E4witpHW006RnkgA4/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3c5aHAz/bXBzc2kzcXdteGRl/ZGRwLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/kcitQYyOwx-6dsGmDlvOZzrMO7E4witpHW006RnkgA4/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3c5aHAz/bXBzc2kzcXdteGRl/ZGRwLnBuZw" alt="blueprint selected" width="880" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After selecting the blueprint you can know more about it on the right pane. What does it do, about its architecture, which aws service components are being used and their explanation, about the IAM role, its permissions and trust policy it needs, account connections environment needs, and what resources it will create?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/ky-m-Ywznyh3yb5CjUKPkpYwOeVLeDPprpa2wL0Tb7s/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3o5YXI5/cGFmY3lhOW54ZDM3/cXo0LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/ky-m-Ywznyh3yb5CjUKPkpYwOeVLeDPprpa2wL0Tb7s/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3o5YXI5/cGFmY3lhOW54ZDM3/cXo0LnBuZw" alt="blueprint-iam role" width="638" height="898"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;About SPA Blueprint&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;This particular blueprint This blueprint creates a single-page application (SPA) project of the web application framework chosen. You can choose either the Angular, React, or Vue web application frameworks. The project uses the AWS Cloud Development Kit (CDK) to deploy to the chosen hosting service, either AWS Amplify Hosting or Amazon Cloudfront + Amazon S3.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;On the next page, give a name to the project and click on add IAM role. It will redirect to role creation and page and after creation, it will be added to your spaces and then added this role to the project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/zSisBmVunnn0yUuouPZei-P8habUJZxmnFNl4Fwg-sw/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzZidWFy/d2t4aTAyemN1amtw/OXZoLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/zSisBmVunnn0yUuouPZei-P8habUJZxmnFNl4Fwg-sw/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzZidWFy/d2t4aTAyemN1amtw/OXZoLnBuZw" alt="project details" width="880" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/6dhOd4kDdFdqZo_3VSIuUeKJoaivmPeA7QS1ATLyEQw/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2puaXlx/ejRoM2hrdXR4NGtv/ZGV5LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/6dhOd4kDdFdqZo_3VSIuUeKJoaivmPeA7QS1ATLyEQw/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2puaXlx/ejRoM2hrdXR4NGtv/ZGV5LnBuZw" alt="iam role" width="880" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;em&gt;If you don't add the role to your project, workflows will not able to run as they need permissions in order to interact with various AWS services.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/daLLjuu03F0yDrcsTCAPVBs7YC32_NakyqZWeBHp_cI/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3Z4aGVh/MzltMWtucXBwdXBw/azBrLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/daLLjuu03F0yDrcsTCAPVBs7YC32_NakyqZWeBHp_cI/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3Z4aGVh/MzltMWtucXBwdXBw/azBrLnBuZw" alt="adding role to project" width="632" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Under additional configurations, you can configure configurations like what kind of framework, hosting and CDK programming language, region, repository name, and stack name.
Of course, these configurations will change from blueprint to blueprint.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/__i5cutjbnZZaVBiWY6mcFt0lMuJXz47LvD6kkLV1M0/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2dhcDhk/anNyaml2cHl2cjhr/eHg3LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/__i5cutjbnZZaVBiWY6mcFt0lMuJXz47LvD6kkLV1M0/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2dhcDhk/anNyaml2cHl2cjhr/eHg3LnBuZw" alt="additional config" width="880" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can also view the code and workflow defined in the blueprint.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/KO1m-rIb3m8Al0eIoTyEcHsbokCU9E78ZuKHrOTdY6A/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3EyY2Vh/cnM2d2UwM2M1czBp/N3pyLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/KO1m-rIb3m8Al0eIoTyEcHsbokCU9E78ZuKHrOTdY6A/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3EyY2Vh/cnM2d2UwM2M1czBp/N3pyLnBuZw" alt="option for code and workflow" width="415" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code&lt;/strong&gt; tells about the code generated in the blueprint.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/dbr01XddfXriqnsNnq1tlKCIrv6m7FJBqybRiC-9Bg8/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL20ybHVw/eWE5cWpkZG9pY3k2/NWFoLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/dbr01XddfXriqnsNnq1tlKCIrv6m7FJBqybRiC-9Bg8/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL20ybHVw/eWE5cWpkZG9pY3k2/NWFoLnBuZw" alt="code" width="640" height="905"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Workflow tells what intermediary actions to be taken for events (like PUSH/PULL PR)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/2PGU_CNAR3LFszXUeqtHl7YP8bZVuVv_6ZH1v70phxA/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2hjMThv/MzFpazY0bmlmcXFt/Nm9iLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/2PGU_CNAR3LFszXUeqtHl7YP8bZVuVv_6ZH1v70phxA/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2hjMThv/MzFpazY0bmlmcXFt/Nm9iLnBuZw" alt="workflow" width="639" height="900"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create Project.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Once the project is created you can view its repository, a README is populated automatically, and You can create a workflow, Create PR, and create Issues or Environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/ZX7Q85rbdOX1WME09CKWd8YKdjWcwDQ6j7LYAtSmYZY/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2Q2Z3J3/ZGRnNmt1MDk3Z3Ns/NWVpLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/ZX7Q85rbdOX1WME09CKWd8YKdjWcwDQ6j7LYAtSmYZY/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2Q2Z3J3/ZGRnNmt1MDk3Z3Ns/NWVpLnBuZw" alt="project screen" width="880" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;In order to deploy the application we need to run the workflow. URL for the application will be in the output of the workflow.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In this blueprint, there are 2 workflows already created:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;For Building and testing the code on PR.&lt;/li&gt;
&lt;li&gt;For running deploy pipeline for push to the Main branch.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/H0jTFqrV9OQknFGxHN6hteVn2mbmxD5SXOomGDeyNRA/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzFma3Rw/eWhibTZldnVxNHNk/bXA3LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/H0jTFqrV9OQknFGxHN6hteVn2mbmxD5SXOomGDeyNRA/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzFma3Rw/eWhibTZldnVxNHNk/bXA3LnBuZw" alt="workflow pictures" width="880" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In order to create a PR, we will create a branch. In this PR we will add the &lt;code&gt;&amp;lt;p&amp;gt; tag&lt;/code&gt;  &lt;strong&gt;Developed and Deployed using CodeCatalyst&lt;/strong&gt;  and then commit it with a commit message.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/PRITsWZAA-su2kHAmE3JOAMil54H5jHHB0MNq7eq-fM/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzN6aGNq/dXk3cG9vNTQwdWR1/d3pjLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/PRITsWZAA-su2kHAmE3JOAMil54H5jHHB0MNq7eq-fM/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzN6aGNq/dXk3cG9vNTQwdWR1/d3pjLnBuZw" alt="create branch" width="880" height="197"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/P9qKZUInP99sd3RU3Jpdh_5eiSTgKxXXAu_JLGR3kPg/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2E1dHNz/aWxqbDd0bXB6ZXZw/anZ2LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/P9qKZUInP99sd3RU3Jpdh_5eiSTgKxXXAu_JLGR3kPg/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2E1dHNz/aWxqbDd0bXB6ZXZw/anZ2LnBuZw" alt="PR changes" width="880" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After PR is created workflow for &lt;strong&gt;build and test will run&lt;/strong&gt;. You can even see the workflow by clicking on its link.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/rI6H_vKG6pKAaLBMiGjEK8K58Q86u8TlhqeSSmmRhj0/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2Zxdnpk/Y2MxOXNtZzhtOXAz/NzZmLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/rI6H_vKG6pKAaLBMiGjEK8K58Q86u8TlhqeSSmmRhj0/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2Zxdnpk/Y2MxOXNtZzhtOXAz/NzZmLnBuZw" alt="link for workflow" width="305" height="902"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/ZwFt3y2328WdyeVGfnb7fPeq476JHCQ_baRqw5DoqXM/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3Bobjly/dmJqZHZwOWlqb2V5/eHVzLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/ZwFt3y2328WdyeVGfnb7fPeq476JHCQ_baRqw5DoqXM/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3Bobjly/dmJqZHZwOWlqb2V5/eHVzLnBuZw" alt="worklow details for build" width="880" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once the workflow is successful, you can ask for a review and then merge it. Upon Merge it will run the &lt;strong&gt;DeployPipeline workflow which will deploy the application&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/S1DVBWJ5wfSrBYukVc1muwchQGSfjks_xx6qc9ZRhPE/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzJkbmV4/dzYzY3dnOWNta25x/Ynk2LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/S1DVBWJ5wfSrBYukVc1muwchQGSfjks_xx6qc9ZRhPE/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzJkbmV4/dzYzY3dnOWNta25x/Ynk2LnBuZw" alt="deploy workflow" width="880" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can also check the code coverage and unit test details.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/jhV3zIaqyWfmZABdeFlGDJXAXsl4wfbNSyA_QvTv_xY/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3V0Ym0z/MGFtOXJ6YTRqcnJw/cjM4LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/jhV3zIaqyWfmZABdeFlGDJXAXsl4wfbNSyA_QvTv_xY/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3V0Ym0z/MGFtOXJ6YTRqcnJw/cjM4LnBuZw" alt="code ceverage" width="880" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Access the application by URL present in workflow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/8nDjGxf-u-IuuZnU2hIzailteXAmw4z6OAHwzaFeBYw/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2JlbGs3/Y3JscmNzZ3FzdDR2/dDh0LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/8nDjGxf-u-IuuZnU2hIzailteXAmw4z6OAHwzaFeBYw/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2JlbGs3/Y3JscmNzZ3FzdDR2/dDh0LnBuZw" alt="React app" width="880" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  From Developer and DevOps Perspective
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CodeCatalyst took me a maximum of 10 minutes ( including deployment minutes) to create and deploy which is really, really fast&lt;/strong&gt;. If I had to do this on my own using IaC, I would have to figure out role permissions, check the documentation, set up CI/CD, and integrate all the components and development environment which would have taken a lot of time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;With this all-in-one software development service, it is very easy and efficient to develop applications on AWS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This is going to save a lot of significant time and resources that software teams spend on various infrastructure components, and development environments, which will enable to deliver to quickly deliver new features or software updates to customers. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do you think CodeCatalyst will help your teams?  Share your thoughts or feedback over &lt;a href="https://www.linkedin.com/in/jatinmehrotra/"&gt;Linkedin&lt;/a&gt; or &lt;a href="https://twitter.com/imjatinmehrotra"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>aws</category>
      <category>cloudops</category>
      <category>tutorials</category>
    </item>
    <item>
      <title>Using CodeCatalyst: I Created and Deployed a React SPA.</title>
      <dc:creator>Jatin Mehrotra</dc:creator>
      <pubDate>Fri, 02 Dec 2022 00:13:22 +0000</pubDate>
      <link>https://community.ops.io/jatin/using-codecatalyst-i-created-and-deployed-a-react-spa-3g4g</link>
      <guid>https://community.ops.io/jatin/using-codecatalyst-i-created-and-deployed-a-react-spa-3g4g</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;In this blog I am going to introduce &lt;strong&gt;AWS CodeCatalyst&lt;/strong&gt; a new service that AWS announced at re:Invent 2022. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;It is a Unified software development service to quickly build and deliver applications on AWS.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;CodeCatalyst project consists of blueprints which setup new software development projects without any human effort, including CI/CD, deployable code, issue tracking, and AWS services (IAM roles and policies) configured according to best practices.&lt;br&gt;
You can know more about &lt;a href="https://codecatalyst.aws/explore"&gt;CodeCatalyst on their website &lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Features of CodeCatalyst
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dev Environments:&lt;/strong&gt; CodeCatalyst Dev Environments are automatically created with pre-installed dependencies and language-specific packages with integrated IDE.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Built-In Issue Tracking:&lt;/strong&gt; It allows to create issues, add custom labels, and feedback on issues.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Customize pipelines:&lt;/strong&gt; Create and customize automated workflows by configuring pre-defined actions using the desired IDE or directly editing the underlying YAML configuration. We can also use any GitHub Action in your workflows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Built-in Code coverage, test support:&lt;/strong&gt; built-in support for code coverage, software composition analysis, and unit tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Easy Deployment to AWS:&lt;/strong&gt;  Deploy applications to AWS services such as S3 or Cloudfront using CDK across accounts or regions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Better Collaboration:&lt;/strong&gt;  Track project activity such as deployments, accepted pull requests through CodeCatalyst’s notifications and personalized activity feed. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You need to create AWS Builder ID ( &lt;a href="https://docs.aws.amazon.com/general/latest/gr/aws_builder_id.html"&gt;to know more about it&lt;/a&gt; )&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/U6xlnd7UUU_2ijG58OSvKiJaO-vjnkMmqfO4VE-tCxc/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3llMnZq/ZDkwZDBuOGliY252/MHlvLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/U6xlnd7UUU_2ijG58OSvKiJaO-vjnkMmqfO4VE-tCxc/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3llMnZq/ZDkwZDBuOGliY252/MHlvLnBuZw" alt="codebuilder Image" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At this moment, &lt;strong&gt;this service is in preview mode and only available in Oregon Region&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to access CodeCatalyst?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CodeCatlyst can access from &lt;a href="https://codecatalyst.aws/explore"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set up an alias for CodeCatalyst. This is a unique identifier in CodeCatalyst. People will use this alias to mention in comments and pull requests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a Space: Space is where you collaborate with others on your software projects, verify your space and create it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/cqmRIjvGHpEGnyKRrNOFD8uWHVbdT46wk-egGH-qIDg/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzdiM3d5/ZzJiMzQ4bXoxcGM0/cG9lLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/cqmRIjvGHpEGnyKRrNOFD8uWHVbdT46wk-egGH-qIDg/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzdiM3d5/ZzJiMzQ4bXoxcGM0/cG9lLnBuZw" alt="alias and space" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's see CodeCatalyst in action.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create a project
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt; Can be either with a blueprint or from scratch. For this blog, we will use a &lt;strong&gt;Single-page application blueprint.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/ELIdlIppKW5U296a4wVc1lDY1ZI2FRwA6ygt6JI2DvM/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2VkeHp0/cGt4Ynptb3plOHl6/ODVmLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/ELIdlIppKW5U296a4wVc1lDY1ZI2FRwA6ygt6JI2DvM/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2VkeHp0/cGt4Ynptb3plOHl6/ODVmLnBuZw" alt="project" width="800" height="215"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/xeH8PwvYYv-Ak2SkWV0QQ1t3rz1EelVx3mauR8-Ka44/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3c5aHAz/bXBzc2kzcXdteGRl/ZGRwLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/xeH8PwvYYv-Ak2SkWV0QQ1t3rz1EelVx3mauR8-Ka44/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3c5aHAz/bXBzc2kzcXdteGRl/ZGRwLnBuZw" alt="blueprint selected" width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After selecting the blueprint you can know more about it on the right pane. What does it do, about its architecture, which aws service components are being used and their explanation, about the IAM role, its permissions and trust policy it needs, account connections environment needs, and what resources it will create?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/stWKHxIiub7Fad2a8phvS8-pU7jOtrfmfYCN8K-y_kg/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3o5YXI5/cGFmY3lhOW54ZDM3/cXo0LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/stWKHxIiub7Fad2a8phvS8-pU7jOtrfmfYCN8K-y_kg/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3o5YXI5/cGFmY3lhOW54ZDM3/cXo0LnBuZw" alt="blueprint-iam role" width="638" height="898"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;About SPA Blueprint&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;This particular blueprint This blueprint creates a single-page application (SPA) project of the web application framework chosen. You can choose either the Angular, React, or Vue web application frameworks. The project uses the AWS Cloud Development Kit (CDK) to deploy to the chosen hosting service, either AWS Amplify Hosting or Amazon Cloudfront + Amazon S3.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;On the next page, give a name to the project and click on add IAM role. It will redirect to role creation and page and after creation, it will be added to your spaces and then added this role to the project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/VqgE5lY_EL_VLSr_8DyJViQBaOsTzk7tnSk-_J9X_gE/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzZidWFy/d2t4aTAyemN1amtw/OXZoLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/VqgE5lY_EL_VLSr_8DyJViQBaOsTzk7tnSk-_J9X_gE/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzZidWFy/d2t4aTAyemN1amtw/OXZoLnBuZw" alt="project details" width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/S5waCvupKrv0Ei9S8iZakSAGQQw2A9k2f_JwHYZyxrA/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2puaXlx/ejRoM2hrdXR4NGtv/ZGV5LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/S5waCvupKrv0Ei9S8iZakSAGQQw2A9k2f_JwHYZyxrA/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2puaXlx/ejRoM2hrdXR4NGtv/ZGV5LnBuZw" alt="iam role" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;em&gt;If you don't add the role to your project, workflows will not able to run as they need permissions in order to interact with various AWS services.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/bX9W6D-FEdFAgo2u6jJDx2TrBccopacYOtfwwqjC_do/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3Z4aGVh/MzltMWtucXBwdXBw/azBrLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/bX9W6D-FEdFAgo2u6jJDx2TrBccopacYOtfwwqjC_do/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3Z4aGVh/MzltMWtucXBwdXBw/azBrLnBuZw" alt="adding role to project" width="632" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Under additional configurations, you can configure configurations like what kind of framework, hosting and CDK programming language, region, repository name, and stack name.
Of course, these configurations will change from blueprint to blueprint.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/qxWGzUfJvoyWO1hSgGfJJeHU3mud6RJh7jk4b1S0xrY/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2dhcDhk/anNyaml2cHl2cjhr/eHg3LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/qxWGzUfJvoyWO1hSgGfJJeHU3mud6RJh7jk4b1S0xrY/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2dhcDhk/anNyaml2cHl2cjhr/eHg3LnBuZw" alt="additional config" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can also view the code and workflow defined in the blueprint.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/dgfe2Z-5y3O9_GIZpGp0eLYM0KaqvwrV9RSnXVsNezo/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3EyY2Vh/cnM2d2UwM2M1czBp/N3pyLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/dgfe2Z-5y3O9_GIZpGp0eLYM0KaqvwrV9RSnXVsNezo/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3EyY2Vh/cnM2d2UwM2M1czBp/N3pyLnBuZw" alt="option for code and workflow" width="415" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code&lt;/strong&gt; tells about the code generated in the blueprint.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/n6cfNQfierFcSPs2allDgzHofMMULehgjjGeeozLIgg/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL20ybHVw/eWE5cWpkZG9pY3k2/NWFoLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/n6cfNQfierFcSPs2allDgzHofMMULehgjjGeeozLIgg/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL20ybHVw/eWE5cWpkZG9pY3k2/NWFoLnBuZw" alt="code" width="640" height="905"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Workflow tells what intermediary actions to be taken for events (like PUSH/PULL PR)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/R73sO9HrISyDwE5-5L2pxjTzTWMVi8W2CjHzOjBNDdo/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2hjMThv/MzFpazY0bmlmcXFt/Nm9iLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/R73sO9HrISyDwE5-5L2pxjTzTWMVi8W2CjHzOjBNDdo/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2hjMThv/MzFpazY0bmlmcXFt/Nm9iLnBuZw" alt="workflow" width="639" height="900"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create Project.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Once the project is created you can view its repository, a README is populated automatically, and You can create a workflow, Create PR, and create Issues or Environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/g3t1EHi-hT61OHCwKvRNF8iHkyI67GFuttNg4w7Miyc/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2Q2Z3J3/ZGRnNmt1MDk3Z3Ns/NWVpLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/g3t1EHi-hT61OHCwKvRNF8iHkyI67GFuttNg4w7Miyc/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2Q2Z3J3/ZGRnNmt1MDk3Z3Ns/NWVpLnBuZw" alt="project screen" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;In order to deploy the application we need to run the workflow. URL for the application will be in the output of the workflow.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In this blueprint, there are 2 workflows already created:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;For Building and testing the code on PR.&lt;/li&gt;
&lt;li&gt;For running deploy pipeline for push to the Main branch.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/BQUa0_uKceXXjslf3_LvTp_L6OKzMQm3I8ydvKqG4xU/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzFma3Rw/eWhibTZldnVxNHNk/bXA3LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/BQUa0_uKceXXjslf3_LvTp_L6OKzMQm3I8ydvKqG4xU/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzFma3Rw/eWhibTZldnVxNHNk/bXA3LnBuZw" alt="workflow pictures" width="800" height="293"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In order to create a PR, we will create a branch. In this PR we will add the &lt;code&gt;&amp;lt;p&amp;gt; tag&lt;/code&gt;  &lt;strong&gt;Developed and Deployed using CodeCatalyst&lt;/strong&gt;  and then commit it with a commit message.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/7yfe254PSp2seikQTxSMnEq-o6Qg0h5cE-zT4iu0SPQ/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzN6aGNq/dXk3cG9vNTQwdWR1/d3pjLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/7yfe254PSp2seikQTxSMnEq-o6Qg0h5cE-zT4iu0SPQ/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzN6aGNq/dXk3cG9vNTQwdWR1/d3pjLnBuZw" alt="create branch" width="800" height="179"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/ZKRM0FrD7xrn8WCs_hcAkVmwacKfrHQKjc_vn0H1sT0/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2E1dHNz/aWxqbDd0bXB6ZXZw/anZ2LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/ZKRM0FrD7xrn8WCs_hcAkVmwacKfrHQKjc_vn0H1sT0/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2E1dHNz/aWxqbDd0bXB6ZXZw/anZ2LnBuZw" alt="PR changes" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After PR is created workflow for &lt;strong&gt;build and test will run&lt;/strong&gt;. You can even see the workflow by clicking on its link.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/OuUFMyn5CKrr308Lt_3Yy7aQ2MAX6qiO0NMy-8tiHmo/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2Zxdnpk/Y2MxOXNtZzhtOXAz/NzZmLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/OuUFMyn5CKrr308Lt_3Yy7aQ2MAX6qiO0NMy-8tiHmo/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2Zxdnpk/Y2MxOXNtZzhtOXAz/NzZmLnBuZw" alt="link for workflow" width="305" height="902"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/A5Y8mPRRg8xBjdQetzue1dThC9GccJT3KaBnIt_Ja48/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3Bobjly/dmJqZHZwOWlqb2V5/eHVzLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/A5Y8mPRRg8xBjdQetzue1dThC9GccJT3KaBnIt_Ja48/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3Bobjly/dmJqZHZwOWlqb2V5/eHVzLnBuZw" alt="worklow details for build" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once the workflow is successful, you can ask for a review and then merge it. Upon Merge it will run the &lt;strong&gt;DeployPipeline workflow which will deploy the application&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/ekR9vFZ9q9WLm5xjOkVjYTQVPawQeYUksqkykUggjsQ/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzJkbmV4/dzYzY3dnOWNta25x/Ynk2LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/ekR9vFZ9q9WLm5xjOkVjYTQVPawQeYUksqkykUggjsQ/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzJkbmV4/dzYzY3dnOWNta25x/Ynk2LnBuZw" alt="deploy workflow" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can also check the code coverage and unit test details.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/TpwuyWkjg5Az8hTwKwEyOKaGNAqoB2Y9pw5picR_yhk/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3V0Ym0z/MGFtOXJ6YTRqcnJw/cjM4LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/TpwuyWkjg5Az8hTwKwEyOKaGNAqoB2Y9pw5picR_yhk/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3V0Ym0z/MGFtOXJ6YTRqcnJw/cjM4LnBuZw" alt="code ceverage" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Access the application by URL present in workflow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/M-VMn8WzIi1Jre5kEghFybsJWDk-798t3Ph_nVyeoOY/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2JlbGs3/Y3JscmNzZ3FzdDR2/dDh0LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/M-VMn8WzIi1Jre5kEghFybsJWDk-798t3Ph_nVyeoOY/w:800/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2JlbGs3/Y3JscmNzZ3FzdDR2/dDh0LnBuZw" alt="React app" width="800" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  From Developer and DevOps Perspective
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CodeCatalyst took me a maximum of 10 minutes ( including deployment minutes) to create and deploy which is really, really fast&lt;/strong&gt;. If I had to do this on my own using IaC, I would have to figure out role permissions, check the documentation, set up CI/CD, and integrate all the components and development environment which would have taken a lot of time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;With this all-in-one software development service, it is very easy and efficient to develop applications on AWS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This is going to save a lot of significant time and resources that software teams spend on various infrastructure components, and development environments, which will enable to deliver to quickly deliver new features or software updates to customers. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do you think CodeCatalyst will help your teams?  Share your thoughts or feedback over &lt;a href="https://www.linkedin.com/in/jatinmehrotra/"&gt;Linkedin&lt;/a&gt; or &lt;a href="https://twitter.com/imjatinmehrotra"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>AWS CodePipeline : CD pipeline with s3!</title>
      <dc:creator>Jatin Mehrotra</dc:creator>
      <pubDate>Sun, 27 Nov 2022 06:42:28 +0000</pubDate>
      <link>https://community.ops.io/jatin/aws-codepipeline-cd-pipeline-with-s3-57m7</link>
      <guid>https://community.ops.io/jatin/aws-codepipeline-cd-pipeline-with-s3-57m7</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;In this series of &lt;code&gt;Build Better CI CD Pipelines&lt;/code&gt; we are going to understand concepts around CI CD and build pipelines by &lt;strong&gt;actually making it&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;This will be a continuous series where I will be adding blogs with different CI CD tools and deploying various services on AWS using the pipeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;In This blog we are going to create our first CD ( continuous deployment ) pipeline which is triggered by uploading on an s3 bucket ( source location ) and deploying a static website on another s3 bucket ( production bucket ).&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Basic knowledge of AWS fundamental services like s3, ec2, and cloud formation.&lt;/li&gt;
&lt;li&gt;Fundamental knowledge of CI-CD concepts. You can read my previous blog where I have covered &lt;a href="https://community.ops.io/jatin/ci-cd-101-with-gitlab-4pol"&gt;CI CD 101 with GitLab.&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why do we need deployment automation
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Manual process involves human effort, prone to errors.&lt;/li&gt;
&lt;li&gt;To get reviews early from the customer.&lt;/li&gt;
&lt;li&gt;To achieve the standard, test, and repeatable process&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What is CI CD?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Developers changes code frequently, several times a day, and push to the central repository.&lt;/li&gt;
&lt;li&gt; In every code submission, automatic builds ( if it is needed) and unit tests are run.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;CI starts with the source stage and finishes with the build stage.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Outcome(aim)&lt;/strong&gt;: To merge code as soon as possible so that integration errors are detected earlier and fixed before deployment.&lt;/li&gt;
&lt;li&gt;Then CD comes and is deployed to staging( depending on the project ) for review ( here more e2e and other types of tests can occur ) and then it is manually approved.&lt;/li&gt;
&lt;li&gt;After approval, the code is deployed to production. This is &lt;strong&gt;continuous delivery.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;When no manual approval is required, it is known as &lt;strong&gt;continuous deployment.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is CodePipeline?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;CD service of AWS&lt;/li&gt;
&lt;li&gt;Could be continuos deployment or continuous delivery&lt;/li&gt;
&lt;li&gt;Integrates with 3rd party tools like Jenkins or add custom actions with lambda&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Basically an orchestrator of CI/CD workflow because it helps in integrating various other services ( CodeBuild, CodeDeploy) within it.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Concepts around CodePipeline
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;source revision&lt;/strong&gt;: source change that triggers pipeline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;stages&lt;/strong&gt;: group of one or more actions. There can be multiple stages like the source stage, and the build stage. At a time only one source revision is processed, even if there are more source revisions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;action&lt;/strong&gt;: task performed such as running test, building code. could be sequentially or in parallel.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;transition&lt;/strong&gt;: connection b/w 2 stages, describes the flow between them. We can enable or disable it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;artifact&lt;/strong&gt;: file or set of files produced as a result of action which is consumed by later action in the same stage or different stage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pipeline execution&lt;/strong&gt;: each execution has its own id. Triggered by commit or manual release of the latest commit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Let's Build the pipeline
&lt;/h2&gt;

&lt;p&gt;Note: In this blog, we are going to use AWS Console so that everyone is on the same page.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Create a source bucket
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a bucket called &lt;code&gt;blog-pipeline-source&lt;/code&gt;, with &lt;strong&gt;versioning enabled&lt;/strong&gt; and keeping other options as default.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;s3 versioning should be enabled as the pipeline will detect source revisions by s3 version IDs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/c6HGnpug8rn0YKu9yjEWAYPmiZFrQUK8hLhCA0vlL-s/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2R2a3Bl/ZHcwNncyaXliNjFv/bnpqLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/c6HGnpug8rn0YKu9yjEWAYPmiZFrQUK8hLhCA0vlL-s/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2R2a3Bl/ZHcwNncyaXliNjFv/bnpqLnBuZw" alt="creating source bucket" width="880" height="725"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/d3VR4sbyxK2HLdfS64Krpb1CjX917lFAHekeHaR6VkQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzczajZs/c3JpNjE4MHB0cWlp/OW9yLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/d3VR4sbyxK2HLdfS64Krpb1CjX917lFAHekeHaR6VkQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzczajZs/c3JpNjE4MHB0cWlp/OW9yLnBuZw" alt="versioning enabled for source bucket" width="880" height="674"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Upload Artifact to Source Bucket
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;We are simply going to upload &lt;code&gt;index.html&lt;/code&gt; and &lt;code&gt;error.html&lt;/code&gt; files as zip to the source bucket.&lt;/li&gt;
&lt;li&gt;Note: Make sure both the files are NOT under the subfolder, they should be under the root, otherwise in the production bucket they can't be directly accessed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The command for creating a zip on Linux/Mac&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;zip &lt;span class="nt"&gt;-r&lt;/span&gt; blog-website.zip error.html index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The index.html and error.html are available on this &lt;a href="https://gist.github.com/jatinmehrotra/8ffa564ab56d2304987f8d537c913a7d"&gt;gist&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/ydI0rS9TAjxiqysrJ_LnAnEeoQ7fiXUbAaX1c6g-020/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3dpbTF2/Z2FyZjVueHNlYzh1/MXJ1LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/ydI0rS9TAjxiqysrJ_LnAnEeoQ7fiXUbAaX1c6g-020/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3dpbTF2/Z2FyZjVueHNlYzh1/MXJ1LnBuZw" alt="uploading zip" width="880" height="916"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Create a production bucket
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create a bucket &lt;code&gt;blog-pipeline-production&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;This bucket can be in a different region or the same region as opposed to the pipeline and source bucket.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ACL should be enabled because CodePipeline will use ACL to make objects public then only the pipeline will succeed.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Since this bucket will be used for bucket hosting, we need to &lt;strong&gt;uncheck block public access and enable static website hosting option&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/sJZrksb9Ew_o58TNuuj2386xdTePTIw29C39o228UbI/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3V0MDR2/b295aHowYW9rZmxu/dGsxLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/sJZrksb9Ew_o58TNuuj2386xdTePTIw29C39o228UbI/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3V0MDR2/b295aHowYW9rZmxu/dGsxLnBuZw" alt="production bucket with acl enabled" width="880" height="938"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://community.ops.io/images/0IhoTVqcyDw-aZwkNOIHNgf5BN3wyhaZ7oe1bEDXvh0/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3E2Nnk3/N3oxY2dxbGZpd2dy/YzRmLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/0IhoTVqcyDw-aZwkNOIHNgf5BN3wyhaZ7oe1bEDXvh0/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3E2Nnk3/N3oxY2dxbGZpd2dy/YzRmLnBuZw" alt="production bucket with uncheck block public access" width="880" height="876"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://community.ops.io/images/sSM2i_Vax0D3f0d7BEg3z6MsdwM-umWeolIh6FIudP8/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3hiY2Ni/NTNteW51Mzh5eWZx/b2J2LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/sSM2i_Vax0D3f0d7BEg3z6MsdwM-umWeolIh6FIudP8/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3hiY2Ni/NTNteW51Mzh5eWZx/b2J2LnBuZw" alt="enabled static website hosting option" width="880" height="728"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Create a CD pipeline
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Pipeline and the source bucket &lt;strong&gt;should be in the same region.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pipeline needs a &lt;strong&gt;service role&lt;/strong&gt;. It is needed for permissions; To access the object in the source and deploy objects in the prod bucket.&lt;/li&gt;
&lt;li&gt;Artifacts are stored in an s3 bucket in the same region, usually, CodePipeline will create a single bucket for all the pipelines or you can create your own bucket for storing artifacts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/WCRVrpkctRDHOIzYE8KKgSONO72VZWs9MRLN1djH5Zo/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3BwcGEz/ZHRwOXlueTB3cHJ4/dmt3LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/WCRVrpkctRDHOIzYE8KKgSONO72VZWs9MRLN1djH5Zo/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3BwcGEz/ZHRwOXlueTB3cHJ4/dmt3LnBuZw" alt="creating pipeline" width="880" height="887"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the next step, select the source for the pipeline as an s3 provider with a source bucket.&lt;/li&gt;
&lt;li&gt;s3 object key should have the name of the zip file we are going to upload.&lt;/li&gt;
&lt;li&gt;Change detection event helps to trigger the pipeline. Cloudwatch events are in real-time unlike making pipeline checks periodically.&lt;/li&gt;
&lt;li&gt;In this blog, we are not going to build anything so we can skip the step, but we have the option to integrate Jenkins or CodeBuild.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/ztbHVjRClzJeWdyZakq3sB0cLfybSsAdnhVYUhNUSao/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzk2N3J2/Z2l2YTBzdGl2OHI3/djByLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/ztbHVjRClzJeWdyZakq3sB0cLfybSsAdnhVYUhNUSao/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzk2N3J2/Z2l2YTBzdGl2OHI3/djByLnBuZw" alt="defining source" width="880" height="603"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the next step we are going to set deployer options with the deploy provider being s3 and the production bucket as the target.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extract file before deployment is important&lt;/strong&gt; to set so that pipeline unzips the artifact before deployment.&lt;/li&gt;
&lt;li&gt;We are going to set &lt;strong&gt;cannel ACL as public-read&lt;/strong&gt; so that our file ( index.html) is available for the public to read since we are hosting it as a static website.&lt;/li&gt;
&lt;li&gt;Note: &lt;strong&gt;CodePipeline deploys all objects to s3 buckets as private&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;There is an option to encrypt production bucket objects too for extra security, if no kms-key is provided there are going to be unencrypted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/vXXWuRZJ_etyUUxu7YELphnQBQLGFX07YulN46IndmI/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzZtMXow/dGJ2bmxuczBpdHZ4/NDU1LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/vXXWuRZJ_etyUUxu7YELphnQBQLGFX07YulN46IndmI/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzZtMXow/dGJ2bmxuczBpdHZ4/NDU1LnBuZw" alt="deploy provider for pipeline" width="880" height="880"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After creation, the pipeline automatically runs for the first time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/9SAqaI6db-Zq1QsonClZNMrMBbaZBsehn3Z--qQ9Ah4/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2YwNTc3/YnFzdzh0OWVuNG1t/enl4LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/9SAqaI6db-Zq1QsonClZNMrMBbaZBsehn3Z--qQ9Ah4/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2YwNTc3/YnFzdzh0OWVuNG1t/enl4LnBuZw" alt="pipeline running for the first time" width="880" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to production bucket and under properties, -&amp;gt; static website hosting -&amp;gt; copy the website bucket endpoint&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/gB91KJD2BT434sYfkaL9ii7FB-3JQvJx0u2X8Aoy0-E/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzdhOGlw/N2RqdDJvam51bG0z/aG11LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/gB91KJD2BT434sYfkaL9ii7FB-3JQvJx0u2X8Aoy0-E/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzdhOGlw/N2RqdDJvam51bG0z/aG11LnBuZw" alt="bucket website endpoint" width="880" height="263"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Access the website by the endpoint URL, Wohoo, you just automated your website with CodePipeline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/JfVlFrcXZ-unnBZ3IxzTBQAMi5HKLPtpUU8s11c5dh0/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzY2bHln/endvaHBiYjFqNmJq/NjR0LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/JfVlFrcXZ-unnBZ3IxzTBQAMi5HKLPtpUU8s11c5dh0/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzY2bHln/endvaHBiYjFqNmJq/NjR0LnBuZw" alt="website on s3" width="880" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Automatically trigger on uploading bucket.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is a stage?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Stages hist the action, here for our pipeline we have 2 stages called &lt;code&gt;Source&lt;/code&gt; and &lt;code&gt;Deploy&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/OVC3_8v7jGjJ6YFsPeGKfDZiTuv0XbwVOsAY3YUI5wo/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzYwOGNu/Mnl2bndieHJhd3pr/M2VuLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/OVC3_8v7jGjJ6YFsPeGKfDZiTuv0XbwVOsAY3YUI5wo/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzYwOGNu/Mnl2bndieHJhd3pr/M2VuLnBuZw" alt="Stage" width="880" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is an Action?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Action by the name, is a step that performs some operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/CNApdLnW9oCofGSlilC8ihIgLxczDJa-qg6-v8mEtJk/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3UwNDJk/em44MXgxcWNpaWY5/ZXczLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/CNApdLnW9oCofGSlilC8ihIgLxczDJa-qg6-v8mEtJk/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3UwNDJk/em44MXgxcWNpaWY5/ZXczLnBuZw" alt="action inside stage" width="408" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What are Transitions?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;They connect stages.&lt;/li&gt;
&lt;li&gt;By default, all transitions are enabled.&lt;/li&gt;
&lt;li&gt;We can disable transition.&lt;/li&gt;
&lt;li&gt;Stages run fast because we use source and deploy buckets in the same region.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each pipeline has a unique execution ID, A successful transition means execution IDs are passed from one stage to another hence they both have the same execution ID.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Let's say we want to update our website and trigger the pipeline automatically, all we have to do is just upload the updated zip package to s3.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Let's make some changes to &lt;code&gt;index.html&lt;/code&gt;. &lt;strong&gt;Adding v2 to to h1&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Static Website for CodePipeline Blog v2&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;body&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"text-align:center;font-family:Verdana;margin:1%;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"color:rgb(128, 55, 0)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This is deployed by CD pipeline! V2&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;hr&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Automate anything and everything!!!&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Made by Jatin Mehrotra!&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Run the zip command again.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;zip &lt;span class="nt"&gt;-r&lt;/span&gt; blog-website.zip error.html index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Upload to s3, and the Pipeline will be triggered again with a different execution ID.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/nyZfE_hBig7dBsz4D3HN9IuOJ8X4GfCM6mvuFZN0LaU/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzJ5c3N5/Nm9lYTZzaGJoaDY3/bjl6LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/nyZfE_hBig7dBsz4D3HN9IuOJ8X4GfCM6mvuFZN0LaU/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzJ5c3N5/Nm9lYTZzaGJoaDY3/bjl6LnBuZw" alt="Pipeline triggered on update" width="880" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Confirm the changes on the website too.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/mfeQIZrImFljliB52xa43DMmgG-qcZ0Qzloq9vAB9og/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzZlY3pk/d3NhMm9tbWtwNTZw/bnBnLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/mfeQIZrImFljliB52xa43DMmgG-qcZ0Qzloq9vAB9og/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzZlY3pk/d3NhMm9tbWtwNTZw/bnBnLnBuZw" alt="website updated on upload" width="880" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Add new action and trigger manually.
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Adding actions to the existing pipeline does not trigger the pipeline automatically as it was triggered automatically upon creation. Therefore we need to trigger the pipeline manually.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the new action we will :

&lt;ul&gt;
&lt;li&gt;Deploy buckets can be in other AWS regions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create a bucket in another region and deploy the website to it for higher availability. This new bucket will be in Singapore as opposed to the Tokyo region like other buckets&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;All the bucket configuration remains like the production bucket except for the name and region.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't forget to enable website bucket hosting&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/7_94WvKQp8RjAcZPYLli7RvjfFFMFLnli775-qfPMXw/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2ZrbzUz/ZmI4bGp1OWgwMXNs/OGM3LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/7_94WvKQp8RjAcZPYLli7RvjfFFMFLnli775-qfPMXw/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2ZrbzUz/ZmI4bGp1OWgwMXNs/OGM3LnBuZw" alt="production bucket in another region" width="806" height="1500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To add the action, we need to edit the pipeline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/EsRhp_WySK4h1qAGejS_h09RW8NMDFtSKS_SR7ggo4Y/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3R2dmpo/cHIwN3VpZXdncnhn/bHJpLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/EsRhp_WySK4h1qAGejS_h09RW8NMDFtSKS_SR7ggo4Y/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3R2dmpo/cHIwN3VpZXdncnhn/bHJpLnBuZw" alt="Edit pipeline" width="880" height="89"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Edit the Deploy stage since we are adding action to deploy in the production bucket.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/8SRfFzFRz3aX31Db8NUx2sO_cqx-ILfL3NlrQTSIMVc/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzVnMHRo/eWlldDFod2xzcWpu/ZXllLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/8SRfFzFRz3aX31Db8NUx2sO_cqx-ILfL3NlrQTSIMVc/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzVnMHRo/eWlldDFod2xzcWpu/ZXllLnBuZw" alt="edit deploy stage" width="880" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;As I mentioned earlier, actions can be executed sequentially or in parallel. The position of &lt;code&gt;add action group&lt;/code&gt; is critical because the box before the deploy action symbolizes execution sequentially before the deploy action. Action group beside deploy action group tells execute the action in parallel. The box of add action group below deploy action means to add an action that will run sequentially after deploying action.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/4vcdIOiG5uciYXNGxS655Gbm5aL7plhxMHaQrq6WMac/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3lxNnFj/YTB6bmNia2c2MGNm/OGkyLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/4vcdIOiG5uciYXNGxS655Gbm5aL7plhxMHaQrq6WMac/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3lxNnFj/YTB6bmNia2c2MGNm/OGkyLnBuZw" alt="action group placement meaning" width="880" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We are adding action in parallel so we will choose to add action beside the deploy action.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/bued4a0UpywFzlhWlXa1wbkfvOVCbUs6XLho5o9tKyE/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3pud3U4/Znh3cmNlaDczZms1/b3k1LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/bued4a0UpywFzlhWlXa1wbkfvOVCbUs6XLho5o9tKyE/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3pud3U4/Znh3cmNlaDczZms1/b3k1LnBuZw" alt="adding action in parallel" width="832" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define action provider as deploy s3.&lt;/li&gt;
&lt;li&gt;Define input artifact, in this case, it is coming from &lt;code&gt;sourceArtifact&lt;/code&gt; defined by source.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/-Irq2dYjcDPukFPLrv7G0DQTnkcUs9DYlV77bvGvlrw/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3h5ZGpm/Zm1jZnBpZDgyYzJo/bjVpLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/-Irq2dYjcDPukFPLrv7G0DQTnkcUs9DYlV77bvGvlrw/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3h5ZGpm/Zm1jZnBpZDgyYzJo/bjVpLnBuZw" alt="aother bucket provider" width="880" height="675"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/ECGGRv8nXFDlu62wAK67aBVyOVU329bh8fhkHYFjM-s/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2QwN3Rl/emcxdmtlMm53aXBq/OXBoLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/ECGGRv8nXFDlu62wAK67aBVyOVU329bh8fhkHYFjM-s/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2QwN3Rl/emcxdmtlMm53aXBq/OXBoLnBuZw" alt="deploy stage after adding action" width="880" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Save pipeline changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;## How to trigger manually without uploading to an s3 bucket&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/eLQM0n1hlYu-JznbBOtOuJJxsLJ11j27HsJLw97Jts4/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzI0NTFu/ZGFuMmxndmF4ZW5z/MmEwLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/eLQM0n1hlYu-JznbBOtOuJJxsLJ11j27HsJLw97Jts4/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzI0NTFu/ZGFuMmxndmF4ZW5z/MmEwLnBuZw" alt="pipeline didn't run" width="880" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Click on release change.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/r9N2IjylXc376I_ivP8cwgKXs4ZcujpSxMjENjeweGY/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzFqOWFp/cTV5aHhnMDdrOWtk/b2xkLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/r9N2IjylXc376I_ivP8cwgKXs4ZcujpSxMjENjeweGY/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzFqOWFp/cTV5aHhnMDdrOWtk/b2xkLnBuZw" alt="release change" width="880" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; We can see the start pipeline execution trigger.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/XaSelPkNAq0GZdMMMEAbQSdtJ7ZXMiATNPAa2_xnyZ8/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2Z6ZGhs/cXZlbjJpcGxmNHVi/eDF5LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/XaSelPkNAq0GZdMMMEAbQSdtJ7ZXMiATNPAa2_xnyZ8/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2Z6ZGhs/cXZlbjJpcGxmNHVi/eDF5LnBuZw" alt="deployment to another region" width="880" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Clearing the environment.
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt; Deleting code pipeline does not delete a source, deployment, and artifact buckets.&lt;/li&gt;
&lt;li&gt; Artifact bucket will be used by all pipelines so no need to delete it.&lt;/li&gt;
&lt;li&gt; Roles are not deleted, even the policies created by roles.&lt;/li&gt;
&lt;li&gt; Different roles for different policies are the best practice.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  From DevOps Perspective.
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;We have successfully achieved the automation of deploying static website using s3 as a source bucket with our first CD pipeline using CodePipeline.&lt;/li&gt;
&lt;li&gt;We did achieve automation, however, there were still manual process elements like creating s3 which can be further automated using Terraform.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Till then, Happy Learning !!!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Feel Free to post any comments or questions.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Connect with me over&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/jatinmehrotra/"&gt;Linkedin&lt;/a&gt; or &lt;a href="https://twitter.com/imjatinmehrotra"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cicd</category>
      <category>devops</category>
      <category>s3</category>
    </item>
    <item>
      <title>DevOps Guru: A new way (AIOps) to fix your AWS Infrastructure issues</title>
      <dc:creator>Jatin Mehrotra</dc:creator>
      <pubDate>Wed, 23 Nov 2022 08:05:27 +0000</pubDate>
      <link>https://community.ops.io/jatin/devops-guru-a-new-way-aiops-to-fix-your-aws-infrastructure-issues-2pkm</link>
      <guid>https://community.ops.io/jatin/devops-guru-a-new-way-aiops-to-fix-your-aws-infrastructure-issues-2pkm</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;An application deployed in production always has some kind of &lt;strong&gt;monitoring and observability to track its performance, operational issues, latency, downtime, error rates, outages, service disruptions, infrastructure code, config changes and ...the list can go on&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Often monitoring and observability operations do not lead to an efficient outcome because &lt;strong&gt;there is a lot of noise and false negatives due to lack of information, alarm fatigues etc&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For a DevOps or SRE, this results in spending &lt;strong&gt;days of time and effort&lt;/strong&gt; to detect, debug and resolve operational issues, which is definitely not good from a business critical application and customer point of view.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;DevOps Guru&lt;/em&gt;&lt;/strong&gt; is an ML-powered service to address the above-mentioned issues and save your precious hours of detecting and resolving operational issues leading to &lt;strong&gt;enhanced application availability and reliability&lt;/strong&gt;.*&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Prequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NO ML KNOWLEDGE/EXPERTISE IS REQUIRED.&lt;/strong&gt; (Trust me when I say this, AWS has made it so easy for us )&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is DevOps Guru?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/7t_yrmHVVVGEWNBZlAkk1T8yf-L2kAw23In1iPaGotw/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9kZXZvcHMt/Z3VydS13b3JraW5n/LmRyYXdpby0yLTMu/cG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/7t_yrmHVVVGEWNBZlAkk1T8yf-L2kAw23In1iPaGotw/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9kZXZvcHMt/Z3VydS13b3JraW5n/LmRyYXdpby0yLTMu/cG5n" alt="How does DevOps Guru Work" width="880" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A service that sends you alerts and recommendations whenever there is an anomaly in the operating patterns that can cause application downtime or service disruptions.&lt;/li&gt;
&lt;li&gt;DevOps Guru uses &lt;strong&gt;ML models learned from more than 20 years of operational expertise in building, scaling, and maintaining universally available applications for Amazon.com.&lt;/strong&gt;. This leads to &lt;em&gt;Reactive and Proactive insights&lt;/em&gt;, so you can identify operational issues long before they impact your customers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reactive Insights&lt;/strong&gt;: Recommendations to address issues that are happening &lt;strong&gt;now&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proactive Insights&lt;/strong&gt;: Recommendations that address issues that DevOps Guru predicts will occur in the &lt;strong&gt;future&lt;/strong&gt; (power of ML).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why to use DevOps Guru?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Saves tons of time, reduces application downtime and ultimately leads to happy customers because it pinpoints the problems with its summary about why the issue took place and how to fix it through an actionable recommendation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How does DevOps Guru work?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Baseline Creation&lt;/strong&gt;: It established a baseline which is treated as "normal". For this process, it consumes metrics like latency, error rate, and request rates.&lt;/li&gt;
&lt;li&gt;Using a pre-trained ML model, when it identifies an anomaly, it generates alerts with its recommendations for its remediation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Use Cases for DevOps Guru
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://aws.amazon.com/devops-guru/features/devops-guru-for-rds/"&gt;Amazon DevOps Guru for RDS&lt;/a&gt; helps in &lt;a href="https://aws.amazon.com/rds/performance-insights/"&gt;detecting performance &amp;amp; operation issues&lt;/a&gt; within RDS based engines.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://aws.amazon.com/devops-guru/features/devops-guru-for-serverless/"&gt;Amazon DevOps Guru for Serverless&lt;/a&gt; to detect and diagnose performance and operational issues for Serverless Applications built using AWS&lt;/li&gt;
&lt;li&gt;Fix your AWS infrastructure misconfigs and limits using proactive insights.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/CGK4lTseyqkFUUDEPD0aHrFV5uU3Pe7qRAeZb7BTVXI/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTEuNTUu/NTEtQU0ucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/CGK4lTseyqkFUUDEPD0aHrFV5uU3Pe7qRAeZb7BTVXI/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTEuNTUu/NTEtQU0ucG5n" alt="insights" width="880" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Enable and disable DevOps Guru and check estimation?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;To enable, Just click &lt;strong&gt;Enable&lt;/strong&gt;. Yes, that's how easy it is and on top of that, you can configure the SNS topic to send alerts and take action :)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/A8mcsdJcz27P0bkGCKR_dTt8PotfJcR6wHJ8QNNwqac/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtOC41Ni4x/Mi1QTS5wbmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/A8mcsdJcz27P0bkGCKR_dTt8PotfJcR6wHJ8QNNwqac/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtOC41Ni4x/Mi1QTS5wbmc" alt="enable" width="880" height="847"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To disable, Again Just click &lt;strong&gt;None&lt;/strong&gt; on resources to analyse, you can decide which resources to analyse based on tags, or cFn stacks or all resources :)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/qpQDsYUoYVu7_oePrdTaZhBd4EIK5tAZX7qG7qmmcj8/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtOC41Ny4y/Ni1QTS1zY2FsZWQu/anBn" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/qpQDsYUoYVu7_oePrdTaZhBd4EIK5tAZX7qG7qmmcj8/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtOC41Ny4y/Ni1QTS1zY2FsZWQu/anBn" alt="disable" width="880" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To estimate cost, you can again choose, either on cFn stack, tags or all resources.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/9mw5rdBwa3XkJb3gktMygwhYF_IYyNy3vVVobnOFq-o/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtOC41OC41/OS1QTS1zY2FsZWQu/anBn" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/9mw5rdBwa3XkJb3gktMygwhYF_IYyNy3vVVobnOFq-o/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtOC41OC41/OS1QTS1zY2FsZWQu/anBn" alt="cost-estimator" width="880" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo Time for DevOps Guru
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;To illustrate the power of DevOps Guru, we will work with RDS and serverless application which is already deployed using this &lt;a href="https://catalog.us-east-1.prod.workshops.aws/workshops/f92df379-6add-4101-8b4b-38b788e1222b/en-US"&gt;workshop from AWS&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to cloud 9, to access the env for this blog.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/YxReKTev2nYY33O9DRWCciBjEAtd361RDhoqIGfxRMg/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTEuMjUu/NDMtQU0tZTE2Njg2/ODg1MjIzMDkucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/YxReKTev2nYY33O9DRWCciBjEAtd361RDhoqIGfxRMg/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTEuMjUu/NDMtQU0tZTE2Njg2/ODg1MjIzMDkucG5n" alt="cloud 9" width="880" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  DevOps Guru for RDS
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scenario 1&lt;/strong&gt;: There is a mission-critical production application which uses Aurora relational database with the PostgreSQL engine. The application has been updated with a new feature and users are complaining about slow performance and time out.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simulation of Scenario&lt;/strong&gt;: We will try to increase the read workload on DB.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;PGPASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;PGPASSWORD3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;psql&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;PGHOST3&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;U&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;PGUSER3&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;PGPORT3&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;c&lt;/span&gt; &lt;span class="nv"&gt;"CREATE EXTENSION pg_stat_statements;"&lt;/span&gt;

&lt;span class="n"&gt;PGPASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;PGPASSWORD3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;pgbench&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;PGHOST3&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;U&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;PGUSER3&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;PGPORT3&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;c&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="mi"&gt;1800&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;PGDATABASE3&lt;/span&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;These commands are using 10 connections with 10 threads.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After a certain time, we can see insights from DevOps Guru.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;DevOps Guru Insights&lt;/strong&gt;: Select the insight and view its details. Here we can an overview about the insight, information about the metrics as well as graphed anomalies.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/LDFf6sEDzJziPbZmaX5i7DsSIfuI4tb2WyKQaPvJq18/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTEuNTMu/MzEtQU0tc2NhbGVk/LmpwZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/LDFf6sEDzJziPbZmaX5i7DsSIfuI4tb2WyKQaPvJq18/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTEuNTMu/MzEtQU0tc2NhbGVk/LmpwZw" alt="anomaly page" width="880" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/8WLKYaKX2rviCptMuBwB2UhkeFbCUxfRLhWeR6njnZI/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTEuNTMu/NDctQU0ucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/8WLKYaKX2rviCptMuBwB2UhkeFbCUxfRLhWeR6njnZI/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTEuNTMu/NDctQU0ucG5n" alt="aggegated metrics" width="880" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It will show which metric is affected in this case ( Average active sessions ( AAS) ), DevOps Guru also shows analysis and recommendations which pinpoints the issue.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/WlMVjUCG0G1dXjMG9-2_KKkmkDo5_TaLMfPGlbEsjA8/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTIuMzMu/MjItUE0ucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/WlMVjUCG0G1dXjMG9-2_KKkmkDo5_TaLMfPGlbEsjA8/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTIuMzMu/MjItUE0ucG5n" alt="metric graph" width="880" height="582"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It also tells the reason and recommendation behind this anomaly to give better insights about the cause.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/mMWRikjG4vd1OIYpsl4JLhBIVGAwCKll2nAxZA9tZ6Y/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTEuNTQu/NTAtQU0ucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/mMWRikjG4vd1OIYpsl4JLhBIVGAwCKll2nAxZA9tZ6Y/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTEuNTQu/NTAtQU0ucG5n" alt="index issue" width="880" height="577"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/yb_no0fq36tcxwxeQD2OkhfeO6mlnLJLzxTDLRbJ8SQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTEuNTUu/MDMtQU0uanBn" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/yb_no0fq36tcxwxeQD2OkhfeO6mlnLJLzxTDLRbJ8SQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTEuNTUu/MDMtQU0uanBn" alt="index recommendation" width="880" height="599"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The query requires aid ( an index ), which is not present in the table (all thanks to DevOps Guru). The takeaway here is that a missing index can ruin application performance and keep the entire system busy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scenario 2&lt;/strong&gt;: Team member took a coffee break but forgot to commit/close the session on RDS which he has opened which leads to an exclusive lock on the table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simulation of the Scenario&lt;/strong&gt;: We will try to use multiple sessions competing for the same "locked" record and of course due to ACID properties of the transaction, they must wait for each other.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Team member work&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;workload&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;lock&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;txn2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;ENDOFFILE&lt;/span&gt;

&lt;span class="k"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;lock&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;hr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;job_history&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;exclusive&lt;/span&gt; &lt;span class="k"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="n"&gt;ENDOFFILE&lt;/span&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Our workload
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;workload&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;lock&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;txn1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;ENDOFFILE&lt;/span&gt;

&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setrandom&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;setrandom&lt;/span&gt; &lt;span class="n"&gt;sleeptime&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;

&lt;span class="k"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;start_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;end_date&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;hr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;job_history&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;employee_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5550&lt;/span&gt; &lt;span class="k"&gt;FOR&lt;/span&gt; &lt;span class="k"&gt;UPDATE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;pg_sleep&lt;/span&gt;&lt;span class="p"&gt;(:&lt;/span&gt;&lt;span class="n"&gt;sleeptime&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;update&lt;/span&gt; &lt;span class="n"&gt;hr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;job_history&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;start_date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="k"&gt;current_date&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="n"&gt;days&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;end_date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;current_date&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;employee_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5550&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;ENDOFFILE&lt;/span&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Running the above workload will create a lock condition.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;PGPASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;PGPASSWORD2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;pgbench&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;PGHOST2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;U&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;PGUSER2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;PGPORT2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;PGDATABASE2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;workload&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;lock&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;txn1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;workload&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;lock&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;txn2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;c&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="mi"&gt;1800&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Just like the previous insight, DevOps Guru is smart enough to find the cause and suggest a reason behind the anomaly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/OaSBYGsfL7MzXnn1my10yNbF8Z_YLIlHd4x7CZ7Sfpc/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTIuMzMu/NDMtUE0ucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/OaSBYGsfL7MzXnn1my10yNbF8Z_YLIlHd4x7CZ7Sfpc/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTIuMzMu/NDMtUE0ucG5n" alt="lock issue" width="880" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/qVxPOoLR9_ToiVBmYWR8ZcDDVE4x0RLgPXtwhQpaZAU/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTIuMzMu/NTEtUE0uanBn" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/qVxPOoLR9_ToiVBmYWR8ZcDDVE4x0RLgPXtwhQpaZAU/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTIuMzMu/NTEtUE0uanBn" alt="lock recommendation" width="880" height="486"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  DevOps Guru For Serverless
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scenario 1&lt;/strong&gt;: As business needs are changing, the production application which was running on virtual machines have been moved to AWS serverless. In the production DynamoDB, there is a misconfiguration of not &lt;strong&gt;enabling point-in-time recovery&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;DevOps Guru not only sends reactive insights but it also provides proactive insights ( takes about 12 hours once enabled) which we can't foresee in the status quo&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check the proactive insights tab, to see the insight recommendation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/h46JWHSBCmnK-InGdUYHo7g30NpgJDmFFq3x-Ljsiqo/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtNC4wMy40/NC1QTS5wbmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/h46JWHSBCmnK-InGdUYHo7g30NpgJDmFFq3x-Ljsiqo/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtNC4wMy40/NC1QTS5wbmc" alt="proactive recommendation" width="880" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scenario 2&lt;/strong&gt;: We will &lt;strong&gt;reduce Read Capacity from 5 to 1 of DynamoDB and update via Cloudformation&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/SAUiM-zOwP1gskp8OjT1sTz2mRlQDRB_JeBpMnld4zI/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTEuNDcu/MDktQU0ucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/SAUiM-zOwP1gskp8OjT1sTz2mRlQDRB_JeBpMnld4zI/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTEuNDcu/MDktQU0ucG5n" alt="misconfig" width="880" height="438"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/environment/amazon-devopsguru-samples/generate-devopsguru-insights
aws cloudformation update-stack &lt;span class="nt"&gt;--stack-name&lt;/span&gt; myServerless-Stack &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--template-body&lt;/span&gt; file:///&lt;span class="nv"&gt;$PWD&lt;/span&gt;/cfn-shops-monitoroper-code.yaml &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--capabilities&lt;/span&gt; CAPABILITY_IAM CAPABILITY_NAMED_IAM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now we will try to inject an HTTP request to  API using 4 instances of the python script. After some time &lt;strong&gt;we can observe 502 internal server errors&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python sendAPIRequest.py &amp;amp;amp&lt;span class="p"&gt;;&lt;/span&gt; python sendAPIRequest.py &amp;amp;amp&lt;span class="p"&gt;;&lt;/span&gt; python sendAPIRequest.py &amp;amp;amp&lt;span class="p"&gt;;&lt;/span&gt; python sendAPIRequest.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://community.ops.io/images/8rZHcGNVMTxDKBSBt1DuujdnvK0c-5q5Yc4cGlUW3lA/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTEuNTAu/NTctQU0ucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/8rZHcGNVMTxDKBSBt1DuujdnvK0c-5q5Yc4cGlUW3lA/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTEuNTAu/NTctQU0ucG5n" alt="502 errors" width="880" height="556"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;DevOps Guru monitors and reports this anomaly with the cause of the anomaly and applicable recommendations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can also confirm the &lt;strong&gt;relevant event&lt;/strong&gt; which caused this issue.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/olpS6h5UoRIrn3WguKaiY-_6qjdkOv0GVKiH9ubcM0E/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTEuNTcu/MzctQU0ucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/olpS6h5UoRIrn3WguKaiY-_6qjdkOv0GVKiH9ubcM0E/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTEuNTcu/MzctQU0ucG5n" alt="event history" width="880" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/DlrAWWskuypWh48PCddl3GlZ5MWa2spT1e3arCbKgVs/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTEuNTcu/NTMtQU0ucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/DlrAWWskuypWh48PCddl3GlZ5MWa2spT1e3arCbKgVs/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtMTEuNTcu/NTMtQU0ucG5n" alt="dynamodb config recommendation" width="880" height="561"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/gNxVxDVa3FAsqISdgCPwdoQ-Sn_WetgUtx-zA-JB8eM/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtNC4xMy4y/MS1QTS5wbmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/gNxVxDVa3FAsqISdgCPwdoQ-Sn_WetgUtx-zA-JB8eM/w:880/mb:500000/ar:1/aHR0cHM6Ly9kMXRs/emlmZDhqZG95NC5j/bG91ZGZyb250Lm5l/dC93cC1jb250ZW50/L3VwbG9hZHMvMjAy/Mi8xMS9TY3JlZW5z/aG90LTIwMjItMTEt/MTctYXQtNC4xMy4y/MS1QTS5wbmc" alt="graph anomaly" width="880" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  From DevOps Perspective
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;DevOps guru removes the need for manual monitoring of applications and infrastructure on AWS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;With the use of pre-trained ML models, it indeed fulfils the essential requirement of a production environment where it generates insights and recommendations for real-time application and infra-related issues as well as for future operational issues which cannot be anticipated at this time.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;I can definitely say it will surely help to achieve the high availability and operational excellence for AWS infrastructure that you promise to your customers.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Till then, &lt;strong&gt;Happy Learning!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Would love to know your opinions on this, let's connect! (&lt;a href="https://twitter.com/imjatinmehrotra"&gt;@imjatinmehrotra&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/jatinmehrotra/"&gt;Linkedin&lt;/a&gt; )&lt;/p&gt;

</description>
      <category>aiops</category>
      <category>aws</category>
      <category>devops</category>
    </item>
    <item>
      <title>CI CD 101 with GitLab</title>
      <dc:creator>Jatin Mehrotra</dc:creator>
      <pubDate>Thu, 28 Jul 2022 03:30:00 +0000</pubDate>
      <link>https://community.ops.io/jatin/ci-cd-101-with-gitlab-4pol</link>
      <guid>https://community.ops.io/jatin/ci-cd-101-with-gitlab-4pol</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This blog talks about fundamental DevOps practices to automate continuous integration and continuous deployment using &lt;strong&gt;GitLab&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is a beginner-friendly blog that assumes you do not know anything about GitLab and CI-CD.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Outcome of the blog
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/WstCuxhAUtWKuqbac3o4xOk3O-Sw9w6WWYvtC3kJX4w/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3Z0ZXBm/a3F3Y3d6MnZnZ2Rr/bW5vLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/WstCuxhAUtWKuqbac3o4xOk3O-Sw9w6WWYvtC3kJX4w/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3Z0ZXBm/a3F3Y3d6MnZnZ2Rr/bW5vLnBuZw" alt="CI-CD with GitLab" width="880" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By the end of this blog, you will be confident to automate 3 major components of any CI-CD pipeline&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running test cases&lt;/li&gt;
&lt;li&gt;Building a docker image&lt;/li&gt;
&lt;li&gt;Deploying it to infrastructure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Bonus:-&lt;/strong&gt; Pushing docker image to the repository&lt;/p&gt;

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

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/0yWAtQ6wYNM"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The idea for this blog comes from my favourite DevOps Teacher who makes it so easy to learn and practice DevOps skills and she is none other than &lt;a href="https://youtu.be/qP8kir2GUgo"&gt;Nana Janashia&lt;/a&gt;. Subscribe to her &lt;a href="https://www.youtube.com/c/TechWorldwithNana"&gt;youtube&lt;/a&gt; channel, to become a better DevOps Engineer and stay with the latest updates on the industry.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;I did mention earlier that it is a beginner-friendly blog, but there are a few basics which can really help you understand these concepts really well. (&lt;strong&gt;Don't worry if you don't know I will post relevant links to brush up wherever needed :D&lt;/strong&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;Linux&lt;/li&gt;
&lt;li&gt;AWS Account&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Let's Build the pipeline
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;For building the pipeline, use this GitLab repository which has a sample python application and &lt;a href="https://docs.gitlab.com/ee/gitlab-basics/start-using-git.html#clone-a-repository"&gt;clone it to your local environment&lt;/a&gt;. You can also fork it and edit in pipeline editor but it's always advisable to work in a local editor like vs-code.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://gitlab.com/jatin-devops/ci-cd-tutorial"&gt;Gitlab Repository&lt;/a&gt; which hosts application code and pipeline configuration &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1. Test and run application locally
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;As a DevOps Engineer, you don't need to know all the details of the application code, &lt;strong&gt;knowledge of how to run and test the application is important&lt;/strong&gt;. So depending on the application, &lt;strong&gt;&lt;em&gt;you should ask your dev team, how to run and test the application locally&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For this particular example application in order to test we use the following command&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://community.ops.io/images/BdpsJx7o_6CD3BWdDOlBLkCbJZ7IzOI-gMgKw5uYbCQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2doZjdm/cHIwdmg0YzRjOGNt/ZTU2LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/BdpsJx7o_6CD3BWdDOlBLkCbJZ7IzOI-gMgKw5uYbCQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2doZjdm/cHIwdmg0YzRjOGNt/ZTU2LnBuZw" alt="running test locally" width="880" height="260"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In order to run the application locally, we use the following command
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://community.ops.io/images/h5Fg8NUVP_h20ddN66d9tpgTxdToZ9z1TgdeCA7cCEY/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2J0b2J1/a2t3dG5lYnF5NDd6/eW1lLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/h5Fg8NUVP_h20ddN66d9tpgTxdToZ9z1TgdeCA7cCEY/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2J0b2J1/a2t3dG5lYnF5NDd6/eW1lLnBuZw" alt="running app locally" width="880" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/-2mPayFomJB3cZLXiXDYiWX5bHJSwLNSrPRE1gryHJc/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2E0bXkw/YnlmaWh4dHp6ZjJv/bTFlLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/-2mPayFomJB3cZLXiXDYiWX5bHJSwLNSrPRE1gryHJc/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2E0bXkw/YnlmaWh4dHp6ZjJv/bTFlLnBuZw" alt="running the app locally on browser" width="880" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Points to Note
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;You need to know from the dev team &lt;strong&gt;how to run and test the application&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;We are using &lt;code&gt;make&lt;/code&gt; command since it's a python application for node-js-based applications we might have to use the &lt;code&gt;npm&lt;/code&gt; command. &lt;strong&gt;So availability of commands where we will run the application is very important&lt;/strong&gt;. &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  2. Gitlab CI CD internals
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;GitLab is one platform which allows doing everything in DevOps perse, planning, CI-CD, and deployment to any cloud which really makes it efficient as there is a single interface to deal with in SDLC.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Nana Janashia&lt;/strong&gt; jas given a great explanation in this &lt;a href="https://youtu.be/qP8kir2GUgo"&gt;video about GitLab architecture&lt;/a&gt;, though I will try to explain my understanding of the same so that it's easy to follow up in the blog&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GitLab has 2 components:-&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/8ms4xs3tUX6BmbCtMism1hVTv4P81xJmHc0t4Dmi4oI/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2hwb214/aWt5eHdsdTZ4bGVr/YnM5LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/8ms4xs3tUX6BmbCtMism1hVTv4P81xJmHc0t4Dmi4oI/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2hwb214/aWt5eHdsdTZ4bGVr/YnM5LnBuZw" alt="GitLab Architecture" width="781" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Gitlab instance/Server (managed &amp;amp; self-managed) -&amp;gt; Hosts app code and pipeline config&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Gitlab Runners (managed &amp;amp; self-managed) -&amp;gt; connected to GitLab servers, runners are agents that run your CI-CD jobs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Runners run on a separate machine ( Linux, windows) wrt to the GitLab instance.&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;For this blog, we will use managed components as it is easier to manage and operate.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Let's Build our CI-CD pipeline
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In order to create a pipeline, &lt;a href="https://docs.gitlab.com/ee/ci/yaml/gitlab_ci_yaml.html"&gt;GitLab&lt;/a&gt; requires us to create a file with the name &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; in the root of the git repository.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Inside this file, there will be commands in the form of scripts which are grouped into jobs&lt;/strong&gt; like running tests, building docker images or deploying could be 3 different jobs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Till this point, we know there are jobs inside the pipeline which perform a task, within the jobs, there is a script which consists of commands, &lt;strong&gt;but the immediate question is where do commands will be executed?&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Commands are executed by GitLab runner's execution environment. There are 2 kinds of execution environments.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;GitLab Runner is installed on different OS like Linux, and Windows; this is called a shell executor.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Instead of a shell executor, we can use a Docker container running on Linux machines. Each job will be run in a separate and isolated container.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Managed runners use docker container as default execution environment with the ruby image as default for that container. Of course, we can choose the docker images of our choice depending on the job and use cases. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For running our test case in the pipeline we need make, pip and python available in our execution env, for that we will use &lt;a href="https://hub.docker.com/_/python"&gt;python docker image (python:3.0-slim-buster)&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Here is the job definition&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;run_tests:
  image: python:3.9-slim-buster
  before_script:
    - apt-get update &amp;amp;&amp;amp; apt-get install make
  script:
    - make test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Semantics :&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;run_tests&lt;/strong&gt;: name of the job.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;image&lt;/strong&gt;: name of the docker image for executing commands.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;script&lt;/strong&gt;: commands which need to be executed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;before_script&lt;/strong&gt;: any commands which need to be installed before running script commands in this case we need the &lt;code&gt;make&lt;/code&gt; command to be installed to run our test.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Commit your changes and push them to the remote repository, GitLab will automatically trigger the pipeline to be executed. ( quite an ease ) &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/Zejn2zmhna92JmFh9u3dKCdt-Kj8r6z2mipODoqnJrA/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3YyZWRp/ZDdrNjhhczFrbHQ0/NG13LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/Zejn2zmhna92JmFh9u3dKCdt-Kj8r6z2mipODoqnJrA/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3YyZWRp/ZDdrNjhhczFrbHQ0/NG13LnBuZw" alt="successful job image" width="880" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Building docker image of our Application
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We want to deploy this application to AWS on ec2 as a docker container, for that we need to make a docker image out of this application and push it to the docker registry. For registry we are going to use &lt;a href="https://hub.docker.com"&gt;dockerhub&lt;/a&gt;, &lt;a href="https://aws.amazon.com/ecr/"&gt;aws ecr&lt;/a&gt; can also be used for this purpose.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Here is the job definition for building a docker image&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variables:
  IMAGE_NAME: jjatdevops/gitlab-ci-cd-python-app
  IMAGE_TAG: python-app-1.0

build_image:
  image: docker:20.10.17
  services:
    - docker:20.10.17-dind
  variables:
   DOCKER_TLS_CERTDIR: "/certs"
  before_script:
    - docker login -u $REGISTRY_USER -p $REGISTRY_PASS
  script:
    - docker build -t $IMAGE_NAME:$IMAGE_TAG .
    - docker push $IMAGE_NAME:$IMAGE_TAG
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In this job, we are using variables and docker insider docker container (dind).&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Variables can be at the job level that is within the job, accessible only inside the job, or can be at the top level like here, which are accessible across all jobs or at the global level ($REGISTRY_USER, $REGISTRY_PASS) accessible across different repositories.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In order to build Docker images we need to configure GitLab runner to support docker containers, for this we need &lt;a href="https://docs.gitlab.com/ee/ci/docker/using_docker_build.html"&gt;docker inside docker(dind)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hub.docker.com/_/docker"&gt;docker:20.10.17&lt;/a&gt; provides docker client which will build image and push to the registry but we also need docker daemon which is a process that allows docker client to execute the command, which is provided by docker:20.10.17-dind container.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Semantics :&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;services&lt;/strong&gt; - &lt;a href="https://docs.gitlab.com/ee/ci/services/"&gt;services&lt;/a&gt; in GitLab are parallel container attacher to job container ( inside same network) when job container needs another container to carry out its operation. This is much faster than installing the dependency in the job container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;DOCKER_TLS_CERTDIR&lt;/strong&gt; - This allows client and daemon to talk to each other by authenticating to each other using a common certificate as mentioned in the &lt;a href="https://hub.docker.com/_/docker"&gt;docs&lt;/a&gt; ( find TLS on the page)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;docker login &amp;amp; docker push&lt;/strong&gt; -  First it logins to the docker hub registry ( since it's a private repository ) and pushes the image to the repository.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;After commit and push, GitLab will automatically trigger the pipeline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/ecMs6B1JkIFiO4eQdBFpHvnZ9wanuDFGa72WKGJHNAE/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3o3ZHZi/c2NwN3Z5Zm0yMzli/NTEyLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/ecMs6B1JkIFiO4eQdBFpHvnZ9wanuDFGa72WKGJHNAE/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3o3ZHZi/c2NwN3Z5Zm0yMzli/NTEyLnBuZw" alt="build job" width="880" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/i86kBtsKoDI-S57X4x1Ya_zjwmHZJGXBbiLzGHwVhU0/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3k1ZGVy/Z25hNzduN3FqN3Q4/ODl2LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/i86kBtsKoDI-S57X4x1Ya_zjwmHZJGXBbiLzGHwVhU0/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3k1ZGVy/Z25hNzduN3FqN3Q4/ODl2LnBuZw" alt="docker image pushed to dockehub" width="727" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Introducing stages to Pipeline
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Till this moment whenever we push both &lt;strong&gt;run_tests&lt;/strong&gt; and &lt;strong&gt;build_image&lt;/strong&gt; jobs run in a parallel fashion. &lt;strong&gt;In most of the cases, you want sequential execution of jobs which means if running tests cases job is successful then only build the docker image.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sequential execution can be achieved in GitLab using stages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using &lt;a href="https://docs.gitlab.com/ee/ci/yaml/#stages"&gt;stages&lt;/a&gt; we can group related jobs into stages that run in the defined order.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Here is the job definition after introducing stages to the pipeline&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;stages:
  - test
  - build


run_tests:
  stage : test
  image: python:3.9-slim-buster
  before_script:
    - apt-get update &amp;amp;&amp;amp; apt-get install make
  script:
    - make test

build_image:
  stage: build
  image: docker:20.10.17
  services:
    - docker:20.10.17-dind
  variables:
   DOCKER_TLS_CERTDIR: "/certs"
  before_script:
    - docker login -u $REGISTRY_USER -p $REGISTRY_PASS
  script:
    - docker build -t $IMAGE_NAME:$IMAGE_TAG .
    - docker push $IMAGE_NAME:$IMAGE_TAG

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;All jobs in the test execute in parallel ( here we have a single job ).&lt;/li&gt;
&lt;li&gt;If all jobs in the test succeed, then only build jobs execute in parallel.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/CfKuXd5D1TWj1SqTbHzjMcxlLwQ67nx1MD0TcaBJjnU/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL20zeGc0/YWJta2NyMjI5bXhi/NnhjLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/CfKuXd5D1TWj1SqTbHzjMcxlLwQ67nx1MD0TcaBJjnU/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL20zeGc0/YWJta2NyMjI5bXhi/NnhjLnBuZw" alt="introducing stages in GitLab cicd pipeline" width="880" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Deploying to Ec2 instance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In the final step for pipeline configuration we are going to run the docker image pushed to docker hub in ec2 instance running in AWS cloud.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We will manually start an ec2 instance with 5000 ports allowed on the security group with a new ec2 key pair.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After starting the ec2 instance we need to prepare the ec2 instance in order to run the docker container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ssh into ec2 instance&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -i "your-ssh-key.pem" ec2-user@ec-your-ip-adress.ap-southeast-1.compute.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Install docker
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
sudo yum install docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add group membership for the default ec2-user so you can run all docker commands without using the sudo command
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo usermod -a -G docker ec2-user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Enable docker service at AMI boot time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;sudo systemctl enable docker.service&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start the Docker service
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl start docker.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We will add &lt;code&gt;$SSH_KEY&lt;/code&gt; as &lt;strong&gt;file variable&lt;/strong&gt; in the GitLab file variable. Contents of this variable will be the private key used for creating an ec2 instance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; :- GitLab create a temporary file from this variable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Here is the job definition for deploy&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;deploy:
  stage: deploy
  before_script:
    - chmod 400 $SSH_KEY
  script: ssh -o StrictHostKeyChecking=no -i $SSH_KEY ec2-user@ec2-3-1-100-185.ap-southeast-1.compute.amazonaws.com "
          docker login -u $REGISTRY_USER -p $REGISTRY_PASS &amp;amp;&amp;amp;
          docker ps -aq | xargs docker stop | xargs docker rm || true   &amp;amp;&amp;amp;
          docker run -d -p 5000:5000 $IMAGE_NAME:$IMAGE_TAG"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Semantics:- &lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;ssh -o StrictHostKeyChecking=no -i $SSH_KEY ec2-user@ec2-3-1-100-185.ap-southeast-1.compute.amazonaws.com&lt;/code&gt; - connect to ec2 instance and run the following commands.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;docker login -u $REGISTRY_USER -p $REGISTRY_PASS &amp;amp;&amp;amp;&lt;br&gt;
      docker ps -aq | xargs docker stop | xargs docker rm || true   &amp;amp;&amp;amp;&lt;br&gt;
      docker run -d -p 5000:5000 $IMAGE_NAME:$IMAGE_TAG"&lt;br&gt;
&lt;/code&gt; - run the docker container on the ec2 instance&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/xL_meUc9r5aHMW8sFOU7P53xesazuuhTPGdw2PsYZS8/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzU5ZnVu/bnd5cWpuOTg2bXU1/czM2LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/xL_meUc9r5aHMW8sFOU7P53xesazuuhTPGdw2PsYZS8/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzU5ZnVu/bnd5cWpuOTg2bXU1/czM2LnBuZw" alt="added deploy stage for GitLab CI CD pipeline" width="880" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/JWcJH7bhHmzqQmntE1LAx5mDS-vquJwpVE8ynXUB_x0/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2g2YXEz/eXRpbW9jandpZTVq/dGRpLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/JWcJH7bhHmzqQmntE1LAx5mDS-vquJwpVE8ynXUB_x0/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2g2YXEz/eXRpbW9jandpZTVq/dGRpLnBuZw" alt="Application deployed to ec2 instance as docker container" width="880" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  From DevOps Perspective
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We have successfully achieved the automation of various SDLC processes like running tests, building docker images, pushing them to the container registry and deploying it to the cloud.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;With this knowledge, you can successfully implement any CI-CD pipeline, it doesn't matter if it is JAVA based application or a nodejs-based application.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;_We did achieve automation, however, there were still manual process elements like creating ec2 which can be further automated using terraform and guess what it will be part 2 of this blog. _&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note:- GitLab platform offers much more features when it comes to CI-CD, feel free to check out the &lt;a href="https://www.techworld-with-nana.com/gitlab-cicd-course?utm_source=youtube&amp;amp;utm_medium=gitlab-in-1-hour&amp;amp;utm_campaign=gitlab-full-course"&gt;Dive deeper in GitLab course from NANA.&lt;/a&gt; and become an expert at GitLab.&lt;/p&gt;

&lt;p&gt;Till then, Happy Learning !!!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Feel Free to post any comments or questions.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>tutorials</category>
      <category>aws</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Let's Terraform IT: Pt 4 -&gt; Count (index), Conditional Expression, Local Values</title>
      <dc:creator>Jatin Mehrotra</dc:creator>
      <pubDate>Sat, 18 Jun 2022 08:02:00 +0000</pubDate>
      <link>https://community.ops.io/jatin/lets-terraform-it-pt-4-count-index-conditional-expression-local-values-4mj5</link>
      <guid>https://community.ops.io/jatin/lets-terraform-it-pt-4-count-index-conditional-expression-local-values-4mj5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;By this time we know how to write a terraform code for simple infrastructure, but in reality, things are never easy, business needs are everchanging leading to complex infrastructure.&lt;/p&gt;

&lt;p&gt;In this blog we will try to build our knowledge on features offered by terraform which helps to transform complex code into simple code and remove redundancy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;From now on, in this series, I want to introduce the topic with a use case because I believe that understanding a concept is one thing but knowing how to apply it in the real world makes the actual difference.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Count and Count Index
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use Case
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Until now, we have been creating single resources for example an ec2 instance or an IAM user, but in production-grade applications, there are multiple resources, what would be an ideal way to create multiple resources of the same type? for instance multiple ec2 instances!!!&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One approach would be to write 3 identical ec2 resource blocks with different local resource names.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;provider "aws" {
  region     = "us-west-2"
  access_key = "your-access-key"
  secret_key = "your-secret-key"
}

resource "aws_instance" "instance1" {

  ami           = "ami-0ca285d4c2cda3300"
  instance_type = "t2.micro"
}

resource "aws_instance" "instance2" {

  ami           = "ami-0ca285d4c2cda3300"
  instance_type = "t2.micro"

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This approach is not scalable &lt;strong&gt;if we are needed to create 40 ec2 instances, which will result in 40 ec2 resource blocks, updating such blocks would be prone to errors and difficult&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Terraform provides a count parameter which &lt;strong&gt;allows creating many resources using a single resource block&lt;/strong&gt;, hence easier updation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The following code allows us to create 5 ec2 instances using the count parameter.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "aws_instance" "instance" {

  ami           = "ami-0ca285d4c2cda3300"
  instance_type = "t2.micro"
  count         = 5
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://community.ops.io/images/b3XmnPerlXSRSZ0N-OJqsTCq9mwhOS1WrzsWOwURmC8/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2U4MDZ6/czcwZTYwNHp6cmEx/dGpsLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/b3XmnPerlXSRSZ0N-OJqsTCq9mwhOS1WrzsWOwURmC8/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2U4MDZ6/czcwZTYwNHp6cmEx/dGpsLnBuZw" alt="resource creating using count" width="880" height="122"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Count Index
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use Case
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Count parameter solved our problem but it also brings its own set of problems with it. We want to create 5 IAM users, an ideal approach to this problem would be to use the count parameter, however using count would result in 5 iam users with the same name, hence it is difficult to identify resources when the count is used.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "aws_iam_user" "users" {
  name  = "iam_users"
  count = 3
  path  = "/system/"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;this result in 3 iam users with the same name iam_users leading to difficulty in the identification of resources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/qmGi5fLuSsLxTcfaZbONnHh6EaoTiRWcO076c0mn-Qs/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzU4dzQ1/ZmlqYTExeGhucjN5/aGJyLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/qmGi5fLuSsLxTcfaZbONnHh6EaoTiRWcO076c0mn-Qs/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzU4dzQ1/ZmlqYTExeGhucjN5/aGJyLnBuZw" alt="difficult indentification using count" width="880" height="868"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;terraform provides a &lt;code&gt;count.index&lt;/code&gt; value which behind the scenes, access count parameter (count runs a loop) index value to identify the loop cycle. This helps in generating unique values with count parameters as &lt;code&gt;count.index&lt;/code&gt; will always be unique for a particular loop cycle ( for example if the loop is running the first time it will be 1 and so on)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "aws_iam_user" "users" {
  name  = "iam_users.${count.index}"
  count = 2
  path  = "/system/"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This results in 3 iam users with the name iam_users.1, iam_user.2.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/thGFIrSrctbNBNFybRqCyN5Pr8Z9Bg72NG72nhH80rs/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL292djNu/OTBhanVtbjltMmxy/OWU1LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/thGFIrSrctbNBNFybRqCyN5Pr8Z9Bg72NG72nhH80rs/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL292djNu/OTBhanVtbjltMmxy/OWU1LnBuZw" alt="easy identification using count index" width="880" height="832"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;count.index with count can be combined together using array data type.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variable "names" {
  type    = list(any)
  default = ["admin", "dev"]
}

resource "aws_iam_user" "users" {
  name  = var.names[count.index]
  count = 2
  path  = "/system/"
}

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This results in 2 iam users with the name admin, dev.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/_4EQ8oSn1VZvZUxFzP3f85r74vIqBfWuF_8jhu0LnKc/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzdjdWc2/ODRrbDluanhnbHFr/eHFsLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/_4EQ8oSn1VZvZUxFzP3f85r74vIqBfWuF_8jhu0LnKc/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzdjdWc2/ODRrbDluanhnbHFr/eHFsLnBuZw" alt="users with name using count.index" width="880" height="931"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Behind the scenes with Count and Count Index
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Count internally runs a loop and the count index maps the count of the particular loop.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conditional Expression
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use Case
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;We need to launch an ec2 instance for the production if a particular variable exists else for the development.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Conditional expression &lt;code&gt;? :&lt;/code&gt; helps us to select a value depending on the condition.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; count         = var.istest ? 1 : 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If is &lt;code&gt;isTest&lt;/code&gt; variable is &lt;code&gt;true&lt;/code&gt;, the count will be &lt;code&gt;1&lt;/code&gt; otherwise &lt;code&gt;0&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "aws_instance" "dev" {

  ami           = "ami-0ca285d4c2cda3300"
  instance_type = "t2.micro"
  count         = var.istest ? 1 : 0
}

resource "aws_instance" "prod" {

  ami           = "ami-0ca285d4c2cda3300"
  instance_type = "t2.large"
  count         = var.istest ? 0 : 1
}

variable "istest" {
  type    = bool
  default = true
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This code block results in the creation of t2.micro instance if &lt;code&gt;istest = true&lt;/code&gt; else t2.large instance for production if &lt;code&gt;istest = false
&lt;/code&gt;
## Locals&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use Case
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;We need to same name tags for 2 ec2 instances and ebs volume. One approach would be to write tags in 2 resource blocks for ec2 and in one resource block for ebs volume. This will work however, this will lead to writing code which is repetitive and if in the future the name tag needs to be changed it needs to be replaced in 3 different places. Quite inconvenient!!!!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;An ideal way would be to define it in one place and reference it in all the places.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Locals assign a name to an expression or value and allow it to be used in multiple places.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;provider "aws" {
  region     = "us-west-2"
  access_key = "your-access-key"
  secret_key = "your-secret-key"
}
locals {
  common_tags = {
    Owner   = "DevOps Team"
    service = "backend"
  }
}
resource "aws_instance" "dev" {
  ami           = "ami-082b5a644766e0e6f"
  instance_type = "t2.micro"
  tags          = local.common_tags
}

resource "aws_instance" "db-dev" {
  ami           = "ami-082b5a644766e0e6f"
  instance_type = "t2.small"
  tags          = local.common_tags
}

resource "aws_ebs_volume" "db_ebs" {
  availability_zone = "us-west-2a"
  size              = 8
  tags              = local.common_tags
}

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://community.ops.io/images/wCdxFx4laKhKqMrKiEEikH1FqZNTsRB5UzDDTt9c6fs/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzZ4Y2l6/bjV3Zmp3dmhqemk2/MmhyLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/wCdxFx4laKhKqMrKiEEikH1FqZNTsRB5UzDDTt9c6fs/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzZ4Y2l6/bjV3Zmp3dmhqemk2/MmhyLnBuZw" alt="common tags using local" width="880" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This code allows us to use the same tags across all resources without repeating the same code in all the resources.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Bonus Accessing data from maps and list in the variable
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variable "types" {
  type    = list(any)
  default = ["t2.micro", "t2.large"]
}


resource "aws_instance" "myFirstEc2Instance" {

  ami           = "ami-0ca285d4c2cda3300"
  instance_type = var.instance[0]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;list values start with &lt;code&gt;index 0&lt;/code&gt; which means instance type t2.micro will be selected.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;provider "aws" {
  region     = "us-west-2"
  access_key = "your-access-key"
  secret_key = "your-secret-key"
}

resource "aws_instance" "myFirstEc2Instance" {

  ami           = "ami-0ca285d4c2cda3300"
  instance_type = var.instance["delhi"]
}


variable "instance" {
  type = map(any)
  default = {
    "mumbai" = "t2.large"
    "delhi"  = "t2.micro"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To access the map data type value of the key is used to access its value within &lt;code&gt;[]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  From a DevOps perspective
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Count, conditional, and local values are the tools which help to write clean and non-repetitive code, which helps to scale easily when the requirements are changing.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>aws</category>
      <category>tutorials</category>
      <category>terraform</category>
    </item>
    <item>
      <title>Let's Terraform IT: Pt 3 -&gt; Provider Versioning, Output, Attributes, Variables and Data types</title>
      <dc:creator>Jatin Mehrotra</dc:creator>
      <pubDate>Sun, 12 Jun 2022 14:41:36 +0000</pubDate>
      <link>https://community.ops.io/jatin/lets-terraform-it-pt-3-provider-versioning-output-attributes-variables-and-data-types-4e29</link>
      <guid>https://community.ops.io/jatin/lets-terraform-it-pt-3-provider-versioning-output-attributes-variables-and-data-types-4e29</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;We are in part 3 of this series (part &lt;a href="https://community.ops.io/jatin/lets-terraform-it-pt-1-providers-resources-5a63"&gt;1&lt;/a&gt; , &lt;a href="https://community.ops.io/jatin/lets-terraform-it-pt-2-commands-state-files-1k4b"&gt;2&lt;/a&gt; ) and now the real fun with terraform begins.&lt;/p&gt;

&lt;p&gt;In this blog, our main focus will be on Production level Best practices with terraform? But wait, we are still in 101 level and talking about production level? Yes, because even at the 101 level, this series tries to inculcate, and grow the sense of production-level practices right from the beginning.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Basic AWS knowledge&lt;/li&gt;
&lt;li&gt;Terminal Access&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://community.ops.io/jatin/lets-terraform-it-pt-1-providers-resources-5a63"&gt;Part 1&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://community.ops.io/jatin/lets-terraform-it-pt-2-commands-state-files-1k4b"&gt;Part 2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Provider Versioning
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform {
  required_providers {
    github = {
      source  = "integrations/github"
      version = "4.25.0-alpha"
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Terraform has 2 kinds of providers one which is managed by terraform and one which is managed by the provider itself.
For terraform managed providers we don't need to write provider block for terraform managed providers like aws.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;But from terraform 0.13 and above, terraform recommends using provider block for all kinds of providers.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/R6bGkKiCesJJdVpMdN_wYRqTz3FZ4NMI47SdtBAB8Z8/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL24zODh4/bmxyMmZ2djFjbWow/cmp0LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/R6bGkKiCesJJdVpMdN_wYRqTz3FZ4NMI47SdtBAB8Z8/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL24zODh4/bmxyMmZ2djFjbWow/cmp0LnBuZw" alt="terraform flow" width="687" height="161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;terraform uses the provider's underlying plugins to interact with the provider and provision infrastructure. Let's say today the version of provider plugins is v1 and some new service came and provider included that service insider new plugin version v2.&lt;/li&gt;
&lt;li&gt;In this case, we need to upgrade our provider version too in order to use that service.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How does provider block work?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;From the official &lt;a href="https://registry.terraform.io/providers/hashicorp/aws/latest"&gt;docs of aws provider&lt;/a&gt; this is how terraform recommends using AWS provider
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "4.18.0"
    }
  }
}

provider "aws" {
  # Configuration options
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This piece of code will download plugins for version 4.18.0&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  terraform init
&lt;/h3&gt;



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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;this command produces a lock file &lt;code&gt;.terraform.lock.hcl&lt;/code&gt; which maintains the version of your provider plugins.&lt;/li&gt;
&lt;li&gt;in order to upgrade to the latest version of plugins, we need to update the version in our lock file and use init command with &lt;code&gt;-upgrade&lt;/code&gt; flag&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/peEwX0USBs-xDMhuYU_hxq-cYAS8zuTVuSBBCZS887k/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3gxODJ0/dTJ3NmM1c3E4ZHBy/djJ0LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/peEwX0USBs-xDMhuYU_hxq-cYAS8zuTVuSBBCZS887k/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3gxODJ0/dTJ3NmM1c3E4ZHBy/djJ0LnBuZw" alt="lock file" width="880" height="609"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform init -upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:-&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if you don't use &lt;code&gt;-upgrade&lt;/code&gt; flag lock file won't allow using the upgraded version even though you mentioned it in the code.&lt;/li&gt;
&lt;li&gt;You many even see symbols like version = ~&amp;gt;3.0 or &amp;gt;=3.0 or &amp;lt;=3.0&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;~&amp;gt;&lt;/strong&gt; simply means download provider plugin in 3.x range&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&amp;gt;=&lt;/strong&gt; simply means download provider plugin ranging = or greater than 3.0 range&lt;/li&gt;
&lt;li&gt;**&amp;lt;= **simply means download provider plugin ranging = or lesser than 3.0 range&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Production Importance
&lt;/h3&gt;

&lt;p&gt;It is considered to use fix version for example &lt;code&gt;version = "4.18.0"&lt;/code&gt;, because there may be a chance when you use &lt;strong&gt;~&amp;gt;&lt;/strong&gt; that terraform installs the latest plugin version which has bugs and your production may break. So it is always advised to use the tested version and then upgrade to newer plugin versions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outputs and Attributes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;When we are provisioning infra, there is always a need to know the attributes of provisioned infra for example deployed ec2 IP address or EIP public IP.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Terraform allows doing this by writing output block for the particular resource.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;code.tf file&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;provider "aws" {
  region     = "us-west-2"
  access_key = "your-access-key"
  secret_key = "your-secret-key"
}


resource "aws_instance" "myFirstEc2Instance" {

  ami           = "ami-0ca285d4c2cda3300"
  instance_type = "t2.micro"
}


output "ec2_ip" {
  value = aws_eip.lb.public_ip
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;output block's has the format of output name followed by value = resource_name.local_resource_name.atrribute_name.&lt;/li&gt;
&lt;li&gt;attributes for each resource can be found in the &lt;a href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance#attributes-reference"&gt;attribute reference documentation.&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;output "ec2_ip" {
  value = aws_eip.lb.public_ip
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://community.ops.io/images/kIzVcTSFOp0Uc3NI4_n-TV32yjC8iWqSPwVg5EM2F-M/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzh4ODJ6/YjI4d2J0NjZtMWZu/aDNnLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/kIzVcTSFOp0Uc3NI4_n-TV32yjC8iWqSPwVg5EM2F-M/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzh4ODJ6/YjI4d2J0NjZtMWZu/aDNnLnBuZw" alt="output" width="620" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the same format of &lt;code&gt;resource_name.local_resource_name.atrribute_name&lt;/code&gt; &lt;strong&gt;can be used to cross-reference resources for example associating eip to ec2.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "aws_eip_association" "eip_assoc" {
  instance_id   = aws_instance.myFirstEc2Instance.id
  allocation_id = aws_eip.lb.id
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Variables
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why do we even need it?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Just like any other programming language, when you want to use a single value, hardcoding it will be fine, but if the same value is being used in 10 other places then if in future that value changes; it needs to be updated in 10 other places too.&lt;/li&gt;
&lt;li&gt;So an ideal practice is to store value in a central place and then reference it in our code. If in future that value changes, just change in source.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to store and reference variables?
&lt;/h3&gt;

&lt;p&gt;There are 4 ways to store variables:-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Default&lt;/li&gt;
&lt;li&gt;Command-line arguments&lt;/li&gt;
&lt;li&gt;file/custom file&lt;/li&gt;
&lt;li&gt;Environment &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Default variables
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Going by the name, if command-line or environment or from a file, variables are sources, then default variables will be used.&lt;/li&gt;
&lt;li&gt;In order to use default variables, create a separate file &lt;code&gt;variables.tf&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variable "instance_type" {
  default = "t2.micro"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In order to access a variable in our code, &lt;code&gt;var.name_of_variable&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "aws_instance" "myFirstEc2Instance" {

  ami           = "ami-0ca285d4c2cda3300"
  instance_type = var.instance_type
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note:- *&lt;em&gt;If there is variable defined in &lt;code&gt;variables.tf&lt;/code&gt;, and there is no default value, then terraform will show a prompt at the time of terraform apply&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variable "instance_type"{}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://community.ops.io/images/Kdd57mxl1ZyjruqyEh_6Ibgjl5UZvZN9hi1Tunw7LVU/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2dlcWg0/bnloMDVsOXJyd3hw/bWV1LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/Kdd57mxl1ZyjruqyEh_6Ibgjl5UZvZN9hi1Tunw7LVU/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL2dlcWg0/bnloMDVsOXJyd3hw/bWV1LnBuZw" alt="terraform variable prompt" width="880" height="71"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Command-line args
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Command-line arguments are used to add values for testing.&lt;/li&gt;
&lt;li&gt;To add command line arguments &lt;code&gt;-var="var_name=value"&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terrform apply -var="instance_type=t2.large"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Note:- &lt;strong&gt;If the default variable is present it will override by the command line argument.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  From File
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Now default variables are used for default when no value is used, but usually, in production, there is always a value specified.&lt;/li&gt;
&lt;li&gt;In order to source variables from a file create a file called &lt;code&gt;terraform.tfvars&lt;/code&gt; ( naming convention is important)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;instance_type = "t2.large"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note :- &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;to use a custom file name you need to use &lt;code&gt;-var-file&lt;/code&gt; flag
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform aply -var-file="custom_file.tfvars"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Environment variables
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;There is another way to source variables i.e by using them as environment variables.&lt;/li&gt;
&lt;li&gt;syntax is as follows
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export TF_VAR_instance_type="t2.nano"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note:- &lt;strong&gt;if you are using environment variables then make sure there is no value present terraform.tfvars otherwise, the export variable value will be overwritten by the tfvars value.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Data type of variable
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Let's say there is a condition to create a iam user which by employee id, which only contains the number.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To add this constraint we need, data type defined as numbers inside &lt;code&gt;variables.tf&lt;/code&gt; file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;variables.tf file&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variable "user_name" {
  type = number
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;code.tf file
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;provider "aws" {
  region     = "us-west-2"
  access_key = "your-access-key"
  secret_key = "your-secret-key"
}

resource "aws_iam_user" "user" {
  name = var.user_name
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;terraform.tfvars file
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This will result in an error because &lt;code&gt;user_name&lt;/code&gt; expects a number rather than a string.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/kLWqNSNel5hyl0UGHkQThQJNuUgBXabhoNK6jrQDNmE/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3RsbnBv/eGR1YXgzdHNtMjF0/cWlqLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/kLWqNSNel5hyl0UGHkQThQJNuUgBXabhoNK6jrQDNmE/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzL3RsbnBv/eGR1YXgzdHNtMjF0/cWlqLnBuZw" alt="data type error" width="880" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;However, if we use a number that works.
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;There are 5 kinds of data types we can use &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;number&lt;/code&gt;, &lt;code&gt;bool&lt;/code&gt;, &lt;code&gt;list&lt;/code&gt;, and &lt;code&gt;map&lt;/code&gt;. &lt;a href="https://www.terraform.io/language/expressions/types"&gt;reference&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  From a cloud engineer perspective
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;In this article, we saw best practices when it comes to provider versioning.&lt;/li&gt;
&lt;li&gt;Different ways to input variables.&lt;/li&gt;
&lt;li&gt;How to type-safe our variables using data types.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Feel free to post your questions or suggestions in the comments, let's learn together.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>tutorials</category>
      <category>aws</category>
      <category>terraform</category>
    </item>
  </channel>
</rss>
