<?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>Forem: Gabriel de Biasi</title>
    <description>The latest articles on Forem by Gabriel de Biasi (@gabrielbiasi).</description>
    <link>https://forem.com/gabrielbiasi</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%2F824758%2Fc72d73e4-619d-49c7-a117-d177ad40511c.jpeg</url>
      <title>Forem: Gabriel de Biasi</title>
      <link>https://forem.com/gabrielbiasi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/gabrielbiasi"/>
    <language>en</language>
    <item>
      <title>Avoid configuration drift on your terraform state when using aws_security_group</title>
      <dc:creator>Gabriel de Biasi</dc:creator>
      <pubDate>Tue, 13 Dec 2022 18:13:08 +0000</pubDate>
      <link>https://forem.com/gabrielbiasi/avoid-configuration-drift-on-your-terraform-state-when-using-awssecuritygroup-40pf</link>
      <guid>https://forem.com/gabrielbiasi/avoid-configuration-drift-on-your-terraform-state-when-using-awssecuritygroup-40pf</guid>
      <description>&lt;p&gt;Terraform is a fantastic tool for provisioning and maintaining infrastructure state, both on-premises and in cloud environments. However, sometimes we go through some situations where we have an expectation that terraform works one way, but terraform ends up working in another way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fjniikg2jrys2xdro6ujs.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fjniikg2jrys2xdro6ujs.gif" alt="this is fine" width="384" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's what happened to me when using the &lt;strong&gt;aws_security_group&lt;/strong&gt;. This resource allows you to create a Security Group within a VPC, which in practice can be applied to other resources, such as EC2 instances, databases, and Kubernetes clusters, to deny connections to specific ports and allow only some specific ports (or none).&lt;/p&gt;

&lt;p&gt;My use case was to create a Security Group for an EC2 instance that would work as a simple job processing worker. In summary, because it works in pull-based, this instance would not need to have any ingress (incoming) rules, only one egress (outgoing) rule for any IP.&lt;/p&gt;

&lt;p&gt;So, I did it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "aws_security_group" "sg" {
  name   = "my-amazing-security-group"
  vpc_id = aws_vpc.main.id

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When running the &lt;strong&gt;terraform apply&lt;/strong&gt; command, I got the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gabriel@machine:~/terraform$ terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_security_group.sg will be created
  + resource "aws_security_group" "sg" {
      + arn                    = (known after apply)
      + description            = "Managed by Terraform"
      + egress                 = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = ""
              + from_port        = 0
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "-1"
              + security_groups  = []
              + self             = false
              + to_port          = 0
            },
        ]
      + id                     = (known after apply)
      + ingress                = (known after apply)
      + name                   = "my-amazing-security-group"
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + tags_all               = (known after apply)
      + vpc_id                 = "vpc-0101010101"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

aws_security_group.sg: Creating...
aws_security_group.sg: Creation complete after 2s [id=sg-0101010101010101]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Excellent! Terraform created the security group and I was able to use it on the EC2 instance I created. However, I realized I had made a mistake while provisioning the EC2 instance and needed to connect to this specific instance using &lt;strong&gt;ssh&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Feof9uwa1du1a1pfjwuh3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Feof9uwa1du1a1pfjwuh3.gif" alt="made a mistake" width="600" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To enable this access, I needed to create a new ingress rule on the security group. So, I went directly to the AWS dashboard, and edited the security group manually, allowing connections on port 22 for just my IP Address.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F11chegazz2ibl30f1ow1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F11chegazz2ibl30f1ow1.gif" alt="hehehe" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After connecting to the instance and solving the problem, I thought to myself:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I'm gonna run terraform apply again, as terraform will notice the extra rule in the security group and create a plan to remove this rule, right?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So when I ran the command I got the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gabriel@machine:~/terraform$ terraform apply
aws_security_group.sg: Refreshing state... [id=sg-0101010101010101]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.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%2Fgutvqwqzsv2ik51ocuh1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fgutvqwqzsv2ik51ocuh1.gif" alt="confused" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I was confused. Did terraform not notice the new rule in the security group? I went to the AWS dashboard and saw that the ingress rule was still present! So what?&lt;/p&gt;

