<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Anuj Bansal</title>
    <description>The latest articles on DEV Community by Anuj Bansal (@anuj_bansal_).</description>
    <link>https://dev.to/anuj_bansal_</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F364778%2Fbeb14122-0906-4884-8b50-c85f6d7ca934.jpg</url>
      <title>DEV Community: Anuj Bansal</title>
      <link>https://dev.to/anuj_bansal_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/anuj_bansal_"/>
    <language>en</language>
    <item>
      <title>Introduction to AWS CloudFormation 📜</title>
      <dc:creator>Anuj Bansal</dc:creator>
      <pubDate>Mon, 30 Aug 2021 13:56:09 +0000</pubDate>
      <link>https://dev.to/aws-builders/introduction-to-aws-cloudformation-4po2</link>
      <guid>https://dev.to/aws-builders/introduction-to-aws-cloudformation-4po2</guid>
      <description>&lt;p&gt;Deploying more than just a handful of services on AWS and setting each one up manually can get quite tedious. Having to configure each AWS resource by hand also leaves you at a much higher risk of making errors or introducing inconsistencies.&lt;/p&gt;

&lt;p&gt;Enter AWS CloudFormation.&lt;/p&gt;

&lt;p&gt;CloudFormation is a service that provides an easy way to create and manage a collection of AWS resources in a controlled and predictable way.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does AWS CloudFormation work?
&lt;/h2&gt;

&lt;p&gt;The key concepts in CloudFormation are templates, stacks, and change sets.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Template:&lt;/strong&gt; A template is a description of your infrastructure, written in JSON or YAML, that can be interpreted by CloudFormation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stack:&lt;/strong&gt; Infrastructure created by CloudFormation using a template is known as a stack.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Change Set:&lt;/strong&gt; A summary of proposed changes to your stack that will allow you to see how those changes might impact your existing resources before implementing them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first thing you do is to create a CloudFormation template in JSON or YAML format.&lt;/p&gt;

&lt;p&gt;You then deploy the template using the CloudFormation console, API, or AWS CLI. CloudFormation provisions and configures resources by making calls to the AWS services that are described in your template.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630061730047%2F_VLhDFzO7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630061730047%2F_VLhDFzO7.png" alt="Screenshot 2021-08-27 at 4.20.14 PM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After all the resources have been created, CloudFormation reports that your stack has been created. If stack creation fails, CloudFormation rolls back your changes by deleting the resources that it created.&lt;/p&gt;

&lt;p&gt;To update a stack, create a change set by submitting a modified version of the original stack template, different input parameter values, or both. CloudFormation compares the modified template with the original template and generates a change set. You can then view the changes that will be deployed before you decide to execute the change.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630061748879%2FgtgSI8Cf8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630061748879%2FgtgSI8Cf8.png" alt="Screenshot 2021-08-27 at 4.18.09 PM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Template Basics
&lt;/h2&gt;

&lt;p&gt;The template can consist of the following sections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Format Version:&lt;/strong&gt; The AWS CloudFormation template version that the template conforms to.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Description:&lt;/strong&gt; A text string that describes the template.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metadata:&lt;/strong&gt; Arbitrary JSON or YAML objects that provide additional information about the template.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parameters:&lt;/strong&gt; Values to pass to your template at runtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rules:&lt;/strong&gt; Validates a parameter or a combination of parameters passed to a template during stack creation or stack update.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mappings:&lt;/strong&gt; A mapping of keys and associated values that you can use to specify conditional parameter values, similar to a lookup table.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conditions:&lt;/strong&gt; Conditions that control whether certain resources are created or whether certain resource properties are assigned a value during stack creation or update.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transform:&lt;/strong&gt; Set of macros to process your template. Basically creates a processed version of your template.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resources:&lt;/strong&gt; AWS resources that you want to include in your stack.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Outputs:&lt;/strong&gt; Declares output values that you can import into other stacks, return in response (to describe stack calls), or view in the console.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is what a basic template looks like 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630061768889%2FEtshsE9jH.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630061768889%2FEtshsE9jH.png" alt="Screenshot 2021-08-27 at 10.08.00 AM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's go a bit more in-depth on some of the sections.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parameters
&lt;/h3&gt;

