<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: LeonardoMarques</title>
    <description>The latest articles on DEV Community by LeonardoMarques (@leonardomarques).</description>
    <link>https://dev.to/leonardomarques</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1018239%2F970273bb-31ee-4c5a-8122-6f8b5f7b36a8.jpeg</url>
      <title>DEV Community: LeonardoMarques</title>
      <link>https://dev.to/leonardomarques</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/leonardomarques"/>
    <language>en</language>
    <item>
      <title>[Java] Solucionando concorrência em schedules</title>
      <dc:creator>LeonardoMarques</dc:creator>
      <pubDate>Fri, 13 Dec 2024 19:49:48 +0000</pubDate>
      <link>https://dev.to/leonardomarques/java-solucionando-concorrencia-em-schedules-93c</link>
      <guid>https://dev.to/leonardomarques/java-solucionando-concorrencia-em-schedules-93c</guid>
      <description>&lt;p&gt;Vivi esse problema em ambiente de trabalho e precisei estudar um pouco mais a fundo para conseguir solucioná-lo. E claro, de forma colaborativa com meus colegas, principalmente o Rafa que foi essencial na solução que vou apresentar. Um salve pro Caio também que nos ajudou a seguir pelo caminho dos schedules, vocês já vão entender. &lt;/p&gt;

&lt;p&gt;Tudo começou com um projeto de Jobs usando Spring Batch do Java. Todos os jobs eram iniciados por schedules. Inicialmente era um job apenas, então rodava sozinho de tempos em tempos, digamos assim. O problema é que a medida que foram surgindo mais jobs, começamos a perceber a degradação da execução. E aqui entra nossa maior dor: um desses jobs iniciava um fluxo de tarifação que concorria com outros produtos da empresa para tarifar. Se a gente demorasse muito, digamos que perdíamos nossa chance de tarifar o cliente. E adivinha o que estava acontecendo? Esses jobs estavam concorrendo e executando de forma síncrona travando a thread principal e impedindo outros jobs de executarem. Uma espécie de dança das cadeiras se for mais fácil de visualizar. &lt;/p&gt;

&lt;p&gt;Inicialmente achávamos que o problema era com os jobs e focamos esforços em resolver isso, até encontramos formas de paralelizar o fluxo "do meio" de um job. A título de curiosidade: a estrutura básica de um job geralmente tem um &lt;strong&gt;reader&lt;/strong&gt;, um &lt;strong&gt;processor&lt;/strong&gt; e um &lt;strong&gt;writer&lt;/strong&gt;. Dependendo do seu problema você consegue paralelizar o processor e/ou o writer usando Future do Java. &lt;br&gt;
Se quiser aprofundar, dá uma olhada nesse vídeo: &lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=AbQcWO91Bx4" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=AbQcWO91Bx4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mas como eu disse, nosso problema não era nos jobs em si e descobrimos isso adicionando logs assim que o schedule executava, antes de acionar o job. E nosso colega Caio fez muitos questionamentos sobre essa parte, dessa forma decidimos investigar e estudar mais sobre schedules para conseguir responder os seus questionamentos com confiança. &lt;strong&gt;A pista de que o problema estava ai&lt;/strong&gt; foi que nosso log não estava acontecendo, ou seja, o schedule sequer estava sendo executado, mesmo com seu tempo bem baixo (5s). &lt;/p&gt;

&lt;p&gt;O ChatGPT nos ajudou muito nesse aprofundamento e aos poucos, conseguimos entender exatamente o que estava acontecendo. E não só teoricamente, mas o Rafael fez uma PoC (Prova de Conceito) para validar nossa teoria que era: &lt;strong&gt;estávamos lidando com um problema de concorrência e a única forma de ter os schedules executando de forma independente era criando um ThreadPool dedicado para cada um deles.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Essa prova de conceito se tornou um case de projeto e pode ser encontrado nesse link: &lt;a href="https://github.com/StringRafa/SchedulerThreadPool" rel="noopener noreferrer"&gt;https://github.com/StringRafa/SchedulerThreadPool&lt;/a&gt;&lt;br&gt;
Mas resumidamente, conforme a documentação do repositório:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A solução utiliza executores dedicados para cada scheduler, configurados por meio de:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;@Async&lt;/strong&gt; com Executors Dedicados: Cada agendador foi configurado para usar um executor específico, garantindo que as tarefas sejam processadas de forma independente.&lt;/li&gt;
&lt;li&gt;Isolamento de Tarefas: Cada tarefa tem seu próprio executor, evitando interferências entre tarefas que possuem tempos de execução distintos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vejamos alguns trechos de códigos que refletem a solução:&lt;/p&gt;

