<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pt-BR"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://thallysonyakko.com.br/feed.xml" rel="self" type="application/atom+xml" /><link href="https://thallysonyakko.com.br/" rel="alternate" type="text/html" hreflang="pt-BR" /><updated>2026-05-08T18:36:30-03:00</updated><id>https://thallysonyakko.com.br/feed.xml</id><title type="html">Thallyson Yakko | DevOps Engineer</title><subtitle>Blog sobre DevOps, Cloud Computing e minha jornada rumo às certificações AWS.  Compartilho dicas, estudos práticos e soluções para infraestrutura em nuvem.</subtitle><entry><title type="html">Desafio SRE – Primeira Parte</title><link href="https://thallysonyakko.com.br/posts/desafio-sre/" rel="alternate" type="text/html" title="Desafio SRE – Primeira Parte" /><published>2025-12-23T00:00:00-03:00</published><updated>2025-12-23T00:00:00-03:00</updated><id>https://thallysonyakko.com.br/posts/desafio-sre</id><content type="html" xml:base="https://thallysonyakko.com.br/posts/desafio-sre/"><![CDATA[<h2 id="contexto-do-desafio">Contexto do Desafio</h2>

<p>O objetivo dessa primeira etapa foi:</p>

<ul>
  <li>Rodar a aplicação localmente</li>
  <li>Dockerizar a aplicação</li>
  <li>Orquestrar App + Redis + PostgreSQL</li>
  <li>Publicar a imagem em um registry</li>
  <li>Provisionar um cluster Kubernetes local com KIND via Terraform</li>
  <li>Subir toda a stack no Kubernetes</li>
  <li>Expor a aplicação via Ingress</li>
  <li>Implementar monitoramento com Prometheus e Grafana</li>
  <li>Criar ServiceMonitor e regras de alerta baseadas no método GOLD</li>
</ul>

<hr />

<h2 id="dockerização-da-aplicação">Dockerização da Aplicação</h2>

<p>Primeira coisa foi containerizar a aplicação Python. Criei um Dockerfile e um docker-compose.yml para subir o app junto com Redis e Postgres.</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="rouge-code"><pre><span class="s">FROM python:3.11-slim</span>

<span class="s">WORKDIR /app</span>

<span class="s">RUN apt-get update &amp;&amp; apt-get install -y gcc libpq-dev &amp;&amp; \</span>
    <span class="s">pip install --no-cache-dir \</span>
        <span class="s">Flask==2.0.3 \</span>
        <span class="s">Werkzeug==2.3.8 \</span>
        <span class="s">prometheus-client==0.13.1 \</span>
        <span class="s">prometheus-flask-exporter==0.18.7 \</span>
        <span class="s">psycopg2-binary==2.9.7 \</span>
        <span class="s">redis==4.5.4 &amp;&amp; \</span>
    <span class="s">apt-get remove -y gcc &amp;&amp; apt-get autoremove -y &amp;&amp; apt-get clean</span>

<span class="s">COPY . .</span>

<span class="s">EXPOSE </span><span class="m">5000</span>

<span class="s">CMD ["python", "app.py"]</span>

</pre></td></tr></tbody></table></code></pre></div></div>

<p>A imagem base é <code class="language-plaintext highlighter-rouge">python:3.11-slim</code> pra manter o tamanho controlado. Precisei instalar <code class="language-plaintext highlighter-rouge">gcc</code> e <code class="language-plaintext highlighter-rouge">libpq-dev</code> porque o <code class="language-plaintext highlighter-rouge">psycopg2</code> tem extensão C e sem eles o build quebra. No final removo o gcc pra não carregar lixo na imagem final.</p>

<h3 id="build-da-imagem-docker">Build da imagem Docker</h3>

<p>Execute no diretório onde está o <code class="language-plaintext highlighter-rouge">Dockerfile</code>:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>docker build <span class="nt">-t</span> app-elven:latest <span class="nb">.</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<h1 id="docker-composeyml">docker-compose.yml</h1>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
</pre></td><td class="rouge-code"><pre><span class="na">version</span><span class="pi">:</span> <span class="s1">'</span><span class="s">3.9'</span>

<span class="na">services</span><span class="pi">:</span>
  <span class="na">app-elven</span><span class="pi">:</span>
    <span class="na">build</span><span class="pi">:</span>
      <span class="na">context</span><span class="pi">:</span> <span class="s">.</span>
      <span class="na">dockerfile</span><span class="pi">:</span> <span class="s">Dockerfile</span>
    <span class="na">ports</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">5001:5000</span>
      <span class="pi">-</span> <span class="s">9999:9999</span>
    <span class="na">networks</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">elven</span>
    <span class="na">environment</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">POSTGRES_HOST=db</span>
      <span class="pi">-</span> <span class="s">POSTGRES_DB=postgres</span>
      <span class="pi">-</span> <span class="s">POSTGRES_USER=postgres</span>
      <span class="pi">-</span> <span class="s">POSTGRES_PASSWORD=senhafacil</span>
      <span class="pi">-</span> <span class="s">REDIS_HOST=redis</span>
    <span class="na">volumes</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">.:/app</span>
    <span class="na">depends_on</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">db</span>
      <span class="pi">-</span> <span class="s">redis</span>
    <span class="na">healthcheck</span><span class="pi">:</span>
      <span class="na">test</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">CMD-SHELL"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">curl</span><span class="nv"> </span><span class="s">-f</span><span class="nv"> </span><span class="s">http://localhost:5000</span><span class="nv"> </span><span class="s">||</span><span class="nv"> </span><span class="s">exit</span><span class="nv"> </span><span class="s">1"</span><span class="pi">]</span>
      <span class="na">interval</span><span class="pi">:</span> <span class="s">30s</span>
      <span class="na">timeout</span><span class="pi">:</span> <span class="s">5s</span>
      <span class="na">retries</span><span class="pi">:</span> <span class="m">3</span>
      <span class="na">start_period</span><span class="pi">:</span> <span class="s">10s</span>

  <span class="na">redis</span><span class="pi">:</span>
    <span class="na">image</span><span class="pi">:</span> <span class="s">redis:8</span>
    <span class="na">ports</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s2">"</span><span class="s">6379:6379"</span>
    <span class="na">networks</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">elven</span>
    <span class="na">healthcheck</span><span class="pi">:</span>
      <span class="na">test</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">CMD"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">redis-cli"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">ping"</span><span class="pi">]</span>
      <span class="na">interval</span><span class="pi">:</span> <span class="s">30s</span>
      <span class="na">timeout</span><span class="pi">:</span> <span class="s">5s</span>
      <span class="na">retries</span><span class="pi">:</span> <span class="m">3</span>
      <span class="na">start_period</span><span class="pi">:</span> <span class="s">10s</span>

  <span class="na">db</span><span class="pi">:</span>
    <span class="na">image</span><span class="pi">:</span> <span class="s">postgres:15</span>
    <span class="na">environment</span><span class="pi">:</span>
      <span class="na">POSTGRES_USER</span><span class="pi">:</span> <span class="s">postgres</span>
      <span class="na">POSTGRES_PASSWORD</span><span class="pi">:</span> <span class="s">senhafacil</span>
      <span class="na">POSTGRES_DB</span><span class="pi">:</span> <span class="s">postgres</span>
    <span class="na">ports</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s2">"</span><span class="s">5432:5432"</span>
    <span class="na">networks</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">elven</span>
    <span class="na">volumes</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">pgdata:/var/lib/postgresql/data</span>
    <span class="na">healthcheck</span><span class="pi">:</span>
      <span class="na">test</span><span class="pi">:</span> <span class="pi">[</span><span class="s2">"</span><span class="s">CMD-SHELL"</span><span class="pi">,</span> <span class="s2">"</span><span class="s">pg_isready</span><span class="nv"> </span><span class="s">-U</span><span class="nv"> </span><span class="s">postgres"</span><span class="pi">]</span>
      <span class="na">interval</span><span class="pi">:</span> <span class="s">30s</span>
      <span class="na">timeout</span><span class="pi">:</span> <span class="s">5s</span>
      <span class="na">retries</span><span class="pi">:</span> <span class="m">3</span>
      <span class="na">start_period</span><span class="pi">:</span> <span class="s">10s</span>

<span class="na">networks</span><span class="pi">:</span>
  <span class="na">elven</span><span class="pi">:</span>
    <span class="na">driver</span><span class="pi">:</span> <span class="s">bridge</span>

<span class="na">volumes</span><span class="pi">:</span>
  <span class="na">pgdata</span><span class="pi">:</span>

</pre></td></tr></tbody></table></code></pre></div></div>

<h2 id="subindo-toda-a-stack">Subindo toda a stack</h2>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>docker-compose up <span class="nt">-d</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p>Acesso pelo navegador no localhost ou por curl. Resultado esperado é ver uma mensagem “App on”.</p>

<p><img src="./assets/2025-12-24-desafio-sre/1.png" alt="Acesso" /></p>

<h3 id="para-ver-os-logs-e-derrubar-a-infra">Para ver os logs e derrubar a infra:</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>docker-compose logs <span class="nt">-f</span> app-elven
</pre></td></tr></tbody></table></code></pre></div></div>

<p>ou</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>docker-compose down
</pre></td></tr></tbody></table></code></pre></div></div>

<h1 id="subindo-a-imagem-para-o-registry">Subindo a imagem para o Registry:</h1>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>docker login
</pre></td></tr></tbody></table></code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>docker tag app-elven:latest seuusuario/app-elven:latest
</pre></td></tr></tbody></table></code></pre></div></div>

<h3 id="puxando-a-imagem-para-o-registry">Puxando a imagem para o Registry:</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>docker push seuusuario/app-elven:latest
</pre></td></tr></tbody></table></code></pre></div></div>

<h1 id="problemas">Problemas:</h1>

<ol>
  <li>
    <p>**Problemas com build por falta do compilator de extensão C:</p>

    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre> Solução: no lugar de fazer multistage com duas fases de build foi feito apenas uma fase e instalado o gcc libpq-dev: ``apt-get install -y gcc libpq-dev``
