Onde estou? – Definição de variável de ambiente para informar a aplicação de qual é o ambiente

Esse é um texto sobre uma definição que é bem simples de arquitetura, mas que muitos “arquitetos” não fazem. O conceito é informar a aplicação, com o uso de uma definição externa, em qual ambiente essa aplicação se encontra. Com isso, a aplicação é capaz de tomar ações com base no ambiente em que ela está em execução.

Leia mais: Onde estou? – Definição de variável de ambiente para informar a aplicação de qual é o ambiente

Nesse cenário, o código é o menos importante. O conceito é o que faz a diferença. Mas caso queira fazer o acompanhamento, aqui está o código: https://github.com/escovabit-tec-br/nodejs-env-environment

Bem, vamos ao conceito.

Nossa aplicação precisa se relacionar com o meio (ambiente) em que ela está em execução, e o meio deve influenciar como nossa aplicação se comporta. Partindo disso, podemos definir um padrão:

Deve existir uma variável de ambiente com o nome environment que pode ter os valores:

  • local
  • development
  • staging
  • production

Sabendo disso. Nossa aplicação deve ser capaz de se adaptar ao “ambiente” que se encontra, abaixo um exemplo bem simples:

const appConfig = {
  development: {
    apiUrl: "https://api.publicapis.org/entries",
  },
  production: {
    apiUrl: "https://catfact.ninja/fact",
  },
};
const environment = process.env.ENVIRONMENT || "development";
const resultData = appConfig[environment];

module.exports = resultData;

Podemos ver que o conteúdo no module.export muda de acordo com o ambiente em que e aplicação se encontra. Assim, para cada ambiente, a apiUrl será diferente.

Este é um modelo bem simples de fazer o uso deste tipo de arquitetura. Já falei aqui de um modelo mais organizado que é usando o spring-cloud.

http://3.139.95.241/2021/05/03/spring-cloud-config-server-o-que-e-e-como-criar-o-seu/

Do lado do “ambiente”, é necessário de alguma forma ter esse valor de ENVIRONMENT disponível para a aplicação. Como exemplo, vou simular a aplicação rodando em um Kubernetes.

Primeiro, criamos uma secret com o dado:

apiVersion: v1
kind: Secret
metadata:
  name: default-cfg-environment
  namespace: l2-app-backend
  labels:
    app.kubernetes.io/managed-by: Helm
  annotations:
    meta.helm.sh/release-name: base
    meta.helm.sh/release-namespace: l4-cfg-helm
type: Opaque
data:
  ENVIRONMENT: ZGV2ZWxvcG1lbnQ= #development


Abaixo em destaque a configuração no deployment:

apiVersion: apps/v1
kind: Deployment
spec:
    spec:
      containers:
        - name: ms-generic
          envFrom:
           - secretRef:
                name: default-cfg-environment

Aqui o arquivo de deployment completo com o uso da secret:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: l2-app-backend
  labels:
    app.kubernetes.io/instance: my-app
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: my-app
  annotations:
    deployment.kubernetes.io/revision: '24'
    meta.helm.sh/release-name: my-app
    meta.helm.sh/release-namespace: l2-app-backend
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/instance: my-app
      app.kubernetes.io/name: my-app
  template:
    metadata:
      creationTimestamp: null
      labels:
        app.kubernetes.io/instance: my-app
        app.kubernetes.io/managed-by: Helm
        app.kubernetes.io/name: my-app
    spec:
      containers:
        - name: ms-generic
          image: ### IMAGE NAME ###
          ports:
            - name: app
              containerPort: 3000
              protocol: TCP
          envFrom:
            - secretRef:
                name: my-app-helm
            - secretRef:
                name: default-cfg-environment
          resources: {}
          livenessProbe:
            httpGet:
              path: /metrics
              port: app
              scheme: HTTP
            initialDelaySeconds: 80
            timeoutSeconds: 10
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
          readinessProbe:
            httpGet:
              path: /metrics
              port: app
              scheme: HTTP
            initialDelaySeconds: 80
            timeoutSeconds: 10
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
          securityContext: {}
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst
      serviceAccountName: my-app
      serviceAccount: my-app
      securityContext: {}
      schedulerName: default-scheduler
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600

Com “tudo” isso feito, agora temos uma aplicação “portável” entre ambientes. Podendo assim levar a mesma aplicação sem precisar recompilar (“re-buildar”) ela.

