<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lays Rodrigues</title>
    <description>The latest articles on DEV Community by Lays Rodrigues (@lays147).</description>
    <link>https://dev.to/lays147</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F957159%2F08244fc2-851f-4e16-a779-4208d643ce95.png</url>
      <title>DEV Community: Lays Rodrigues</title>
      <link>https://dev.to/lays147</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lays147"/>
    <language>en</language>
    <item>
      <title>How to create a temporary token for your GitHub Actions pipeline to deploy into AWS</title>
      <dc:creator>Lays Rodrigues</dc:creator>
      <pubDate>Fri, 30 Jun 2023 21:41:20 +0000</pubDate>
      <link>https://dev.to/aws-builders/how-to-create-a-temporary-token-for-your-github-actions-pipeline-to-deploy-into-aws-3h51</link>
      <guid>https://dev.to/aws-builders/how-to-create-a-temporary-token-for-your-github-actions-pipeline-to-deploy-into-aws-3h51</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;TLDR;&lt;br&gt;
    &lt;a href="https://gist.github.com/lays147/e252045c640a600bed75f483b5695f0d"&gt;Terraform Gist&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most often that I would like to admit, I learn to do a thing, and I do that thing in that way for the rest of my life. I don’t search for better ways to do it.&lt;/p&gt;

&lt;p&gt;Until yesterday, my way to deploy to AWS was to create IAM users and save the access and secret key as environment secrets and go in that way.&lt;/p&gt;

&lt;p&gt;The major issue for me with that process is that I don’t rotate the secrets as I should to protect my application and infrastructure. And this is clearly a security issue, even using IAM policies to get the minimum access configuration right.&lt;/p&gt;

&lt;p&gt;A couple of days ago, I was trying to deploy an app to AWS App Runner and using ECR as the source for the service. So, I needed a GitHub Actions pipeline to build and push the image to my private ECR, where App Runner could use it.&lt;/p&gt;

&lt;p&gt;And, while reading the docs (what was the last time that you have done this? properly hahaha) of the configure aws credentials action, I noticed that there are 5 ways to authenticate in AWS and the recommended one is using temporary tokens and OIDC:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ENNJ2VNa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ewuxbb0x743yw8m8b1ap.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ENNJ2VNa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ewuxbb0x743yw8m8b1ap.png" alt="OIDC Docs" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And I’ve got curious about how to use the recommended path for authentication.&lt;/p&gt;

&lt;p&gt;With OIDC and an Assume Role, I can generate temporary tokens that only live for one hour to make everything that I require in AWS.&lt;/p&gt;

&lt;p&gt;The next step was to read GitHub and AWS docs and translate that into Terraform code. The step by step using the AWS console are in the mentioned docs, so from here I’ll show to you how I translated those 10 steps into a couple terraform files.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub OIDC AWS auth with Terraform
&lt;/h2&gt;

&lt;p&gt;I’m going to set up a &lt;code&gt;locals&lt;/code&gt; with some variables to help us out with this process:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vgegyHjK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4oucc12cbdn6jnfmps4x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vgegyHjK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4oucc12cbdn6jnfmps4x.png" alt="Terraform Config" width="800" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the screenshot (I’ll put a gist with all this code in the end), I set up the github_oidc_domain with the URL from GitHub token provider as shown in the GitHub docs.&lt;/p&gt;

&lt;p&gt;The next step is to create and register GitHub as an Identity Provider on AWS with this code:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L7q9uNoK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yyoc7aze5550rp8hocwh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L7q9uNoK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yyoc7aze5550rp8hocwh.png" alt="Terraform Config" width="800" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To configure this resource, we need to fill 3 variables: the URL from the OIDC that we get from the locals, the client id that is the AWS Security Token Service and the thumbprint.&lt;/p&gt;