</pre></td></tr></tbody></table></code></pre></div>    </div>
  </li>
  <li>
    <p><strong>Healthcheck da aplicação falhando</strong>:
     A aplicação subia mais devagar do que o tempo estipulado no healthcheck, problema solucionado colocando o “<code class="language-plaintext highlighter-rouge">start_period: 10s</code>”</p>
  </li>
</ol>

<hr />

<h1 id="criando-o-cluster-kind-com-terraform">Criando o cluster KIND com Terraform</h1>

<p>Usei o provider <code class="language-plaintext highlighter-rouge">loft-sh/kind</code> pra provisionar o cluster via Terraform em vez de rodar <code class="language-plaintext highlighter-rouge">kind create cluster</code> na mão.</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
</pre></td><td class="rouge-code"><pre><span class="s">terraform {</span>
  <span class="s">required_providers {</span>
    <span class="s">kind = {</span>
      <span class="s">source  = "loft-sh/kind"</span>
      <span class="s">version = "0.4.0"</span>
    <span class="s">}</span>
  <span class="s">}</span>
<span class="err">}</span>

<span class="s">provider "kind" {}</span>

<span class="c1"># Criação do cluster Kind</span>
<span class="s">resource "kind_cluster" "kind" {</span>
  <span class="s">name           = "kind-elven"</span>
  <span class="s">wait_for_ready = </span><span class="kc">true</span>

  <span class="s">node_image = "kindest/node:v1.30.0"</span>

  <span class="s"># Configuração do cluster Kind (equivalente ao kind.yaml)</span>
  <span class="s">config = &lt;&lt;EOF</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Cluster</span>
<span class="na">apiVersion</span><span class="pi">:</span> <span class="s">kind.x-k8s.io/v1alpha4</span>
<span class="na">nodes</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="na">role</span><span class="pi">:</span> <span class="s">control-plane</span>
    <span class="na">extraPortMappings</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">containerPort</span><span class="pi">:</span> <span class="m">30000</span>
        <span class="na">hostPort</span><span class="pi">:</span> <span class="m">30000</span>
      <span class="pi">-</span> <span class="na">containerPort</span><span class="pi">:</span> <span class="m">30001</span>
        <span class="na">hostPort</span><span class="pi">:</span> <span class="m">30001</span>
  <span class="pi">-</span> <span class="na">role</span><span class="pi">:</span> <span class="s">worker</span>
  <span class="pi">-</span> <span class="na">role</span><span class="pi">:</span> <span class="s">worker</span>
<span class="s">EOF</span>
<span class="err">}</span>

<span class="s">output "kubeconfig_file" {</span>
  <span class="s">value = kind_cluster.kind.kubeconfig_path</span>
<span class="err">}</span>

</pre></td></tr></tbody></table></code></pre></div></div>

<h2 id="iniciando-o-terraform">Iniciando o Terraform:</h2>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>terraform init
</pre></td></tr></tbody></table></code></pre></div></div>

<h2 id="criando-o-cluster">Criando o cluster:</h2>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>terraform apply <span class="nt">-auto-approve</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<h1 id="verificando-o-cluster">Verificando o cluster:</h1>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>kubectl get nodes <span class="nt">-A</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<hr />

<hr />

<h1 id="kubernetes-com-kind">Kubernetes com KIND</h1>

<p>A stack rodou inteira dentro do namespace <strong>desafio-sre</strong>:</p>

<ul>
  <li>App Flask</li>
  <li>Redis</li>
  <li>Postgres</li>
  <li>Ingress NGINX</li>
  <li>Prometheus + Grafana via Helm (kube-prometheus-stack)</li>
  <li>Regras personalizadas</li>
  <li>Monitoramento via ServiceMonitor</li>
</ul>

<p>O monitoramento ficou no namespace <strong>monitoring</strong>.</p>

<h1 id="criação-namespace">Criação Namespace:</h1>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>kubectl create namespace desafio-sre
</pre></td></tr></tbody></table></code></pre></div></div>

<h1 id="aplicação--deployment">Aplicação – Deployment</h1>

<p>Arquivo: <code class="language-plaintext highlighter-rouge">app-deployment.yaml</code></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
</pre></td><td class="rouge-code"><pre><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">apps/v1</span>    <span class="c1">#Sempre vai ser apps/v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Deployment</span>         <span class="c1">#Tipo do manisfesto</span>
<span class="na">metadata</span><span class="pi">:</span>
  <span class="na">labels</span><span class="pi">:</span>
    <span class="na">app</span><span class="pi">:</span> <span class="s">app-sre</span>
  <span class="na">name</span><span class="pi">:</span> <span class="s">app-sre</span>
  <span class="na">namespace</span><span class="pi">:</span> <span class="s">desafio-sre</span>
<span class="na">spec</span><span class="pi">:</span>             <span class="c1">#caracteristicas do deployment</span>
  <span class="na">replicas</span><span class="pi">:</span> <span class="m">3</span>
  <span class="na">selector</span><span class="pi">:</span>       <span class="c1">#Controla os Pods referentes a essa aplicação</span>
    <span class="na">matchLabels</span><span class="pi">:</span>  <span class="c1">#Todos os Pods que tiverem a mesma label é esse deployment que vai cuidar</span>
      <span class="na">app</span><span class="pi">:</span> <span class="s">app-sre</span>
  <span class="na">strategy</span><span class="pi">:</span>     <span class="c1">#Estrategias de deployment</span>
      <span class="na">type</span><span class="pi">:</span> <span class="s">RollingUpdate</span>  <span class="c1">#Estrategia de atualização</span>
      <span class="na">rollingUpdate</span><span class="pi">:</span>
          <span class="na">maxSurge</span><span class="pi">:</span> <span class="m">1</span>     <span class="c1"># Pode ter até 1 pod a mais do que eu pedi</span>
          <span class="na">maxUnavailable</span><span class="pi">:</span> <span class="m">2</span>  <span class="c1">#Vai atualizar de 2 em 2</span>
  <span class="na">template</span><span class="pi">:</span>       <span class="c1">#Template criado para o POD</span>
    <span class="na">metadata</span><span class="pi">:</span>
      <span class="na">labels</span><span class="pi">:</span>
        <span class="na">app</span><span class="pi">:</span> <span class="s">app-sre</span>
    <span class="na">spec</span><span class="pi">:</span>          <span class="c1"># Caracteristica agora do meu POD/Container</span>
      <span class="na">containers</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">image</span><span class="pi">:</span> <span class="s">thallysonyakko/desafiosre:1.0</span>
        <span class="na">env</span><span class="pi">:</span>                     <span class="c1">#Variaveis de ambiente DB-postgres</span>
        <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">POSTGRES_PASSWORD</span>
          <span class="na">valueFrom</span><span class="pi">:</span>
            <span class="na">secretKeyRef</span><span class="pi">:</span>
              <span class="na">name</span><span class="pi">:</span> <span class="s">postgres-secret</span>         <span class="c1">#Nome do postgres-secret</span>
              <span class="na">key</span><span class="pi">:</span> <span class="s">POSTGRES_PASSWORD</span>
        <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">POSTGRESS_DB</span>
          <span class="na">valueFrom</span><span class="pi">:</span>
            <span class="na">secretKeyRef</span><span class="pi">:</span>
              <span class="na">name</span><span class="pi">:</span> <span class="s">postgres-secret</span>         <span class="c1">#Nome do postgres-secret</span>
              <span class="na">key</span><span class="pi">:</span> <span class="s">POSTGRES_DB</span>
        <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">POSTGRESS_USER</span>
          <span class="na">valueFrom</span><span class="pi">:</span>
            <span class="na">secretKeyRef</span><span class="pi">:</span>
              <span class="na">name</span><span class="pi">:</span> <span class="s">postgres-secret</span>         <span class="c1">#Nome do postgres-secret</span>
              <span class="na">key</span><span class="pi">:</span> <span class="s">POSTGRES_USER</span>
        <span class="na">name</span><span class="pi">:</span> <span class="s">app-sre</span>
        <span class="na">resources</span><span class="pi">:</span>     <span class="c1">#Resources do meu POD e seus limits</span>
            <span class="na">limits</span><span class="pi">:</span>
              <span class="na">cpu</span><span class="pi">:</span> <span class="s2">"</span><span class="s">0.8"</span>
              <span class="na">memory</span><span class="pi">:</span> <span class="s2">"</span><span class="s">256Mi"</span>
            <span class="na">requests</span><span class="pi">:</span>
              <span class="na">cpu</span><span class="pi">:</span> <span class="s2">"</span><span class="s">0.3"</span>
              <span class="na">memory</span><span class="pi">:</span> <span class="s2">"</span><span class="s">64Mi"</span>
        <span class="na">livenessProbe</span><span class="pi">:</span>       <span class="c1"># Tipo de helthcheck</span>
          <span class="na">httpGet</span><span class="pi">:</span>
            <span class="na">path</span><span class="pi">:</span> <span class="s">/</span>          <span class="c1">#Pasta raiz</span>
            <span class="na">port</span><span class="pi">:</span> <span class="m">5000</span>
          <span class="na">initialDelaySeconds</span><span class="pi">:</span> <span class="m">10</span>    <span class="c1">#Tempo que vai esperar até testar a primeira probes</span>
          <span class="na">periodSeconds</span><span class="pi">:</span> <span class="m">10</span>     <span class="c1"># De quanto em quanto tempo ele vai testar</span>
          <span class="na">timeoutSeconds</span><span class="pi">:</span> <span class="m">5</span>
          <span class="na">failureThreshold</span><span class="pi">:</span> <span class="m">3</span>    <span class="c1"># Após 3 vezes ele vai tentar restartar o POD</span>


</pre></td></tr></tbody></table></code></pre></div></div>

<p>Comando aplicado:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>kubectl apply <span class="nt">-f</span> app-deployment.yaml <span class="nt">-n</span> desafio-sre
</pre></td></tr></tbody></table></code></pre></div></div>

<h1 id="aplicação---service">Aplicação - Service</h1>

<p>Arquivo: <code class="language-plaintext highlighter-rouge">app-service.yaml</code></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="rouge-code"><pre><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Service</span>
<span class="na">metadata</span><span class="pi">:</span>
  <span class="na">name</span><span class="pi">:</span> <span class="s">app-sre</span>
  <span class="na">namespace</span><span class="pi">:</span> <span class="s">desafio-sre</span>
  <span class="na">labels</span><span class="pi">:</span>
    <span class="na">app</span><span class="pi">:</span> <span class="s">app-sre</span>
    <span class="na">env</span><span class="pi">:</span> <span class="s">dev</span>