&lt;p&gt;Then I dig a little further and I understood that the aws_security_group does &lt;strong&gt;not&lt;/strong&gt; maintain the state of the rules, if this is not &lt;strong&gt;explicit&lt;/strong&gt;. That is, we need to make it explicit in the resource definition that we don't want any ingress rules. Correcting our code, it would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "aws_security_group" "sg" {
  name   = "my-amazing-security-group"
  vpc_id = data.aws_vpc.main.id

  ingress = []    # no ingress rules allowed

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that the &lt;strong&gt;ingress&lt;/strong&gt; attribute takes an empty list. This makes it explicit to terraform that we don't want any ingress rules for this security group. Then, running the terraform apply command again, we can finally have the guaranteed state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gabriel@machine:~/terraform$ terraform apply
aws_security_group.sg: Refreshing state... [id=sg-0110522c7ec4870d0]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_security_group.sg will be updated in-place
  ~ resource "aws_security_group" "sg" {
        id                     = "sg-0110522c7ec4870d0"
      ~ ingress                = [
          - {
              - cidr_blocks      = [
                  - "169.169.169.169/32",
                ]
              - description      = "My IP"
              - from_port        = 22
              - ipv6_cidr_blocks = []
              - prefix_list_ids  = []
              - protocol         = "tcp"
              - security_groups  = []
              - self             = false
              - to_port          = 22
            },
        ]
        name                   = "my-amazing-security-group"
        tags                   = {}
        # (7 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

aws_security_group.sg: Modifying... [id=sg-0110522c7ec4870d0]
aws_security_group.sg: Modifications complete after 0s [id=sg-0110522c7ec4870d0]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.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%2Fsxrnlmvmex6amnevb33v.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fsxrnlmvmex6amnevb33v.gif" alt="ufa" width="200" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, terraform guarantees that this security group does not gain new rules through the AWS dashboard and maintains this state for us!&lt;/p&gt;

</description>
      <category>career</category>
    </item>
    <item>
      <title>Automatic SSO in Kubernetes workloads using a sidecar container</title>
      <dc:creator>Gabriel de Biasi</dc:creator>
      <pubDate>Mon, 12 Dec 2022 13:01:06 +0000</pubDate>
      <link>https://forem.com/gabrielbiasi/automatic-sso-in-kubernetes-workloads-using-a-sidecar-container-3752</link>
      <guid>https://forem.com/gabrielbiasi/automatic-sso-in-kubernetes-workloads-using-a-sidecar-container-3752</guid>
      <description>&lt;p&gt;⚠ &lt;em&gt;This post assumes you have a pretty good knowledge of Kubernetes, Helm, and creating your helm charts by yourself.&lt;/em&gt; ⚠ &lt;/p&gt;

&lt;p&gt;For security reasons, it is quite common the need to protect our workloads in Kubernetes with some kind of authentication, or even using &lt;em&gt;basic auth&lt;/em&gt;, for example. However, some applications don't offer this option natively.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fq7mbt2adh8p5janlvxqw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fq7mbt2adh8p5janlvxqw.png" alt="Image description" width="514" height="641"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have the basic structure of an application that has to be exposed to the Internet, but still without authentication.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fyogflh5j66as3okabs8e.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fyogflh5j66as3okabs8e.gif" alt="outsiders" width="260" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To achieve that, we'll need an &lt;em&gt;Identity Provider&lt;/em&gt; and a &lt;em&gt;sidecar container&lt;/em&gt; to handle this process for us, without the need to make modifications to our own application. But, how is this possible?? 😧&lt;/p&gt;

&lt;p&gt;An IdP provides us the identities to be used. It might be OIDC, AD, Google Workspace, GitHub, Auth0, among others. In this example, we will use a &lt;strong&gt;Keycloak&lt;/strong&gt; instance, which has an IdP configuration with Google Workspace.&lt;/p&gt;

&lt;p&gt;The star here is &lt;a href="https://oauth2-proxy.github.io/oauth2-proxy/" rel="noopener noreferrer"&gt;oauth2-proxy&lt;/a&gt;. This project provides a super small Docker image (~12.8 MB) that can serve static files directly, or upstream to another web server.&lt;/p&gt;

&lt;p&gt;This proxy is fully configurable using environment variables. We can now define, within our helm chart templates, the default settings to use. In this example, if the developer wants to enable this functionality, he can set this value in the &lt;code&gt;values.yaml&lt;/code&gt; file as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# chart/values.yaml&lt;/span&gt;
&lt;span class="na"&gt;authProxy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're gonna need to change the template of the &lt;strong&gt;Deployment&lt;/strong&gt; and the &lt;strong&gt;Service&lt;/strong&gt;. First, let's see what the changes in the Deployment look like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# chart/templates/deployment.yaml&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;include "chart.fullname" .&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
  &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;- include "chart.labels" . | nindent 4&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;.Values.replicaCount&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;- include "chart.selectorLabels" . | nindent 6&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;- include "chart.selectorLabels" . | nindent 8&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:1.19&lt;/span&gt;
          &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;
              &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;.Values.containerPort&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
              &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&lt;/span&gt;
          &lt;span class="na"&gt;envFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;configMapRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;include "chart.fullname" .&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;secretRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;include "chart.fullname" .&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
       &lt;span class="c1"&gt;# ---&lt;/span&gt;
       &lt;span class="c1"&gt;# changes start HERE!&lt;/span&gt;
       &lt;span class="c1"&gt;# ---&lt;/span&gt;
      &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="pi"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;- if .Values.authProxy.enabled&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;auth&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;quay.io/oauth2-proxy/oauth2-proxy:v7.3.0&lt;/span&gt;
          &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;auth&lt;/span&gt;
              &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5001&lt;/span&gt;
              &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&lt;/span&gt;
          &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;OAUTH2_PROXY_HTTP_ADDRESS&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:5001"&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;OAUTH2_PROXY_UPSTREAMS&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;print "http&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;//127.0.0.1&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;.Values.containerPort&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}&lt;/span&gt;
            &lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;name:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;OAUTH2_PROXY_COOKIE_SECRET&lt;/span&gt;
              &lt;span class="s"&gt;value:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;randAlphaNum&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;32&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;|&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;quote&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}&lt;/span&gt;
            &lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;name:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;OAUTH2_PROXY_COOKIE_NAME&lt;/span&gt;
              &lt;span class="s"&gt;value:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;include&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;chart.fullname" .&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;OAUTH2_PROXY_SKIP_PROVIDER_BUTTON&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true"&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;OAUTH2_PROXY_AUTH_LOGGING&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true"&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;OAUTH2_PROXY_REQUEST_LOGGING&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;false"&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;OAUTH2_PROXY_FORCE_CODE_CHALLENGE_METHOD&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;S256"&lt;/span&gt;
          &lt;span class="na"&gt;envFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;configMapRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;include "chart.fullname" .&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;secretRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;include "chart.fullname" .&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
        &lt;span class="pi"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;- end&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that if &lt;code&gt;authProxy.enabled&lt;/code&gt; is &lt;strong&gt;true&lt;/strong&gt;, a new container is included in the Deployment, called "auth". This container already has some environment variables configured, however, some environment variables are still needed, depending on which provider we use to authenticate.&lt;/p&gt;