&lt;p&gt;Primeiro definimos um executor dedicado através de uma classe de configuração:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TaskExecutorConfig&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"threadPool-task1"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Executor&lt;/span&gt; &lt;span class="nf"&gt;task1&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;ThreadPoolTaskExecutor&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ThreadPoolTaskExecutor&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setCorePoolSize&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setMaxPoolSize&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setQueueCapacity&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setThreadNamePrefix&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"threadPool-task1-"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;initialize&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vincule esse &lt;em&gt;taskExecutor&lt;/em&gt; dedicado ao seu método agendado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ScheduledTasks&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Async&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"threadPool-task1"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@Scheduled&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fixedRate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;executeTask1&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//Sua lógica de negócio&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Observações:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Se você define um &lt;em&gt;@Scheduled&lt;/em&gt; sem definir nada, por default ele executará na thread principal da sua aplicação. Se existir outros schedules independente da configuração, eles ficarão aguardando a execução desse schedule, pois ele está ocupando a thread principal, então você tem um problema de concorrência. &lt;/li&gt;
&lt;li&gt;Se você definir um &lt;em&gt;@Scheduled&lt;/em&gt; com &lt;em&gt;@Async&lt;/em&gt; sem definir um threadExecutor/threadPool específico, ele executará em um executor chamado &lt;strong&gt;SingleAsyncThreadPool&lt;/strong&gt;, nesse caso ele executará uma tarefa por vez de forma sequêncial, mas ainda sofrerá bloqueio de algum scheduled que estiver usando a thread principal, como no primeiro caso. 
Esse tipo de configuração é ideal para tarefas sequenciais simples que não precisam de ajustes ou gerenciamento avançado.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Não sei se existem outras formas de resolver esse problema, caso saibam podem deixar nos comentários sua contribuição. Mas na situação que vivi, a única forma que encontramos de isolar cada agendador de forma mutuamente exclusiva, ou seja, sem que a execução deles não impactassem uns aos outros e mesmo assim fossem altamente configurações e flexíveis, foi usando um &lt;em&gt;ThreadPoolTaskExecutor&lt;/em&gt; como exemplificado anteriormente. &lt;/p&gt;

&lt;p&gt;Bom, o artigo de hoje era esse, espero que essa solução possa ajudar você se um dia passar por esse mesmo problema de concorrência. Estamos há um tempo rodando com essa solução em produção e foi com certeza um sucesso: até os gráficos do &lt;em&gt;NewRelic&lt;/em&gt; ficam melhores de ver cada pool de thread executando, sua porcentagem de processamento ao longo do tempo, e até os logs agora possuem a &lt;em&gt;threadpool&lt;/em&gt; de execução, facilitando entender como a dinâmica dos agendadores está ocorrendo. &lt;/p&gt;

&lt;p&gt;Obrigado e até a próxima!&lt;br&gt;
Um salve e agradecimento a Caio Senna e &lt;a class="mentioned-user" href="https://dev.to/rafael_j_souza"&gt;@rafael_j_souza&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>java</category>
      <category>scheduled</category>
      <category>concorrencia</category>
    </item>
    <item>
      <title>5 coisas que aprendi na minha carreira de TI - Parte 1</title>
      <dc:creator>LeonardoMarques</dc:creator>
      <pubDate>Mon, 25 Nov 2024 13:39:04 +0000</pubDate>
      <link>https://dev.to/leonardomarques/5-coisas-que-aprendi-na-minha-carreira-de-ti-parte-1-3gk3</link>
      <guid>https://dev.to/leonardomarques/5-coisas-que-aprendi-na-minha-carreira-de-ti-parte-1-3gk3</guid>
      <description>&lt;p&gt;Faala pessoal, no momento que escrevo esse artigo, eu estou com aproximadamente 7 anos de carreira. Sinto que cada pequeno &lt;em&gt;insight&lt;/em&gt; aqui poderia ser um artigo inteiro e quem sabe um dia seja, mas nesse momento queria apenas condensar de forma que isso possa ajudar muitos que estão em diversos momentos da carreira. &lt;/p&gt;

&lt;h2&gt;
  
  
  Sua carreira não é linear
&lt;/h2&gt;

&lt;p&gt;Na minha história com TI tive momentos de muito aprendizado: geralmente quando você mergulha em um problema a fundo ou quando tudo que está aprendendo é novo. E também momentos de leve estagnação, onde você meio que já dominou o dia a dia, não tem nada muito novo pra mexer, ficamos dando manutenção no que existe (sustentação). &lt;br&gt;
E aqui temos um ponto de atenção: esse período é normal em qualquer empresa e momento da sua carreira, mas na minha visão é perigoso se ele se estender demais. Digo isso se você é uma pessoa que quer estar em constante evolução e aprendizado, pois ou você encontra uma maneira de continuar evoluindo na empresa, por quaisquer motivos que seja ou talvez seja o momento de &lt;strong&gt;alçar novos horizontes&lt;/strong&gt;. Precisa aprender a analisar isso. Mas caso esteja confortável com isso, continuo achando perigoso, mas é um direito seu, o importante é se sentir bem e feliz, mas esteja ciente das consequências. E uma delas é sua *&lt;em&gt;empregabilidade ficar ameaçada. *&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Síndrome do Impostor é normal em TI
&lt;/h2&gt;

&lt;p&gt;Se você se deparar com algo chamado "síndrome do impostor" é normal. É um sentimento de que você não é bom o suficiente, não sabe o suficiente, não está pronto para entrevistas, não está pronto para oportunidades melhores. E tudo bem, pode ser que não esteja mesmo, mas muitas vezes você já está bem melhor do que realmente acha, por isso a tal da síndrome. É algo que precisa aprender a lidar, pois trabalhar com TI vai te desafiar diariamente de modo que você certamente terá dúvidas se é bom de verdade ou se a carreira é pra você mesmo. Acho que a dica aqui é se preocupar mais com a sua postura do que só com suas habilidades e conhecimentos. A sua postura diante de como lidar e de quais atitudes tomar pode contar muito para se sentir mais confiante. Eu deixo como dica conversar com outros devs, procurar conteúdos de carreira, assim você terá uma noção melhor de como está o "sentimento de mercado", das pessoas e assim vai conseguir entender se está se cobrando demais. &lt;br&gt;
&lt;strong&gt;Esse assunto também nos leva ao terceiro ponto.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Caso você ache que está com esses sentimentos de forma muito recorrente, não deixe de procurar ajuda profissional, pois pode ser um caso de terapia.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Você nunca vai saber tudo, pare de se cobrar tanto (essa é especialmente pra mim)
&lt;/h2&gt;