<span class="na">spec</span><span class="pi">:</span>
  <span class="na">selector</span><span class="pi">:</span>       <span class="c1">#Quais pods vão ser expostos</span>
    <span class="na">app</span><span class="pi">:</span> <span class="s">app-sre</span>    <span class="c1">#Seleciona os Pods com essa label</span>
  <span class="na">ports</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="na">port</span><span class="pi">:</span> <span class="m">5000</span>      <span class="c1">#Porta do serviço</span>
    <span class="na">name</span><span class="pi">:</span> <span class="s">http</span>
    <span class="na">targetPort</span><span class="pi">:</span> <span class="m">5000</span>   <span class="c1">#A porta onde o cluster tá escutando</span>
  <span class="na">type</span><span class="pi">:</span> <span class="s">ClusterIP</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>kubectl apply <span class="nt">-f</span> app-service.yaml <span class="nt">-n</span> desafio-sre
</pre></td></tr></tbody></table></code></pre></div></div>

<hr />
<h1 id="redis---deploy-service-e-secret">Redis - Deploy, Service e Secret:</h1>

<p>Arquivo: <code class="language-plaintext highlighter-rouge">redis-deployment.yaml</code></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
</pre></td><td class="rouge-code"><pre><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">apps/v1</span>    <span class="c1">#Sempre vai ser apps/v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Deployment</span>         <span class="c1">#Tipo do manisfesto</span>
<span class="na">metadata</span><span class="pi">:</span>
  <span class="na">labels</span><span class="pi">:</span>
    <span class="na">app</span><span class="pi">:</span> <span class="s">redis</span>
  <span class="na">name</span><span class="pi">:</span> <span class="s">redis</span>
  <span class="na">namespace</span><span class="pi">:</span> <span class="s">desafio-sre</span>
<span class="na">spec</span><span class="pi">:</span>             <span class="c1">#caracteristicas do deployment</span>
  <span class="na">replicas</span><span class="pi">:</span> <span class="m">2</span>
  <span class="na">selector</span><span class="pi">:</span>       <span class="c1">#Controla os Pods referentes a essa aplicação</span>
    <span class="na">matchLabels</span><span class="pi">:</span>  <span class="c1">#Todos os Pods que tiverem a mesma label é esse deployment que vai cuidar</span>
      <span class="na">app</span><span class="pi">:</span> <span class="s">redis</span>
  <span class="na">strategy</span><span class="pi">:</span>     <span class="c1">#Estrategias de deployment</span>
      <span class="na">type</span><span class="pi">:</span> <span class="s">RollingUpdate</span>  <span class="c1">#Estrategia de atualização</span>
      <span class="na">rollingUpdate</span><span class="pi">:</span>
          <span class="na">maxSurge</span><span class="pi">:</span> <span class="m">1</span>     <span class="c1"># Pode ter até 1 pod a mais do que eu pedi</span>
          <span class="na">maxUnavailable</span><span class="pi">:</span> <span class="m">1</span>  <span class="c1">#Vai atualizar de 2 em 2</span>
  <span class="na">template</span><span class="pi">:</span>       <span class="c1">#Template criado para o POD</span>
    <span class="na">metadata</span><span class="pi">:</span>
      <span class="na">labels</span><span class="pi">:</span>
        <span class="na">app</span><span class="pi">:</span> <span class="s">redis</span>
    <span class="na">spec</span><span class="pi">:</span>          <span class="c1"># Caracteristica agora do meu POD/Container</span>
      <span class="na">containers</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">image</span><span class="pi">:</span> <span class="s">redis:7</span>
        <span class="na">name</span><span class="pi">:</span> <span class="s">redis</span>
        <span class="na">resources</span><span class="pi">:</span>     <span class="c1">#Resources do meu POD e seus limits</span>
            <span class="na">limits</span><span class="pi">:</span>
              <span class="na">cpu</span><span class="pi">:</span> <span class="s2">"</span><span class="s">0.8"</span>
              <span class="na">memory</span><span class="pi">:</span> <span class="s2">"</span><span class="s">500Mi"</span>
            <span class="na">requests</span><span class="pi">:</span>
              <span class="na">cpu</span><span class="pi">:</span> <span class="s2">"</span><span class="s">0.3"</span>
              <span class="na">memory</span><span class="pi">:</span> <span class="s2">"</span><span class="s">256Mi"</span>

</pre></td></tr></tbody></table></code></pre></div></div>

<p>Arquivo: <code class="language-plaintext highlighter-rouge">redis-secret.yaml</code></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
</pre></td><td class="rouge-code"><pre><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Secret</span>
<span class="na">metadata</span><span class="pi">:</span>
  <span class="na">name</span><span class="pi">:</span> <span class="s">redis-secret</span>
  <span class="na">namespace</span><span class="pi">:</span> <span class="s">desafio-sre</span>
<span class="na">type</span><span class="pi">:</span> <span class="s">Opaque</span>
<span class="na">data</span><span class="pi">:</span>
  <span class="na">redis-password</span><span class="pi">:</span> <span class="s">ZGVzYWZpb2VsdmVu</span>       <span class="c1"># "desafioelven"</span>

</pre></td></tr></tbody></table></code></pre></div></div>

<p>Arquivo: <code class="language-plaintext highlighter-rouge">redis-service.yaml</code></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="rouge-code"><pre><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Service</span>
<span class="na">metadata</span><span class="pi">:</span>
  <span class="na">name</span><span class="pi">:</span> <span class="s">redis-service</span>
  <span class="na">namespace</span><span class="pi">:</span> <span class="s">desafio-sre</span>
  <span class="na">labels</span><span class="pi">:</span>
    <span class="na">app</span><span class="pi">:</span> <span class="s">redis</span>
    <span class="na">env</span><span class="pi">:</span> <span class="s">dev</span>
<span class="na">spec</span><span class="pi">:</span>
  <span class="na">selector</span><span class="pi">:</span>       <span class="c1">#Quais pods vão ser expostos</span>
    <span class="na">app</span><span class="pi">:</span> <span class="s">redis</span>   <span class="c1">#Seleciona os Pods com essa label</span>
  <span class="na">ports</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="na">port</span><span class="pi">:</span> <span class="m">6379</span>      <span class="c1">#Porta do serviço</span>
    <span class="na">name</span><span class="pi">:</span> <span class="s">http</span>
    <span class="na">targetPort</span><span class="pi">:</span> <span class="m">6379</span>   <span class="c1">#A porta onde o cluster tá escutando</span>
  <span class="na">type</span><span class="pi">:</span> <span class="s">ClusterIP</span>

</pre></td></tr></tbody></table></code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>kubectl apply <span class="nt">-f</span> ./REDIS <span class="nt">-n</span> desafio-sre
</pre></td></tr></tbody></table></code></pre></div></div>

<h1 id="problemas-enfrentados">Problemas enfrentados:</h1>

<h3 id="yaml-com-erro-de-indentação">YAML com erro de indentação</h3>

<p><code class="language-plaintext highlighter-rouge">yaml: line 25: mapping values are not allowed in this context</code></p>

<p>Ajustei o <code class="language-plaintext highlighter-rouge">redis-deployment.yaml</code>.</p>

<hr />

<p>Service sem nome (“resource name may not be empty”)</p>

<p>Corrigido para:</p>

<p><code class="language-plaintext highlighter-rouge">metadata:   name: redis-service</code></p>

<hr />
<h1 id="postgres">Postgres</h1>

<p>Arquivo: <code class="language-plaintext highlighter-rouge">postgres-deployment.yaml</code></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
</pre></td><td class="rouge-code"><pre><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">apps/v1</span>    <span class="c1">#Sempre vai ser apps/v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Deployment</span>         <span class="c1">#Tipo do manisfesto</span>
<span class="na">metadata</span><span class="pi">:</span>
  <span class="na">labels</span><span class="pi">:</span>
    <span class="na">app</span><span class="pi">:</span> <span class="s">postgres</span>
  <span class="na">name</span><span class="pi">:</span> <span class="s">postgres</span>
  <span class="na">namespace</span><span class="pi">:</span> <span class="s">desafio-sre</span>
<span class="na">spec</span><span class="pi">:</span>             <span class="c1">#caracteristicas do deployment</span>
  <span class="na">replicas</span><span class="pi">:</span> <span class="m">2</span>
  <span class="na">selector</span><span class="pi">:</span>       <span class="c1">#Controla os Pods referentes a essa aplicação</span>
    <span class="na">matchLabels</span><span class="pi">:</span>  <span class="c1">#Todos os Pods que tiverem a mesma label é esse deployment que vai cuidar</span>
      <span class="na">app</span><span class="pi">:</span> <span class="s">postgres</span>
  <span class="na">strategy</span><span class="pi">:</span>     <span class="c1">#Estrategias de deployment</span>
      <span class="na">type</span><span class="pi">:</span> <span class="s">RollingUpdate</span>  <span class="c1">#Estrategia de atualização</span>
      <span class="na">rollingUpdate</span><span class="pi">:</span>
          <span class="na">maxSurge</span><span class="pi">:</span> <span class="m">1</span>     <span class="c1"># Pode ter até 1 pod a mais do que eu pedi</span>
          <span class="na">maxUnavailable</span><span class="pi">:</span> <span class="m">1</span>  <span class="c1">#Vai atualizar de 2 em 2</span>
  <span class="na">template</span><span class="pi">:</span>       <span class="c1">#Template criado para o POD</span>
    <span class="na">metadata</span><span class="pi">:</span>
      <span class="na">labels</span><span class="pi">:</span>
        <span class="na">app</span><span class="pi">:</span> <span class="s">postgres</span>
    <span class="na">spec</span><span class="pi">:</span>          <span class="c1"># Caracteristica agora do meu POD/Container</span>
      <span class="na">containers</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">image</span><span class="pi">:</span> <span class="s">postgres:15</span>
        <span class="na">name</span><span class="pi">:</span> <span class="s">postgres</span>
        <span class="na">envFrom</span><span class="pi">:</span>
          <span class="pi">-</span> <span class="na">secretRef</span><span class="pi">:</span>
              <span class="na">name</span><span class="pi">:</span> <span class="s">postgres-secret</span>
        <span class="na">resources</span><span class="pi">:</span>     <span class="c1">#Resources do meu POD e seus limits</span>
            <span class="na">limits</span><span class="pi">:</span>
              <span class="na">cpu</span><span class="pi">:</span> <span class="s2">"</span><span class="s">0.8"</span>
              <span class="na">memory</span><span class="pi">:</span> <span class="s2">"</span><span class="s">500Mi"</span>
            <span class="na">requests</span><span class="pi">:</span>
              <span class="na">cpu</span><span class="pi">:</span> <span class="s2">"</span><span class="s">0.3"</span>
              <span class="na">memory</span><span class="pi">:</span> <span class="s2">"</span><span class="s">256Mi"</span>