&lt;p&gt;In this example, we define the environment variables using a mix of ConfigMaps and Secrets, which are referenced in &lt;code&gt;configMapRef&lt;/code&gt; and &lt;code&gt;secretRef&lt;/code&gt;. You can see all the environment variables available to use in the &lt;a href="https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/overview" rel="noopener noreferrer"&gt;project documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, let's see the changes that we need to do in the &lt;strong&gt;Service&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# chart/templates/service.yaml&lt;/span&gt;
&lt;span class="pi"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;- $targetPort&lt;/span&gt; &lt;span class="pi"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;= .Values.authProxy.enabled | ternary "auth" "http")&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;include "chart.fullname" .&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
  &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;- include "chart.labels" . | nindent 4&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;.Values.service.type&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;.Values.service.port&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;$targetPort | quote&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
      &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;- include "chart.selectorLabels" . | nindent 4&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the first line, we create a new variable called &lt;code&gt;$targetPort&lt;/code&gt;. This variable changes its value depending on the value of &lt;code&gt;authProxy.enabled&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In a nutshell, we switch the value of &lt;code&gt;spec.ports[0].targetPort&lt;/code&gt; between &lt;strong&gt;http&lt;/strong&gt; or &lt;strong&gt;auth&lt;/strong&gt;, depending if &lt;code&gt;authProxy.enabled&lt;/code&gt; is true or not.&lt;/p&gt;

&lt;p&gt;Let's see how these modifications work out together.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ftd0f6ksew92gonvpnsnq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ftd0f6ksew92gonvpnsnq.png" alt="Image description" width="574" height="703"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that we don't need to make any modifications in the original container, as we are simply proxying the traffic using the sidecar container.&lt;/p&gt;

