<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Keet Malin Sugathadasa on Medium]]></title>
        <description><![CDATA[Stories by Keet Malin Sugathadasa on Medium]]></description>
        <link>https://medium.com/@keetmalin?source=rss-5b64fe2de783------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*OnnyGxhvKyUj9a05woYvfw.jpeg</url>
            <title>Stories by Keet Malin Sugathadasa on Medium</title>
            <link>https://medium.com/@keetmalin?source=rss-5b64fe2de783------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Tue, 12 May 2026 02:00:49 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@keetmalin/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[EKS Cluster Network Architecture for Worker Nodes]]></title>
            <link>https://keetmalin.medium.com/eks-cluster-network-architecture-for-worker-nodes-635e067c8c2a?source=rss-5b64fe2de783------2</link>
            <guid isPermaLink="false">https://medium.com/p/635e067c8c2a</guid>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[networking]]></category>
            <category><![CDATA[ek]]></category>
            <category><![CDATA[vpc]]></category>
            <category><![CDATA[aws]]></category>
            <dc:creator><![CDATA[Keet Malin Sugathadasa]]></dc:creator>
            <pubDate>Mon, 29 Jul 2024 12:41:13 GMT</pubDate>
            <atom:updated>2024-07-29T12:41:13.485Z</atom:updated>
            <content:encoded><![CDATA[<p>AWS EKS (Elastic Kubernetes Service) is Amazon’s managed Kubernetes Service, which works like magic once provisioned. But this would be the default setup of EKS. What if you intend to customize it according to your organization&#39;s designs, compliance standards, and privacy requirements? This is where things get complicated.</p><p>I want to share my experience and issues I ran into when building a fully private EKS cluster, meaning it can only be accessed via the VPC with no internet access. Based on the textbook guidelines, I provisioned the private EKS cluster in a private VPC, and when I tried to attach nodes to my cluster, BOOM!!! it started giving networking errors. Amazon always tries to provide a very user-friendly interface to provision resources in AWS. Still, some subtle attributes in their setup can burn up your entire week, if you don’t fully understand how it works under the hood.</p><p>Today, let me explain how the EKS network is set up, maybe start with a public EKS setup and dive deep into each component and how we can achieve a fully private EKS cluster.</p><h3>Two VPCs for each EKS Cluster</h3><p>An EKS cluster consists of 2 VPCs. The first VPC is managed by AWS where the Kubernetes Control Plane resides within this VPC (this cannot be seen by the users). The second VPC is the customer VPC which we specify during the cluster creation. This is where we place all the worker nodes.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0iWuyeDR5HVk89EUYSW6pw.png" /><figcaption>2 VPCs for EKS — AWS Managed VPC and Customer Managed VPC</figcaption></figure><h3>Cluster Endpoint Access Types</h3><p>The cluster endpoint configures how the Kubernetes API server can be accessed.</p><ol><li><strong>Public</strong>: The cluster endpoint is accessible from outside of your VPC (Customer Managed VPC). Worker node traffic will leave your VPC (Customer Managed VPC) to connect to the endpoint (in the AWS Managed VPC).</li><li><strong>Public and private</strong>: The cluster endpoint is accessible from outside of your VPC (Customer Managed VPC). Worker node traffic to the endpoint will stay within your VPC (Customer Managed VPC).</li><li><strong>Private</strong>: The cluster endpoint is only accessible through your VPC. Worker node traffic to the endpoint will stay within your VPC.</li></ol><h4>Public Endpoint Only</h4><p>This is the default behavior of the EKS Cluster. Access to the public endpoint can be controlled with the Security Group allowing only known IP ranges to access the EKS control plan. Anyone accessing the EKS Cluster from outside (eg: using kubectl), will enter through the public endpoint, pass the security group rules and access the control plane.</p><p>Any traffic originating from the VPC (eg: worker nodes trying to communicate with the EKS control plane), would leave the VPC, pass the Security Group rules, and access the control plane. Even though the traffic leaves the VPC, it does not leave the AWS network.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gOMIaTjWbre0HpgOcKp5bA.png" /></figure><p>For these nodes to connect to the EKS Control Plane, it at least requires one of the following:</p><p>1. Public IP address and a route to an Internet Gateway — (where nodes reside in public subnets)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AyOcbUC88mpz3HKzLfHnYA.png" /></figure><p>2. NAT Gateway (which already has a public IP address) — (where nodes are in a private subnet and the NAT Gateway is in a public subnet)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*SLw5JAZ13MNveLuCjYAR1g.png" /></figure><h4>Public and Private Endpoints</h4><p>This option allows the public endpoint as explained above, but the Customer Managed VPC traffic (eg: worker nodes trying to connect to the EKS control plane) will go through the EKS-managed Elastic Network Interface (ENI) through a private endpoint.</p><p>This situation is ideal if you’d like to allow your cluster to be accessible via the internet, but you’d like to allow your worker nodes to be in a private subnet and communicate with the EKS control plane through a private endpoint.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*x5OlfluqJAHSOtZPXBzCVw.png" /></figure><h4>Private Endpoint Only</h4><p>This is the most secure option. But it doesn&#39;t mean that the others are insecure. With the right configurations, every setup can be made secure. With this setup, the worker nodes will talk to the EKS control plane via the EKS-managed ENI.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PfYB6ugyTuY5yu_T2R9E-Q.png" /></figure><p>If you wish for someone to access the EKS cluster with kubectl, you can allow that to be done from within the VPC. No external traffic will be allowed into the cluster.</p><h3>What Happens when we provision a Worker Node?</h3><p>When we request a new node, it has to do the following.</p><ol><li>A new EC2 instance spin-up</li><li>Install Kubelet and Kubernetes Node Agent as part of the boot process on each node</li><li>Kubelet reaches out to the EKS Control Plane to register the node.</li><li>Kubelet receives API commands from the control plane and regularly sends updates to the control plane on node status, capacity, etc.</li></ol><h3>VPC Configurations for EKS</h3><p>Now that you understand how these different endpoint types work, let’s take a deeper look into different ways we can configure our customer-managed VPC.</p><p>The VPC networking is made up of Subnets and the specified networking configurations like routing, to control the traffic flows. So, there are different ways of configuring your VPC, and let’s take a look at each of them. In this, I’ll also explain the problem I faced with fully private VPC setups.</p><p>A VPC is made up of subnets which can either be public or private. We have the following network combinations possible in an EKS setup.</p><ul><li>Public Subnets only</li><li>Public and Private Subnets</li><li>Private Subnets only</li></ul><h4>Public Subnets only</h4><p>In this setup, all the resources like load balancers and worker nodes will be installed into public subnets. This means, all these resources are accessible from the internet. I mean, they are accessible, but controlled with the right configurations.</p><p>When provisioning worker nodes within the public subnets, each EC2 instance (worker node) will be assigned a public IP on launch. This limits the number of nodes as the number of IP addresses is limited in a given network.</p><p>With this setup, you could use any cluster endpoint setup for your EKS cluster.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lANxefOKyvvoMd2qcOe_pQ.png" /></figure><h4>Public and Private Subnets</h4><p>This is the widely used VPC setup for EKS, where the worker nodes reside within the private subnets and the NAT Gateway and load balancers are placed within the public subnet.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3gmiOlweWrAV5VE6ySRtHg.png" /></figure><h4>Private Subnets Only</h4><p>This is what we call a fully private VPC. There is no egress traffic nor ingress traffic to/from the VPC. For this setup, only the private cluster endpoint should be enabled for your EKS cluster.</p><p>This is an uncommon architecture, but can be seen in organizations where data is super sensitive, like banks, hospitals, etc.</p><p>The important thing to note here is, that we can easily set up an EKS with a cluster endpoint and allow your worker nodes to communicate with the EKS control plane. This is managed by EKS with their EKS-managed ENIs. But for the EKS nodes to spin up, they would require access to a few other AWS services. This is a common mistake that everyone makes when provisioning a fully private VPC for EKS.</p><p>EKS nodes require access to the following AWS service in general, to be able to function within EKS</p><ul><li>Amazon ECR (pull-down container images)</li><li>Amazon EC2</li><li>Amazon S3</li><li>Cloudwatch logs</li><li>Amazon STS (for IRSA)</li></ul><p>Without the above VPC endpoints, you could never create a worker node for EKS, because it requires access to these above AWS services to function as an EKS worker node. (Please note that in certain cases, you might not need all of the above. But it’s always good to have the above).</p><p>For example, ECR access is essential and that is the only place where docker images can be pulled down from a fully private VPC setup. Without this, your nodes would not be able to install the initial cluster addons and function as an EKS worker node.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7VRMO_bOCMUfSGkKYzRFAA.png" /></figure><p>That’s it. Hope this article helps someone to understand and troubleshoot any EKS-related issues and provision a much better architecture. I will do another write-up on how to provision these types of clusters using Terraform. Stay tuned.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=635e067c8c2a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Troubleshooting DNS issues with dig]]></title>
            <link>https://keetmalin.medium.com/troubleshooting-dns-issues-with-dig-b90ae7885d1f?source=rss-5b64fe2de783------2</link>
            <guid isPermaLink="false">https://medium.com/p/b90ae7885d1f</guid>
            <category><![CDATA[networking]]></category>
            <category><![CDATA[dig]]></category>
            <category><![CDATA[nameserver]]></category>
            <category><![CDATA[dns]]></category>
            <category><![CDATA[linux]]></category>
            <dc:creator><![CDATA[Keet Malin Sugathadasa]]></dc:creator>
            <pubDate>Sun, 27 Aug 2023 18:41:11 GMT</pubDate>
            <atom:updated>2023-08-27T18:41:11.171Z</atom:updated>
            <content:encoded><![CDATA[<p>Domain Name Systems are responsible for translating human-readable hostnames into IP addresses of backend servers. It sounds straightforward, but in reality, this process is complicated underneath and there are many hops for a request until it reaches the destination.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tWtUINwwOqAvfwXgSG-zIQ.jpeg" /></figure><p>To continue with this article, you would need a good understanding of how DNS works, its caching, nameserver, and record types.</p><p>Let’s go through some of the basic commands first and dive deep into troubleshooting certain scenarios using these commands.</p><h3>Installing dig</h3><p>First of all, let’s see whether these tools are already installed on your Linux machine. You could also install these on your Windows machine, but it is beyond the scope of this article.</p><p>Let’s install dnsutils which comes with both dig , nslookup and some other dns tools.</p><pre>&gt; apt install dnsutils</pre><p>To verify the installation run the following command:</p><pre>&gt; dig -v<br>DiG 9.10.6</pre><h3>Basic commands for dig</h3><h4>How to use the dig command</h4><pre>dig &lt;@dns-server&gt; &lt;domain&gt; &lt;record-type&gt; &lt;class&gt; &lt;query-options&gt; &lt;default-options&gt;</pre><ul><li>&lt;@dns-server&gt; → Default is the local DNS server given in /etc/resolve.conf . But we can also specify a server with the @ sign</li><li>&lt;domain&gt; → Domain or host address to be queried</li><li>&lt;record-type&gt; → is one of (a,any,mx,ns,soa,hinfo,axfr,txt,…) [default:a]</li><li>&lt;class&gt; → is one of (in,hs,ch,…) [default: in]</li><li>&lt;query-options&gt; → query options start with - . Some common query options are</li></ul><pre>-b address[#port]   (bind to source address/port)<br>-p port             (specify port number)<br>-x dot-notation     (shortcut for reverse lookups)</pre><ul><li>&lt;display-options&gt; → is of the form +keyword[=value]. Some common display options are</li></ul><pre> +[no]additional     (Control display of additional section)<br> +[no]answer         (Control display of answer section)<br> +[no]authority      (Control display of authority section)<br> +[no]cl             (Control display of class in records)<br> +[no]comments       (Control display of comment lines)<br> +[no]expire         (Request time to expire)<br> +[no]fail           (Don&#39;t try next server on SERVFAIL)<br> +[no]question       (Control display of question section)<br> +[no]short          (Display nothing except short form of answer)<br> +[no]trace          (Trace delegation down from root [+dnssec])</pre><h4>Understanding the output of dig</h4><pre>➜  ~ dig google.com<br><br>; &lt;&lt;&gt;&gt; DiG 9.10.6 &lt;&lt;&gt;&gt; google.com<br>;; global options: +cmd<br>;; Got answer:<br>;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 39959<br>;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1<br><br>;; OPT PSEUDOSECTION:<br>; EDNS: version: 0, flags:; udp: 4096<br>;; QUESTION SECTION:<br>;google.com.   IN A<br><br>;; ANSWER SECTION:<br>google.com.  200 IN A 74.125.68.138<br>google.com.  200 IN A 74.125.68.102<br>google.com.  200 IN A 74.125.68.113<br>google.com.  200 IN A 74.125.68.139<br>google.com.  200 IN A 74.125.68.101<br>google.com.  200 IN A 74.125.68.100<br><br>;; Query time: 67 msec<br>;; SERVER: 172.20.10.1#53(172.20.10.1)<br>;; WHEN: Sun Aug 27 18:58:34 +0530 2023<br>;; MSG SIZE  rcvd: 135</pre><p>Let’s break down each section and try to understand the response.</p><ul><li>Lines starting with ; are comments. They do not include the actual DNS server details.</li><li>; &lt;&lt;&gt;&gt; DiG 9.10.6 &lt;&lt;&gt;&gt; google.com → shows the dig version and the query we entered</li><li>The HEADER section is the response it received from the DNS server. The flags refer to the answer section.</li></ul><pre>;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 39959<br>;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1</pre><ul><li>The OPT PSEUDOSECTION displays advanced data.</li></ul><p><strong>EDNS</strong> — Extension system for DNS, if used<br><strong>Flags</strong> — blank because no flags were specified<br><strong>UDP</strong> — UDP packet size</p><pre>;; OPT PSEUDOSECTION:<br>; EDNS: version: 0, flags:; udp: 4096</pre><ul><li>The QUESTION SECTION displays the query that was sent.</li></ul><p>google.com. → domain name queried</p><p>IN → type of query (IN: Internet)</p><p>A → DNS record type</p><pre>;; QUESTION SECTION:<br>;google.com.   IN A</pre><ul><li>The ANSWER SECTION is what gives the relevant records</li></ul><p>google.com. → domain name queried</p><p>200 → this is the TTL for each record in seconds</p><p>IN → type of query (IN: Internet)</p><p>A → DNS record type</p><p>74.125.68.138 → the IP address associated with the domain name</p><pre>;; ANSWER SECTION:<br>google.com.  200 IN A 74.125.68.138<br>google.com.  200 IN A 74.125.68.102<br>google.com.  200 IN A 74.125.68.113<br>google.com.  200 IN A 74.125.68.139<br>google.com.  200 IN A 74.125.68.101<br>google.com.  200 IN A 74.125.68.100</pre><ul><li>The STATISTICS section shows metadata about the query</li></ul><p><strong>Query time</strong> — The amount of time it took for a response<br><strong>SERVER</strong> — The IP address and port of the responding DNS server. You may notice a loopback address in this line — this refers to a local setting that translates DNS addresses. Usually found in /etc/resolv.conf<br><strong>WHEN</strong> — Timestamp when the command was run<br><strong>MSG SIZE rcvd </strong>— The size of the reply from the DNS server</p><pre>;; Query time: 67 msec<br>;; SERVER: 172.20.10.1#53(172.20.10.1)<br>;; WHEN: Sun Aug 27 18:58:34 +0530 2023<br>;; MSG SIZE  rcvd: 135</pre><h3>Troubleshooting with dig</h3><h4>Check if the server is reachable</h4><p>In the HEADER SECTION , the status shows the status of the DNS or backend server.</p><ul><li><strong>NOERROR</strong> — Everything’s cool. The zone is being served by the requested authority without issues.</li><li><strong>SERVFAIL</strong> — The name that was queried exists, but there’s no data or invalid data for that name at the requested authority.</li><li><strong>NXDOMAIN</strong> — The name in question does not exist, and therefore there is no authoritative DNS data to be served.</li><li><strong>REFUSED</strong> — Not only does the zone not exist at the requested authority, but their infrastructure is not in the business of serving things that don’t exist at all.</li></ul><p>Let’s try out a few examples</p><pre>➜  ~ dig google.com<br><br>....<br>;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 46275<br>....</pre><pre>➜  ~ dig keetmalin.com<br><br>....<br>;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NXDOMAIN, id: 58183<br>....</pre><h4>Specify a DNS resolver for a query</h4><p>This helps you understand how a DNS is resolved by a public DNS resolver. By default, dig uses the local configuration given in /etc/resolv.conf to decide which nameserver to query. These are known as public DNS resolvers. Some examples are</p><ul><li>cloudflare: 1.1.1.1</li><li>google: 8.8.8.8</li><li>quad9: 9.9.9.9</li></ul><pre>➜  ~ dig @1.1.1.1 google.com<br><br>; &lt;&lt;&gt;&gt; DiG 9.10.6 &lt;&lt;&gt;&gt; @1.1.1.1 google.com<br>; (1 server found)<br>;; global options: +cmd<br>;; Got answer:<br>;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 18888<br>;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1<br><br>;; OPT PSEUDOSECTION:<br>; EDNS: version: 0, flags:; udp: 1232<br>;; QUESTION SECTION:<br>;google.com.   IN A<br><br>;; ANSWER SECTION:<br>google.com.  114 IN A 142.251.37.46<br><br>;; Query time: 200 msec<br>;; SERVER: 1.1.1.1#53(1.1.1.1)<br>;; WHEN: Sun Aug 27 20:32:08 +0530 2023<br>;; MSG SIZE  rcvd: 55</pre><h4>Verify whether the DNS reaches the final server IP</h4><p>This is probably the most common use case of dig. Let’s see the final server IP address of <a href="http://keetmalin.medium.com">keetmalin.medium.com</a>. You can also do the same for your domains and see if it lists your relevant backend servers.</p><p>As you can see below, <a href="http://keetmalin.medium.com">keetmalin.medium.com</a> points to 2 backend servers 162.159.152.4 and 162.159.153.4.</p><pre>➜  ~ dig keetmalin.medium.com<br><br>; &lt;&lt;&gt;&gt; DiG 9.10.6 &lt;&lt;&gt;&gt; keetmalin.medium.com<br>;; global options: +cmd<br>;; Got answer:<br>;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 55713<br>;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1<br><br>;; OPT PSEUDOSECTION:<br>; EDNS: version: 0, flags:; udp: 4096<br>;; QUESTION SECTION:<br>;keetmalin.medium.com.  IN A<br><br>;; ANSWER SECTION:<br>keetmalin.medium.com. 377 IN A 162.159.153.4<br>keetmalin.medium.com. 377 IN A 162.159.152.4<br><br>;; Query time: 77 msec<br>;; SERVER: 172.20.10.1#53(172.20.10.1)<br>;; WHEN: Sun Aug 27 21:42:46 +0530 2023<br>;; MSG SIZE  rcvd: 81</pre><h4>Trace hostname A records and DNS name server records</h4><p>For the sake of this article, let’s do this with a single command. If I summarise the journey of a request in DNS, it goes through the following</p><ul><li><strong>DNS recursive resolver</strong>: This is the first stop in a DNS query. The recursive resolver acts as a middleman between a client and a DNS nameserver. It accepts a hostname from the client, checks with DNS servers and returns an IP address to the client.</li><li><strong>DNS root nameserver</strong>: The 13 DNS root nameservers are known to every recursive resolver, and they are the first stop in a recursive resolver’s quest for DNS records. A root server accepts a recursive resolver’s query which includes a domain name, and the root nameserver responds by directing the recursive resolver to a TLD nameserver, based on the extension of that domain (.com, .net, .org, etc.).</li><li><strong>TLD nameserver</strong>: A TLD nameserver maintains information for all the domain names that share a common domain extension, such as .com, .net, or whatever comes after the last dot in a URL. This nameserver responds by directing the resolver to an authoritative nameserver.</li><li><strong>Authoritative nameserver:</strong> The authoritative nameserver is usually the resolver’s last step in the journey for an IP address. This returns an A record, or a CNAME record pointing to an alias A record. However it is done, the resolver should get an IP address if it exists.</li></ul><p>Now let’s debug this with +trace , for the hostname: <a href="http://keetmalin.medium.com">keetmalin.medium.com</a>.</p><pre>➜  ~ dig keetmalin.medium.com +trace<br><br>; &lt;&lt;&gt;&gt; DiG 9.10.6 &lt;&lt;&gt;&gt; keetmalin.medium.com +trace<br>;; global options: +cmd<br>.   2745 IN NS a.root-servers.net.<br>.   2745 IN NS c.root-servers.net.<br>.   2745 IN NS j.root-servers.net.<br>.   2745 IN NS m.root-servers.net.<br>.   2745 IN NS g.root-servers.net.<br>.   2745 IN NS e.root-servers.net.<br>.   2745 IN NS d.root-servers.net.<br>.   2745 IN NS h.root-servers.net.<br>.   2745 IN NS l.root-servers.net.<br>.   2745 IN NS i.root-servers.net.<br>.   2745 IN NS b.root-servers.net.<br>.   2745 IN NS f.root-servers.net.<br>.   2745 IN NS k.root-servers.net.<br>;; Received 239 bytes from 172.20.10.1#53(172.20.10.1) in 42 ms<br><br>com.   172800 IN NS e.gtld-servers.net.<br>com.   172800 IN NS b.gtld-servers.net.<br>com.   172800 IN NS a.gtld-servers.net.<br>com.   172800 IN NS d.gtld-servers.net.<br>com.   172800 IN NS i.gtld-servers.net.<br>com.   172800 IN NS f.gtld-servers.net.<br>com.   172800 IN NS j.gtld-servers.net.<br>com.   172800 IN NS k.gtld-servers.net.<br>com.   172800 IN NS c.gtld-servers.net.<br>com.   172800 IN NS g.gtld-servers.net.<br>com.   172800 IN NS h.gtld-servers.net.<br>com.   172800 IN NS l.gtld-servers.net.<br>com.   172800 IN NS m.gtld-servers.net.<br>com.   86400 IN DS 30909 8 2 E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CF C41A5766<br>com.   86400 IN RRSIG DS 8 1 86400 20230909050000 20230827040000 11019 . Jg5GfQXXzS37hg6eMjYtwr4Sq7L7ojgJS2bsLN8/zxv8K3i+R4Lj8v9j nfUT5v2MImm1rel0y0NLfNMGuJhawllnCWrgYoGPbm6+lZugixjLkm/7 XWcR4/vXDwBDChPp7+wBH5K97yk+b8NraN4/F/J5Xf+PuJKdoKLH5pSn vxkt1pf25fqvfAhiofiJRvrZ6ayVJf0p5svBArSgDvB+YdbV/x6AA5PD d7tkNNR4QCGLAtzj5hRKe5UJUTsFmXuohlNEnSo+tPUboNAhWNfGEXez JgCkZjfFQOB4UlnYcwAit4ocWYj19o3Voa5iUXg4FCQnXoZ0ETdxMLQ9 X6pduA==<br>;; Received 1180 bytes from 192.203.230.10#53(e.root-servers.net) in 182 ms<br><br>medium.com.  172800 IN NS kip.ns.cloudflare.com.<br>medium.com.  172800 IN NS alina.ns.cloudflare.com.<br>CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - CK0Q2D6NI4I7EQH8NA30NS61O48UL8G5  NS SOA RRSIG DNSKEY NSEC3PARAM<br>CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20230903042431 20230827031431 4459 com. OROhP15YNzk5K7aj9L7UbApWHWLqii/AeMOR8oZdBfKYWk3+wmtoeD+R PjYwx4pOLvcrxaA6nV/kCkdNyU1cPv1434vMHkrjbarCx+Ri+tzpEByX jtTLGNzY3XAF3MoyU+nbYqM0PNRCgujYUV+PW3AR2J4UxQviKuyrCAaO 0cbrds7Qw8bxSwGHRz3F2NbkHc0D9gNjkNBFSCvo+8ttxw==<br>78A5DP9D1TN3VTQRVL40V82OTKSFKVFP.com. 86400 IN NSEC3 1 1 0 - 78A5S0E2MBIKEB8RG0QO9ULGBOQQFBCP  NS DS RRSIG<br>78A5DP9D1TN3VTQRVL40V82OTKSFKVFP.com. 86400 IN RRSIG NSEC3 8 2 86400 20230903045253 20230827034253 4459 com. SSMkDi+YTY/Wn+VrjbfCEMpxTFYflgCbMI/lxhf1UqqiN7kB5BWpf7uR +A0nrovj5mVwKF5b4BN/CzpEfey02Amt0xuXq+XCoecVUtWHNFxJ6Pre IK4v4TnPVKR7qNWw/t295rXiENoc1vRtpPYAGokXc6wFa41+fYZsmg+S 2inELesbkFAQYpXCpLUYk0Mn4J0FbC21gzooRCvlluJByA==<br>;; Received 914 bytes from 192.43.172.30#53(i.gtld-servers.net) in 170 ms<br><br>keetmalin.medium.com. 300 IN A 162.159.152.4<br>keetmalin.medium.com. 300 IN A 162.159.153.4<br>;; Received 81 bytes from 173.245.58.61#53(alina.ns.cloudflare.com) in 176 ms</pre><ul><li>Your <strong>DNS recursive resolver</strong> is 172.20.10.1 and it knows a set of root-servers. And it queries from e.root-servers.net .</li></ul><pre>.   2745 IN NS a.root-servers.net.<br>.   2745 IN NS c.root-servers.net.<br>.   2745 IN NS j.root-servers.net.<br>.   2745 IN NS m.root-servers.net.<br>.   2745 IN NS g.root-servers.net.<br>.   2745 IN NS e.root-servers.net.<br>.   2745 IN NS d.root-servers.net.<br>.   2745 IN NS h.root-servers.net.<br>.   2745 IN NS l.root-servers.net.<br>.   2745 IN NS i.root-servers.net.<br>.   2745 IN NS b.root-servers.net.<br>.   2745 IN NS f.root-servers.net.<br>.   2745 IN NS k.root-servers.net.<br>;; Received 239 bytes from 172.20.10.1#53(172.20.10.1) in 42 ms</pre><ul><li>Your <strong>DNS root nameserver</strong> is e.root-servers.net. Since our initial query hostname ended with .com , this root server will direct your resolver to the .com TLD nameservers. In this case it i.gtld-servers.net.</li></ul><pre>com.   172800 IN NS e.gtld-servers.net.<br>com.   172800 IN NS b.gtld-servers.net.<br>com.   172800 IN NS a.gtld-servers.net.<br>com.   172800 IN NS d.gtld-servers.net.<br>com.   172800 IN NS i.gtld-servers.net.<br>com.   172800 IN NS f.gtld-servers.net.<br>com.   172800 IN NS j.gtld-servers.net.<br>com.   172800 IN NS k.gtld-servers.net.<br>com.   172800 IN NS c.gtld-servers.net.<br>com.   172800 IN NS g.gtld-servers.net.<br>com.   172800 IN NS h.gtld-servers.net.<br>com.   172800 IN NS l.gtld-servers.net.<br>com.   172800 IN NS m.gtld-servers.net.<br>com.   86400 IN DS 30909 8 2 E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CF C41A5766<br>com.   86400 IN RRSIG DS 8 1 86400 20230909050000 20230827040000 11019 . Jg5GfQXXzS37hg6eMjYtwr4Sq7L7ojgJS2bsLN8/zxv8K3i+R4Lj8v9j nfUT5v2MImm1rel0y0NLfNMGuJhawllnCWrgYoGPbm6+lZugixjLkm/7 XWcR4/vXDwBDChPp7+wBH5K97yk+b8NraN4/F/J5Xf+PuJKdoKLH5pSn vxkt1pf25fqvfAhiofiJRvrZ6ayVJf0p5svBArSgDvB+YdbV/x6AA5PD d7tkNNR4QCGLAtzj5hRKe5UJUTsFmXuohlNEnSo+tPUboNAhWNfGEXez JgCkZjfFQOB4UlnYcwAit4ocWYj19o3Voa5iUXg4FCQnXoZ0ETdxMLQ9 X6pduA==<br>;; Received 1180 bytes from 192.203.230.10#53(e.root-servers.net) in 182 ms</pre><ul><li>Your <strong>TLD nameserver</strong> is i.gtld-servers.net . This server knows where the medium.com domain (which is the domain for the subdomain keetmalin.medium.com) resides. There are two locations and it picks alina.ns.cloudflare.com, which is an authoritative nameserver.</li></ul><pre>medium.com.  172800 IN NS kip.ns.cloudflare.com.<br>medium.com.  172800 IN NS alina.ns.cloudflare.com.<br>...<br>;; Received 914 bytes from 192.43.172.30#53(i.gtld-servers.net) in 170 ms</pre><ul><li>Your <strong>Authoritative nameserver</strong> is alina.ns.cloudflare.com . And this returns 2 A records, pointing to 2 server IPs. 162.159.152.4 and 162.159.153.4.</li></ul><p>If you run the dig command again, you will be able to see that the selected nameservers at each step are different. At each step, since there are multiple nameservers the DNS resolver decides which one to use.</p><h4>Reverse DNS lookup</h4><p>This is helpful when you have the IP address and would like to know the domains or subdomains associated with it. For this to work, the network admins of that website should have set up the PTR Records to allow reverse lookups.</p><p>As an example, let’s look at sb-in-f101.1e100.net and let’s find the IP of this hostname.</p><pre>➜  ~ dig sb-in-f101.1e100.net +nocomment +nostat<br>...<br>sb-in-f101.1e100.net. 2158 IN A 74.125.130.101</pre><p>If we take this IP and do a reverse lookup, it should have a PTR record pointing to the above hostname.</p><pre>➜  ~ dig -x 74.125.130.101 +nocomment +nostat<br>...<br>101.130.125.74.in-addr.arpa. 4502 IN PTR sb-in-f101.1e100.net.</pre><p>In the above example, the reverse lookup status was NOERROR since there was a PTR Record in place. But let’s look at the following IP of keetmalin.medium.com which does not have a PTR.</p><pre>➜  ~ dig keetmalin.medium.com +nocomment +nostat<br>...<br>keetmalin.medium.com. 377 IN A 162.159.152.4<br>keetmalin.medium.com. 377 IN A 162.159.153.4</pre><pre>➜  ~ dig -x 162.159.153.4<br>...<br>;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NXDOMAIN, id: 45635<br>...</pre><p>Here you can clearly see that the status is NXDOMAIN , and this is because the PTR record is not in place for this host.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b90ae7885d1f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Common DNS record types explained]]></title>
            <link>https://keetmalin.medium.com/common-dns-record-types-explained-fe0a83d20115?source=rss-5b64fe2de783------2</link>
            <guid isPermaLink="false">https://medium.com/p/fe0a83d20115</guid>
            <category><![CDATA[dns]]></category>
            <category><![CDATA[networking]]></category>
            <category><![CDATA[dns-records]]></category>
            <category><![CDATA[route-53]]></category>
            <dc:creator><![CDATA[Keet Malin Sugathadasa]]></dc:creator>
            <pubDate>Sat, 26 Aug 2023 12:19:54 GMT</pubDate>
            <atom:updated>2023-08-26T12:19:54.834Z</atom:updated>
            <content:encoded><![CDATA[<p>Domain Name Systems (or DNS) is a global system that is responsible for translating human-readable hostnames into their corresponding IP (Internet Protocol) addresses. DNS record types on the other hand are entries that explain how to resolve each hostname. The DNS resolver uses these DNS records to translate the hostname into relevant IP addresses.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Eo-48fRMP-_ii3nMe8X9zA.png" /></figure><p>In this article, let&#39;s take a look at the most common DNS record types and understand when they are used.</p><h3>What is a DNS record?</h3><p>DNS records (aka zone files) are simple instructions on how a hostname should be mapped to an IP address. These records live in DNS servers. Each record contains the following attributes (at least).</p><ul><li><strong>name</strong>: this will be the hostname (e.g: example.com)</li><li><strong>value</strong>: the IP address or another value based on the record type (e.g. 10.20.30.40)</li><li><strong>type</strong>: this is the record type (e.g. A record)</li><li><strong>TTL</strong>: Time To Live, indicates how often a DNS server will refresh that record (e.g. 60 seconds)</li></ul><h3>Common DNS Record Types</h3><p>Let’s take a quick look at the following most common DNS record types. This list also covers all the AWS Route53 record types.</p><ol><li>A records</li><li>AAAA records</li><li>CNAME records</li><li>NS records</li><li>MX records</li><li>TXT Records</li><li>CERT Records</li><li>PTR Records</li><li>SRV Records</li><li>CAA Records</li></ol><h4>A Records (Address Records)</h4><p>This is the most common and most important DNS record type. An A record shows the IPV4 address for a specific hostname or domain. These records reside at the authoritative DNS servers.</p><ul><li>Type: A</li><li>Domain Name: example.com</li><li>IP Address: 10.24.34.44</li><li>TTL: 1 hour</li></ul><h4>AAAA Records</h4><p>Same as A Records, but these records point to an IPV6 address for a specific hostname or domain.</p><ul><li>Type: AAAA</li><li>Domain Name: example.com</li><li>IP Address: 2001:db8:3333:4444:5555:6666:7777:8888</li><li>TTL: 1 hour</li></ul><h4>CNAME Records (Canonical NAME Records)</h4><p>These records point a domain name or hostname (aka alias) to another domain name or hostname (aka canonical name). They do <strong>not</strong> point to an IP address. It is important to note that you can add only one CNAME record per hostname.</p><p>This can prove convenient when running multiple services (like an FTP server and a web server, each running on different ports) from a single IP address.</p><p>CNAME records usually contain subdomains that point to a domain’s A or AAAA record. This prevents having to create an extra A or AAAA record for each subdomain.</p><p>It is not recommended to have CNAME records pointing to other CNAME records, as this creates unnecessary steps in the DNS lookup process.</p><ul><li>Type: CNAME</li><li>Domain Name (alias): ftp.example.com</li><li>Domain Name (canonical name): example.com</li><li>TTL: 1 hour</li></ul><h4>NS Records (Name Server Records)</h4><p>These records specify an Authoritative DNS server for a domain or a hostname. NS records help find the right DNS server for browsers to find the IP address for a domain name. When a browser is resolving a DNS record, usually it asks from multiple nameservers until it locates the correct Authoritative DNS server to fetch the IP address. Basically, it specifies that a DNS Zone, such as “example.com” is delegated to a specific Authoritative Name Server, and provides the address of the name server.</p><ul><li>Type: NS</li><li>Domain Name: example.com</li><li>Name Server: ns1.example.com</li><li>TTL: 1 hour</li></ul><h4>MX Records (Mail Exchange Records)</h4><p>These records show where emails for a domain should be routed. This allows traffic following the SMTP protocol, to be routed to their relevant mail servers (mail exchange).</p><p>Since mail servers also have backup mail servers, you are allowed to have multiple MX records for the same domain. For this the attribute Priority routes traffic to the primary and backup mail servers. For example, MX record with priority 10 will be the primary mail server, while the secondary server will only be used when the primary server is unavailable (or fails to send emails).</p><p>An MX record can only point to a name of an email server. This means that each referenced email server must also have a valid A record specifying its IP address</p><ul><li>Type: MX</li><li>Domain Name: example-mail.com</li><li>Mail Server: mail.example.com</li><li>Priority: 10</li><li>TTL: 1 hour</li></ul><h4>TXT Records (Text Records)</h4><p>Allows administrators to add limited human and machine-readable notes and can be used for things such as email validation, site, and ownership verification, framework policies, etc., and doesn’t require specific formatting.</p><p>The TXT record allows you to add and store text-based information about a domain name. There are all kinds of TXT records and some of them people can easily understand, and others are specifically for machines to read.</p><ul><li>Type: TXT</li><li>Domain Name: example.com</li><li>Value: verification=some-server.com (any text you want)</li><li>Priority: 10</li></ul><h4>CERT Records (Certificate Records)</h4><p>CERT records provide a space for storing certificates and related certificate revocation lists (CRL). The certificates can verify the authenticity of sending and receiving parties, while CRLs identify unauthorized parties.</p><ul><li>Type: CERT</li><li>Domain Name: example.com (domain name which is being certified)</li><li>Value: (Base 64 encoded string of the certificate)</li><li>Cert Type: PGP (Defines the type of certificate/CRL used. Eg: PKIX, SPKI, etc)</li><li>Algorithm: RSA (algorithm used to produce the certificate/CRL)</li></ul><h4>PTR Records (Pointer Records)</h4><p>This provides a domain name for reverse lookup. It’s the opposite of an A record as it provides the domain name linked to an IP address instead of the IP address for a domain.</p><ul><li>Type: PTR</li><li>IP Address: 10.22.11.40</li><li>Value: example.com</li><li>TTL: 1 hour</li></ul><h4>SRV Records (Service Records)</h4><p>With this, it is possible to store the IP address and port for specific services. It allows services such as instant messaging or VoIP to be directed to a separate host and port location.</p><ul><li>Type: SRV</li><li>Service: name of the service (eg: xmpp-server)</li><li>Value: example.com. (the canonical hostname of the machine providing the service, ending in a dot.)</li><li>Protocol: TCP or UDP</li><li>TTL: 1 hour</li><li>Port: 3333 The TCP or UDP port the service is running on</li><li>Priority: 23 (The priority of the target host, lower value means more preferred among same service records)</li><li>Weight: 12 (A relative weight for records with the same priority, higher value means more preferred.)</li></ul><h4>CAA Records (Certification Authority Authorization Records)</h4><p>This allows domain owners to state which certificate authorities can issue certificates for that domain. If no CAA record exists, then anyone can issue a certificate for the domain. CAA records can set policy for the entire domain, or for specific hostnames.</p><p>They are also inherited by subdomains, therefore a CAA record set on domain.com will also apply to any subdomain, such as subdomain.domain.com (unless overridden).</p><ul><li>Type: CAA</li><li>Domain: example.com (Domain name/Subdomain)</li><li>Flag: 0/182 (0 means non-critical, 182 means critical)</li><li>Type: issue/issuewild/iode</li><li>Value: caa.example.com (The value given from the preferred CA)</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fe0a83d20115" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Infrastructure Drift Detection with Crossplane]]></title>
            <link>https://faun.pub/infrastructure-drift-detection-with-crossplane-c365386f133?source=rss-5b64fe2de783------2</link>
            <guid isPermaLink="false">https://medium.com/p/c365386f133</guid>
            <category><![CDATA[terraform]]></category>
            <category><![CDATA[crossplane]]></category>
            <category><![CDATA[iac]]></category>
            <dc:creator><![CDATA[Keet Malin Sugathadasa]]></dc:creator>
            <pubDate>Thu, 14 Jul 2022 17:37:29 GMT</pubDate>
            <atom:updated>2022-07-21T11:20:04.648Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ibiVe5zWvFfl0Qg_RtJ6QQ.png" /></figure><p>Early in the day, infrastructure management tools were called configuration management tools. It is the same concept as IaC (Infrastructure as Code) but bundled differently. Some of the tools we used were CFEngine, Chef, Puppet, Terraform, and Pulumi. Ansible is another configuration management tool that was trending over Chef and Puppet.</p><p>All these tools managed to fulfill the infrastructure-related requirements we had back then. Each of these tools had its own engines, sometimes own languages, and own set of APIs. Even though it used to cater to our requirements back then, there are much bigger problems in IaC today. Some of the problems are:</p><ul><li><strong>Identifying drift detection </strong>(monitor and identify infrastructure changes, where these changes will only be fixed after the subsequent execution of the tool)</li><li><strong>Auto synchronization of state</strong> (when the current state changes, there is no automatic synchronization to bring the current state to the desired state)</li><li><strong>A common API </strong>(a common API for services, applications, and infrastructure to deal with the provisioning)</li><li><strong>State management </strong>(some state objects need to be managed safely and securely giving the burden on the infrastructure engineers)</li></ul><p>There are ways to tackle some of these problems and some are inherent problems that we need to live with. But today, the needs are different.</p><p>If you have a look at services deployed in Kubernetes, you will see that they are managed by configs (manifests), and maintained by the platform (Kubernetes) itself. If the service drifts away from its desired state, Kubernetes will bring it back to its desired state. If a pod gets killed accidentally, it will be restarted.</p><p>But, what if this approach could also be used to maintain infrastructure in your desired platform? Whenever an infrastructure component drifts in configuration, it will be automatically brought back to its desired state.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Y4L6GS-Ul1bMI0PhQhiowg.png" /><figcaption><a href="https://crossplane.io/">https://crossplane.io/</a></figcaption></figure><p>This is where Crossplane comes into place. This is the next generation of Infrastructure as Code, which manages auto synchronization, drift detection, and all through the Kubernetes API, just like how we manage our services in Kubernetes.</p><p>Imagine someone deleting a Virtual Machine or manually changing something in a cluster. Terraform will not detect this nor fix the drift. Today the need for GitOps is different. It’s not just to store definitions in Git and manage infrastructure, but to detect drift and have automatic synchronization. Even Pulumi doesn’t have this. Although this is not directly supported, there are ways to tackle this problem in other ways.</p><p>This article will talk to you about how we can use Crossplane to manage your infrastructure with automatic drift detection and synchronization. In the end, let’s have a look at some examples to deploy a simple cloud resource via Crossplane.</p><h3>What is Drift Detection</h3><p>Drift detection enables you to detect whether a stack’s actual configuration differs, or has drifted, from its expected configuration. A drift in service is detected, when certain attributes of a component are different from the desired (expected) state or if the component is deleted.</p><p>When it comes to drifting off service or infrastructure, we use the term synchronization to discuss that problem. When the drifting happens, we call it unsynchronized. When the drifting is fixed, it becomes synchronized. Mostly, the synchronization of IaC is done manually. But Crossplane gives you the inherent capability of detecting and handling drift automatically.</p><h3>What is Crossplane</h3><p>Crossplane is an open source, CNCF project built on the foundation of Kubernetes to orchestrate anything. Encapsulate policies, permissions, and other guardrails behind a custom API line to enable your customers to self-service without needing to become an infrastructure expert.</p><p><a href="https://crossplane.io/">Crossplane</a></p><h3>Why Crossplane over Terraform</h3><p>Crossplane is often compared with Terraform, as both of them serve the same purpose, but with different capabilities. Some of the common features are</p><ul><li>Manage infrastructure in a declarative language configuration</li><li>Support all major cloud platforms via provider plugins</li><li>Open Source tools</li></ul><p>Terraform is a command line tool (CLI) that provides an interface to a control plane. Crossplane on the other hand is a control plane and uses Kubernetes as the API. Let’s talk about some key problems faced by Terraform which are addressed in Crossplane</p><ul><li><strong>State lock and wait time for other collaborators (Strong consistency)</strong></li></ul><p>Terraform is a great way to manage infrastructure with declarative configurations and version controlling for a small team of engineers. But this can fall apart when more engineers want to collaborate and maintain the infrastructure. In Terraform, a lock must be held on the state file while the configuration is being applied, and applying a Terraform configuration is a blocking process that can take minutes to complete. During this time, no other engineer can apply changes to the configuration.</p><ul><li><strong>Parallel updates are not allowed to different components (monolithic state)</strong></li></ul><p>Terraform uses a monolithic state file and this file gets locked for every piece of modification made to the configuration. If engineers need to update separate resources at the same time, they would have to wait for each of them to run, one after the other. Terraform provides an option for scoped configurations, but it is a bit complicated.</p><ul><li><strong>Calculate a graph of dependencies and differences to make a change</strong></li></ul><p>With each planning, a graph of dependencies is calculated to figure out the sequence of executions. The same happens for the destroy operation as well. When you have an entire production environment in Terraform, it will contain a complex dependency graph and diff calculations. Crossplane on the other hand uses the Crossplane Resource Model (XRM) and promotes loose coupling and eventual consistency. In Crossplane every piece of infrastructure is an API endpoint that supports create, read, update, and delete operations. So you can easily operate on a single database, even if you manage your entire production environment with Crossplane.</p><ul><li><strong>Developers need to learn HCL in order to provision resources</strong></li></ul><p>When it comes to collaboration and self-service, each user needs to understand and learn the Hashicorp Configuration Language (HCL). Therefore, what happens in organizations is that Terraform is owned and managed by an infrastructure/platform team which enables development teams to use the resources they provide.</p><ul><li><strong>Cannot easily grant specific access controls to teams</strong></li></ul><p>Access control remains down at the cloud provider API level and not each resource level. (eg: Delete access to RDS and not database x). For example, if the infrastructure team invites the application teams to manage their own databases, they would need group permissions like RDS read access. The Crossplane equivalent of a Terraform module is a Composite Resource — an XR. Each XR is exposed as an API endpoint. In each API, we can enforce Role Based Access Control (RBAC) at the API level. RBAC access can be given to each team’s database: read only for team&#39;s database A, rather than having to manage access to various underlying cloud concepts like RDS instances or subnet groups. Because Crossplane builds on the battle-hardened Kubernetes RBAC system, a platform team can easily support many teams of application developers within a single control plane.</p><ul><li><strong>Attempts to reconcile your desired state on-demand only (configuration drift)</strong></li></ul><p>Terraform is a command line tool, not a control plane. Because it is a short-lived, one-shot process it will only attempt to reconcile your desired configuration with actual infrastructure when it is invoked. Whether run from a CI/CD pipeline or a laptop Terraform is typically invoked only when an engineer expects that infrastructure needs updating. Crossplane, on the other hand, is built as a series of long-lived, always-on control loops. It constantly observes and corrects an organization’s infrastructure to match its desired configuration whether changes are expected or not. When Crossplane has been asked to manage a piece of infrastructure any change made outside it will automatically and persistently be reverted.</p><ul><li><strong>Additional overhead in setting up GitOps</strong></li></ul><p>Terraform does not have its own API and Terraform works differently from how services are deployed in an organization. Therefore, it needs a specific setup and maintenance of its own. In this process, with version controlling, we would like for our CI/CD pipelines to execute Terraform as part of its pipeline. This is an improvement relative to a team running Terraform from their laptops.</p><ul><li><strong>All or nothing provisioning of resources for each apply</strong></li></ul><p>The process of applying in Terraform is an “all or nothing” process. If you decide to apply something in Terraform, you need to update all components: cache, state file, and the configuration of infrastructure. This means that if anyone in your organization circumvents Terraform, the next person to trigger a Terraform run will be faced with a surprising plan as it attempts to undo the change. During an incident, if you decide to update the infrastructure without letting Terraform know, that’s gonna open up a can of worms that you would have to deal with later. Hence, configuration around Terraform can be risky.</p><ul><li><strong>Terraform has no API. Has to be invoked via command line tools</strong></li></ul><p>Integrating Terraform with CI/CD or other scripts becomes challenging as it does not provide an API. Terraform is a command line tool, and each of these scripts needs to execute a command in order to run Terraform. Crossplane on the other hand can be contacted via an API. Whether the team decides to write a Python script or a separate tool, crossplane can be invoked by a simple API call. This API is not a typical REST API. Building on the Kubernetes API means that teams can orchestrate all of their infrastructure — cloud and otherwise — using tools like kubectl. Crossplane can even expose the details an application needs to connect to infrastructure as a Kubernetes secret to ease integration. It can be paired with projects like ArgoCD, Gatekeeper, or Velero to enable GitOps, advanced policy, and backups.</p><h3>Let’s Try it Out</h3><p>Given below is a working example for you to try out Crossplane and see how it works.</p><h4>Step 1: Get access to a Kubernetes cluster</h4><p>As the first step, you need a Kubernetes cluster. This could be a cloud cluster like AKS or EKS, but you can also do this for free by spinning up a Kubernetes cluster locally via <a href="https://minikube.sigs.k8s.io/docs/">minikube</a>.</p><h4>Step 2: Install Helm in your cluster</h4><p>Follow this guide and install Helm.</p><p><a href="https://helm.sh/docs/intro/install/">Installing Helm | Helm</a></p><h4>Step 3: Install Crossplane in your cluster</h4><p>Execute the following commands if you are using Helm 3. Else find the right commands from this <a href="https://crossplane.io/docs/v1.8/getting-started/install-configure.html#install-crossplane">guide</a>.</p><pre>kubectl create namespace crossplane-system<br><br>helm repo add crossplane-stable https://charts.crossplane.io/stable<br>helm repo update<br><br>helm install crossplane --namespace crossplane-system crossplane-stable/crossplane</pre><p>Check the status of Crossplane by</p><pre>helm list -n crossplane-system<br><br>kubectl get all -n crossplane-system</pre><h4>Step 4: Install the Crossplane CLI on your local machine</h4><p>Run the following command</p><pre>curl -sL https://raw.githubusercontent.com/crossplane/crossplane/master/install.sh | sh</pre><p>Run the following command to make it available in your CLI.</p><pre>sudo mv kubectl-crossplane /usr/local/bin</pre><h4>Step 5: Install the relevant provider</h4><p>In this example, we will be using AWS as our cloud provider. Run the following command.</p><pre>kubectl crossplane install provider crossplane/provider-aws:v0.29.0</pre><p>Check whether the installation is healthy.</p><pre>kubectl get providers</pre><h4>Step 6: Creating a provider config to grant access to the provider</h4><p>Here, we will grant access to AWS. For crossplane to talk to AWS, we need to give it the credentials. We do that through the provider config.</p><p>Run aws configure and give the AWS access key and secret in your default profile. Next, run the following command.</p><pre>AWS_PROFILE=default &amp;&amp; echo -e &quot;[default]\naws_access_key_id = $<strong>(</strong>aws configure get aws_access_key_id --profile $AWS_PROFILE<strong>)</strong>\naws_secret_access_key <strong>=</strong> $(aws configure get aws_secret_access_key --profile $AWS_PROFILE)&quot; &gt; creds.conf</pre><p>Next, create a secret in Kubernetes and store the credentials.</p><pre>kubectl create secret generic aws-creds -n crossplane-system --from-file=creds=./creds.conf</pre><p>Next, let’s apply the following manifest into Kubernetes. This will create a provider config.</p><pre>apiVersion: aws.crossplane.io/v1beta1<br>kind: ProviderConfig<br>metadata:<br>  name: default<br>spec:<br>  credentials:<br>    source: Secret<br>    secretRef:<br>      namespace: crossplane-system<br>      name: aws-creds<br>      key: creds</pre><p>To apply the above manifest to Kubernetes, use the following command.</p><pre>kubectl apply -f <a href="https://raw.githubusercontent.com/crossplane/crossplane/release-1.8/docs/snippets/configure/aws/providerconfig.yaml">https://raw.githubusercontent.com/crossplane/crossplane/release-1.8/docs/snippets/configure/aws/providerconfig.yaml</a></pre><h4>Step 7: Create an AWS SQS resource</h4><p>Now we are almost there. Apply the following manifest to create an SQS queue in AWS. Make sure your credentials have enough access to create the AWS resource. If you want, get yourself familiarized with the <a href="https://doc.crds.dev/github.com/crossplane/provider-aws/sqs.aws.crossplane.io/Queue/v1beta1@v0.29.0">API doc for SQS</a>.</p><pre>apiVersion: sqs.aws.crossplane.io/v1beta1<br>kind: Queue<br>metadata:<br>    name: my-sqs2<br>    namespace: default<br>spec:<br>    forProvider:<br>        region: us-east-1</pre><p>Now, go to the AWS console, and see whether this resource is created.</p><h4>Step 8: Check for your resources via kubectl</h4><p>Run the following command.</p><pre>kubectl get queue</pre><p>That’s it. We are done.</p><h4>Step 9: Creating other resources</h4><p>Check out the following documentation of your provider to understand how to create other resources in AWS. Simply follow the same steps as above. Create your manifest for the resource and apply it. Always make sure to grant the necessary permissions to your credentials.</p><p><a href="https://doc.crds.dev/github.com/crossplane/provider-aws">crossplane/provider-aws</a></p><h3>References</h3><ol><li><a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-stack-drift.html">https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-stack-drift.html</a></li><li><a href="https://blog.crossplane.io/crossplane-vs-terraform/">https://blog.crossplane.io/crossplane-vs-terraform/</a></li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*mc4bJFK7p9FzfKVu.png" /></figure><h4>If this post was helpful, please click the clap 👏 button below a few times to show your support for the author 👇</h4><h4>🚀Developers: Learn and grow by keeping up with what matters, <a href="https://faun.to/8zxxd">JOIN FAUN.</a></h4><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c365386f133" width="1" height="1" alt=""><hr><p><a href="https://faun.pub/infrastructure-drift-detection-with-crossplane-c365386f133">Infrastructure Drift Detection with Crossplane</a> was originally published in <a href="https://faun.pub">FAUN.dev() 🐾</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[All you need to know about Terraform]]></title>
            <link>https://faun.pub/all-you-need-to-know-about-terraform-b4ac21d76562?source=rss-5b64fe2de783------2</link>
            <guid isPermaLink="false">https://medium.com/p/b4ac21d76562</guid>
            <category><![CDATA[terraform]]></category>
            <category><![CDATA[hashicorp]]></category>
            <category><![CDATA[iac]]></category>
            <dc:creator><![CDATA[Keet Malin Sugathadasa]]></dc:creator>
            <pubDate>Sun, 10 Jul 2022 06:18:45 GMT</pubDate>
            <atom:updated>2022-07-15T11:43:05.053Z</atom:updated>
            <content:encoded><![CDATA[<p>Terraform is an infrastructure as code (IaC) tool that lets you define both cloud and on-prem resources in human-readable configuration files that you can version, reuse, and share. It is a free and open-source tool that installs as a single binary to create, manage and destroy resources in a matter of minutes.</p><p>You can then use a consistent workflow to provision and manage all of your infrastructure throughout its lifecycle. Terraform can manage low-level components like compute, storage, and networking resources, as well as high-level components like DNS entries and SaaS features.</p><p>This article describes the concepts and basics of Terraform and how to use it. This will also help you quickly ramp up on Terraform, covering all fundamentals even required for tech interviews.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XrXy7ya8mOAqyQhSPjLsCw.png" /><figcaption><a href="https://www.terraform.io/intro">https://www.terraform.io/intro</a></figcaption></figure><h3>How does Terraform work</h3><p>Terraform creates and manages resources on cloud platforms and other services through its application programming interfaces (APIs). Terraform has the ability to deploy across multiple platforms.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fKDkxpJfdv8sTqChvmrhNg.png" /></figure><p>Terraform connects with other platforms through providers (terraform plugins), which are programmed to interact with the provider APIs.</p><p>Terraform allows you to provision resources ranging from</p><ul><li>cloud infrasture</li><li>networking tools</li><li>monitoring tools</li><li>databases</li><li>version control systems</li><li>and much more</li></ul><p>Terraform uses its own language called HCL (Hashicorp Configuration Language). This is a declarative language and every configuration file (written in HCL) requires the .tf file extension. These configuration files contain code describing the desired infrastructure for our requirements. This is also called the desired state for our infrastructure. What Terraform does is, it brings the current state of the infrastructure to the desired state, as defined in the configuration files.</p><h3>Terminology</h3><ul><li><strong>configuration files</strong>: these are files written in HCL with the extension .tf . These files describe the desired state of the infrastructure</li><li><strong>desired state (target state)</strong>: how our final infrastructure setup should look like</li><li><strong>target environment</strong> → the environment in which our resources that is being maintained by Terraform are running in (eg: AWS, Local, Docker…)</li><li><strong>resource</strong> → every object that Terraform manages is called a resource. This can be any database, cloud resource, or even a physical resource on-premise</li></ul><h3>3 Phases in Terraform</h3><ul><li><strong>init → </strong>initializes the project and identifies the providers required for the target environments</li><li><strong>plan → </strong>drafts a plan to get to the target state. This shows a report on the required changes</li><li><strong>apply →</strong> makes the necessary changes in the target environment to bring it to the desired state.</li></ul><p>The apply phase is what makes the actual change in the target environment. If our resources deviate from the desired state, the subsequent apply calls will bring them back to the desired state, by only updating the deviated resources.</p><p>For some reason, if the environment deviates from the desired state, a subsequent apply will bring it back to the desired state by only fixing the missing component.</p><h3><strong>Lifecycle of a Resource</strong></h3><p>This is about the lifecycle of a resource which is managed by Terraform. Resources have a strict lifecycle and can be thought of as basic state machines. A resource roughly follows the steps below</p><ul><li><strong>ValidateResource </strong>→ is called to do a high-level structural validation of a resource’s configuration.</li><li><strong>Diff</strong> → is called with the current state and the configuration. The resource provider inspects this and returns a diff, outlining all the changes that need to occur to the resource</li><li><strong>Apply</strong> → is called with the current state and the diff. Apply does not have access to the configuration. This is a safety mechanism that limits the possibility that a provider changes a diff on the fly.</li></ul><p>Once Terraform applies the changes to the target environment, it records the state of the infrastructure as it is seen in the real world. This is recorded in a file named terraform.tfstate . The state is a blueprint of the infrastructure deployed by Terraform. We will learn more about this in the sections below.</p><p>Terraform can also import other resources created either manually or by other IAC tools. And bring it under its control. So that it can manage those resources going forward.</p><h3>Terraform Cloud and Enterprise</h3><p>Terraform Cloud and Terraform Enterprise are different distributions of the same application. <a href="https://www.terraform.io/cloud">Terraform Cloud</a> is an application that helps teams use Terraform together. It manages Terraform runs in a consistent and reliable environment, and includes easy access to shared state and secret data, access controls for approving changes to infrastructure, a private registry for sharing Terraform modules, and detailed policy controls for governing the contents of Terraform configurations, and more.</p><p>Enterprises with advanced security and compliance needs can purchase <a href="https://www.terraform.io/enterprise">Terraform Enterprise</a>, our self-hosted distribution of Terraform Cloud. It offers enterprises a private instance that includes the advanced features available in Terraform Cloud.</p><p>Both of these provide the following benefits</p><ul><li>better collaboration</li><li>improved security</li><li>a centralized UI to manage deployments</li></ul><h3>Installing Terraform</h3><p>You can use the following link to download and install Terraform to your local machine.</p><p><a href="https://www.terraform.io/downloads?_ga=2.246991170.730719665.1657340579-717239105.1655212063">Downloads | Terraform by HashiCorp</a></p><h3>Basics of HCL</h3><pre>&lt;block&gt; &lt;parameters&gt; {</pre><pre>    key1 = value1 (these are arguments)</pre><pre>    key2 = value2</pre><pre>}</pre><ul><li>block → contains the infrastructure platform and the resource it wants to create. (eg: resource, variable, data etc)</li></ul><p>See the following example:</p><pre>resource &quot;local_file&quot; &quot;test&quot; {<br>   filename = &quot;/user/test.txt&quot;<br>   content = &quot;This is a test file&quot;<br>}</pre><ul><li>block name → resource</li><li>resource type → local_file (local = provider name which gets downloaded as a plugin from terraform init ; file = resource). Always the first part before the underscore (_) is the provider. The remaining part is the resource.</li><li>provider → local</li><li>resource → file (a component of the provider)</li><li>resource name → test</li><li>arguments → filename and content . Which are inside the block (curly braces {} )</li></ul><h3>Terraform workflow</h3><ol><li>write the configuration file</li><li>run terraform init → downloads the provider plugin</li><li>review the execution plan using the terraform plan command</li><li>then apply via terraform apply command</li></ol><p>During a terraform plan you will receive a report. This indicates which resources will be created, updated, or destroyed.</p><ul><li>plus (+) symbol in the plan indicates that the resource will be created.</li><li>plus and minus (-/+) symbol in the plan indicates that the resource will be destroyed and created.</li><li>minus (-) symbol in the plan indicates that the resource will be destroyed.</li></ul><h3>Updating Resources</h3><p>If we try to update a configuration file and then run a terraform apply, the resource will be deleted and created. This is because the infrastructure is immutable. This will be explained in a later section.</p><h3>Terraform Providers</h3><p>There are 3 tiers of providers</p><ul><li><strong>official providers </strong>— owned and maintained by HashiCorp. Includes the major cloud providers.</li><li><strong>verified provider </strong>— this is owned by a 3rd party technology company that has gone through a partner provider process with HashiCorp. (Heroku, digital ocean, etc)</li><li><strong>community provider</strong> — published and maintained by individual contributors in the HashiCorp community</li></ul><h4>The provider plugin name format</h4><p>There are two formats.</p><p>organizational namespace / type (name of the provider)</p><ul><li>eg: hashicorp/local → (this is the source address identifier used by Terraform to locate and download from the registry).</li></ul><p>hostname / organizational namespace / type (name of the provider)</p><ul><li>eg: registry.terraform.io/hashicorp/local</li></ul><h4>Provider plugin versions</h4><p>When we execute terraform init , these provider plugins get downloaded into the .terraform/plugins folder. With this command, we can see which plugin version has been downloaded.</p><p>We can lock down our configuration files to use a specific version of the provider plugins. New plugin versions may break the code sometimes.</p><p>For this, we need to add an additional code block called terraform. If we don’t specify this explicitly, Terraform downloads the latest version of the plugin.</p><ul><li>Specific Version</li></ul><pre>terraform {<br>   required_providers {<br>      local = {<br>         source = &quot;hashicorp/local&quot;<br>         version = &quot;1.4.0&quot;<br>      }<br>   }<br>}</pre><ul><li>Should not be a specific version. (This will use the latest version or previous version of this if this is the latest version)</li></ul><pre>terraform {<br>   required_providers {<br>      local = {<br>         source = &quot;hashicorp/local&quot;<br>         version = &quot;!= 1.4.0&quot;<br>      }<br>   }<br>}</pre><ul><li>A version before a specified version or a version after a specified version.( Can use &lt; or &gt;)</li></ul><pre>terraform {<br>   required_providers {<br>      local = {<br>         source = &quot;hashicorp/local&quot;<br>         version = &quot;&lt; 1.4.0&quot;<br>      }<br>   }<br>}</pre><ul><li>Stricter version constraints with a specific range</li></ul><pre>terraform {<br>   required_providers {<br>      local = {<br>         source = &quot;hashicorp/local&quot;<br>         version = &quot;&gt; 1.2.0, &lt; 2.0.0 , != 1.4.0&quot;<br>      }<br>   }<br>}</pre><ul><li>An incremental version update is allowed. For ~&gt;1.4 the maximum allowed version is 1.9 . For ~&gt;1.4.1 the maximum allowed version is 1.4.9</li></ul><pre>terraform {<br>   required_providers {<br>      local = {<br>         source = &quot;hashicorp/local&quot;<br>         version = &quot;~&gt; 1.4&quot;<br>      }<br>   }<br>}</pre><h4>Multiple Providers</h4><p>We can maintain multiple providers in the same configuration file. Whenever we add/remove a provider or make a version update, we need to run the terraform init command as this command downloads the necessary plugins for the providers.</p><h3>Configuration directory</h3><p>This is where we have the terraform files. You can have any number of .tf files in this directory. This can be considered as the working directory for running Terraform commands. Types of files:</p><ul><li>main.tf : main configuration file containing resource definition</li><li>variables.tf: variable declarations</li><li>outputs.tf: contains outputs from resources</li><li>provider.tf: contains provider definitions</li></ul><h3>Defining variables (input variables)</h3><p>Variables are defined in the variables.tf file. See the structure of this file:</p><pre>variable &lt;variable-name&gt; {</pre><pre>    default = &lt;default-value&gt;</pre><pre>}</pre><p>This variable can be referenced by var.&lt;variable-name&gt; .</p><p>A variable block has three parameters all of which are optional.</p><ul><li><strong>default</strong>: the default value, if a value is not set</li><li><strong>description</strong>: describing the purpose and use of the variable</li><li><strong>type</strong>: string, number, bool, any (default), list, map, set, object, tuple</li></ul><p>string, number, bool, any → are variable types</p><p>list, map, set, object, tuple → are data types</p><h4>list data type</h4><pre>default=[&quot;Mr&quot;,&quot;Mrs&quot;]</pre><p>for lists, we can put type constraints</p><pre>type=list(string)</pre><pre>type=list(number)</pre><h4>Map data type</h4><pre>default={<br>   &quot;key1&quot;=&quot;value1&quot;<br>}</pre><p>to access this,</p><pre>var.map[“key1”]</pre><p>for maps, we can put type constraints for the values. The keys will always be strings.</p><pre>type=map(string)</pre><pre>type=map(number)</pre><h4>Set data type</h4><p>This is similar to lists. Can’t have duplicate elements. Can have type constraints</p><pre>type=set(string)</pre><pre>type=set(number)</pre><h4>Object data type</h4><p>complex data structures with a mix of variables and data types.</p><pre>variable &quot;bella&quot; = {<br>  type=object({<br>         name=string<br>         food=list(string)<br>  })<br>}</pre><h4>Tuple data type</h4><p>tuples are similar to lists. but can have different variable types.</p><pre>type=tuple([string, number, bool])<br>default=[&quot;car&quot;, 7, true]</pre><h3>Injecting values to Input Variables</h3><p>if we don’t enter default values to the input variables, the values for the variables will be prompted during the terraform apply command. (interactive)</p><p>If not. we can pass command-line flags in the terraform apply command.</p><h4>Using -var flag</h4><p>terraform apply -var &quot;filename=name&quot; -var &quot;content=this is a file&quot;</p><h4>Using environment variables</h4><pre>export TF_VAR_filename=&quot;name&quot;<br>export TF_VAR_content=&quot;this is a file&quot;</pre><pre>terraform apply</pre><h4>Using variable definition files</h4><p>If we are dealing with a lot of variables, we can use terraform.tfvars variable definition files. The file name should end with .tfvars or .tfvars.json . Example file content:</p><pre>filename=&quot;name&quot;<br>content=&quot;this is a file&quot;</pre><p>The following file formats will be automatically loaded by Terraform</p><ul><li>terraform.tfvars</li><li>terraform.tfvars.json</li><li>*.auto.tfvars</li><li>*.auto.tfvars.json</li></ul><p>Other files need to be manually loaded via</p><p>terraform apply -var-file variables.tfvars</p><h4>Input variable option precedence</h4><p>If we use multiple ways to assign values to the same variable name, there is a precedence. Variable definition precedence</p><ol><li>-var or -var-file (highest precedence)</li><li>*.auto.tfvars or *.auto.tfvars.json (in alphabetical order)</li><li>terraform.tfvars</li><li>Environment variables (lowest precedence)</li></ol><h3>Reference Expressions (using the result of a resource in another resource)</h3><p>Use the output from one resource as the input for another. For each resource type, see what attributes are given as outputs. (mostly id’s). We can reference by</p><p>&lt;resource-type&gt;.&lt;resource-name&gt;.attribute</p><p>Eg:</p><pre>resource &quot;local_file&quot; &quot;test&quot; {<br>   filename = &quot;/user/test.txt&quot;<br>   content = &quot;This is a test file ${random_pet.mypet.id}&quot;<br>}</pre><p>This is a test file ${random_pet.mypet.id} → This is called a reference expression because it references the output of another resource named mypet . With this, there is an implicit dependency assigned as well. The resource test will not be created until the resource mypet is created. This is because the result mypet is required to create the content of the resource test .</p><h3>Resource Dependencies</h3><p>If the output of one resource is used in another, the order of execution is determined by Terraform itself. When resources are deleted, terraform deletes in the reverse order. This is called <strong>implicit dependency.</strong></p><p>But we can also specify the dependencies via <strong>explicit dependency. </strong>We should use the depends_on argument for this</p><pre>resource &quot;local_file&quot; &quot;test&quot; {<br>   filename = &quot;/user/test.txt&quot;<br>   content = &quot;This is a test file&quot;</pre><pre>   depends_on=[random_pet.mypet]<br>}</pre><h3>Terraform output variables</h3><p>To save the output in a variable name, we use the output block</p><pre>output &quot;&lt;variable_name&gt;&quot; {<br>   value=&quot;&lt;variable-value&gt;&quot;<br>   ...arguments<br>}</pre><p>Example:</p><pre>output pet-name {<br>   value=random_pet.my-pet.id<br>   description=&quot;some description&quot;<br>}</pre><p>When we run terraform apply, we can see that the output variable is printed on the screen. This is one advantage of using output variables.</p><p>To specifically print these output variables, we can also use terraform outputcommand. To print a specific value terraform output &lt;variable-name&gt;</p><p>The best use case for output variables is to quickly display output variables on the screen. Or can be given out to other scripts for testing or configuration management (eg: to Ansible or shell scripts)</p><h3>Terraform State</h3><p>This is a JSON file by default. terraform apply is the command that will update the state. terraform plan will only read from the state.</p><p>Terraform makes execution plans when there is a difference between the current state (state file) and the desired state in the (configuration files). When terraform creates a resource, it records its identity in the state. Each resource will have a unique ID.</p><p>The state file also tracks metadata details such as resource dependencies. This is useful when resources need to be deleted to identify which order. When destroying resources, the relevant resource configuration will be deleted from the configuration files. Hence, it is impossible to identify the dependency from the deleted code blocks. So, the state file can be used to get this information to determine the destroy order.</p><p>The terraform state file has the following name: terraform.tfstate .</p><p>Another advantage of the state is its performance. If this didn&#39;t exist, terraform would have to compare with the real-world infrastructure and the resources configuration files. Instead, the state is used as the record of truth.</p><p>Terraform stores a cache of attribute values for all resources in the state. We can specify terraform to use the state file alone when running commands and bypass having to refresh the state every time. Use the following command for this.</p><p>terraform plan -refresh=false</p><p>Another benefit is collaboration when working as a team. When we run this locally, the terraform.tfstate file is generated locally. For better collaboration with a team, it is highly recommended to store this in a remote location allowing the state to be shared. A few remote locations for state storage are:</p><ul><li>AWS S3</li><li>Google cloud storage</li><li>HashiCorp Consul</li><li>Terraform Cloud</li></ul><p>We can’t get rid of the state file. It is a mandatory file.</p><h4>Statefile has sensitive information</h4><p>This file contains sensitive information of resources. This includes IP address, hostname, and even file contents. Therefore it needs to be handled with care.</p><p>To make the Terraform configuration files shareable and versioned, it is recommended to store these files in a distributed version controlling system (VCS). Eg: Github, Gitlab, Bitbucket.</p><p>But since the state file is sensitive, it should not be saved in a git repository. Instead, save it in a remote backend storage like S3.</p><p>If you want to update the state file, always use terraform state commands instead of doing it manually.</p><h3>Mutable and Immutable infrastructure</h3><p>When the underlying infrastructure remains but a config or software can be updated: we call it Mutable infrastructure.</p><p>During this process, if two servers get updated and one fails, we call this a <strong>configuration drift</strong>. The 3rd one cannot be updated due to an underlying issue. This can make it difficult to plan and carry out subsequent updates</p><p>A solution would be to create a new server with the configuration and delete the old server. This is an immutable infrastructure. Immutability makes it easier to roll back and roll forward between versions. It is simply a matter of recreating. Terraform uses this approach. Terraform destroys and creates new resources. But if we want the other way around, we should use lifecycle rules in that resource block.</p><h3>Lifecycle Rules</h3><p>syntax of a resource block with a lifecycle rule is given in the following examples.</p><h4>create_before_destroy</h4><pre>resource &quot;local_file&quot; &quot;test&quot; {<br>   filename = &quot;/user/test.txt&quot;<br>   content = &quot;This is a test file&quot;</pre><pre>lifecycle {<br>      create_before_destroy = true<br>   }<br>}</pre><h4>prevent_destroy</h4><p>prevent_destroy: terraform will reject any request for this resource to be destroyed during changes made to the configuration with a subsequent apply. But terraform destroy command will still destroy these resources even if this lifecycle rule was set.</p><pre>resource &quot;local_file&quot; &quot;test&quot; {<br>   filename = &quot;/user/test.txt&quot;<br>   content = &quot;This is a test file&quot;</pre><pre>lifecycle {<br>      prevent_destroy = true<br>   }<br>}</pre><h4>ignore_changes</h4><p>ignore_changes rule will prevent from the resource being updated based on a set of attributes we specify (eg: tags).</p><p>For example, if we make this change manually in the cloud, and then run terraform apply, this will try to revert it back as per the configuration. But if we want to ignore it, we can use this command. So if someone changes the tags manually, those changes will be ignored in the subsequent apply commands.</p><pre>resource &quot;local_file&quot; &quot;test&quot; {<br>   filename = &quot;/user/test.txt&quot;<br>   content = &quot;This is a test file&quot;</pre><pre>lifecycle {<br>      ignore_changes = [tags]<br>   }<br>}</pre><p>or you can ignore changes in all attributes by</p><pre>resource &quot;local_file&quot; &quot;test&quot; {<br>   filename = &quot;/user/test.txt&quot;<br>   content = &quot;This is a test file&quot;</pre><pre>lifecycle {<br>      ignore_changes = all<br>   }<br>}</pre><h3>Data Sources</h3><p>This allows Terraform to read resources provisioned outside of its control. (For example, if a shell script creates a resource, or is defined by AWS). If the following file was created manually or by a separate resource provisioning tool, we can make it available as a local_file for Terraform to read.</p><pre>data &quot;local_file&quot; &quot;test&quot; {<br>   filename = &quot;/user/test.txt&quot;<br>}</pre><p>You can have a look at the data sources documentation of the relevant provider to learn more. To use the above data source:</p><pre>resource &quot;local_file&quot; &quot;dummy&quot; {<br>   filename = &quot;/user/test.txt&quot;<br>   content = data.local_file.test.content<br>}</pre><p>Resources are managed resources. Data sources are data resources that are read-only.</p><h3>Meta Arguments</h3><ul><li>depends_on (discussed above)</li><li>lifecycle (discussed above)</li><li>for_each</li><li>count</li></ul><h4>for_each</h4><p>Used when creating multiple instances of the same resource. for_each will only work with a map or set. This will not work with a list.</p><pre>variable &quot;filename&quot; {<br>  type=set(string)<br>  default=[&quot;a&quot;,&quot;b&quot;,&quot;c&quot;]<br>}</pre><pre>resource &quot;local_file&quot; &quot;dummy&quot; {<br>   filename = each.value<br>   for_each = var.file_name<br>}</pre><p>if we are using a list, we can convert the list to a set by using toset .</p><pre>variable &quot;filename&quot; {<br>  type=list(string)<br>  default=[&quot;a&quot;,&quot;b&quot;,&quot;c&quot;]<br>}</pre><pre>resource &quot;local_file&quot; &quot;dummy&quot; {<br>   filename = each.value<br>   for_each = toset(var.file_name)<br>}</pre><p>Now if we try to output the resources, they are stored as a map. This is only when we use for_each.</p><pre>variable &quot;filename&quot; {<br>  type=list(string)<br>  default=[&quot;a&quot;,&quot;b&quot;,&quot;c&quot;]<br>}</pre><pre>resource &quot;local_file&quot; &quot;dummy&quot; {<br>   filename = each.value<br>   for_each = toset(var.file_name)<br>}</pre><pre>output &quot;pets&quot; {<br>   value=local_file.dummy<br>}</pre><h4>count</h4><p>When we use count, the resources are created as list.</p><pre>resource &quot;local_file&quot; &quot;name&quot; {<br>   filename = &quot;/root/user-data&quot;<br>   sensitive_content = &quot;password: S3cr3tP@ssw0rd&quot;<br>   count = 3<br>}</pre><p>This will create the same resource 3 times. All attributes are the same. (eg: Useful when we need multiple instances of a virtual machine)</p><h3>More commands</h3><p>terraform validate : whether the syntax used is correct. Even provider configurations as per the documentation.</p><p>terraform fmt : format terraform files.</p><p>terraform show current state of all the resources. This will show the attributes of the created resources, from the terraform state.</p><p>terraform show -json : to print in a JSON format.</p><p>terraform providers to see a list of all providers used in the configuration directory.</p><p>terraform output to print all outputs or a specific variable.</p><p>terraform refresh to refresh the state with the real-world infrastructure. terraform refresh is automatically run by terraform plan and apply. This can be bypassed by -refresh=false</p><p>terraform graph visualizing the dependencies in the resource configurations. Output can be visualized using a tool named graphviz</p><p>Use terraform destroy to destroy all resources given in the state file.</p><h3>References</h3><ol><li><a href="https://www.terraform.io/">https://www.terraform.io/</a></li><li><a href="https://kodekloud.com/courses/lab-terraform-for-beginners/?utm_source=youtube&amp;utm_medium=labs&amp;utm_campaign=terraform">https://kodekloud.com/courses/lab-terraform-for-beginners/?utm_source=youtube&amp;utm_medium=labs&amp;utm_campaign=terraform</a></li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*qca7dVYdIlCHMYu9.png" /></figure><h4>If this post was helpful, please click the clap 👏 button below a few times to show your support for the author 👇</h4><h4>🚀Developers: Learn and grow by keeping up with what matters, <a href="https://faun.to/8zxxd">JOIN FAUN.</a></h4><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b4ac21d76562" width="1" height="1" alt=""><hr><p><a href="https://faun.pub/all-you-need-to-know-about-terraform-b4ac21d76562">All you need to know about Terraform</a> was originally published in <a href="https://faun.pub">FAUN.dev() 🐾</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introduction to Infrastructure as Code (IaC)]]></title>
            <link>https://keetmalin.medium.com/introduction-to-infrastructure-as-code-iac-e9b3bb4ef95c?source=rss-5b64fe2de783------2</link>
            <guid isPermaLink="false">https://medium.com/p/e9b3bb4ef95c</guid>
            <category><![CDATA[cloud]]></category>
            <category><![CDATA[iac]]></category>
            <category><![CDATA[infrastructure-as-code]]></category>
            <dc:creator><![CDATA[Keet Malin Sugathadasa]]></dc:creator>
            <pubDate>Sat, 09 Jul 2022 18:23:25 GMT</pubDate>
            <atom:updated>2022-07-09T18:23:25.145Z</atom:updated>
            <content:encoded><![CDATA[<p>Back in the day, the traditional software systems ran on top of on-premise infrastructure, which was managed by a separate team of engineers with their own hardware.</p><p>When a requirement was received, the architects plan the required resources and hand over the requirements to the infrastructure teams. This team will allocate the required hardware resources for this and sometimes purchases the required hardware, allowing the developers to deploy their code once the infrastructure platform is ready.</p><p>Within this entire process, the turnover time was significant, causing the deployments to slow down drastically. Some challenges in the approach were:</p><ul><li><strong>Slow deployment</strong> (certain deployments had specific hardware requirements which had to be provisioned by the infrastructure team. This provisioning and maintenance of infrastructure takes time, causing the deployment velocity to drop down)</li><li><strong>Expensive</strong> (Maintaining your own hardware came in with inherent costs of upgrading them, networking them, and even controlling your own server rooms. All these were simply to cater to a single organizational requirement)</li><li><strong>Limited automation </strong>(Except for a few processes, most works around this provisioning had to be done manually. As the system grows, you would require more and more operations engineers to maintain the hardware resources in your on-premise environment)</li><li><strong>Human error</strong> (Due to the higher number of manual processes, certain pipelines in this process were prone to human errors)</li><li><strong>Wasted resources</strong> (When the architects decide on the required hardware resources, they would make assumptions based on the maximum load capacity expected. With this, they had to allocate additional resources just to cope with the unexpected traffic from users)</li><li><strong>Inconsistencies</strong> (Since most servers are deployed separately, each of them needs software maintenance, system upgrades, and OS-level patching. This would have to be done manually to each of the servers, where there could occur certain inconsistencies when trying these on each server separately)</li></ul><h3>Cloud Service Providers</h3><p>With time, when cloud infrastructure and services came into play, people started moving all their services to the cloud. Cloud computing came to relieve some of the pains you’ve just read about. It frees you from having to build and maintain your data centers and the high cost associated with it. They really didn&#39;t have to worry about infrastructure, because the infrastructure itself was provided as a service to the users. This came with a lesser cost due to their hardware virtualizations and even came with a fancy user interface (aka cloud console) to provide the resources.</p><p>This eliminated most of the problems mentioned above related to on-premise infrastructure, moving the burden of infrastructure maintenance completely to the cloud service provider. With elastic and highly scalable environments, the worry was around adding the required configurations and deploying the right software to the cloud.</p><p>As software systems grew, still the level of manual work to request and provision these resources in the cloud was high. Human errors and inconsistencies were high as well since the provisioning had to be done manually.</p><h3>Infrastructure as Code</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*h5P02F7WkalfABzy_MKNOg.png" /><figcaption><a href="https://www.spec-india.com/blog/infrastructure-as-code-a-devops-way-to-manage-it-infrastructure">https://www.spec-india.com/blog/infrastructure-as-code-a-devops-way-to-manage-it-infrastructure</a></figcaption></figure><p>As a solution to this, engineers started using the APIs and SDKs provided by the cloud providers, to access and provision resources in the cloud in a programmatic manner. They started writing their own scripts to provision their hardware and update them. Many used shell scripts, python, and other scripting languages for this purpose. This gave birth to the process of writing Infrastructure as Code (IaC).</p><blockquote>Infrastructure as Code (IaC) is the managing and provisioning of infrastructure through code instead of through manual processes.</blockquote><p>When this became a common problem in the industry, several communities started building generalized tools for infrastructure provisioning, which became widely used by engineers all around the world and became a wide community around writing infrastructure as code in a human readable, simple, and high-level language.</p><h3>Version Controlling of your Infrastructure</h3><p>A major advantage of IaC is to provide support for version controlling your infrastructure resources. Technically, this happens to your code which describes the infrastructure. Indirectly it also applies version controlling to the infrastructure provisioned by that code.</p><p>Deploying your infrastructure as code also means that you can divide your infrastructure into modular components that can then be combined in different ways through automation.</p><h3>IaC Tools</h3><p>Some of the common tools available out there are:</p><ul><li>Ansible</li><li>Terraform</li><li>Puppet</li><li>Cloudformation</li><li>Packer</li><li>Saltstack</li><li>Vagrant</li><li>Docker</li><li>And many more…</li></ul><p>These are all addressing the same problem. But IAC can be broadly classified into three types</p><ul><li>Configuration management (eg: Saltstack, Ansible, Puppet)</li><li>Server templating (eg: Docker, Packer, Vagrant)</li><li>Provisioning tools (eg: Terraform, Cloud formation)</li></ul><h4>Configuration Management</h4><p>This was mainly around the required configurations around hardware resources. To install and manage software on existing infrastructure resources. (servers, DBs, networking devices, etc).</p><p>These tools introduce an easy way of writing required configuration as code, so that consistency can be maintained in terms of used configurations in the infrastructure resources.</p><p>This also gives the ability to control versions of configurations and software updates/upgrades allowing quick roll forward and backward of software versions when required with a few lines of code. In an organization with over 100 servers, if this had to be done manually, the engineers would have to go through each server to update the relevant software.</p><p>Another advantage of codifying this process was being idempotent. This means, that no matter how many times we execute these tools, they will only try to bring the infrastructure into the desired state and not repeat the changes over and over again.</p><h4>Server templating tools</h4><p>These tools are mainly responsible for maintaining custom images, virtual machines, containers, and templates required by infrastructure resources.</p><p>These images and virtual machines come with pre-installed software and dependencies which can be readily used based on the company standards and processes. These are specifically tailored for the company’s software requirements and allow engineers to worry about deploying software than installing the underlying dependencies of their servers.</p><p>This makes the infrastructure immutable as well. Once the VM or container is deployed, it will remain as it is, where changes will not be done manually to them. If changes are needed, then we need to make those changes via our server templating tools to update the image and redeploy.</p><h4>Provisioning tools</h4><p>This is about provisioning infrastructure resources with a simple declarative code. Based on our required cloud service provider, we simply have to declare which resources we need and these tools will simply provide them for us via the relevant cloud provider&#39;s APIs/SDKs.</p><p>Terraform is the infamous infrastructure provisioning tool available in the market today which is vendor-agnostic and provides provider plugins for over 100s of vendors out there.</p><p>On the other hand, Cloud Formation is also another well-used tool that is specifically built for AWS.</p><h3>References</h3><ol><li><a href="https://www.redhat.com/en/topics/automation/what-is-infrastructure-as-code-iac">https://www.redhat.com/en/topics/automation/what-is-infrastructure-as-code-iac</a></li><li><a href="https://kodekloud.com/courses/lab-terraform-for-beginners/?utm_source=youtube&amp;utm_medium=labs&amp;utm_campaign=terraform">https://kodekloud.com/courses/lab-terraform-for-beginners/?utm_source=youtube&amp;utm_medium=labs&amp;utm_campaign=terraform</a></li><li><a href="https://stackify.com/what-is-infrastructure-as-code-how-it-works-best-practices-tutorials/">https://stackify.com/what-is-infrastructure-as-code-how-it-works-best-practices-tutorials/</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e9b3bb4ef95c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Continuous Integration (CI) and Continous Delivery/Deployment (CD)]]></title>
            <link>https://keetmalin.medium.com/continuous-integration-ci-and-continous-delivery-deployment-cd-bb36b250a0c2?source=rss-5b64fe2de783------2</link>
            <guid isPermaLink="false">https://medium.com/p/bb36b250a0c2</guid>
            <category><![CDATA[continuous-deployment]]></category>
            <category><![CDATA[cicd]]></category>
            <category><![CDATA[continuous-integration]]></category>
            <category><![CDATA[continuous-delivery]]></category>
            <dc:creator><![CDATA[Keet Malin Sugathadasa]]></dc:creator>
            <pubDate>Sun, 03 Jul 2022 12:11:17 GMT</pubDate>
            <atom:updated>2022-07-03T12:11:17.406Z</atom:updated>
            <content:encoded><![CDATA[<p>When it comes to a software organization, the primary responsibility of the developers is to implement changes and the primary responsibility of the operations team is to deliver (deploy) the changes to production. This process of sending written code to production involves a set of steps, to ensure proper standards are maintained, the code complies with the security requirements, the changes are versioned efficiently, it is delivered to the suitable clusters and it becomes available to customers with minimal effort and time. Doing this manually every time a change is implemented, could be error-prone, tedious, and time-consuming (often referred to as the integration hell).</p><p>In simple terms, CI/CD would be the part right after development to how it gets delivered to a customer. As an accepted definition, CI/CD refers to the automation of these steps, and it is also often referred to as a pipeline. In this article, I would like to explain the basics of CI/CD, why we have it, and how it helps automate the operation side of the software.</p><p>Here, I have separated the CD as Delivery and Deployment for clarity. But in general, these are both interchangeably used to represent both terms.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*v57IL3HDCCgbowOLbzFVkw.png" /><figcaption>Ref: <a href="https://betterprogramming.pub/devops-in-flutter-734cb268d7db">https://betterprogramming.pub/devops-in-flutter-734cb268d7db</a></figcaption></figure><h3>What is CI/CD</h3><p>CI/CD is the process of introducing automation to frequently deliver application changes to production. The term CI stands for “Continuous Integration” and the term CD stands for both “Continuous Delivery” and/or “Continuous Deployment”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CxWsxm4BpRbV8YCDppKLdw.png" /><figcaption>Ref: <a href="https://www.redhat.com/en/topics/devops/what-is-ci-cd">https://www.redhat.com/en/topics/devops/what-is-ci-cd</a></figcaption></figure><p>CI/CD embodies a culture, operating principles, and a set of practices that application development teams use to deliver code changes more frequently and reliably. This allows organizations to ship software quickly and efficiently.</p><p>Let’s have a look at what CI and CD mean, as separate terms. I would also like to separately explain the two sides of CD (Delivery/Deployment). It’s important to understand each separation so that the right set of tools and processes can be picked to achieve this.</p><h4>Continuous Integration (CI)</h4><p>This is a set of practices that drive development teams to frequently implement small code changes and check them, into a version control repository. In many organizations, code changes are often committed to a version control system (eg: git). With these changes, it is important to collaborate with other changes and the other developers working with the same code base. Once the necessary changes are reviewed, they are merged into a common branch often referred to as the master/main branch. This branch would be the final code, that gets deployed to production.</p><p>Therefore, it is important to make sure that the changes being merged to the final branch, are working, reliable, and acceptable. These changes need to be verified, reviewed, and tested before merging into the final branch.</p><p>Now imagine having many changes, or even having huge changes, that take a longer time to review and test, whereas frequent changes would make this even harder. This hinders the process of delivering code changes to production. Continuous Integration (CI) tries to solve this problem by automating this entire process.</p><p>Of course, there is some work up front to set this up and add the relevant unit and integration testing. But it would make the life of developers and operations teams much easier and reduces the number of human errors that could occur. In general, the following areas are covered in CI</p><ul><li>Building the code</li><li>Testing the code</li><li>Merging the code (to a final branch)</li></ul><p>When a developer sets up a pull request (or a merge request), the build process kicks in. Once it is built, the testing will run on top of it. Once it is completed, it would be ready to merge.</p><p>See the following high-level setup of CI in your code base.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UBxWJRsayWUvS7VNXpvqTA.png" /></figure><p>Some common tools, available out there for you to achieve CI, are:</p><ul><li>Github actions</li><li>Gitlab pipelines</li><li>Jenkins</li><li>Travis CI</li><li>Circle CI</li><li>Etc</li></ul><h4>Continuous Delivery (CD)</h4><p>Once the builds are tested and verified in CI, those builds need to move to a repository, artifact store, or registry. A common example would be a Docker Image Registry. The goal of continuous delivery would be to get a build ready for deployment in a suitable format. This is often referred to as a production-ready build.</p><p>This also contains versioning, but it is often referred to as releases of the build.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EB8UJtDnG2MzBzS4MfIv7A.png" /></figure><p>Some common tools, available out there for you to achieve CD (Delivery), are:</p><ul><li>Github actions</li><li>Gitlab pipelines</li><li>Jenkins</li><li>Etc</li></ul><p>Next, let’s have a look at what Continuous Deployment means. Please note that Delivery and Deployment are often used interchangeably as CD to represent both.</p><h4>Continuous Deployment (CD)</h4><p>This is the final stage of a CI/CD pipeline. This stage is all about releasing a production-ready build to production. In other words, this is about making the changes available to the customer. In the end stage, the developers&#39; efforts will go live at this point.</p><p>In most cases, this happens in multiple stages. First, the release happens in a staging environment. With a manual trigger, it gets released to the production environment. When it comes to CD, there are many deployment models out there, that make the releases smooth and seamless. For example, we may want to deploy the changes to a set of Beta customers in production and then roll it out to everyone in production. These deployment models are a topic for another article.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yutX7QxZjmF4d8evTqBuPQ.png" /></figure><p>Some common CD tools are:</p><ul><li>Spinnaker</li><li>Go CD</li><li>Argo CD</li><li>Concourse</li><li>Screwdriver</li><li>Etc</li></ul><h3>CI/CD Fundamentals</h3><p>For your CI/CD process to be efficient, it is important to include the following fundamentals when building your CI/CD process for each application. There are no hard and fast rules as to what is the right way of implementing your CI/CD pipelines, but this would guide you towards building a more robust set of pipelines for a smoother delivery of applications.</p><ul><li><strong>A single source repository</strong>: having a code base for each build would serve the purpose of a repository. This will contain the build files, test scripts, and the actual feature code. Some teams maintain a monolithic repo, doing multiple builds from the same code base. All these drills down to how the system is designed.</li><li><strong>Frequent commits:</strong> Having focused and small commits in a VCS repo, would help in quicker deliveries and cleaner changes. Multiple commits to the repository results in fewer places for conflicts to hide. Make small, frequent iterations rather than major changes. By doing this, it’s possible to roll changes back easily if there’s a problem or conflict.</li><li><strong>Automated Builds</strong>: This is to support the CI process by having scripts, allowing automated builds when triggered.</li><li><strong>Testable code</strong>: This also includes test scripts along with having a code base that is testable. Unit tests and integration tests will help determine issues in the CI phase itself.</li><li><strong>Deployment controls</strong>: This refers to the way the code should be deployed in production. Some teams use blue/green deploys, canary deploys, and traffic vectoring to reduce risk during deploys. This can actually take many shapes as people interpret the idea differently to suit their needs</li></ul><h3>Benefits of CI/CD for your organization</h3><ul><li><strong>Satisfied users:</strong> Fewer bugs and errors make it into production, so your users and customers have a better experience. This leads to improved levels of customer satisfaction, confidence, and reputation.</li><li><strong>Accelerated time-to-value:</strong> When you can deploy anytime, you can bring products and new features to market faster. Your development costs are lower, and a faster turnaround frees your team for other work. Customers get results faster and gain a competitive edge.</li><li><strong>Less fire fighting:</strong> Testing code more often, in smaller batches, and earlier in the development cycle can seriously cut down on fire drills. This results in a smoother development cycle and less team stress. Results are more predictable, and it’s easier to find and fix bugs.</li><li><strong>Hit dates more reliably:</strong> Removing deployment bottlenecks and making deployments predictable can remove a lot of the uncertainty around hitting key dates. Breaking work into smaller, manageable bites means it’s easier to complete each stage on time and track progress. This approach gives plenty of time to monitor overall progress and determine completion dates more accurately.</li><li><strong>Free up developers’ time:</strong> With more of the deployment process automated, the team has time for more rewarding projects. It’s estimated that developers spend between 35% and 50% of their time testing, validating, and debugging code. By automating these processes, developers significantly improve their productivity.</li><li><strong>Less context switching:</strong> Getting real-time feedback on the code developers commit makes it easier to work on one thing at a time and minimize <a href="https://techbeacon.com/app-dev-testing/forget-monoliths-vs-microservices-cognitive-load-what-matters">cognitive load</a>. By working with small sections of code that are automatically tested, developers can debug code quickly while their minds are still fresh from programming. Finding bugs is easier because there’s less code to review.</li><li><strong>Reduce burnout:</strong> Research shows that continuous delivery measurably reduces deployment pain and team burnout. Developers experience less frustration and strain when working with CI/-CD processes. This directly leads to happier and healthier employees and less burnout.</li><li><strong>Recover faster:</strong> CI/CD makes it easier to fix issues and recover from incidents (MTTR). Continuous deployment practices mean frequent small software updates so when bugs appear, it’s easier to pin them down. Developers have the option of fixing bugs quickly or rolling back the change so that the customer can get back to work quickly.</li></ul><h3>References</h3><ol><li><a href="https://about.gitlab.com/topics/ci-cd/">https://about.gitlab.com/topics/ci-cd/</a></li><li><a href="https://www.synopsys.com/glossary/what-is-cicd.html">https://www.synopsys.com/glossary/what-is-cicd.html</a></li><li><a href="https://www.infoworld.com/article/3271126/what-is-cicd-continuous-integration-and-continuous-delivery-explained.html">https://www.infoworld.com/article/3271126/what-is-cicd-continuous-integration-and-continuous-delivery-explained.html</a></li><li><a href="https://www.redhat.com/en/topics/devops/what-is-ci-cd">https://www.redhat.com/en/topics/devops/what-is-ci-cd</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bb36b250a0c2" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What is OpenID Connect (OIDC)?]]></title>
            <link>https://keetmalin.medium.com/what-is-openid-connect-oidc-fd1b5715098f?source=rss-5b64fe2de783------2</link>
            <guid isPermaLink="false">https://medium.com/p/fd1b5715098f</guid>
            <category><![CDATA[oauth2]]></category>
            <category><![CDATA[oidc]]></category>
            <category><![CDATA[openid-connect]]></category>
            <category><![CDATA[openid]]></category>
            <dc:creator><![CDATA[Keet Malin Sugathadasa]]></dc:creator>
            <pubDate>Fri, 12 Jun 2020 17:47:05 GMT</pubDate>
            <atom:updated>2020-06-12T17:47:05.467Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yE8mNG8GDak9WLb59UmYpw.png" /><figcaption>OpenID Connect Cover Picture</figcaption></figure><p>OpenID Connect is a simple authentication protocol, built on top of the OAuth2 protocol as a separate identity layer. OAuth2 is an authorization protocol, which is being extended by the OIDC, to implement its authentication mechanism. OIDC allows the applications to authenticate and verify the end-users based on the authentication performed by an Authorization Server, which supports OIDC. This also allows the application to obtain basic profile information, about the end-user in an interoperable and REST-like manner. It uses straightforward REST/JSON message flows with a design goal of “making simple things simple and complicated things possible”.</p><blockquote><strong>(Identity, Authentication) + (OAuth 2.0) = (OpenID Connect)</strong></blockquote><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FKb56GzQ2pSk%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DKb56GzQ2pSk&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FKb56GzQ2pSk%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="640" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/31393ee30b8d86544316874322c9338f/href">https://medium.com/media/31393ee30b8d86544316874322c9338f/href</a></iframe><p>The OpenID Connect protocol is very flexible in which it gives the power to the client, to easily customize the authentication process according to their needs. OIDC gives the power to clients of all types, including Web-Based, mobile, and JavaScript clients, to request and receive information regarding the authenticated sessions and end-users. The main extensible features provided by the OIDC protocol are,</p><ol><li>Encryption of Identity Data</li><li>Discovery of OpenID Providers</li><li>Session Management</li></ol><p>This blog provides an abstract idea of what OpenID Connect is and, its important specifications.</p><h3>History of OpenID Connect</h3><p>OpenID Connect is the third generation of OpenID Technology. The original OpenID authentication protocol was developed by <a href="http://en.wikipedia.org/wiki/Brad_Fitzpatrick">Brad Fitzpatick</a> in May 2005. This was more like a visionary tool which never got much commercial adoption, but it got people to think of its possibilities and extensions. In the meantime, OpenID and OAuth were focused on two different aspects of an internet identity, whilst OpenID played the role of authentication, whereas the OAuth played the role of authorization. Since these two extensions were playing a huge role in each of its domains, the need to combine both these protocols arose.</p><p>As the second generation of OpenID, it came as an extension for OAuth, which was named as OpenID 2.0. This was better than the earlier version, and it provided much more security and worked seamlessly when implemented properly. Even though it had some design limitations, the implementation of OpenID 2.0 was fully thought through. The third generation of OpenID is the “OpenID Connect.” Unlike OpenID 2.0, this was built on top of OAuth 2.0 as a separate identity layer. The “OpenID Connect’s goal is to be much more developer-friendly and providing a wide range of use cases where it can be implemented. Currently, this has been very successful and deployments are happening on huge scales.</p><h3>OpenID Connect vs OpenID 2.0</h3><p>The functionalities available in the OIDC and OpenID 2.0 are pretty much the same whereas the OIDC provides much more API-friendly and usable implementations for native mobile applications. “OpenID Connect” defines optional capabilities for robust signing and encryption. To integrate OpenID 2.0 and OAuth 1.0, we require an extension, whereas in OIDC, OAuth 2.0 protocols, OAuth 2.0 functionalities are integrated within the protocols itself.</p><p>OpenID 2.0 used XML and custom message signature schemes that in practice, sometimes proved to be difficult for developers to implement. But in OAuth 2.0, the OIDC outsources the necessary encryption to the web’s built-in TLS (also called HTTPS or SSL) infrastructure, which is universally implemented on both client and server platforms. OIDC uses standard JSON Web Tokens (JWT) when signatures are required. Since JWT is more familiarized and easier to use, this makes OIDC dramatically easier for developers to implement, and practically has resulted in much better inter-operability.</p><h3>About the OpenID Foundation (OIDF)</h3><p>The OpenID Foundation was formed in June 2007, and it is an international non-profit organization of individuals and companies committed to enabling, promoting, and protecting OpenID technologies. The OIDF serves as a public trust organization representing the open community of developers, vendors, and users.</p><p>This foundation provides a much-needed infrastructure to the community and helps in promoting and expanding OpenID technologies. This entails managing intellectual property and brand marks as well as fostering viral growth and global participation in the proliferation of OpenID.</p><h4>What Companies &amp; People involved in the development of OIDC?</h4><p>Contributors include a diverse international representation of the industry, academia and independent technology leaders: AOL, Deutsche Telekom, Facebook, Google, Microsoft, Mitre Corporation, mixi, Nomura Research Institute, Orange, PayPal, Ping Identity, Salesforce, Yahoo! Japan, among other individuals and organizations.</p><h3>Mobile Network Operators and OpenID Connect</h3><p>In the modern digital era, we can see a considerable increase in the number of users using online services via mobile devices, and due to this reason, there is an increase in identity thefts all around the world. The <a href="http://www.gsma.com/">GSMA</a> created a valuable business proposal for Mobile Network Operators so that they can join hands with OIDC to implement and render many services to its customers. This business model states that Mobile Network Operators, short for MNOs, with their differentiated identity and authentication assets, have the ability to provide sufficient authentication to enable consumers, businesses, and governments to interact in a private, trusted, and secure environment and enable access to services.</p><p>MNOs increasingly are interested in identity services currently being used online (i.e. login, marketing, post-sales engagement, payments, etc.), to mitigate some of the pain points encountered in existing services, in order to meet the rapidly increasing market demand for mobile identity services.</p><h3>OpenID Specifications</h3><h4>OpenID Connect Flow</h4><p>OpenID Connect follows the following sequence of steps.</p><ul><li>RP — Relying Party</li><li>OP — OpenID Provider</li></ul><ol><li>The RP (Client) sends a request to the OpenID Provider (OP)</li><li>The OP authenticates the End-User and obtains authorization</li><li>The OP responds with an ID Token and usually an Access Token</li><li>The RP can send a request with the Access Token to the UserInfo Endpoint</li><li>The UserInfo Endpoint returns Claims about the End-User</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MsWfT_2DdZx3h_X7Rk8eOg.png" /><figcaption>OIDC flow</figcaption></figure><h4>The flow of events in OIDC</h4><ol><li>The client prepares an Authentication Request containing the desired request parameters.</li><li>The client sends the request to the Authorization Server.</li><li>Authorization Server authenticates the End-User.</li><li>Authorization Server obtains End-User Consent/Authorization.</li><li>Authorization Server sends the End-User back to the Client with code.</li><li>The client sends the code to the Token Endpoint to receive an Access Token and ID Token in the response.</li><li>The client validates the tokens and retrieves the End-User’s Subject Identifier.</li></ol><h4>Contacting the Authorization Endpoint</h4><p><strong>Mandatory Parameters:</strong></p><ul><li><strong>response_type</strong>: <em>Asking for the response required</em></li><li><strong>client_id</strong> : <em>OAuth 2.0 Client Identifier valid at the Authorization Server</em></li><li><strong>scope</strong>: <em>Specify what access privileges are being requested for Access Tokens</em></li><li><strong>redirect_uri</strong> : <em>Redirection URI to which the response will be sent</em></li><li><strong>state</strong> : <em>Value used to maintain state between the request and the callback</em></li></ul><p><strong>Optional Parameters:</strong></p><ul><li><strong>nonce</strong>: <em>Value used to associate a Client session with an ID Token, and to mitigate replay attacks</em></li><li><strong>display</strong>: <em>Value that specifies how the Authorization Server displays the authentication and consent user interface pages to the End-User</em></li><li><strong>prompt</strong>: <em>Values that specifies whether the Authorization Server prompts the End-User for reauthentication and consent</em></li><li><strong>max_age</strong>: <em>Maximum Authentication Age</em></li><li><strong>ui_locales</strong>: <em>End-User’s preferred languages and scripts for the user interface</em></li><li><strong>claims_locales</strong>: <em>End-User’s preferred languages and scripts for Claims being returned</em></li><li><strong>id_token_hint</strong>: <em>ID Token previously issued by the Authorization Server</em></li><li><strong>login_hint</strong>: <em>Hint to the Authorization Server about the login identifier</em></li><li><strong>acr_values</strong>: <em>Requested Authentication Context Class Reference values</em></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*K7FGHPr_W2N1ZmoheD4U7w.png" /><figcaption>Sample request to the authorization endpoint</figcaption></figure><h4>End-user Grants Authorization</h4><p>If the End-User grants the access request, the Authorization Server issues a code and delivers it to the Client by adding the following query parameters to the query component of the redirection URI.</p><p><strong>Mandatory Parameters</strong></p><ul><li><strong>code</strong>: <em>Authorization Code</em></li><li><strong>state</strong>: <em>OAuth 2.0 state value</em></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GGvCdAnyyyIS88cwwkIB1g.png" /><figcaption>Redirecting to the provided URL</figcaption></figure><h4>Contact the Token Endpoint:</h4><p>A Client makes a Token Request by presenting its Authorization Grant (in the form of an Authorization Code) to the Token Endpoint</p><p><strong>Mandatory Parameters:</strong></p><ul><li><strong>grant_type</strong> : <em>The type of “code” that is being submitted</em></li><li><strong>code</strong>: <em>Value you received from the Authentication request’s response</em></li><li><strong>redirect_uri</strong>: <em>Used as an extra level of security.</em></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*W8MYswUqXHsrVkRnXiox8A.png" /><figcaption>Sample request to the token endpoint</figcaption></figure><h4>Client Receives Token</h4><p><strong>Mandatory Parameters</strong></p><ul><li><strong>access_token</strong>: <em>Access Token for the UserInfo Endpoint</em></li><li><strong>token_type</strong>: <em>OAuth 2.0 Token Type value</em></li><li><strong>id_token</strong>: <em>ID Token</em></li></ul><p><strong>Optional Parameters</strong></p><ul><li><strong>expires_in</strong>: <em>Expiration time of the Access Token in seconds since the response was generated</em></li><li><strong>refresh_token</strong>: <em>Refresh Token</em></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7ooJSkYhzisps_FUK3OMcg.png" /><figcaption>Sample response to the client with a token</figcaption></figure><h4>Contact User Info Endpoint</h4><p>Clients send requests to the UserInfo Endpoint to obtain Claims about the End-User using an Access Token obtained through OpenID Connect Authentication. The request SHOULD use the HTTP GET method and the Access Token SHOULD be sent using the Authorization header field.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*I6GUYhR34uSwq0IowDvSCA.png" /><figcaption>Sending a GET request to the user-info endpoint</figcaption></figure><h3>References</h3><ol><li><a href="http://blog.facilelogin.com/2014/10/brief-history-of-openid-connect.html">http://blog.facilelogin.com/2014/10/brief-history-of-openid-connect.html</a></li><li><a href="http://en.wikipedia.org/wiki/OpenID">https://en.wikipedia.org/wiki/OpenID</a></li><li><a href="http://openid.net/">http://openid.net/</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fd1b5715098f" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>