</pre></td></tr></tbody></table></code></pre></div></div>

<p>Arquivo: <code class="language-plaintext highlighter-rouge">postgres-secret.yaml</code></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="rouge-code"><pre><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Secret</span>
<span class="na">metadata</span><span class="pi">:</span>
  <span class="na">name</span><span class="pi">:</span> <span class="s">postgres-secret</span>
  <span class="na">namespace</span><span class="pi">:</span> <span class="s">desafio-sre</span>
<span class="na">type</span><span class="pi">:</span> <span class="s">Opaque</span>
<span class="na">data</span><span class="pi">:</span>
  <span class="na">POSTGRES_DB</span><span class="pi">:</span> <span class="s">ZGVzYWZpbw==</span>          <span class="c1"># desafio</span>
  <span class="na">POSTGRES_USER</span><span class="pi">:</span> <span class="s">cG9zdGdyZXM=</span>        <span class="c1"># postgres</span>
  <span class="na">POSTGRES_PASSWORD</span><span class="pi">:</span> <span class="s">MTIzNDU2</span>        <span class="c1"># 123456</span>
  <span class="na">POSTGRES_HOST</span><span class="pi">:</span> <span class="s">cG9zdGdyZXMtc2VydmljZQ==</span>   <span class="c1"># postgres-service</span>
  <span class="na">POSTGRES_PORT</span><span class="pi">:</span> <span class="s">NTQzMg==</span>            <span class="c1"># 5432</span>

</pre></td></tr></tbody></table></code></pre></div></div>

<p>Arquivo: <code class="language-plaintext highlighter-rouge">postgres-service.yaml</code></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="rouge-code"><pre>
<span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Service</span>
<span class="na">metadata</span><span class="pi">:</span>
  <span class="na">name</span><span class="pi">:</span> <span class="s">postgres-service</span>
  <span class="na">namespace</span><span class="pi">:</span> <span class="s">desafio-sre</span>
  <span class="na">labels</span><span class="pi">:</span>
    <span class="na">app</span><span class="pi">:</span> <span class="s">postgres</span>
    <span class="na">env</span><span class="pi">:</span> <span class="s">dev</span>
<span class="na">spec</span><span class="pi">:</span>
  <span class="na">selector</span><span class="pi">:</span>       <span class="c1">#Quais pods vão ser expostos</span>
    <span class="na">app</span><span class="pi">:</span> <span class="s">postgres</span>   <span class="c1">#Seleciona os Pods com essa label</span>
  <span class="na">ports</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="na">port</span><span class="pi">:</span> <span class="m">5432</span>      <span class="c1">#Porta do serviço</span>
    <span class="na">name</span><span class="pi">:</span> <span class="s">http</span>
    <span class="na">targetPort</span><span class="pi">:</span> <span class="m">5432</span>   <span class="c1">#A porta onde o cluster tá escutando</span>
  <span class="na">type</span><span class="pi">:</span> <span class="s">ClusterIP</span>

</pre></td></tr></tbody></table></code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>kubectl apply <span class="nt">-f</span> ./POSTGRES <span class="nt">-n</span> desafio-sre
</pre></td></tr></tbody></table></code></pre></div></div>

<h1 id="conferência-dos-pods">Conferência dos Pods</h1>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>kubectl get pods <span class="nt">-A</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p><img src="./assets/2025-12-24-desafio-sre/2.png" alt="Pods" /></p>

<hr />

<h1 id="configurando-o-ingress-no-cluster">Configurando o Ingress no cluster</h1>

<ol>
  <li>Crie um arquivo chamado <code class="language-plaintext highlighter-rouge">kind-config.yaml</code> com o conteúdo abaixo:</li>
</ol>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="rouge-code"><pre><span class="na">kind</span><span class="pi">:</span> <span class="s">Cluster</span>
<span class="na">apiVersion</span><span class="pi">:</span> <span class="s">kind.x-k8s.io/v1alpha4</span>
<span class="na">nodes</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">role</span><span class="pi">:</span> <span class="s">control-plane</span>
  <span class="na">kubeadmConfigPatches</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="pi">|</span>
    <span class="s">kind: InitConfiguration</span>
    <span class="s">nodeRegistration:</span>
      <span class="s">kubeletExtraArgs:</span>
        <span class="s">node-labels: "ingress-ready=true"</span>
  <span class="na">extraPortMappings</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="na">containerPort</span><span class="pi">:</span> <span class="m">80</span>
    <span class="na">hostPort</span><span class="pi">:</span> <span class="m">80</span>
    <span class="na">protocol</span><span class="pi">:</span> <span class="s">TCP</span>
  <span class="pi">-</span> <span class="na">containerPort</span><span class="pi">:</span> <span class="m">443</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<ol>
  <li>Em seguida, crie o cluster usando este arquivo de configuração:</li>
</ol>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>kind create cluster <span class="nt">--config</span> kind-config.yaml
</pre></td></tr></tbody></table></code></pre></div></div>

<h1 id="instalando-o-ingress-nginx-controller">Instalando o Ingress Nginx Controller</h1>

<ol>
  <li>Instalação:</li>
</ol>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre>kubectl apply <span class="nt">-f</span> https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/kind/deploy.yaml

</pre></td></tr></tbody></table></code></pre></div></div>

<ol>
  <li>Aguarda os pods ficarem prontos:</li>
</ol>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
</pre></td><td class="rouge-code"><pre>kubectl <span class="nb">wait</span> <span class="nt">--namespace</span> ingress-nginx <span class="se">\</span>
<span class="nt">--for</span><span class="o">=</span><span class="nv">condition</span><span class="o">=</span>ready pod <span class="se">\</span>
<span class="nt">--selector</span><span class="o">=</span>app.kubernetes.io/component<span class="o">=</span>controller <span class="se">\</span>
<span class="nt">--timeout</span><span class="o">=</span>90s
</pre></td></tr></tbody></table></code></pre></div></div>

<h1 id="criando-a-primeira-regra-de-ingress">Criando a primeira regra de Ingress:</h1>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
</pre></td><td class="rouge-code"><pre><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">networking.k8s.io/v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Ingress</span>
<span class="na">metadata</span><span class="pi">:</span>
  <span class="na">name</span><span class="pi">:</span> <span class="s">desafio-sre-ingress</span>
  <span class="na">namespace</span><span class="pi">:</span> <span class="s">desafio-sre</span>
  <span class="na">annotations</span><span class="pi">:</span>
    <span class="na">nginx.ingress.kubernetes.io/rewrite-target</span><span class="pi">:</span> <span class="s">/</span>        <span class="c1">#Rewrite= Rescreva, idenpendente do que for passado ele vai redirecionar para o /</span>
<span class="na">spec</span><span class="pi">:</span>
  <span class="na">rules</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="na">host</span><span class="pi">:</span> <span class="s">app.elven.works</span><span class="err">							</span><span class="s">#Criando um dns na minha maquina, preciso modificar no /etc/hosts para passar esse "dominio" par o meu local hostt</span>
    <span class="na">http</span><span class="pi">:</span>
      <span class="na">paths</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">path</span><span class="pi">:</span> <span class="s">/</span>
        <span class="na">pathType</span><span class="pi">:</span> <span class="s">Prefix</span>
        <span class="na">backend</span><span class="pi">:</span>
          <span class="na">service</span><span class="pi">:</span>
            <span class="na">name</span><span class="pi">:</span> <span class="s">app-sre</span>
            <span class="na">port</span><span class="pi">:</span>
              <span class="na">number</span><span class="pi">:</span> <span class="m">5000</span>
<span class="nn">---</span>
<span class="c1">#---------</span>
<span class="na">apiVersion</span><span class="pi">:</span> <span class="s">networking.k8s.io/v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Ingress</span>
<span class="na">metadata</span><span class="pi">:</span>
  <span class="na">name</span><span class="pi">:</span> <span class="s">monitoring-ingress</span>
  <span class="na">namespace</span><span class="pi">:</span> <span class="s">monitoring</span>
<span class="na">spec</span><span class="pi">:</span>
  <span class="na">rules</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="na">host</span><span class="pi">:</span> <span class="s">grafana.elven.works</span>
    <span class="na">http</span><span class="pi">:</span>
      <span class="na">paths</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">path</span><span class="pi">:</span> <span class="s">/</span>
        <span class="na">pathType</span><span class="pi">:</span> <span class="s">Prefix</span>
        <span class="na">backend</span><span class="pi">:</span>
          <span class="na">service</span><span class="pi">:</span>
            <span class="na">name</span><span class="pi">:</span> <span class="s">prometheus-stack-grafana</span>
            <span class="na">port</span><span class="pi">:</span>
              <span class="na">number</span><span class="pi">:</span> <span class="m">80</span>

  <span class="pi">-</span> <span class="na">host</span><span class="pi">:</span> <span class="s">prometheus.elven.works</span>
    <span class="na">http</span><span class="pi">:</span>
      <span class="na">paths</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">path</span><span class="pi">:</span> <span class="s">/</span>
        <span class="na">pathType</span><span class="pi">:</span> <span class="s">Prefix</span>
        <span class="na">backend</span><span class="pi">:</span>
          <span class="na">service</span><span class="pi">:</span>
            <span class="na">name</span><span class="pi">:</span> <span class="s">prometheus-stack-kube-prom-prometheus</span>
            <span class="na">port</span><span class="pi">:</span>
              <span class="na">number</span><span class="pi">:</span> <span class="m">9090</span>