&lt;p&gt;Parameters are used to customize a template with values. They give us the flexibility to change settings without having to modify the template code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630061782160%2Fe6Cw6ltIGm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630061782160%2Fe6Cw6ltIGm.png" alt="Screenshot 2021-08-27 at 12.38.02 PM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;p&gt;This is the bulk of the template. Here is where we define and configure the resources that CloudFormation will manage for us. When defining resources, you need to know about the type and that type’s properties.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630061816994%2FT44l8NEDN.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630061816994%2FT44l8NEDN.png" alt="Screenshot 2021-08-27 at 12.38.59 PM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Outputs
&lt;/h3&gt;

&lt;p&gt;These are like return values for the template. We use them to make it easy to find some of the resources that CloudFormation will create for us.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630061829480%2FEpSSoaMHGp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630061829480%2FEpSSoaMHGp.png" alt="Screenshot 2021-08-27 at 12.39.16 PM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Intrinsic Functions
&lt;/h2&gt;

&lt;p&gt;CloudFormation has several intrinsic functions that you can use to refer to other resources and their properties. You can use them to assign values to properties that are not available until runtime.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fn::Base64&lt;/strong&gt; - returns the Base64 representation of the input string&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fn::Cidr&lt;/strong&gt; - returns an array of CIDR address blocks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Condition functions&lt;/strong&gt; - Used to conditionally create stack resources. These are Fn::And, Fn::Equals, Fn::If, Fn::Not and Fn::Or.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fn::FindInMap&lt;/strong&gt; - returns the value corresponding to keys in a two-level map that's declared in the Mappings section&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fn::GetAtt&lt;/strong&gt; - returns the value of an attribute from a resource in the template&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fn::GetAZs&lt;/strong&gt; - returns an array that lists Availability Zones for a specified region in alphabetical order&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fn::ImportValue&lt;/strong&gt; - returns the value of an output exported by another stack&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fn::Join&lt;/strong&gt; - appends a set of values into a single value, separated by the specified delimiter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fn::Select&lt;/strong&gt; - returns a single object from a list of objects by index&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fn::Split&lt;/strong&gt; - split a string into a list of string values using a delimiter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fn::Sub&lt;/strong&gt; - substitutes variables in an input string with values that you specify&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fn::Transform&lt;/strong&gt; - specifies a macro to perform custom processing on part of a stack template&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ref&lt;/strong&gt; - returns the value of the specified parameter or resource&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CloudFormation allows you to either use the full function name (Fn::Sub) or the short form (!Sub).&lt;/p&gt;

&lt;p&gt;This is what a sample template would look like with intrinsic functions 👇&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;AWSTemplateFormatVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2010-09-09'&lt;/span&gt;
&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Creating&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;an&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;EC2&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;instance&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;using&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;security&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;group&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;that&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;has&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;already&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;been&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;created&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;or&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;new&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;security&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;group'&lt;/span&gt;

&lt;span class="na"&gt;Parameters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ExistingSecurityGroup&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
    &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;An existing security group ID (optional).&lt;/span&gt;
    &lt;span class="na"&gt;Default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NONE&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;String&lt;/span&gt;

&lt;span class="na"&gt;Conditions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;CreateNewSecurityGroup&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Equals&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="nv"&gt;ExistingSecurityGroup&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;NONE&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;Resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;MyInstance&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AWS::EC2::Instance"&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
      &lt;span class="na"&gt;ImageId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ami-0ff8a91507f77f867"&lt;/span&gt;
      &lt;span class="na"&gt;SecurityGroups&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!If&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;CreateNewSecurityGroup&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="nv"&gt;NewSecurityGroup&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="nv"&gt;ExistingSecurityGroup&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
            &lt;span class="na"&gt;Tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Name&lt;/span&gt;
                &lt;span class="na"&gt;Value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Sub&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;${AWS::StackName}-webserver'&lt;/span&gt;

  &lt;span class="na"&gt;NewSecurityGroup&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AWS::EC2::SecurityGroup"&lt;/span&gt;
    &lt;span class="na"&gt;Condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CreateNewSecurityGroup&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;GroupDescription&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Enable HTTP access via port &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;
      &lt;span class="na"&gt;SecurityGroupIngress&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;IpProtocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tcp&lt;/span&gt;
          &lt;span class="na"&gt;FromPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
          &lt;span class="na"&gt;ToPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
          &lt;span class="na"&gt;CidrIp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;0.0.0.0/0&lt;/span&gt;