&lt;p&gt;Aprenda a selecionar o que deve aprender, o que vai te trazer mais resultado no momento. Conhece o princípio de pareto? &lt;br&gt;
TI é gigante de uma forma que não dá pra explicar, mas nas poucos vezes que procurei um &lt;em&gt;roadmap de backend&lt;/em&gt; eu me deparei com algo assim: &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg05kqeoi6t57e7ky0ftf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg05kqeoi6t57e7ky0ftf.png" alt="Image description" width="800" height="1124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Muitos iniciantes vão achar que devem obrigatoriamente dominar isso tudo para ser um bom desenvolvedor, mas aprendi que isso tudo não passa de um Guia. São coisas que você vai encontrar e que vai aprender naturalmente. Outros você vai precisar buscar quando necessário. Não ache que isso é uma árvore de habilidades de um jogo que você gosta e quer completá-la. &lt;br&gt;
Tá, sobre o Princípio de Pareto, também conhecido como princípio 80/20. Ele pode ser aplicado em diversos cenários da vida, mas nesse caso ele se aplica assim:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quais são os 20% de conteúdo/conhecimento nessa árvore que eu preciso saber e que vão resolver 80% das minhas necessidades diárias como um desenvolvedor &lt;em&gt;backend&lt;/em&gt; Java? 
Dessa forma você foca em 20% de tudo que está aí e terá 80% de resultado e o resto você vai aprendendo aos poucos, conforme os problemas aparecem, conforme seus estudos avançam, sem pressão. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Desenvolva habilidades não técnicas
&lt;/h2&gt;

&lt;p&gt;Trabalhar com TI apesar de ser muito técnico, também é muito sobre o que chamam de &lt;em&gt;softskils&lt;/em&gt; que são habilidades não técnicas, como saber se relacionar com outras pessoas harmonicamente, principalmente trabalhar em equipe. Saiba negociar não só salários melhores e condições melhores de trabalho, mas também escopo de entregas, prazos e soluções. Na sua carreira, muitas vezes você não vai conseguir executar tecnicamente da melhor forma. Muitas vezes o prazo é rei e precisamos entregar do jeito que der, senão podemos perder o "&lt;em&gt;time&lt;/em&gt;" e consequentemente dinheiro para a empresa. Pensa ai na &lt;strong&gt;Black Friday&lt;/strong&gt;. Então, aprenda a entender as nuances de negociar prazos e soluções, isso certamente te dará maturidade para crescer na carreira. &lt;/p&gt;

&lt;h2&gt;
  
  
  Saiba interpretar o contexto da sua empresa
&lt;/h2&gt;

&lt;p&gt;Trabalhar em uma startup é diferente de uma empresa grande. Eu sinceramente recomendo que tenha as duas experiências na sua carreira, vai te fazer um profissional melhor. Empresa grande geralmente tem mais burocracia, tem mais legado do que coisa nova, porém, os &lt;strong&gt;problemas&lt;/strong&gt; tendem a ser &lt;strong&gt;mais complexos&lt;/strong&gt;, dado que uma empresa grande muitas vezes já tem um &lt;strong&gt;volume de negócio grande&lt;/strong&gt; e qualquer movimento em falso pode &lt;strong&gt;gerar prejuízo&lt;/strong&gt;. &lt;u&gt;A burocracia geralmente protege a empresa e mitiga riscos&lt;/u&gt;, pois é muito maior do que numa startup que muitas vezes ou não tem um produto que lucra ou o lucro ainda é baixo então os impactos são menores. Porém, &lt;u&gt;tendem a ter menos legado, ser mais inovadores e ágeis para entrega de software&lt;/u&gt;. Outra grande diferença são questões financeiras, pois uma empresa grande é mais difícil quebrar ou te demitir por questões de custos, já startups possuem mais incertezas nesse sentido.&lt;br&gt;
Por fim, sugiro que tenha as duas vivências e decida onde gosta mais de estar, um ambiente não é melhor que o outro, depende do seu perfil também. &lt;/p&gt;