</pre></td></tr></tbody></table></code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>kubectl apply <span class="nt">-f</span> ingress.yaml
</pre></td></tr></tbody></table></code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>kubectl get ingress
</pre></td></tr></tbody></table></code></pre></div></div>

<p><img src="./assets/2025-12-24-desafio-sre/3.png" alt="Ingress" /></p>

<h1 id="teste-do-ingress">Teste do Ingress:</h1>

<ol>
  <li>
    <p>Via Navegador:</p>

    <p><img src="./assets/2025-12-24-desafio-sre/4.png" alt="Navegador" /></p>
  </li>
  <li>
    <p>Via CLI:</p>
  </li>
</ol>

<p><img src="./assets/2025-12-24-desafio-sre/5.png" alt="NCLI" /></p>

<hr />

<h1 id="instalação-do-prometheus-via-helm">Instalação do Prometheus via Helm:</h1>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre>helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
</pre></td></tr></tbody></table></code></pre></div></div>

<ol>
  <li>Criando o namespace:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>kubectl create namespace monitoring
</pre></td></tr></tbody></table></code></pre></div>    </div>
  </li>
  <li>Instalando:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>helm <span class="nb">install </span>prometheus-stack prometheus-community/kube-prometheus-stack <span class="nt">-n</span> monitoring
</pre></td></tr></tbody></table></code></pre></div>    </div>
  </li>
  <li>Verificando:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>kubectl get pods <span class="nt">-n</span> monitoring
</pre></td></tr></tbody></table></code></pre></div>    </div>
  </li>
</ol>

<p><img src="./assets/2025-12-24-desafio-sre/6.png" alt="GetPods" /></p>

<h1 id="acessando-o-grafana-via-ingress">Acessando o Grafana via Ingress:</h1>

<ol>
  <li>
    <p>Navegador:
 <img src="./assets/2025-12-24-desafio-sre/7.png" alt="Navegador-2" /><code class="language-plaintext highlighter-rouge">url: grafana.elven.works</code></p>
  </li>
  <li>
    <p>Dashboards</p>
  </li>
</ol>

<p><img src="./assets/2025-12-24-desafio-sre/8.png" alt="Dashboard" /></p>

<ol>
  <li>Métricas do cluster:</li>
</ol>

<p><img src="./assets/2025-12-24-desafio-sre/9.png" alt="Dashboard" /></p>

<ol>
  <li>Secrets:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre>kubectl get secret prometheus-stack-grafana <span class="nt">-n</span> monitoring <span class="nt">-o</span> <span class="nv">jsonpath</span><span class="o">=</span><span class="s1">'{.data.admin-password}'</span> | <span class="nb">base64</span> <span class="nt">--decode</span>
</pre></td></tr></tbody></table></code></pre></div>    </div>
  </li>
  <li>Prometheus acesso via ingress:</li>
</ol>

<p><img src="./assets/2025-12-24-desafio-sre/10.png" alt="Ingress-Prometheus" />
<code class="language-plaintext highlighter-rouge">url:prometheus.elven.works</code></p>

<h1 id="criando-o-servicemonitor-da-aplicação">Criando o ServiceMonitor da aplicação:</h1>

<p>Arquivo: <code class="language-plaintext highlighter-rouge">app-sre-monitor.yaml</code></p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="rouge-code"><pre><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">monitoring.coreos.com/v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">ServiceMonitor</span>
<span class="na">metadata</span><span class="pi">:</span>
  <span class="na">name</span><span class="pi">:</span> <span class="s">app-sre-monitor</span>
  <span class="na">namespace</span><span class="pi">:</span> <span class="s">monitoring</span> <span class="c1"># O ServiceMonitor DEVE estar no mesmo namespace do Prometheus</span>
  <span class="na">labels</span><span class="pi">:</span>
    <span class="na">release</span><span class="pi">:</span> <span class="s">prometheus-stack</span> <span class="c1"># Importante: Selecionar o Prometheus Operator</span>
<span class="na">spec</span><span class="pi">:</span>
  <span class="na">namespaceSelector</span><span class="pi">:</span>
    <span class="na">matchNames</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">desafio-sre</span> <span class="c1"># O namespace onde sua aplicação está</span>
  <span class="na">selector</span><span class="pi">:</span>
    <span class="na">matchLabels</span><span class="pi">:</span>
      <span class="na">app</span><span class="pi">:</span> <span class="s">app-sre</span> <span class="c1"># Use o rótulo do seu Service (verifique o Service 'app-sre' para o rótulo correto)</span>
  <span class="na">endpoints</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="na">port</span><span class="pi">:</span> <span class="s">http-metrics</span> <span class="c1"># Nome da porta (deve ser definido no seu Service, veja nota abaixo)</span>
    <span class="na">path</span><span class="pi">:</span> <span class="s">/metrics</span>       <span class="c1"># O caminho onde as métricas estão (ex: /metrics ou /actuator/prometheus)</span>
    <span class="na">interval</span><span class="pi">:</span> <span class="s">30s</span>        <span class="c1"># Frequência de coleta (opcional)</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre>kubectl apply <span class="nt">-f</span> app-sre-monitor.yaml

</pre></td></tr></tbody></table></code></pre></div></div>

<h1 id="criando-o-prometheusrule">Criando o PrometheusRule:</h1>

<p>Arquivo: <code class="language-plaintext highlighter-rouge">prometheus-gold-rules.yaml</code></p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
</pre></td><td class="rouge-code"><pre>apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: application-gold-alerts
  namespace: monitoring <span class="c"># Altere se seu PrometheusRule estiver em outro namespace</span>
  labels:
    prometheus: k8s
    role: alert-rules
    app.kubernetes.io/name: application-gold
spec:
  <span class="nb">groups</span>:

    <span class="c"># ----------------------------------------------------</span>
    <span class="c"># GRUPO 1: REGRAS GOLD PARA APLICAÇÃO FLASK (flask-app)</span>
    <span class="c"># ----------------------------------------------------</span>
    - name: flask.gold.alerts
      rules:

      <span class="c"># [G/D] - Get/Duration: Alta Taxa de Erros (5xx)</span>
      - alert: FlaskHighErrorRate
        <span class="nb">expr</span>: |
          <span class="nb">sum</span><span class="o">(</span>rate<span class="o">(</span>http_requests_total<span class="o">{</span><span class="nv">job</span><span class="o">=</span><span class="s2">"flask-app"</span>, <span class="nv">code</span><span class="o">=</span>~<span class="s2">"5xx"</span><span class="o">}[</span>5m]<span class="o">))</span>
          /
          <span class="nb">sum</span><span class="o">(</span>rate<span class="o">(</span>http_requests_total<span class="o">{</span><span class="nv">job</span><span class="o">=</span><span class="s2">"flask-app"</span><span class="o">}[</span>5m]<span class="o">))</span>
          <span class="o">&gt;</span> 0.05 <span class="c"># Mais de 5% de erros de servidor</span>
        <span class="k">for</span>: 3m
        labels:
          severity: critical
        annotations:
          summary: <span class="s2">"Flask: Taxa de Erros 5xx Acima do Limite ({{ </span><span class="nv">$value</span><span class="s2"> | printf </span><span class="se">\"</span><span class="s2">%.2f%%</span><span class="se">\"</span><span class="s2"> }})"</span>
          description: <span class="s2">"Mais de 5% das requisições resultaram em erro de servidor nas últimas 3 minutos."</span>

      <span class="c"># [O] - Output: Alta Latência P95</span>
      - alert: FlaskHighLatencyP95
        <span class="nb">expr</span>: |
          histogram_quantile<span class="o">(</span>0.95, <span class="nb">sum</span><span class="o">(</span>rate<span class="o">(</span>http_request_duration_seconds_bucket<span class="o">{</span><span class="nv">job</span><span class="o">=</span><span class="s2">"flask-app"</span><span class="o">}[</span>5m]<span class="o">))</span> by <span class="o">(</span>le<span class="o">))</span>
          <span class="o">&gt;</span> 0.8 <span class="c"># Latência P95 acima de 800ms</span>
        <span class="k">for</span>: 5m
        labels:
          severity: warning
        annotations:
          summary: <span class="s2">"Flask: Latência P95 Acima do Limite ({{ </span><span class="nv">$value</span><span class="s2"> | printf </span><span class="se">\"</span><span class="s2">%.3f</span><span class="se">\"</span><span class="s2"> }}s)"</span>
          description: <span class="s2">"O 95º percentil de requisições está lento por 5 minutos, afetando a experiência do usuário."</span>

      <span class="c"># [L] - Load: Queda Súbita de Tráfego</span>
      - alert: FlaskTrafficDrop
        <span class="nb">expr</span>: |
          <span class="nb">sum</span><span class="o">(</span>rate<span class="o">(</span>http_requests_total<span class="o">{</span><span class="nv">job</span><span class="o">=</span><span class="s2">"flask-app"</span><span class="o">}[</span>5m]<span class="o">))</span>
          &lt;
          <span class="o">(</span>
            <span class="nb">sum</span><span class="o">(</span>rate<span class="o">(</span>http_requests_total<span class="o">{</span><span class="nv">job</span><span class="o">=</span><span class="s2">"flask-app"</span><span class="o">}[</span>30m] offset 5m<span class="o">))</span>
            <span class="k">*</span> 0.2
          <span class="o">)</span>
        <span class="k">for</span>: 5m
        labels:
          severity: warning
        annotations:
          summary: <span class="s2">"Flask: Queda Súbita de Tráfego"</span>
          description: <span class="s2">"O RPS caiu mais de 80% em comparação com os 30 minutos anteriores. Pode indicar uma falha de serviço ou de coleta de métricas."</span>

    <span class="c"># ----------------------------------------------------</span>
    <span class="c"># GRUPO 2: REGRAS GOLD PARA REDIS (redis-exporter)</span>
    <span class="c"># ----------------------------------------------------</span>
    - name: redis.gold.alerts
      rules:

      <span class="c"># [G] - Get: Verificação de Saúde (up)</span>
      - alert: RedisDown
        <span class="nb">expr</span>: up<span class="o">{</span><span class="nv">job</span><span class="o">=</span><span class="s2">"redis"</span><span class="o">}</span> <span class="o">==</span> 0
        <span class="k">for</span>: 1m
        labels:
          severity: critical
        annotations:
          summary: <span class="s2">"Redis: Serviço Inativo"</span>
          description: <span class="s2">"O Prometheus não consegue raspar (scrape) o exporter do Redis por mais de 1 minuto. Instância: {{ </span><span class="nv">$labels</span><span class="s2">.instance }}"</span>

      <span class="c"># [O] - Output: Alta Utilização de Memória (Overhead)</span>
      - alert: RedisMemoryHigh
        <span class="nb">expr</span>: redis_memory_used_bytes<span class="o">{</span><span class="nv">job</span><span class="o">=</span><span class="s2">"redis"</span><span class="o">}</span> / redis_total_system_memory_bytes<span class="o">{</span><span class="nv">job</span><span class="o">=</span><span class="s2">"redis"</span><span class="o">}</span> <span class="o">&gt;</span> 0.85
        <span class="k">for</span>: 10m
        labels:
          severity: warning
        annotations:
          summary: <span class="s2">"Redis: Memória Utilizada Excedeu 85%"</span>
          description: <span class="s2">"O Redis está próximo de atingir o limite de memória. Valor atual: {{ </span><span class="nv">$value</span><span class="s2"> | humanizePercentage }}"</span>

    <span class="c"># ----------------------------------------------------</span>
    <span class="c"># GRUPO 3: REGRAS GOLD PARA POSTGRESQL (postgres-exporter)</span>
    <span class="c"># ----------------------------------------------------</span>
    - name: postgres.gold.alerts
      rules:

      <span class="c"># [G] - Get: Verificação de Saúde (up)</span>
      - alert: PostgresDown
        <span class="nb">expr</span>: up<span class="o">{</span><span class="nv">job</span><span class="o">=</span><span class="s2">"postgres"</span><span class="o">}</span> <span class="o">==</span> 0
        <span class="k">for</span>: 1m
        labels:
          severity: critical
        annotations:
          summary: <span class="s2">"PostgreSQL: Serviço Inativo"</span>
          description: <span class="s2">"O Prometheus não consegue raspar (scrape) o exporter do PostgreSQL por mais de 1 minuto. Instância: {{ </span><span class="nv">$labels</span><span class="s2">.instance }}"</span>

      <span class="c"># [D] - Duration/Details: Bloqueios no Banco de Dados (Deadlocks)</span>
      - alert: PostgresDeadlocks
        <span class="nb">expr</span>: rate<span class="o">(</span>pg_stat_database_deadlocks<span class="o">{</span><span class="nv">job</span><span class="o">=</span><span class="s2">"postgres"</span><span class="o">}[</span>5m]<span class="o">)</span> <span class="o">&gt;</span> 0
        <span class="k">for</span>: 2m
        labels:
          severity: critical
        annotations:
          summary: <span class="s2">"PostgreSQL: Deadlocks Detectados"</span>
          description: <span class="s2">"Foram detectados deadlocks no banco de dados nas últimas 5 minutos. Isso requer atenção imediata."</span>

      <span class="c"># [L] - Load: Muitas Conexões Ativas (Pode causar esgotamento de recursos)</span>
      - alert: PostgresTooManyConnections
        <span class="nb">expr</span>: pg_stat_activity_count<span class="o">{</span><span class="nv">datname</span><span class="o">=</span><span class="s2">"mydatabase"</span><span class="o">}</span> <span class="o">&gt;</span> 100 <span class="c"># Exemplo: mais de 100 conexões ativas</span>
        <span class="k">for</span>: 5m
        labels:
          severity: warning
        annotations:
          summary: <span class="s2">"PostgreSQL: Excesso de Conexões"</span>
          description: <span class="s2">"O banco de dados 'mydatabase' tem mais de 100 conexões ativas. Valor: {{ </span><span class="nv">$value</span><span class="s2"> }}. Revise o pool de conexões da aplicação."</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre>kubectl apply <span class="nt">-f</span> prometheus-gold-rules.yaml <span class="nt">-n</span> monitoring