&lt;p&gt;The next step now is to create the IAM role and the Assume Role configuration, so this role can properly authenticate in AWS when used in our pipeline:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eeWgBlRu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0djsodp8227m7dw7focd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eeWgBlRu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0djsodp8227m7dw7focd.png" alt="Terraform Config" width="800" height="724"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I’ll update the locals to have the URL from my GitHub repository to authenticate:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZaiLPL7R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zhkho91cvtkvv5gvw5ml.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZaiLPL7R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zhkho91cvtkvv5gvw5ml.png" alt="Terraform Config" width="800" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As always, I’ll use my good old friend the data resource from terraform the aws_iam_policy_document:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lGwl42zr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1p7cn5leav59qmope0we.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lGwl42zr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1p7cn5leav59qmope0we.png" alt="Terraform Config" width="800" height="620"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now in there are plenty of things to uncouple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Principal to assume the role is the ARN of the OpenID connect that we created in the previous step;

&lt;ul&gt;
&lt;li&gt;The action is to AssumeRoleWithWebIdentity, that allows the STS service to issue the temporary tokens that we need;&lt;/li&gt;
&lt;li&gt;We have two sets of conditions:

&lt;ul&gt;
&lt;li&gt;The first ensures that the audience is the STS service&lt;/li&gt;
&lt;li&gt;The second ensures that the subject&lt;a href="https://dev.toor%20the%20user"&gt;sub&lt;/a&gt; is the GitHub repository that is trying to push the image to ECR.

&lt;ul&gt;
&lt;li&gt;This one is a little tricky to configure to specific GitHub tags, branches, etc. The configuration that I have made only allows the authentication from pipelines triggered by releases and tags. Check these docs to see how you can build your URL.&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;Presently, that it’s just a policy that needs to be created and attached somewhere, let’s create the IAM Role and attach that:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--snexayUo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/al4pkvxte7jxf7gn9zlt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--snexayUo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/al4pkvxte7jxf7gn9zlt.png" alt="Terraform Config" width="800" height="247"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we have our OIDC configuration, and the IAM Role configured. Now we should only configure our Action in our GitHub pipeline, right? Wrong. What we did so far only allows the authentication, but the IAM Role does not have permission to use the ECR service. Let’s fix that:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wSu5Bit---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/weu26tly0weo27dr5c1j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wSu5Bit---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/weu26tly0weo27dr5c1j.png" alt="Terraform Config" width="800" height="1099"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we attach this policy to our IAM Role:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LnWoZFV1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ay817sjfk12j0gloftwv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LnWoZFV1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ay817sjfk12j0gloftwv.png" alt="Terraform Config" width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can run our traditional terraform plan and apply and we are ready to go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring our pipeline
&lt;/h2&gt;

&lt;p&gt;For the GitHub Actions pipeline, we have the following configuration:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--spoUign7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fbnewfh0hzlzm2z84ppn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--spoUign7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fbnewfh0hzlzm2z84ppn.png" alt="Terraform Config" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that when configuring the configure-aws-credentials action that I don’t pass the Access and Secret key, I just pass the ARN of the IAM Role (as a secret in my pipeline) that was created and attached to the OIDC in our previous section. In the next step, it authenticates to ECR and then builds and pushes the image to ECR with double tagging.&lt;/p&gt;

&lt;p&gt;And now we are done. But a question remains:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How can I do that for multiple repositories? It isn’t possible to create an OIDC for each of them (because they are unique). And I can’t add many repositories in the IAM Role because that breaks the minimum responsibility for the Role. Apparently, the solution is to create an IAM Role for each repository and attach the OIDC as the principal. But does that create a security issue?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question already has an answer thanks to Ana Cunha &amp;lt;3 from AWS: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Regarding the security issue question, it seems that by scoping the IAM Role's audience to your GitHub account/repo/branch combination, you are guaranteeing that workflows in a different GitHub account/repo/branch won't be able to assume that role, even if they use the same OIDC identity provider.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_oidc.html#idp_oidc_Create_GitHub"&gt;https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_oidc.html#idp_oidc_Create_GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#defining-trust-conditions-on-cloud-roles-using-oidc-claims"&gt;https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#defining-trust-conditions-on-cloud-roles-using-oidc-claims&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Please let me know in the comments what you think.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/lays147/e252045c640a600bed75f483b5695f0d"&gt;Check the full code here :)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s all folks!&lt;/p&gt;