</description>
      <category>carreira</category>
      <category>bolhadev</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Uma breve história de infraestrutura - Parte 1: Mainframes.</title>
      <dc:creator>LeonardoMarques</dc:creator>
      <pubDate>Tue, 25 Apr 2023 12:05:41 +0000</pubDate>
      <link>https://dev.to/leonardomarques/uma-breve-historia-de-infraestrutura-parte-1-mainframes-23la</link>
      <guid>https://dev.to/leonardomarques/uma-breve-historia-de-infraestrutura-parte-1-mainframes-23la</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: _A intenção do artigo é expor meu entendimento do assunto, não sou especialista. Pelo contrário, estou em fase de estudo, então me avisem se eu me equivocar em alguma explicação. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Este artigo é um &lt;strong&gt;resumo&lt;/strong&gt; do vídeo Entendendo "Devops" para Iniciantes em Programação (Parte 1) | Série "Começando aos 40" do Fabio Akita. &lt;a href="https://www.youtube.com/watch?v=bwO8EZf0gLI&amp;amp;list=PLdsnXVqbHDUdjNjfekBoCBfGtJ6kNRef-" rel="noopener noreferrer"&gt;(Link)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Meu objetivo é entender melhor o caminho que percorremos desde o mainframe até as infraestruturas modernas com Docker e Kubernetes. Nessa parte 1, buscarei traçar uma linha histórica &lt;strong&gt;em alto nível&lt;/strong&gt; dos anos 60 até meados de 2010.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mainframes
&lt;/h2&gt;

&lt;p&gt;Essa história começa nos anos 60, onde os mainframes reinavam. Eles eram máquinas imensas numa época onde o hardware era muito caro. Não eram tão poderosas, então alguns processos demoravam para executar, como a escrita (&lt;em&gt;output&lt;/em&gt;) por exemplo. Com diversas pesquisas e estudos aliado ao avanço do poder das máquinas, foi possível particionar o mainframe para rodar mais de uma &lt;strong&gt;kernel&lt;/strong&gt; (&lt;em&gt;componente central de um sistema operacional responsável por ser o elo entre hardware software&lt;/em&gt;) por vez, cada um com seu sistema operacional e acesso a uma parte real dos recursos de I/O. Dessa forma foi possível otimizar melhor os recursos e ganhar produtividade. &lt;/p&gt;

&lt;h2&gt;
  
  
  Primeiras gerações de websites
&lt;/h2&gt;