&lt;span class="na"&gt;Outputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;SecurityGroupId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;The group ID of the security group used.&lt;/span&gt;
    &lt;span class="na"&gt;Value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!If&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;CreateNewSecurityGroup&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="nv"&gt;NewSecurityGroup&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="nv"&gt;ExistingSecurityGroup&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;By leveraging an IaC tool such as CloudFormation, you can streamline the AWS deployment process. You can define your resource configurations once, then deploy them as many times as you need. You can manage anything from a single Amazon EC2 instance to a complex multi-tier multi-region application.&lt;/p&gt;

&lt;p&gt;Feel free to reach out to me on &lt;a href="https://twitter.com/anuj_bansal_" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;! 😊&lt;/p&gt;

</description>
      <category>aws</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Git internal architecture 🏛</title>
      <dc:creator>Anuj Bansal</dc:creator>
      <pubDate>Sun, 19 Apr 2020 20:51:34 +0000</pubDate>
      <link>https://dev.to/anuj_bansal_/git-internal-architecture-o1j</link>
      <guid>https://dev.to/anuj_bansal_/git-internal-architecture-o1j</guid>
      <description>&lt;p&gt;Git is a really simple and elegant solution to a complex problem. I think it’s important that we understand what’s going on behind the scenes and the engineering decisions made to fully grasp it's simplicity and power.&lt;/p&gt;

&lt;p&gt;How does Git store files? What happens when we run the various Git commands? How is everything linked? What is the data structure used?&lt;/p&gt;

&lt;p&gt;We are going to answer all of the questions below 👇&lt;/p&gt;

&lt;h1&gt;
  
  
  Initialising the repo
&lt;/h1&gt;

&lt;p&gt;When you run &lt;code&gt;git init&lt;/code&gt; in a directory, Git creates the &lt;code&gt;.git&lt;/code&gt; directory, which is where almost everything that Git stores and manipulates is located.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fahhda.github.io%2Fassets%2Fimages%2Fgit_init.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fahhda.github.io%2Fassets%2Fimages%2Fgit_init.gif" alt="Git%20internal%20architecture/git_init.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👆 Output of &lt;code&gt;tree .git&lt;/code&gt; when we run the &lt;code&gt;git init&lt;/code&gt; command&lt;/p&gt;

&lt;p&gt;It contains a few different types of files and directories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Configuration&lt;/em&gt;: the &lt;code&gt;.git/config&lt;/code&gt;, &lt;code&gt;.git/description&lt;/code&gt; and &lt;code&gt;.git/info/exclude&lt;/code&gt; files essentially help configure the local repository.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Hooks&lt;/em&gt;: the &lt;code&gt;.git/hooks&lt;/code&gt; directory contains scripts that can be run on certain lifecycle events of the repository.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Staging Area&lt;/em&gt;: the &lt;code&gt;.git/index&lt;/code&gt; file (which is not yet present in our tree listing above) will provide a staging area for our working directory.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Object Database&lt;/em&gt;: the &lt;code&gt;.git/objects&lt;/code&gt; directory is the default Git object database, which contains all content or pointers to local content.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;References&lt;/em&gt;: the &lt;code&gt;.git/refs&lt;/code&gt; directory is the default location for storing reference pointers for both local and remote branches, tags and heads. A reference is a pointer to an object, usually of type &lt;code&gt;tag&lt;/code&gt; or &lt;code&gt;commit&lt;/code&gt;. References are managed outside of the Object Database to allow the references to change where they point to as the repository evolves. Special cases of references may point to other references, e.g. &lt;code&gt;HEAD&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Staging a file
&lt;/h1&gt;