</description>
      <category>github</category>
      <category>githubactions</category>
      <category>aws</category>
      <category>iam</category>
    </item>
    <item>
      <title>AWS Networking 101</title>
      <dc:creator>Lays Rodrigues</dc:creator>
      <pubDate>Wed, 28 Dec 2022 16:04:44 +0000</pubDate>
      <link>https://dev.to/aws-builders/aws-networking-101-17j5</link>
      <guid>https://dev.to/aws-builders/aws-networking-101-17j5</guid>
      <description>&lt;p&gt;Last week I gave a training to my team about AWS Networking. And I realized that this training would be perfect for a post here. So, grab your coffee and let’s start it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Agenda
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Reviewing the Basics&lt;br&gt;
    IP's – How do we define a network&lt;br&gt;
    CIDR&lt;br&gt;
    Private and Public networks&lt;br&gt;
AWS&lt;br&gt;
    VPC&lt;br&gt;
    Subnets&lt;br&gt;
    Routing Table&lt;br&gt;
    Internet Gateway&lt;br&gt;
    Elastic IP&lt;br&gt;
    Nat Gateway&lt;br&gt;
    Security Groups and ACL’s&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Reviewing the basics&lt;br&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  IP’s - How do we define a network
&lt;/h3&gt;

&lt;p&gt;An IP (Internet Protocol) is an internet address that we attach to a resource. Quoting a definition by &lt;a href="https://nordvpn.com/what-is-my-ip/" rel="noopener noreferrer"&gt;NordVPN&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your internet service provider assigns a numeric label, called the Internet Protocol (IP) address, to identify your device among billions of others. In a way, an IP address functions as an online home address because devices use IPs to find and communicate with each other.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are two formal definitions for an IP: &lt;strong&gt;IPv4&lt;/strong&gt; and &lt;strong&gt;IPv6&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Internet_Protocol_version_4" rel="noopener noreferrer"&gt;IPv4&lt;/a&gt; is the most common format that you will find around, and you may already see it in the format of &lt;code&gt;192.168.0.1&lt;/code&gt; on your house network, for example. An IPv4 is defined by a set of 32 bits divided in 4 groups of 8 bits each.&lt;/p&gt;

&lt;p&gt;The second format is &lt;a href="https://en.wikipedia.org/wiki/IPv6" rel="noopener noreferrer"&gt;IPv6&lt;/a&gt;, that was created to complement (or substitute) the IPv4 because the latest was reaching its limit in the available addresses that could be used. It is defined by a set of 64 bits, divided in 8 groups of 4 hexadecimals digits: &lt;code&gt;2804:3d28:12:4438:5ecd:5bff:febc:b862&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  CIDR → Classless Inter-Domain Routing
&lt;/h3&gt;

&lt;p&gt;A CIDR goes hand by hand with IP’s. A CIDR number defines the size and the addresses available in a network. With the following screenshot, we can see that this network has a mask of /16 where it translates to the network mask. The network mask defines how many bits of the IPv4 address will be frozen and also defines the size of the network.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9sbualloqc427k1sr704.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9sbualloqc427k1sr704.png" alt="Example of the definition of a CIDR"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that a /16 mask, gives the number of 65,536 IPs to be used in the network.&lt;/p&gt;

&lt;p&gt;The network mask can go in a range of /8 to /32, where /16 or /24 or /28 can be the most common values used in private networks. You can play with CIDR definition at this &lt;a href="https://cidr.xyz/" rel="noopener noreferrer"&gt;website&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Public and Private Networks
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;Public Network&lt;/strong&gt; is reachable by any user on the internet. An example is the github.com website:&lt;/p&gt;

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

&lt;p&gt;A &lt;strong&gt;Private Network&lt;/strong&gt; is a restricted access network most commonly used for house and enterprise networks. Here is an example on how I connect to a VPN using the Pritunl service:&lt;/p&gt;

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

&lt;p&gt;The “Server Address” is a public address that I connect to jump to the private network defined in the “Client Address”, where now I’m able to access my private resources through it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s build our AWS Network?
&lt;/h2&gt;

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