&lt;p&gt;Now, whenever outsider users try to access our application, they are gonna see the Keycloak login page first.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fq2g0xcfm5pipxzt8sfxw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fq2g0xcfm5pipxzt8sfxw.png" alt="Image description" width="800" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Feh1jbnaoe9xxyrhx7uri.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Feh1jbnaoe9xxyrhx7uri.gif" alt="you shall not pass" width="400" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What do you think about this solution? 🤔&lt;br&gt;
Thank you for reading!&lt;br&gt;
🍀🍀🍀&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>cloudnative</category>
      <category>career</category>
      <category>devrel</category>
    </item>
    <item>
      <title>Como a Trybe corrige mais de 20 mil avaliações por semana!</title>
      <dc:creator>Gabriel de Biasi</dc:creator>
      <pubDate>Tue, 29 Mar 2022 18:06:46 +0000</pubDate>
      <link>https://forem.com/trybe/como-a-trybe-corrige-mais-de-20-mil-avaliacoes-por-semana-1i6f</link>
      <guid>https://forem.com/trybe/como-a-trybe-corrige-mais-de-20-mil-avaliacoes-por-semana-1i6f</guid>
      <description>&lt;p&gt;Para quem não conhece a &lt;a href="https://www.betrybe.com/" rel="noopener noreferrer"&gt;Trybe&lt;/a&gt;, é uma escola de desenvolvimento web que tem comprometimento genuíno com o sucesso profissional de quem estuda conosco. Com o Modelo de Sucesso Compartilhado (MSC) ofertado pela Trybe Fintech, a pessoa estudante tem a opção de pagar apenas quando já estiver trabalhando, você acredita nesse nível de confiança?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/PudZiAbQDUEik/giphy-downsized.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/PudZiAbQDUEik/giphy-downsized.gif" alt="gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E para isso precisamos ter um infraestrutura para avaliar todos os projetos enviados pelas pessoas estudantes! Hoje utilizamos GitHub Actions, entretanto, usar os executores oferecidos pelo próprio GitHub Cloud não é o suficiente, pois esgotaríamos os minutos oferecidos pelo plano rapidamente.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/l4FGjq205dsq8mcw0/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/l4FGjq205dsq8mcw0/giphy.gif" alt="Simulação de uma pessoa estudante esperando pela sua avaliação"&gt;&lt;/a&gt;&lt;/p&gt;
Simulação de uma pessoa estudante esperando pela sua avaliação



&lt;p&gt;Logo, optamos por manter nossa própria infraestrutura de self-hosted runners, e melhor ainda, tudo orquestrado usando &lt;a href="https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Veja na imagem abaixo como é o esquema de funcionamento. Após isso, temos o passo-a-passo explicando o fluxo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Passo 1:&lt;/strong&gt; A pessoa estudante envia seu projeto como um &lt;em&gt;pull request&lt;/em&gt; no repositório.&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%2Fjhe3yiz1rb2lgyf5ey0a.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%2Fjhe3yiz1rb2lgyf5ey0a.png" alt="Passo 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Passo 2:&lt;/strong&gt; De acordo com a configuração do workflow, o trigger é acionado e uma nova avaliação é inserida na fila de workflows do repositório;&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%2Fzfdmg2eql07kx6csonn0.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%2Fzfdmg2eql07kx6csonn0.png" alt="Passo 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Passo 3:&lt;/strong&gt; Os self-hosted runners funcionam como &lt;strong&gt;pull-based&lt;/strong&gt;, ou seja, eles fazem &lt;strong&gt;pulling&lt;/strong&gt; no GitHub API aguardando por jobs à serem executados.&lt;/p&gt;