</pre></td></tr></tbody></table></code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre>kubectl get prometheusrules <span class="nt">-n</span> monitoring

</pre></td></tr></tbody></table></code></pre></div></div>

<hr />
<p><sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup></p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>Esse foi o resultado da primeira semana do desafio em que tinha que ser desenvolvido:</p>

      <ul>
        <li>Rodar a aplicação na máquina</li>
        <li>Dockernizar essa aplicação e provisionar</li>
        <li>Provisionar a app usando o terraform local na maquina</li>
        <li>Usar kind para provisionar a mesma</li>
        <li>Monitorar o cluster local com prometheus + grafana (instalação via helm)</li>
      </ul>
      <p><a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;&#xfe0e;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Thallyson Yakko</name></author><category term="sre" /><category term="devops" /><category term="kubernetes" /><category term="docker" /><category term="terraform" /><category term="observabilidade" /><category term="sre" /><category term="devops" /><category term="kubernetes" /><category term="docker" /><category term="terraform" /><category term="prometheus" /><category term="grafana" /><summary type="html"><![CDATA[Contexto do Desafio]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://thallysonyakko.com.br/assets/2025-12-24-desafio-sre/kubetux.png" /><media:content medium="image" url="https://thallysonyakko.com.br/assets/2025-12-24-desafio-sre/kubetux.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Hands-On Terraform - Criando uma VPC</title><link href="https://thallysonyakko.com.br/posts/hands-on-terraform-criando-uma-vpc/" rel="alternate" type="text/html" title="Hands-On Terraform - Criando uma VPC" /><published>2025-08-05T00:00:00-03:00</published><updated>2025-08-05T00:00:00-03:00</updated><id>https://thallysonyakko.com.br/posts/hands-on-terraform-criando-uma-vpc</id><content type="html" xml:base="https://thallysonyakko.com.br/posts/hands-on-terraform-criando-uma-vpc/"><![CDATA[<h1 id="desafio-provisionando-uma-vpc-com-terraform">Desafio: Provisionando uma VPC com Terraform</h1>

<p>Esse desafio foi criar uma VPC completa usando Terraform, sem tocar no console da AWS. Trabalhei com subnets públicas e privadas, Internet Gateway, NAT Gateway e tabelas de rota, tudo via código.</p>

<hr />

<h2 id="pré-requisitos">Pré-requisitos</h2>

<p>Criar uma rede básica na AWS com os seguintes recursos:</p>

<ul>
  <li>1 VPC</li>
  <li>2 Subnets privadas</li>
  <li>2 Subnets públicas</li>
  <li>2 NAT Gateways</li>
  <li>1 Internet Gateway</li>
</ul>

<hr />

<h2 id="por-que-terraform">Por que Terraform?</h2>

<p>Já usei CloudFormation antes, mas o Terraform tem uma vantagem clara: funciona em qualquer provider. Com ele dá pra subir o mesmo ambiente várias vezes sem variação, e o state garante que você sempre sabe o que está rodando. Terraform Workspaces então facilitam muito quando precisa isolar ambientes do mesmo projeto.</p>

<hr />

<h2 id="como-foi-pensada-a-resolução-do-desafio">Como foi pensada a resolução do desafio</h2>

<p>Para deixar o código mais <strong>dinâmico e reutilizável</strong>, utilizei <strong>Built-in Functions</strong> e <strong>Meta-Arguments</strong>.</p>

<h3 id="o-que-são-built-in-functions">O que são Built-in Functions?</h3>

<p>O Terraform tem funções nativas que evitam repetição de lógica. As que usei aqui:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">cidrsubnet()</code> → calcula automaticamente o CIDR das subnets</li>
  <li><code class="language-plaintext highlighter-rouge">lower()</code> → transforma strings em minúsculas</li>
  <li><code class="language-plaintext highlighter-rouge">format()</code> → formata strings dinamicamente</li>
</ul>

<h3 id="o-que-são-meta-arguments">O que são Meta-Arguments?</h3>

<p>Meta-arguments controlam como os recursos se comportam. Os principais que usei:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">for_each</code> → cria múltiplos recursos a partir de listas ou mapas</li>
  <li><code class="language-plaintext highlighter-rouge">depends_on</code> → garante a ordem correta de criação de recursos</li>
</ul>

<hr />

<h2 id="resolução-e-criação-da-vpc">Resolução e criação da VPC</h2>
<p>A VPC é sua rede privada dentro da AWS. É nela que fica o CIDR, as subnets, as tabelas de rota. Basicamente a base de tudo.</p>

<h3 id="vpctf">vpc.tf</h3>