Obrigado pela atenção, e até a próxima.

Parametrizar aplicações, segregando as responsabilidades [1/2]

Ao desenvolver aplicações devemos pensar em segregar as responsabilidades, colocar cada coisa no melhor local possível. Isso também é verdade para as variáveis e parâmetros de configuração. Trabalhar com projetos onde essas estrutura não são organizadas, faz com que o ambiente se torne caótico, confuso, pouco adaptado, lento e muito cheio de tentativas erros.

Nesse post, eu vou explicar o modelo que acredito se o mais adequado para o trabalho, demonstrar o seu formato e sua padronização.

Continue reading “Parametrizar aplicações, segregando as responsabilidades [1/2]”

Trabalhando com Spring Cloud Config Server

Nesse post, vamos falar como organizar seus projetos (micro serviços) para utilizar o Spring Cloud Config Server, esta é a forma como eu acredito ser a melhor organização, a qual sempre resolveu meus problemas nesses anos de trabalho.

Continue reading “Trabalhando com Spring Cloud Config Server”

Como organizar o Spring Boot Application Properties – Monofile e Multiple Profiles

Quando trabalhamos com o Spring Boot uma das principais necessidades é parametrizar a nossa aplicação. Isso pode se tornar um caos se não seguir algum padrão e alguma organização.

Nesse post, vamos falar sobre o que pra mim é o “melhor” modelo de como organizar essas configurações.

Continue reading “Como organizar o Spring Boot Application Properties – Monofile e Multiple Profiles”

Dependency Track – Ou como o Continuous Delivery (CD) de projetos Open Source afetam em vulnerabilidades para os seus micro serviços.

Ola, agora que já passamos pelo problema do Log4j (CVE-2021-44228) que colocou em evidencia o tema de como uma biblioteca compartilhada pode criar uma vulnerabilidade de alto risco para os sistemas.

Vamos falar de como isso acontece o tempo todo, com exite outras vulnerabilidades iguais ao Log4j, como isso é pior ainda para a modalidade de micro serviços e como minimizar os riscos do seu “ambiente”.

Continue reading “Dependency Track – Ou como o Continuous Delivery (CD) de projetos Open Source afetam em vulnerabilidades para os seus micro serviços.”

Kubernetes HPA escalando por requisições http

Ola. Nesse post, vamos tratar como fazer o HPA do Kubernetes conseguir identificar a quantidade de requisições http que o POD esta recebendo e assim escalar a quantidade de PODs de acordo com a demanda.

Essa é uma ótima alternativa do que utilizar HPA por CPU ou memória, principalmente se for aplicações Spring Boot (Java) em que muitas vezes o consumo de CPU ou memória não são indicativos de capacidade de resposta.

Continue reading “Kubernetes HPA escalando por requisições http”

Nomeando Namespaces no Kubernetes – Modelo 4 camadas

O K8s (sigla para Kubernetes) tem um modelo de divisão lógica para as aplicações chamado de Namespaces. Contudo, não existe um modelo oficial de como nomear, categorizar e/ou organizar essas Namespaces. Nesse post, vamos conversar sobre um ótimo modelo, bem funcional e que facilita em muito o dia a dia de quem utiliza o K8s.

Continue reading “Nomeando Namespaces no Kubernetes – Modelo 4 camadas”

Modelo das 5 camadas no CI/CD

Sempre que vou falar sobre CI/CD (Continuous integration and continuous delivery) e principalmente de pipeline para fazer essa automatização, sinto que falta esse conhecimento nas pessoas. Entender que é possível dividir a responsabilidades e tarefas, segregar o seu conteúdo e ter algo mais “modular”.

Nesse modelo temos 5 camadas, sendo elas: Código, Teste, Artefato, Distribuição e Publicação.

Continue reading “Modelo das 5 camadas no CI/CD”

IaC Ansible – Estruturando um inventário

Na ideia de fazer um IaC precisamos ter um local que represente o estado de como nossa estrutura deve ser, para o Ansible esse local é o inventory. Nele ficam armazenadas as informações dos seus hosts e variáveis que são usadas na execução do seu playbook.

A dificuldade esta em como “montar” um “bom” inventário, pois nem tudo esta bem claro na documentação. 🙂

Continue reading “IaC Ansible – Estruturando um inventário”