&lt;p&gt;A &lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/how-it-works.html" rel="noopener noreferrer"&gt;&lt;strong&gt;VPC&lt;/strong&gt;&lt;/a&gt; represents your private network inside AWS. It’s totally isolated and nobody can access it besides (Except with the use of &lt;a href="https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html" rel="noopener noreferrer"&gt;VPC Peering&lt;/a&gt;.) your account.&lt;/p&gt;

&lt;p&gt;In AWS, we can define a VPC’s using a CIDR’s number with a network mask between /16 to /28. It is suggested that you create your VPC using the most known private CIDR’s that are:&lt;/p&gt;

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

&lt;p&gt;The network mask is up to you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Subnets
&lt;/h3&gt;

&lt;p&gt;A &lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/configure-subnets.html" rel="noopener noreferrer"&gt;&lt;strong&gt;Subnet&lt;/strong&gt;&lt;/a&gt; is a subnetwork inside your VPC and is defined by another CIDR, with a different network mask. In other words, we divide the addresses available in the VPC in groups that we call subnets.&lt;/p&gt;

&lt;p&gt;Let’s take a small detour and talk about :&lt;/p&gt;

&lt;h3&gt;
  
  
  Regions and Availability Zones
&lt;/h3&gt;

&lt;p&gt;A &lt;a href="https://aws.amazon.com/about-aws/global-infrastructure/regions_az/" rel="noopener noreferrer"&gt;&lt;strong&gt;Region&lt;/strong&gt;&lt;/a&gt; in AWS is defined by a state where AWS provides its services, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;us-east-1 represents the state of Virginia in the US&lt;/li&gt;
&lt;li&gt;sa-east-1 represents the state of São Paulo in Brazil&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An &lt;strong&gt;Availability Zones&lt;/strong&gt; is the redundancy that AWS provides in different datacenters in the same state, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;us-east-1 {a to f} (6 datacenters)&lt;/li&gt;
&lt;li&gt;sa-east-1 {a to c} (3 datacenters)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Going back to Subnets:&lt;/p&gt;

&lt;h3&gt;
  
  
  Good practices to create Subnets
&lt;/h3&gt;

&lt;p&gt;We should create a subnet for each type of resource that we will deploy in our Network:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One for databases&lt;/li&gt;
&lt;li&gt;One for caching services&lt;/li&gt;
&lt;li&gt;One for containers, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As AWS have redundancy, our network must have too. It is recommended that we have at least 4 subnets(2 public and 2 private) in two different Availability Zones. &lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/configure-subnets.html" rel="noopener noreferrer"&gt;The ideal is 3 or 4 subnets per public and private networks&lt;/a&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: The &lt;a href="https://github.com/terraform-aws-modules/terraform-aws-vpc" rel="noopener noreferrer"&gt;Terraform AWS VPC module&lt;/a&gt; will help you to create a VPC and all the required resources without sweat, following all the best practices that we have mentioned here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  State of our Network so far:
&lt;/h3&gt;

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

&lt;h3&gt;
  
  
  Routing Tables
&lt;/h3&gt;

&lt;p&gt;A &lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Route_Tables.html" rel="noopener noreferrer"&gt;&lt;strong&gt;Routing Table&lt;/strong&gt;&lt;/a&gt; represents a group of one or more subnets. It is the router created based on the groups that will handle where the traffic in our VPC will go.&lt;/p&gt;

&lt;p&gt;Subnets aren’t the only resource that we can attach to the table. Now let’s learn about them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Internet Gateway
&lt;/h3&gt;

&lt;p&gt;An &lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html" rel="noopener noreferrer"&gt;&lt;strong&gt;Internet Gateway&lt;/strong&gt;&lt;/a&gt; allows your VPC to connect to the Internet and vice-versa. We create an Internet Gateway and attach to a Routing Table. Attaching an Internet Gateway to a Routing Table makes the subnets that are attached to it public.&lt;/p&gt;

&lt;h3&gt;
  
  
  Elastic IP
&lt;/h3&gt;