<div class="language-hcl highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
</pre></td><td class="rouge-code"><pre><span class="c1">// Criando VPC</span>
<span class="nx">resource</span> <span class="s2">"aws_vpc"</span> <span class="s2">"main"</span> <span class="p">{</span>
  <span class="nx">cidr_block</span> <span class="o">=</span> <span class="nx">var</span><span class="p">.</span><span class="nx">vpc_cidr_block</span>
  <span class="nx">tags</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">Name</span>        <span class="o">=</span> <span class="s2">"vpc-project-elven"</span>
    <span class="nx">terraformed</span> <span class="o">=</span> <span class="s2">"true"</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// Subnets Públicas</span>
<span class="nx">resource</span> <span class="s2">"aws_subnet"</span> <span class="s2">"public"</span> <span class="p">{</span>
  <span class="nx">for_each</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">for</span> <span class="nx">idx</span><span class="p">,</span> <span class="nx">name</span> <span class="nx">in</span> <span class="nx">local</span><span class="p">.</span><span class="nx">subnet_public</span> <span class="o">:</span> <span class="nx">idx</span> <span class="o">=&gt;</span> <span class="nx">name</span> <span class="p">}</span> <span class="c1"># Cria o recurso com base em uma lista</span>
  <span class="nx">vpc_id</span> <span class="o">=</span> <span class="nx">aws_vpc</span><span class="p">.</span><span class="nx">main</span><span class="p">.</span><span class="nx">id</span>
  <span class="nx">cidr_block</span> <span class="o">=</span> <span class="nx">cidrsubnet</span><span class="p">(</span><span class="nx">var</span><span class="p">.</span><span class="nx">vpc_cidr_block</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="nx">each</span><span class="p">.</span><span class="nx">key</span><span class="p">)</span> <span class="c1"># Calcula automaticamente o CIDR</span>
  <span class="nx">map_public_ip_on_launch</span> <span class="o">=</span> <span class="kc">true</span>

  <span class="nx">tags</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">Name</span> <span class="o">=</span> <span class="nx">lower</span><span class="p">(</span><span class="nx">format</span><span class="p">(</span><span class="s2">"subnet-%s"</span><span class="p">,</span> <span class="nx">each</span><span class="p">.</span><span class="nx">value</span><span class="p">))</span> <span class="c1"># Formata o nome da subnet</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// Subnets Privadas</span>
<span class="nx">resource</span> <span class="s2">"aws_subnet"</span> <span class="s2">"priv"</span> <span class="p">{</span>
  <span class="nx">for_each</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">for</span> <span class="nx">idx</span><span class="p">,</span> <span class="nx">name</span> <span class="nx">in</span> <span class="nx">local</span><span class="p">.</span><span class="nx">subnet_priv</span> <span class="o">:</span> <span class="nx">idx</span> <span class="o">=&gt;</span> <span class="nx">name</span> <span class="p">}</span>
  <span class="nx">vpc_id</span> <span class="o">=</span> <span class="nx">aws_vpc</span><span class="p">.</span><span class="nx">main</span><span class="p">.</span><span class="nx">id</span>
  <span class="nx">cidr_block</span> <span class="o">=</span> <span class="nx">cidrsubnet</span><span class="p">(</span><span class="nx">var</span><span class="p">.</span><span class="nx">vpc_cidr_block</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="nx">each</span><span class="p">.</span><span class="nx">key</span> <span class="o">+</span> <span class="nx">length</span><span class="p">(</span><span class="nx">local</span><span class="p">.</span><span class="nx">subnet_public</span><span class="p">))</span>
  <span class="nx">map_public_ip_on_launch</span> <span class="o">=</span> <span class="kc">false</span>

  <span class="nx">tags</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">Name</span> <span class="o">=</span> <span class="nx">lower</span><span class="p">(</span><span class="nx">format</span><span class="p">(</span><span class="s2">"subnet-%s"</span><span class="p">,</span> <span class="nx">each</span><span class="p">.</span><span class="nx">value</span><span class="p">))</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// Internet Gateway</span>
<span class="nx">resource</span> <span class="s2">"aws_internet_gateway"</span> <span class="s2">"igw"</span> <span class="p">{</span>
  <span class="nx">vpc_id</span> <span class="o">=</span> <span class="nx">aws_vpc</span><span class="p">.</span><span class="nx">main</span><span class="p">.</span><span class="nx">id</span>
  <span class="nx">tags</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">Name</span>        <span class="o">=</span> <span class="s2">"igw"</span>
    <span class="nx">terraformed</span> <span class="o">=</span> <span class="s2">"true"</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// Tabela de Rotas Públicas</span>
<span class="nx">resource</span> <span class="s2">"aws_route_table"</span> <span class="s2">"public"</span> <span class="p">{</span>
  <span class="nx">vpc_id</span> <span class="o">=</span> <span class="nx">aws_vpc</span><span class="p">.</span><span class="nx">main</span><span class="p">.</span><span class="nx">id</span>
<span class="p">}</span>

<span class="nx">resource</span> <span class="s2">"aws_route"</span> <span class="s2">"internet_access"</span> <span class="p">{</span>
  <span class="nx">route_table_id</span> <span class="o">=</span> <span class="nx">aws_route_table</span><span class="p">.</span><span class="nx">public</span><span class="p">.</span><span class="nx">id</span>
  <span class="nx">destination_cidr_block</span> <span class="o">=</span> <span class="s2">"0.0.0.0/0"</span>
  <span class="nx">gateway_id</span> <span class="o">=</span> <span class="nx">aws_internet_gateway</span><span class="p">.</span><span class="nx">igw</span><span class="p">.</span><span class="nx">id</span>
<span class="p">}</span>

<span class="nx">resource</span> <span class="s2">"aws_route_table_association"</span> <span class="s2">"public"</span> <span class="p">{</span>
  <span class="nx">for_each</span> <span class="o">=</span> <span class="nx">aws_subnet</span><span class="p">.</span><span class="nx">public</span> <span class="c1"># Associa cada subnet à tabela de rota</span>
  <span class="nx">subnet_id</span> <span class="o">=</span> <span class="nx">each</span><span class="p">.</span><span class="nx">value</span><span class="p">.</span><span class="nx">id</span>
  <span class="nx">route_table_id</span> <span class="o">=</span> <span class="nx">aws_route_table</span><span class="p">.</span><span class="nx">public</span><span class="p">.</span><span class="nx">id</span>
<span class="p">}</span>

<span class="c1">// EIP para NAT Gateways</span>
<span class="nx">resource</span> <span class="s2">"aws_eip"</span> <span class="s2">"nat"</span> <span class="p">{</span>
  <span class="nx">for_each</span> <span class="o">=</span> <span class="nx">aws_subnet</span><span class="p">.</span><span class="nx">public</span> <span class="c1"># Cria um EIP por subnet pública</span>
  <span class="nx">domain</span>   <span class="o">=</span> <span class="s2">"vpc"</span>
  <span class="nx">tags</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">Name</span>        <span class="o">=</span> <span class="s2">"nat-eip-${each.key}"</span>
    <span class="nx">terraformed</span> <span class="o">=</span> <span class="s2">"true"</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// NAT Gateway</span>
<span class="nx">resource</span> <span class="s2">"aws_nat_gateway"</span> <span class="s2">"ngw"</span> <span class="p">{</span>
  <span class="nx">for_each</span> <span class="o">=</span> <span class="nx">aws_subnet</span><span class="p">.</span><span class="nx">public</span>
  <span class="nx">subnet_id</span> <span class="o">=</span> <span class="nx">each</span><span class="p">.</span><span class="nx">value</span><span class="p">.</span><span class="nx">id</span>
  <span class="nx">allocation_id</span> <span class="o">=</span> <span class="nx">aws_eip</span><span class="p">.</span><span class="nx">nat</span><span class="p">[</span><span class="nx">each</span><span class="p">.</span><span class="nx">key</span><span class="p">].</span><span class="nx">id</span>

  <span class="nx">tags</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">Name</span>        <span class="o">=</span> <span class="s2">"nat-gw-${each.key}"</span>
    <span class="nx">terraformed</span> <span class="o">=</span> <span class="s2">"true"</span>
  <span class="p">}</span>

  <span class="nx">depends_on</span> <span class="o">=</span> <span class="p">[</span><span class="nx">aws_internet_gateway</span><span class="p">.</span><span class="nx">igw</span><span class="p">]</span> <span class="c1"># Garante que o IGW seja criado antes do NAT Gateway</span>
<span class="p">}</span>

<span class="c1">// Tabela de Rotas Privadas</span>
<span class="nx">resource</span> <span class="s2">"aws_route_table"</span> <span class="s2">"priv"</span> <span class="p">{</span>
  <span class="nx">for_each</span> <span class="o">=</span> <span class="nx">aws_subnet</span><span class="p">.</span><span class="nx">public</span>
  <span class="nx">vpc_id</span> <span class="o">=</span> <span class="nx">aws_vpc</span><span class="p">.</span><span class="nx">main</span><span class="p">.</span><span class="nx">id</span>
  <span class="nx">tags</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">Name</span>        <span class="o">=</span> <span class="s2">"rtb-priv-${each.key}"</span>
    <span class="nx">terraformed</span> <span class="o">=</span> <span class="s2">"true"</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// Rotas Privadas</span>
<span class="nx">resource</span> <span class="s2">"aws_route"</span> <span class="s2">"priv"</span> <span class="p">{</span>
  <span class="nx">for_each</span> <span class="o">=</span> <span class="nx">aws_route_table</span><span class="p">.</span><span class="nx">priv</span>
  <span class="nx">route_table_id</span> <span class="o">=</span> <span class="nx">each</span><span class="p">.</span><span class="nx">value</span><span class="p">.</span><span class="nx">id</span>
  <span class="nx">destination_cidr_block</span> <span class="o">=</span> <span class="s2">"0.0.0.0/0"</span>
  <span class="nx">nat_gateway_id</span> <span class="o">=</span> <span class="nx">aws_nat_gateway</span><span class="p">.</span><span class="nx">ngw</span><span class="p">[</span><span class="nx">each</span><span class="p">.</span><span class="nx">key</span><span class="p">].</span><span class="nx">id</span>
<span class="p">}</span>

<span class="c1">// Associações de Subnets Privadas às Tabelas de Rotas</span>
<span class="nx">resource</span> <span class="s2">"aws_route_table_association"</span> <span class="s2">"priv"</span> <span class="p">{</span>
  <span class="nx">for_each</span> <span class="o">=</span> <span class="nx">aws_subnet</span><span class="p">.</span><span class="nx">priv</span>
  <span class="nx">subnet_id</span> <span class="o">=</span> <span class="nx">each</span><span class="p">.</span><span class="nx">value</span><span class="p">.</span><span class="nx">id</span>
  <span class="nx">route_table_id</span> <span class="o">=</span> <span class="nx">aws_route_table</span><span class="p">.</span><span class="nx">priv</span><span class="p">[</span><span class="nx">each</span><span class="p">.</span><span class="nx">key</span> <span class="o">%</span> <span class="nx">length</span><span class="p">(</span><span class="nx">aws_nat_gateway</span><span class="p">.</span><span class="nx">ngw</span><span class="p">)].</span><span class="nx">id</span>
<span class="p">}</span>

</pre></td></tr></tbody></table></code></pre></div></div>
<hr />

<h2 id="criação-do-módulo-locals">Criação do módulo Locals</h2>

<p>Locals são variáveis internas do Terraform. Em vez de repetir as mesmas listas em vários recursos, centralizo tudo num lugar só.</p>

<p><em>locals.tf</em></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="rouge-code"><pre>locals {
  subnet_public = [
    "public-1a",
    "public-1c"
  ]

  subnet_priv = [
    "priv-1a",
    "priv-1c"
  ]
}

</pre></td></tr></tbody></table></code></pre></div></div>

<hr />

<h2 id="criação-das-variables">Criação das Variables</h2>

<p>Variables evitam que você fixe valores no código. Com elas dá pra subir ambientes diferentes sem mudar nada no Terraform, só passando os valores via <code class="language-plaintext highlighter-rouge">.tfvars</code> ou linha de comando.</p>

<p><em>variables.tf</em></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="rouge-code"><pre>variable "region" {
  description = "Região da AWS"
  default     = "us-east-1"
}

variable "vpc_cidr_block" {
  type        = string
  description = "Bloco CIDR /16 para VLSM"
  default     = "10.100.0.0/16"
}

variable "aws_subnet" {
  type        = number
  description = "Tamanho do bloco /24"
  default     = 24
}

</pre></td></tr></tbody></table></code></pre></div></div>

<hr />

<h2 id="criação-do-main">Criação do Main</h2>

<p>O main.tf é o ponto de entrada: aqui fica a definição do provider e a versão do Terraform. Os outros arquivos complementam, mas é o main que amarra tudo.</p>

<p><em>main.tf</em></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="rouge-code"><pre>// Definindo provedor
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~&gt; 5.0"
    }
  }
}

provider "aws" {
  region = var.region
}

</pre></td></tr></tbody></table></code></pre></div></div>

<h2 id="finalização-do-desafio">Finalização do Desafio</h2>

<p>Esse desafio faz parte do <strong>Programa SRE Advanced da Elvenworks</strong>.</p>

<ul>
  <li>Repositório oficial da Elven: <a href="https://github.com/Formacao-SRE/minha-primeira-vpc-com-terraform">Minha Primeira VPC com Terraform</a></li>
  <li>Meu repositório com o código deste desafio: <a href="https://gitlab.com/desafio-elven-programadeformacao/terraform-vpc">Terraform VPC no GitLab</a></li>
</ul>]]></content><author><name>Thallyson Yakko</name></author><category term="vpc" /><category term="aws" /><category term="terraform" /><category term="aws" /><category term="terraform" /><summary type="html"><![CDATA[Desafio: Provisionando uma VPC com Terraform]]></summary></entry><entry><title type="html">VPC em Subnet Pública</title><link href="https://thallysonyakko.com.br/posts/vpc-em-subnet-publica/" rel="alternate" type="text/html" title="VPC em Subnet Pública" /><published>2025-03-28T00:00:00-03:00</published><updated>2025-03-28T00:00:00-03:00</updated><id>https://thallysonyakko.com.br/posts/vpc-em-subnet-publica</id><content type="html" xml:base="https://thallysonyakko.com.br/posts/vpc-em-subnet-publica/"><![CDATA[<p>O intuito deste post é iniciar falando sobre VPC e desenvolver o projeto em futuras postagens. Primeiramente, criaremos uma instância em uma sub-rede pública para servir como bastion host de acesso a uma instância em uma sub-rede privada. Ao longo dos próximos posts, iremos detalhar mais sobre o projeto.</p>