&lt;p&gt;É possível que não haja runners disponíveis no momento. Então, nós temos um &lt;em&gt;controller&lt;/em&gt; que se comunica com o GitHub API sobre a condição atual dos runners. Se não houver runners disponíveis no momento, o controler aciona o &lt;strong&gt;Horizontal Runner Autoscaler&lt;/strong&gt; para escalar para cima o número de runners em nossa infraestrutura.&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%2Fjy2hmnc69inijp3isr49.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%2Fjy2hmnc69inijp3isr49.png" alt="Passo 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao mesmo tempo, nosso &lt;em&gt;controler&lt;/em&gt; também verifica se não temos "runners demais": Se mais de 50% dos runners atuais estão em &lt;em&gt;idle&lt;/em&gt;, isso significa que podemos diminuir o número de runners para melhorarmos nossos custos com infraestrutura. O controler aciona o &lt;strong&gt;Horizontal Runner Autoscaler&lt;/strong&gt; para escalar para baixo o número de runners em nossa infraestrutura.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Passo 4:&lt;/strong&gt; A avaliação é feita utilizando uma série de actions implementados pelo time da Trybe. Essas actions envolvem &lt;em&gt;linters&lt;/em&gt; de arquivos, execução do &lt;em&gt;cypress&lt;/em&gt;, testes unitários, etc.&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%2Fb9vhn3an2httespgiwb3.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%2Fb9vhn3an2httespgiwb3.png" alt="Passo 4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Passo 5:&lt;/strong&gt; Após executar a avaliação, a última action do workflow envia o resultado obtido para o nosso backend de avaliações, para ser armazenado em nosso banco de dados.&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%2F2j4xcbvhezd5afdp7uz0.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%2F2j4xcbvhezd5afdp7uz0.png" alt="Passo 5"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Passo 6:&lt;/strong&gt; Como muitas pessoas estudantes enviam suas avaliações ao mesmo tempo, foi implementado uma solução utilizando &lt;strong&gt;Amazon MQ&lt;/strong&gt;, para enfilieirar o processo de avaliação e também evitar um possível &lt;em&gt;rate limit&lt;/em&gt; na API do GitHub.&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%2Fnrbck64fswqm00bd92l9.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%2Fnrbck64fswqm00bd92l9.png" alt="Passo 6"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Passo 7-8:&lt;/strong&gt; Após processar a avaliação que estava na fila de mensageria, o backend de avaliação faz um comentário no PR da pessoa estudante, informando o resultado!&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%2Fcqt7yhrkapdnf0l2us5r.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%2Fcqt7yhrkapdnf0l2us5r.png" alt="Passo 7-8"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bem simples, né&lt;/strong&gt;? O processo parece ser complicado, mas é necessário pelo tamanho da demanda que temos em corrigir mais de 20 mil avaliações por semana. Agora veja todo o processo em apenas uma figura:&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%2Frybftr82dy0loaim0fa2.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%2Frybftr82dy0loaim0fa2.png" alt="Processo Completo"&gt;&lt;/a&gt;Processo de correção&lt;/p&gt;

&lt;p&gt;Gostou do que viu? Quer ajudar a Trybe a manter esta infraestrutura? Venha pois temos várias &lt;a href="https://www.betrybe.com/trabalhe-conosco" rel="noopener noreferrer"&gt;vagas abertas&lt;/a&gt;!!&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>github</category>
      <category>githubactions</category>
      <category>devops</category>
    </item>
    <item>
      <title>Evite configuration drift no seu estado de terraform ao usar aws_security_group</title>
      <dc:creator>Gabriel de Biasi</dc:creator>
      <pubDate>Tue, 08 Mar 2022 11:02:37 +0000</pubDate>
      <link>https://forem.com/trybe/evite-configuration-drift-no-seu-estado-de-terraform-ao-usar-awssecuritygroup-2ndp</link>
      <guid>https://forem.com/trybe/evite-configuration-drift-no-seu-estado-de-terraform-ao-usar-awssecuritygroup-2ndp</guid>
      <description>&lt;p&gt;O &lt;a href="https://www.terraform.io/intro"&gt;terraform&lt;/a&gt; é uma ferramenta fantástica para provisionar e manter o estado de uma infraestrutura, tanto on-premises quanto nos ambientes de cloud. Entretanto, algumas vezes passamos por algumas situações que nós temos uma expectativa de que o terraform funcione de uma maneira, porém o terraform acaba funcionando de outra forma.&lt;/p&gt;

&lt;p&gt;Foi o que aconteceu comigo ao utilizar o recurso &lt;a href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group"&gt;aws_security_group&lt;/a&gt;. Este recurso permite criar um &lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html"&gt;Security Group&lt;/a&gt; dentro de uma VPC, que na prática pode ser aplicado a outros recursos, como instâncias EC2, banco de dados, clusters Kubernetes, para fechar portas de conexão e liberar apenas algumas portas específicas (ou nenhuma).&lt;/p&gt;

&lt;p&gt;Meu caso de uso foi criar um Security Group para uma instância EC2 que iria trabalhar como um &lt;em&gt;worker&lt;/em&gt;, ou seja, essa instância iria obter os jobs através de uma fonte externa, realizar o processamento e enviar o resultado. Em resumo, por trabalhar em &lt;strong&gt;pull-based&lt;/strong&gt;, essa instância não precisaria ter nenhuma regra de ingresso (entrada), apenas uma regra de egresso (saída) para qualquer IP.&lt;/p&gt;