&lt;p&gt;Avançamos até os anos 90, com o hardware se tornando mais acessível a pequenas empresas, as máquinas se tornando mais poderosas e novas pesquisas e tecnologias surgindo. Nessa época a experiência do Unix foi trazida para o Linux permitindo multiusuário e multitarefa. Foi um cenário favorável para o surgimento de um novo modelo de negócios: empresas começaram a prover sites ao preço de uma assinatura mensal. Esses serviços de hospedagem conseguiam prover dezenas de sites numa mesma máquina, dividindo os recursos e o acesso utilizando o recurso de &lt;em&gt;Virtual Host&lt;/em&gt; dos servidores web (mapeando urls para pastas de estáticos ou ativando programas cgi). Assim surgiram as primeiras gerações de websites usando a famosa stack LAMP (Linux, Apache, MySQL e PHP). Mas como é de se esperar, aqui começamos a ter muitos problemas de segurança. (&lt;em&gt;se quiser aprofundar, veja o vídeo completo&lt;/em&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Container vs Virtualização
&lt;/h2&gt;

&lt;p&gt;No início dos anos 2000, algumas pesquisas começaram a dar frutos. Nessa época tivemos tentativas de limitar o que um processo poderia fazer &lt;strong&gt;isolando recursos de uma mesma máquina&lt;/strong&gt; com as tecnologias Jail(&lt;em&gt;FreeBSD&lt;/em&gt;), &lt;em&gt;LinuxVServer&lt;/em&gt; e containers de &lt;em&gt;Solaris&lt;/em&gt;. Na prática essas soluções são baseadas em mentiras que o kernel conta para os processos fazendo-os acreditarem que possuem mais recursos e acessos do que realmente têm. A esse conceito damos o nome de  &lt;strong&gt;containers&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Em contrapartida, a &lt;strong&gt;virtualização&lt;/strong&gt; apesar de também querer otimizar recursos de uma mesma máquina, possui duas abordagens diferentes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bare Metal&lt;/strong&gt;: Gerencia e compartilha recursos reais da máquina. Por isso os mainframes eram muito eficientes, cada máquina virtual tinha acesso a recursos reais de I/O.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosted&lt;/strong&gt;: Um programa especial chamado &lt;em&gt;Hypervisor&lt;/em&gt; que executa em um sistema operacional(SO) hospedeiro simula uma máquina virtual (recursos) executando um SO convidado. Consequentemente gera um peso grande de execução. Exemplo: VirtualBox &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Com essa definição podemos entender a grande diferença entre virtualização e containers. Containers faziam processos &lt;strong&gt;executarem de forma restrita num mesmo sistema operacional&lt;/strong&gt;. Já a virtualização, &lt;strong&gt;permite que um processo rode como se fosse numa máquina real ao virtualizar uma máquina inteira&lt;/strong&gt; com um SO até mesmo diferente do SO original da máquina real. Essa virtualização é chamada de completa. &lt;/p&gt;

&lt;p&gt;Apesar da vantagem da virtualização de conseguir executar um Linux numa máquina Windows por exemplo, isso era um processo muito lento e pesado pois o &lt;em&gt;Hypervisor&lt;/em&gt; precisava "mentir sozinho" quando os processos precisavam fazer &lt;em&gt;system calls&lt;/em&gt;. (Chamadas a instruções do kernel) Como evolução, surgiu a &lt;strong&gt;paravirtualização&lt;/strong&gt; onde agora o SO também consegue mentir para os processos, tornando o desempenho do SO convidado melhor diminuindo a dependência do &lt;em&gt;Hypervisor&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
Visando ainda mais performance, a AMD e Intel começaram a  trazer instruções de máquina específicas para virtualizações, tornando o desempenho quase de uma máquina real. &lt;/p&gt;

&lt;h2&gt;
  
  
  O início da infraestrutura como código
&lt;/h2&gt;

&lt;p&gt;Esses avanços na virtualização se tornaram muito importantes para empresas que tinham que gerir &lt;em&gt;datacenters&lt;/em&gt;. Pois poderiam de forma performática dividir os recursos das máquinas para diversos clientes diferentes. Mas configurar diversos servidores, com máquinas virtuais, redes e aplicações era uma tarefa bem trabalhosa. A tecnologia &lt;em&gt;VPS(Virtual Private Server)&lt;/em&gt; da Microsoft aliviou esse problema. Ela conseguia automatizar a criação de máquinas virtuais usando imagens de SO (snapshots) tornando possível subir uma máquina nova em minutos. Mas isso ainda não resolvia o problema das empresas que precisavam gerir uma infraestrutura bem mais complexa. &lt;/p&gt;

&lt;p&gt;Diante do quão trabalhoso era prover uma infraestrutura do zero "na mão", em 1993 já começavam a surgir ferramentas para automatização desse processo como a &lt;em&gt;CFEngine&lt;/em&gt; (em 1998 a &lt;em&gt;CFEngine3&lt;/em&gt;). Com essa ferramenta era possível escrever "receitas" de configuração (linguagem declarativa) que instalava várias máquinas da mesma forma com apenas um comando. Em 2005, tivemos o &lt;em&gt;Puppet&lt;/em&gt; escrito em &lt;em&gt;Ruby&lt;/em&gt; e em 2009 o &lt;em&gt;Chef&lt;/em&gt; também escrito em &lt;em&gt;Ruby&lt;/em&gt;. Essas ferramentas deram início a infraestrutura como código, sendo possível criar e compartilhar receitas em repositórios bem semelhante ao &lt;em&gt;Git/Github&lt;/em&gt; usufruindo assim da colaboração da comunidade OpenSource. &lt;br&gt;
Essas ferramentas funcionavam em uma arquitetura cliente e servidor. Onde cada cliente possui um processo agente que fica escutando um servidor para instalar e configurar o que for requisitado. Consequentemente era preciso configurar o agente e o servidor, o que poderia ser trabalhoso demais para uma única máquina.&lt;/p&gt;

&lt;p&gt;Anos depois tivemos ferramentas &lt;em&gt;agentless&lt;/em&gt; como &lt;strong&gt;Capistrano&lt;/strong&gt; e &lt;strong&gt;Ansible&lt;/strong&gt; que são mais simples de configurar para uma única máquina, em relação as outras ferramentas citadas anteriormente. O que torna mais simples é ter apenas o servidor usando conexão &lt;strong&gt;ssh&lt;/strong&gt; como túnel para executar arquivos em máquinas remotas.&lt;br&gt;
Cada ferramenta tem seu propósito, a grosso modo, sendo as &lt;em&gt;agentless&lt;/em&gt; mais voltadas para casos de uso mais simples (desenvolvedores) e as baseadas em &lt;em&gt;agent&lt;/em&gt; mais voltadas a infraestruturas mais complexas.&lt;/p&gt;

&lt;p&gt;Mas será que essas ferramentas só servem para automatizar? Pelo contrário, além de agilizar a criação e configuração, essas ferramentas são essenciais para &lt;strong&gt;manter&lt;/strong&gt; uma infraestrutura atualizada e segura. Também ajudam a destruir e reconstruir rapidamente máquinas que foram atacadas por exemplo. Tentar fazer essas tarefas "na mão", comando a comando torna o processo além de trabalhoso e improdutivo, também muito passível de erro por esquecimento de algum comando, além de difícil replicação. &lt;/p&gt;

&lt;h2&gt;
  
  
  Surgimento e expansão das &lt;strong&gt;Big Techs&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Do meio para o final dos anos 2000, temos o surgimento e a expansão de grandes &lt;em&gt;Tech Startups&lt;/em&gt; trazendo serviços e produtos que faziam as pessoas ficarem mais tempos conectadas na internet de um jeito nunca visto antes. Muitas tecnologias surgiram e evoluíram para conseguirem apoiar a escala dessas empresas. Na parte 2 do vídeo vamos entender como a evolução dessas tecnologias culminaram no Docker e Kubernetes que temos hoje. &lt;/p&gt;

&lt;p&gt;Continua...&lt;/p&gt;

</description>
      <category>containers</category>
      <category>virtualmachine</category>
      <category>virtualization</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Uma introdução conceitual em IaaC com Terraform</title>
      <dc:creator>LeonardoMarques</dc:creator>
      <pubDate>Mon, 06 Mar 2023 10:38:08 +0000</pubDate>
      <link>https://dev.to/leonardomarques/uma-introducao-conceitual-em-iaac-com-terraform-3jcn</link>
      <guid>https://dev.to/leonardomarques/uma-introducao-conceitual-em-iaac-com-terraform-3jcn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: _A intenção do artigo é expor meu entendimento do assunto, não sou especialista. Pelo contrário, estou em fase de estudo, então me avisem se eu me equivocar em alguma explicação.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Na minha jornada de desenvolvedor, infra nunca foi um assunto que eu curti. Sempre achei chato esses detalhes de "baixo nível". Mas num cenário de mercado de trabalho cada vez mais acelerado e competitivo, as empresas estão buscando e exigindo que saibamos sobre todo o processo de desenvolvimento de software (talvez eu escreva sobre &lt;em&gt;code ownership&lt;/em&gt;). Então vamos lá, entender de vez, esse tal de Terraform. &lt;/p&gt;

&lt;h2&gt;
  
  
  Por que usar Terraform?
&lt;/h2&gt;

&lt;p&gt;Para disponibilizar e manter um produto, site ou plataforma digital, é necessária toda uma infraestrutura de máquinas virtuais, banco de dados, rede, entre outros recursos. Existem profissionais dedicados a cuidar de toda essa parte, que antigamente era toda feita manualmente.&lt;/p&gt;

&lt;p&gt;Mas isso certamente não era algo muito prático de se fazer e gerenciar. Não é de hoje que a &lt;strong&gt;infraestrutura&lt;/strong&gt; começou a ser pensada &lt;strong&gt;como código&lt;/strong&gt;. O que faz todo sentido, pois é algo que nós profissionais de TI já estamos acostumados. Hoje existem diversas ferramentas para prover infraestrutura através de código, sendo o Terraform uma das mais usadas . &lt;/p&gt;

&lt;h2&gt;
  
  
  IaaC - Infrastructure as a Code
&lt;/h2&gt;

&lt;p&gt;Vamos olhar o seguinte projeto de infraestrutura para um website e entender onde o Terraform entra:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqxmcvqubv819ig5oisb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqxmcvqubv819ig5oisb.png" alt="Arquitetura de um site estático usando Amazon AWS" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Caso queira se aprofundar praticando a criação dessa infra com Terraform, vou deixar a referência no final do artigo. &lt;br&gt;
Mas aqui eu não quero focar na sintaxe ou em detalhes de implementação do Terraform, eu quero conectar o código do Terraform com a arquitetura de uma infraestrutura. &lt;/p&gt;

&lt;p&gt;Explicando o projeto:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A infraestrutura foi projetada dentro da cloud da Amazon: AWS. &lt;/li&gt;
&lt;li&gt;O código encontra-se versionado no Github e de lá ele passa pelo pipeline de CI/CD que utiliza 2 serviços também da Amazon (CodePipeline e CodeBuild). Mas aqui poderia ser também um GitLab ou CircleCI por exemplo. &lt;/li&gt;
&lt;li&gt;Como estamos falando de um site estático, no final do pipeline teremos um build com os arquivos do site que serão disponibilizados num bucket do S3 (serviço de armazenamento simples da Amazon). &lt;/li&gt;
&lt;li&gt;Para disponibilizar esse site de forma rápida e com baixa latência, foi utilizado o serviço CloudFront da AWS junto de algumas configurações de certificados e políticas de acesso. &lt;/li&gt;
&lt;li&gt;Por fim, foi utilizado o Route 53 como serviço de DNS que é a camada mais próxima do acesso externo ao site pelo browser. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Ok, mas onde entra o Terraform?
&lt;/h3&gt;

&lt;p&gt;O Terraform vai nos ajudar a provisionar infraestrutura, isto é, na parte de &lt;strong&gt;recursos&lt;/strong&gt; e &lt;strong&gt;configurações&lt;/strong&gt; necessárias para disponibilizar esse site na internet. E aqui começa o paralelo entre o Terraform e uma infraestrutura física: vamos mapear e configurar &lt;code&gt;resources&lt;/code&gt;. &lt;br&gt;
Por exemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O &lt;strong&gt;bucket do S3&lt;/strong&gt; é um recurso que precisamos configurar, pois vamos guardar os arquivos de build do site dentro dele. &lt;/li&gt;
&lt;li&gt;o &lt;strong&gt;cloudfront&lt;/strong&gt; é um recurso que vamos configurar, pois através dele vamos disponibilizar o acesso aos estáticos no bucket com a maior rapidez possível. Também não queremos ninguém acessando o bucket diretamente, por questões de segurança. &lt;/li&gt;
&lt;li&gt;O &lt;strong&gt;Route 53&lt;/strong&gt; é um recurso que vamos utilizar para configurar DNS do site apontando para zonas e domínios seguros. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Principais blocos e comandos
&lt;/h2&gt;

&lt;p&gt;Quando falamos de Terraform, estamos falando de código, então é esperado que tenhamos automatização e reutilização. Dessa forma, além do bloco &lt;code&gt;resource&lt;/code&gt;, o terraform também possui outros blocos importantes como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;variable&lt;/code&gt;- uso padrão de sempre.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;output&lt;/code&gt;- usado para obter informações pós criação de recursos e assim construir infraestrutura de forma dinâmica. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data&lt;/code&gt;- usado para obter informações de recursos externos. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;modules&lt;/code&gt;- um dos blocos mais importantes do Terraform. Basicamente segue a mesma ideia geral em termos de programação: &lt;em&gt;evitar replicação de código através do reuso&lt;/em&gt;. Com ele é possível tanto reutilizar módulos locais quanto módulos publicados externamente, trazendo mais facilidade, rapidez e flexibilidade na montagem da sua infraestrutura.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Por fim, o Terraform trabalha com poucos comandos, mas com muitas opções de customização. A ideia geral dos comandos é bem intuitiva: primeiro vamos inicializar o que for necessário, planejar o que vamos construir e aplicar de fato. Os respectivos comandos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;terraform init&lt;/code&gt; (inicializa os arquivos do terraform e baixa módulos, caso especificados)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;terraform plan&lt;/code&gt; (mostra um resumo do que será executado, ótimo para validar suas mudanças antes de executar)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;terraform apply&lt;/code&gt; (executa o plano e cria a infraestrutura real)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;terraform destroy&lt;/code&gt; (bastante usada para estudo)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E outros comandos que gosto de usar são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;terraform validate&lt;/code&gt; (para validar seu código antes do plan)
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;terraform fmt&lt;/code&gt;      (para formatação no padrão do Terraform) &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Terraform State
&lt;/h3&gt;

&lt;p&gt;Outro conceito incrível e importante do Terraform é o &lt;strong&gt;state&lt;/strong&gt;. O arquivo &lt;code&gt;terraform.tfstate&lt;/code&gt; mapeia e armazena o estado da sua infra de forma que seja possível recriá-la inteira, caso precise. Também é usado para melhorar a performance de escalabilidade, além de ser possível versioná-lo para manter um histórico de mudanças. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Bom, pra quem chegou até aqui eu gostaria de agradecer e espero que tenham conseguido pelo menos criar uma imagem mental de como saímos de uma infraestrutura física (em nuvem na verdade) para entendê-la como código através do Terraform. Para mim foi meio abstrato no início, mas é só questão de exposição e um pouco de prática para ficar mais claro. Como desenvolvedor, acho importante sabermos entender o suficiente para dar manutenção num código Terraform. Acho que entender os conceitos e o paralelo com uma arquitetura de um projeto é um bom começo. &lt;/p&gt;

&lt;p&gt;Abaixo vou deixar alguns conteúdos para se aprofundarem, caso se interessem. &lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;p&gt;Documentação oficial Terraform: &lt;a href="https://developer.hashicorp.com/terraform" rel="noopener noreferrer"&gt;https://developer.hashicorp.com/terraform&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Curso fiz na Udemy e recomendo:&lt;br&gt;
DevOps: AWS com Terraform Automatizando sua infraestrutura - Cleber Gasparoto&lt;/p&gt;

&lt;p&gt;Artigo da arquitetura usada no exemplo:&lt;br&gt;
&lt;a href="https://medium.com/@zakariakhalaf/automate-your-static-website-deployment-on-aws-with-terraform-2419d91102cc" rel="noopener noreferrer"&gt;https://medium.com/@zakariakhalaf/automate-your-static-website-deployment-on-aws-with-terraform-2419d91102cc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O que é uma infraestrutura como código?&lt;br&gt;
&lt;a href="https://www.redhat.com/pt-br/topics/automation/what-is-infrastructure-as-code-iac" rel="noopener noreferrer"&gt;https://www.redhat.com/pt-br/topics/automation/what-is-infrastructure-as-code-iac&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>terraform</category>
      <category>aws</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Uma introdução ao GitLab CI/CD</title>
      <dc:creator>LeonardoMarques</dc:creator>
      <pubDate>Mon, 06 Feb 2023 20:42:36 +0000</pubDate>
      <link>https://dev.to/leonardomarques/uma-introducao-ao-gitlab-cicd-5760</link>
      <guid>https://dev.to/leonardomarques/uma-introducao-ao-gitlab-cicd-5760</guid>
      <description>&lt;h2&gt;
  
  
  Conceitos básicos sobre CI/CD
&lt;/h2&gt;

&lt;p&gt;Integração Contínua&lt;br&gt;
Resumidamente, é uma prática de desenvolvimento de software em que os desenvolvedores, de forma regular e confiável, juntam suas alterações de código em um repositório central. Depois disso, builds e testes são executados.&lt;/p&gt;

&lt;p&gt;Este processo pode ser muito trabalhoso se feito de forma manual. Por isso, hoje utilizamos diversas ferramentas para automatizar esse processo, sendo o Gitlab uma delas. Dessa forma, é possível criarmos scripts que vão “buildar” e “testar” nossa aplicação automaticamente sempre que um desenvolvedor fizer um “push” no repositório que especificarmos.&lt;/p&gt;
&lt;h3&gt;
  
  
  Entrega Contínua
&lt;/h3&gt;

&lt;p&gt;Segundo a documentação do Gitlab, é um passo além da integração contínua. Onde sua aplicação não é somente “buildada” e testada, mas também “deployada” continuamente. Mas você ainda realiza o deploy manualmente.&lt;/p&gt;
&lt;h3&gt;
  
  
  Implantação Contínua
&lt;/h3&gt;

&lt;p&gt;Segundo documentação do Gitlab, é outro passo além da Integração Contínua onde o deploy ocorre de forma automática sem intervenção humana.&lt;/p&gt;

&lt;p&gt;Por fim, Segundo Lucas Gertel:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Juntas, essas práticas conectadas costumam ser chamadas de “𝗖𝗜/𝗖𝗗 𝗣𝗶𝗽𝗲𝗹𝗶𝗻𝗲”. Eles geralmente são mantidos usando a abordagem DevOps ou SRE. Existem vários benefícios de ter pipelines de CI/CD, como melhor colaboração e qualidade de código, bem como sistemas mais ágeis e confiáveis.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Agora vamos entender na prática como construir um simples pipeline com Gitlab.&lt;/p&gt;
&lt;h2&gt;
  
  
  Gitlab
&lt;/h2&gt;

&lt;p&gt;O que é o Gitlab?&lt;br&gt;
Segundo meu entendimento: é uma plataforma com ferramentas e soluções de DevSecOps que busca ajudar as empresas a entregar software de maneira mais rápida através da automatização de processos.&lt;br&gt;
Para mais informações, sugiro visitar o site oficial: &lt;a href="https://about.gitlab.com/" rel="noopener noreferrer"&gt;https://about.gitlab.com/&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Conceitos de CI/CD no Gitlab
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;pipeline&lt;/strong&gt;: É um fluxo de etapas chamadas de stages que executam um ou mais jobs. A ideia é que quando realizamos um ‘push’ para alguma branch mapeada, esse pipeline vai ser disparado pelo Gitlab e vai realizar todas as etapas necessárias para entregar essas alterações no ambiente em questão, tudo de forma automática.&lt;br&gt;
&lt;strong&gt;stage&lt;/strong&gt;: é uma agregação lógica de jobs. Exemplos de stages: build, test.&lt;br&gt;
&lt;strong&gt;job&lt;/strong&gt;: É um dos elementos fundamentais do pipeline. Sua principal função é executar scripts que contém comandos de Linux, Node, Maven, depende do objetivo do job.&lt;/p&gt;
&lt;h3&gt;
  
  
  Construindo um pipeline com Gitlab
&lt;/h3&gt;

&lt;p&gt;Para começar, precisamos criar um arquivo específico na raiz do seu repositório, chamado: .gitlab-ci.yml&lt;/p&gt;

&lt;p&gt;O Gitlab reconhece esse arquivo e executa automaticamente qualquer pipeline configurado nele assim que uma ação específica acontece, como por exemplo um merge na branch master.&lt;/p&gt;

&lt;p&gt;É neste arquivo que vamos descrever todo nosso pipeline e diferentes estratégias para diferentes branches, dependendo do seu contexto. É complicado mostrar um exemplo real, pois o pipeline é construído de forma particular ao seu código, projeto, estratégias, etc… então vou mostrar um exemplo simples da Digital Ocean (veja referências).&lt;/p&gt;

&lt;p&gt;Arquivo .gitlab-ci.yml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;image: node:latest

stages:
  - build
  - test

cache:
  paths:
    - node_modules/

install_dependencies:
  stage: build
  script:
    - npm install
  artifacts:
    paths:
      - node_modules/

test_with_lab:
  stage: test
  script: npm test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste simples pipeline temos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A definição global de uma image do tipo “node:latest” que será usado por todos os jobs que não especificarem uma imagem.&lt;/li&gt;
&lt;li&gt;Dois estágios, sendo eles “build” e “test”&lt;/li&gt;
&lt;li&gt;Realizaremos cache do diretório node_modules, porque pode ser necessário em outro job&lt;/li&gt;
&lt;li&gt;Temos o job install_dependencies que vai executar no stage de build. Seu script possui um único comando “npm install” que gera o artefato node_modules&lt;/li&gt;
&lt;li&gt;Temos um segundo job test_with_lab que vai executar no stage de “test” cujo script possui apenas o comando “npm test”&lt;/li&gt;
&lt;li&gt;Como neste exemplo não foi especificado onde esses jobs vão executar, por exemplo “only: master”, então basta realizar um commit de teste e o pipeline começa a executar conforme imagem abaixo:
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvi4n147mr9o8sj993oi.png" alt="Exemplo de pipeline executando no Gitlab" width="800" height="362"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Chegamos ao final deste overview de Gitlab, a ideia realmente não era aprofundar, mas introduzir conceitos de CI/CD, exemplificar com o Gitlab e mostrar as vantagens de utilizar essas práticas que hoje já são bem difundidas e utilizadas no mercado.&lt;br&gt;
Espero ter contribuído e qualquer dúvida, crítica ou sugestão, fiquem a vontade para deixar nos comentários.&lt;/p&gt;

&lt;h3&gt;
  
  
  Referências
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.redhat.com/pt-br/topics/devops/what-is-ci-cd" rel="noopener noreferrer"&gt;https://www.redhat.com/pt-br/topics/devops/what-is-ci-cd&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/feed/update/urn:li:activity:7026552798615941120/" rel="noopener noreferrer"&gt;https://www.linkedin.com/feed/update/urn:li:activity:7026552798615941120/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.gitlab.com/ee/ci/introduction/" rel="noopener noreferrer"&gt;https://docs.gitlab.com/ee/ci/introduction/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.digitalocean.com/community/tutorials/como-configurar-pipelines-de-integracao-continua-com-o-gitlab-ci-no-ubuntu-16-04-pt" rel="noopener noreferrer"&gt;https://www.digitalocean.com/community/tutorials/como-configurar-pipelines-de-integracao-continua-com-o-gitlab-ci-no-ubuntu-16-04-pt&lt;/a&gt;&lt;/p&gt;

</description>
      <category>automation</category>
      <category>tooling</category>
      <category>softwaredevelopment</category>
    </item>
  </channel>
</rss>