<h2 id="serviços-utilizados">Serviços Utilizados</h2>
<ul>
  <li><strong>VPC (Virtual Private Cloud)</strong>: Rede isolada na AWS.</li>
  <li><strong>Internet Gateway (IGW)</strong>: Conecta sua VPC à internet.</li>
  <li><strong>Subnet</strong>: Subdivisão de uma VPC.</li>
  <li><strong>Tabela de Rotas</strong>: Define o tráfego dentro da VPC e para a internet.</li>
  <li><strong>EC2</strong>: Serviço da AWS para instâncias de máquinas virtuais.</li>
</ul>

<h2 id="cenário">Cenário</h2>

<p><img src="./assets/2025-03-28-vpc-em-subnet-publica/Captura de tela de 2025-03-28 17-26-13.png" alt="Cenario" /></p>
<ol>
  <li>Criar uma VPC.</li>
  <li>Criar um Internet Gateway e associá-lo à VPC.</li>
  <li>Criar uma subnet pública.</li>
  <li>Criar uma tabela de rotas.</li>
  <li>Associar a tabela de rotas à subnet.</li>
  <li>Criar uma instância EC2.</li>
  <li>Conectar-se à EC2 usando SSH.</li>
</ol>

<h2 id="passo-1-criando-a-vpc">Passo 1: Criando a VPC</h2>
<ol>
  <li>Acesse a AWS Console e vá para “VPC”.</li>
  <li>Clique em “Criar VPC”.</li>
  <li>Nomeie como <strong>VPC-A</strong>.</li>
  <li>Defina o CIDR como <strong>10.100.0.0/16</strong>.</li>
  <li>Clique em “Criar VPC”.</li>
</ol>

<p><img src="./assets/2025-03-28-vpc-em-subnet-publica/Captura de tela de 2025-03-28 17-03-44.png" alt="VPC Criada" /></p>

<h2 id="passo-2-criar-internet-gateway-e-associar-à-vpc">Passo 2: Criar Internet Gateway e Associar à VPC</h2>
<ol>
  <li>Acesse “Internet Gateway” na AWS Console e crie um novo.</li>
  <li>Nomeie como <strong>VPC-A-IGW</strong>.</li>
  <li>Após a criação, associe o IGW à VPC <strong>VPC-A</strong>.</li>
</ol>

<p><img src="./assets/2025-03-28-vpc-em-subnet-publica/Captura de tela de 2025-03-28 17-04-08.png" alt="Associar IGW" />
<img src="./assets/2025-03-28-vpc-em-subnet-publica/Captura de tela de 2025-03-28 17-04-26.png" alt="Criar IGW" />
<img src="./assets/2025-03-28-vpc-em-subnet-publica/Captura de tela de 2025-03-28 17-04-26.png" alt="Associar IGW" />
<img src="./assets/2025-03-28-vpc-em-subnet-publica/Captura de tela de 2025-03-28 17-04-45.png" alt="Criado IGW" /></p>

<h2 id="passo-3-criar-a-subnet">Passo 3: Criar a Subnet</h2>
<ol>
  <li>Acesse <strong>VPC &gt; Subnets</strong> e crie uma nova subnet com o nome <strong>VPC-A-Public</strong>.</li>
  <li>Escolha uma AZ e defina o CIDR <strong>10.100.0.0/24</strong>.</li>
</ol>

<p><img src="./assets/2025-03-28-vpc-em-subnet-publica/Captura de tela de 2025-03-28 17-05-14.png" alt="Sub-rede Criada" />
<img src="./assets/2025-03-28-vpc-em-subnet-publica/Captura de tela de 2025-03-28 17-05-35.png" alt="Sub-rede2 Criada" /></p>

<ol>
  <li><strong>Colocando IP Public</strong>:
    <ul>
      <li>Ações &gt; Editar configuração de sub-rede . Configurações de atribuição automática de IP &gt; Habilitar endereço IPV4 Público de atribuição automática &gt; Habilitar</li>
    </ul>
  </li>
</ol>

<p><img src="./assets/2025-03-28-vpc-em-subnet-publica/Captura de tela de 2025-03-28 17-06-01.png" alt="Sub-rede3 Criada" /></p>

<h2 id="passo-4-criar-tabela-de-rotas">Passo 4: Criar Tabela de Rotas</h2>
<ol>
  <li>Vá para <strong>VPC &gt; Tabelas de rotas</strong> e crie uma nova tabela chamada <strong>VPC-A-Public-RT</strong>.</li>
  <li>Adicione a rota <strong>0.0.0.0/0</strong> com o target <strong>IGW</strong>.</li>
</ol>

<p><img src="./assets/2025-03-28-vpc-em-subnet-publica/Captura de tela de 2025-03-28 17-06-31.png" alt="Tabela de Rotas" /></p>

<h2 id="passo-5-associar-tabela-de-rotas-à-subnet">Passo 5: Associar Tabela de Rotas à Subnet</h2>
<ol>
  <li>Selecione a tabela <strong>VPC-A-Public-RT</strong>.</li>
  <li>Associe a subnet <strong>VPC-A-Public</strong> à tabela de rotas.</li>
</ol>

<p><img src="./assets/2025-03-28-vpc-em-subnet-publica/Captura de tela de 2025-03-28 17-06-51.png" alt="Associar Tabela" />
<img src="./assets/2025-03-28-vpc-em-subnet-publica/Captura de tela de 2025-03-28 17-19-32.png" alt="Associar Tabela1" /></p>

<h2 id="passo-6-criar-uma-ec2">Passo 6: Criar uma EC2</h2>
<ol>
  <li>Ao criar a EC2, escolha a <strong>VPC-A</strong> e a <strong>subnet VPC-A-Public</strong>.</li>
  <li>Habilite a opção para atribuir um IP público.</li>
</ol>

<p><img src="./assets/2025-03-28-vpc-em-subnet-publica/Captura de tela de 2025-03-28 17-19-50.png" alt="EC2 Configuração" /></p>

<h2 id="passo-7-configuração-de-segurança">Passo 7: Configuração de Segurança</h2>
<ol>
  <li>Crie um Grupo de Segurança permitindo SSH (porta 22) para qualquer IP (0.0.0.0/0).</li>
</ol>

<p><img src="./assets/2025-03-28-vpc-em-subnet-publica/Captura de tela de 2025-03-28 17-20-07.png" alt="Grupo de Seguranca" /></p>

<hr />

<p>No próximo post, abordaremos como configurar uma instância EC2 em uma subnet privada.</p>]]></content><author><name>Thallyson Yakko</name></author><category term="vpc" /><category term="aws" /><category term="aws" /><summary type="html"><![CDATA[O intuito deste post é iniciar falando sobre VPC e desenvolver o projeto em futuras postagens. Primeiramente, criaremos uma instância em uma sub-rede pública para servir como bastion host de acesso a uma instância em uma sub-rede privada. Ao longo dos próximos posts, iremos detalhar mais sobre o projeto.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://thallysonyakko.com.br/assets/2025-03-28-vpc-em-subnet-publica/aws.jpeg" /><media:content medium="image" url="https://thallysonyakko.com.br/assets/2025-03-28-vpc-em-subnet-publica/aws.jpeg" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>