&lt;p&gt;Logo, fiz o recurso da seguinte maneira:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "aws_security_group" "sg" {
  name   = "my-amazing-security-group"
  vpc_id = aws_vpc.main.id

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao executar o comando &lt;strong&gt;terraform apply&lt;/strong&gt;, obtive a seguinte saída:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gabriel@machine:~/terraform$ terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_security_group.sg will be created
  + resource "aws_security_group" "sg" {
      + arn                    = (known after apply)
      + description            = "Managed by Terraform"
      + egress                 = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = ""
              + from_port        = 0
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "-1"
              + security_groups  = []
              + self             = false
              + to_port          = 0
            },
        ]
      + id                     = (known after apply)
      + ingress                = (known after apply)
      + name                   = "my-amazing-security-group"
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + tags_all               = (known after apply)
      + vpc_id                 = "vpc-0101010101"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

aws_security_group.sg: Creating...
aws_security_group.sg: Creation complete after 2s [id=sg-0101010101010101]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ótimo! O terraform criou o security group e eu pude utilizar na instância EC2 que criei. Entretanto, percebi que tinha cometido um erro ao provisionar a instância EC2 e eu precisava me conectar nessa instância usando &lt;strong&gt;ssh&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/QBpnlzndcEeIS57v15/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/QBpnlzndcEeIS57v15/giphy.gif" alt="made a mistake" width="600" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para possibilitar o acesso, eu precisava criar a regra de ingresso no security group. Logo, fui diretamente no dashboard da AWS, editei o security group manualmente liberando a porta 22 para apenas o meu IP.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/xThtaxbIPLT9XqWcDK/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/xThtaxbIPLT9XqWcDK/giphy.gif" alt="hehehe" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após me conectar na instância e resolver o problema, pensei: “&lt;em&gt;Vou simplesmente executar terraform apply, pois o terraform irá perceber a regra extra no security group e criar um plano para remover esta regra&lt;/em&gt;”. Então, ao executar o comando, obtive a seguinte saída:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gabriel@machine:~/terraform$ terraform apply
aws_security_group.sg: Refreshing state... [id=sg-0101010101010101]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://i.giphy.com/media/nTfdeBvfgzV26zjoFP/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/nTfdeBvfgzV26zjoFP/giphy.gif" alt="confuso" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na hora fiquei confuso. O terraform não percebeu a regra nova no security group? Fui no dashboard da AWS e vi que a regra de ingresso ainda estava presente! E agora?&lt;/p&gt;

&lt;p&gt;Pesquisando melhor, entendi que o recurso aws_security_group não mantém o estado das regras, se isso não for &lt;strong&gt;explícito&lt;/strong&gt;. Ou seja, precisamos deixar explícito na definição do recurso que não queremos nenhuma regra de ingresso. Corrigindo nosso código, ficaria assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "aws_security_group" "sg" {
  name   = "my-amazing-security-group"
  vpc_id = data.aws_vpc.main.id

  ingress = []    # explicitamente nenhuma regra de ingresso

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perceba que o atributo &lt;strong&gt;ingress&lt;/strong&gt; recebe uma lista vazia. Isto deixa explícito que não queremos nenhuma regra de ingresso para este security group. Logo, executando o comando terraform apply novamente, finalmente podemos ter o estado garantido:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gabriel@machine:~/terraform$ terraform apply
aws_security_group.sg: Refreshing state... [id=sg-0110522c7ec4870d0]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_security_group.sg will be updated in-place
  ~ resource "aws_security_group" "sg" {
        id                     = "sg-0110522c7ec4870d0"
      ~ ingress                = [
          - {
              - cidr_blocks      = [
                  - "169.169.169.169/32",
                ]
              - description      = "My IP"
              - from_port        = 22
              - ipv6_cidr_blocks = []
              - prefix_list_ids  = []
              - protocol         = "tcp"
              - security_groups  = []
              - self             = false
              - to_port          = 22
            },
        ]
        name                   = "my-amazing-security-group"
        tags                   = {}
        # (7 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

aws_security_group.sg: Modifying... [id=sg-0110522c7ec4870d0]
aws_security_group.sg: Modifications complete after 0s [id=sg-0110522c7ec4870d0]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://i.giphy.com/media/nXxOjZrbnbRxS/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/nXxOjZrbnbRxS/giphy.gif" alt="ufa" width="200" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ufa! Agora sim o terraform nos garante que este security group não ganhe novas regras através do dashboard da AWS e mantenha este estado pra gente. &lt;/p&gt;

</description>
      <category>aws</category>
      <category>terraform</category>
      <category>sre</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