&lt;p&gt;When we run the command &lt;code&gt;git add .&lt;/code&gt; Git adds all the changes from the working directory to the staging area and creates blob files in the &lt;code&gt;.git/objects&lt;/code&gt; sub-directory.&lt;/p&gt;

&lt;p&gt;Each objects file has a 40-char SHA-1 hash as its filename. Git uses the first 2 chars to organise the objects in directories.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fahhda.github.io%2Fassets%2Fimages%2Fgit_add_kap.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fahhda.github.io%2Fassets%2Fimages%2Fgit_add_kap.gif" alt="Git%20internal%20architecture/git_add_kap.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This blob object has the contents of the file. &lt;strong&gt;All objects are immutable once created.&lt;/strong&gt; Making changes to a file and staging it will result in an entirely new object getting created.&lt;/p&gt;

&lt;p&gt;Let's verify and check the contents of this blob file. When we run the command&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;cat .git/objects/55/7db03de997c86a4a028e1ebd3a1ceb225be238&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
 we don't get what we expected.&lt;/p&gt;

&lt;p&gt;Well, Git actually compresses each and every object using &lt;a href="https://www.zlib.net/" rel="noopener noreferrer"&gt;zlib&lt;/a&gt; and therefore what you see is the compressed content.&lt;/p&gt;

&lt;p&gt;To see the actual file content use the command &lt;code&gt;git cat-file -p &amp;lt;SHA-1&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fahhda.github.io%2Fassets%2Fimages%2Fgit-cat_file.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fahhda.github.io%2Fassets%2Fimages%2Fgit-cat_file.gif" alt="Git%20internal%20architecture/git-cat_file.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Commits
&lt;/h1&gt;

&lt;p&gt;Running the &lt;code&gt;git commit&lt;/code&gt; command creates two more objects in the &lt;code&gt;objects&lt;/code&gt; sub-directory. One is a tree object and the other is a commit object.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fahhda.github.io%2Fassets%2Fimages%2Fgit_commit_with_tree_2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fahhda.github.io%2Fassets%2Fimages%2Fgit_commit_with_tree_2.gif" alt="Git%20internal%20architecture/git_commit_with_tree_2.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tree Objects
&lt;/h2&gt;

&lt;p&gt;A single tree object contains one or more entries, each of which is the SHA-1 hash of a blob or subtree with its associated mode, type, and filename.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fahhda.github.io%2Fassets%2Fimages%2Ftree.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fahhda.github.io%2Fassets%2Fimages%2Ftree.png" alt="Git%20internal%20architecture/Untitled.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Commit Objects
&lt;/h2&gt;

&lt;p&gt;The format for a commit object is simple: it specifies the top-level tree for the snapshot of the project at that point, the parent commits if any, the author/committer information and a commit message.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fahhda.github.io%2Fassets%2Fimages%2Fcommit.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fahhda.github.io%2Fassets%2Fimages%2Fcommit.png" alt="Git%20internal%20architecture/Untitled%201.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The commit id that we commonly use is the SHA-1 hash of the contents of the commit object.&lt;/p&gt;

&lt;p&gt;Git stores all the content as a directed acyclic graph using these different types of objects. Here is what the data structure would look like at this point of time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fahhda.github.io%2Fassets%2Fimages%2Fdata_structure.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fahhda.github.io%2Fassets%2Fimages%2Fdata_structure.png" alt="Git%20internal%20architecture/Untitled%202.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Branches
&lt;/h1&gt;

&lt;p&gt;A branch in Git is simply a lightweight movable pointer to one of the commit objects. Because of this reason, creating new branches in Git is "cheap".&lt;/p&gt;

&lt;p&gt;Every time you commit, the branch pointer moves forward automatically.&lt;/p&gt;