&lt;p&gt;An &lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/vpc-eips.html" rel="noopener noreferrer"&gt;&lt;strong&gt;Elastic IP&lt;/strong&gt;&lt;/a&gt;, it’s a public IP address that you can attach to a resource. This resource can be a EC2 or a Nat Gateway, for example. It’s only available for IPv4 addresses, since IPv6 addresses are public. One of the most common uses of an Elastic IP is to attach to a Nat Gateway, that is our next topic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nat Gateway
&lt;/h3&gt;

&lt;p&gt;A &lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html" rel="noopener noreferrer"&gt;&lt;strong&gt;Nat Gateway&lt;/strong&gt;&lt;/a&gt; is a resource that allows our instances that are in the private subnets to connect to the internet, but the “internet” cannot connect to the instances in our VPC. We create the Nat Gateway in a public subnet and attach it to the routing table related to the private subnets.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How can we discover if a subnet is public or private?&lt;br&gt;
If the routing table has an Internet Gateway attached the subnets on it are public, if the routing table has a Nat Gateway attached instead, is a private group of subnets.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now that we covered the base of AWS Networking, let’s talk about security.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security Groups
&lt;/h3&gt;

&lt;p&gt;A &lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html" rel="noopener noreferrer"&gt;&lt;strong&gt;Security Group&lt;/strong&gt;&lt;/a&gt; is created to control the traffic that is allowed to leave or reach the resources associated with it. In this case resources mean: EC2 instances, Containers, Elastic Load Balancers, etc.&lt;/p&gt;

&lt;p&gt;In a security group configuration, we can set up Inbound and Outbound rules. For example: If we have an EC2 instance that we want to ssh into it, we need to have an inbound rule that allows connection through the port 22. Or, if our containers need to access a Postgres RDS instance, we have to create an outbound rule that allows the container to reach the instance in the port 5432. It can be attached to one or more resources in our VPC. We can only create “allow” rules for the security groups. When you create an inbound rule, the same port is automatically available for the outbound, removing the need to create an outbound rule for the same port. Everything else is “denied” by default. Check the Security Group documentation for more of the default configuration of this resource.&lt;/p&gt;

&lt;p&gt;In other words, the security groups allow us to control what can and cannot access our AWS compute resources, and what our resource can access in or out of the AWS Cloud.&lt;/p&gt;

&lt;h3&gt;
  
  
  ACL’s
&lt;/h3&gt;

&lt;p&gt;The last resource that we will learn today is the &lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html" rel="noopener noreferrer"&gt;&lt;strong&gt;Network Access Control List&lt;/strong&gt;&lt;/a&gt; (NACL’s or ACL’s).&lt;/p&gt;

&lt;p&gt;The ACL’s works similar to the security groups, but at the subnet level. By default, the rules of an ACL allows all the traffic to reach the networks. The main difference from a security group, besides the attachment to the subnet, is the ability to create deny rules. For example, we can create a rule where we do not allow connections to the port 22(ssh) or 3389(rdp) in our subnets, giving us an extra layer of security, preventing insecure connections to the resources available in the subnets.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Takeaway: The security groups are associated with the AWS resources available in our VPC, and the ACL’s are associated with one or more subnets in our VPC.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Let’s review the resources that we created on this diagram:&lt;/p&gt;

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

&lt;p&gt;→ We have a VPC with the CIDR 10.0.0.0/16, divided in four subnets, where two are public, and two are private divided in two availability zones, with its CIDR’s containing the network mask /24 size.&lt;/p&gt;

&lt;p&gt;→ We also have an Internet Gateway associated with our VPC that allows our resources to access the internet, and a Nat Gateway that allows our private subnets to access the internet, deployed in one of the public subnets.&lt;/p&gt;

&lt;p&gt;→ Furthermore, we also have 3 security groups: 2 of them for a group of instances and one for an RDS instance. The instances associated with the security-group-02 is allowed to reach the RDS instance by a rule added to the outbound of its security group. And an inbound rule was added to the security-group-3 related to the RDS to allow the instances to access it. The security-group-01 does not have any inbound and outbound rules associated.&lt;/p&gt;

&lt;p&gt;→ Finally, we have a router representing our routing tables, managing the connections between our resources in the subnets.&lt;/p&gt;

&lt;p&gt;That’s all folks!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>vpc</category>
      <category>networking</category>
    </item>
  </channel>
</rss>