&lt;p&gt;How does Git know what branch you’re currently on? It keeps a special pointer called &lt;code&gt;HEAD&lt;/code&gt;. HEAD is nothing but a special pointer which points towards a branch. The branch that you are currently working on.&lt;/p&gt;

&lt;p&gt;When we run the command &lt;code&gt;git checkout -b &amp;lt;NAME&amp;gt;&lt;/code&gt; Git creates a new file in the &lt;code&gt;refs/heads&lt;/code&gt; directory with the branch name. The file contains the pointer to the latest commit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fahhda.github.io%2Fassets%2Fimages%2Fgit_checkout_with_diagram.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fahhda.github.io%2Fassets%2Fimages%2Fgit_checkout_with_diagram.gif" alt="Git%20internal%20architecture/git_checkout_with_diagram.gif"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;In conclusion, Git commands are an abstraction over the data storage. Hashes, file based key-value storage and tree data structure, these are the key things behind Git.&lt;/p&gt;

&lt;p&gt;Feel free to reach out to me on &lt;a href="https://twitter.com/anuj_bansal_" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let me know what other architectural deep dives would interest you. Comment below. 👇&lt;/p&gt;

</description>
      <category>git</category>
      <category>tutorial</category>
      <category>computerscience</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Top Mac Apps for becoming more productive 💪</title>
      <dc:creator>Anuj Bansal</dc:creator>
      <pubDate>Sat, 11 Apr 2020 16:52:04 +0000</pubDate>
      <link>https://dev.to/anuj_bansal_/top-mac-apps-for-becoming-more-productive-1dko</link>
      <guid>https://dev.to/anuj_bansal_/top-mac-apps-for-becoming-more-productive-1dko</guid>
      <description>&lt;p&gt;Thousands of apps have been made for mac. I am going to list a few that I use on a day-to-day basis to help you become more productive and save some time.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://rectangleapp.com/" rel="noopener noreferrer"&gt;Rectangle&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Move and resize windows in macOS using keyboard shortcuts or snap areas&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff8i2cmpqdkembtgwn1u6.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff8i2cmpqdkembtgwn1u6.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://hazeover.com/" rel="noopener noreferrer"&gt;HazeOver&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Too many windows to manage? Large display? Or sometimes getting lost in multiple monitors? HazeOver is for you! This app automatically highlights the front window by fading out all the background windows.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flmfxdifpw4myxz2lxkjx.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flmfxdifpw4myxz2lxkjx.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://recordit.co/" rel="noopener noreferrer"&gt;Recordit&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Recordit is a screencast tool for Mac and Windows operating systems. Recordit is a GIF-based screencast tool that provides desktop clients for both Windows and Mac. It allows users to record desktop screen for as long as five minutes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frecordit.co%2Fimages%2Frecordit.gif%3Fv%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frecordit.co%2Fimages%2Frecordit.gif%3Fv%3D1" alt="https://recordit.co/images/recordit.gif?v=1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://github.com/TermiT/Flycut" rel="noopener noreferrer"&gt;Flycut&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Clean and simple clipboard manager for developers. Every time you copy a code piece, Flycut stores it in history. Later, you can paste it using Shift-Command-V even if you have something different in your current clipboard. You can change the hotkey and other settings in preferences.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6zfzzyyl9xpy475tds0c.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6zfzzyyl9xpy475tds0c.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.mowglii.com/itsycal/" rel="noopener noreferrer"&gt;Itsycal&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;It is weird that Mac doesn't have a calendar in the menu bar if you want to have a quick look at the dates. If you want to have a quick look for the date next Friday, you would have to open up the calendar application on Mac, which is time consuming.&lt;/p&gt;

&lt;p&gt;Itsycal is a tiny menu bar calendar. If you want, it will display your events as a companion to the Mac Calendar app. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjzb9blub49z683onilgd.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjzb9blub49z683onilgd.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These were some of the apps that I use regularly. &lt;br&gt;
What other apps do you think should be on the list? Comment below 👇&lt;/p&gt;

</description>
      <category>productivity</category>
    </item>
  </channel>
</rss>
