DEV Community

Cover image for AWS Systems Manager Parameter Store: 7 práticas recomendadas ao usar AWS SSM Parameter Store
Eduardo Rabelo
Eduardo Rabelo

Posted on

AWS Systems Manager Parameter Store: 7 práticas recomendadas ao usar AWS SSM Parameter Store

Créditos da Imagem

Segurança é um dos 5 pilares do AWS Well-Architected Framework, pode ser alcançada aplicando práticas recomendadas e princípios no IAM, Encriptação, Compliance e Governança. Obviamente, as melhores práticas não são suficientes, você precisa estar sempre atento. Nesse artigo, compartilho as nossas melhores práticas e dicas ao trabalhar com o AWS SSM Parameter Store. Minha esperança é incentivá-lo a criar e implantar aplicativos seguros e confiáveis, e também, compartilhar sua experiência nos comentários.

Como você sabe, o AWS Lambda oferece suporte a variáveis ​​de ambiente, você pode definir e adicionar com facilidade quaisquer variáveis ​​de ambiente que desejar durante a implantação ou alteração no AWS Console Management. Mas o uso de variáveis ​​de ambiente contém algumas desvantagens:

  • São armazenadas como texto puro que são fáceis de ver seu valor. Você tem a opção de criptografar variáveis ​​no console usando o KMS, mas como é contabilizado por cada invocação, o aumento da sua fatura é inviável.
  • Difícil de compartilhar entre projetos e equipes, aumentando complexidade nos seus aplicativos e serviços. Mais complexidade requer mais tempo para operar e aumenta o custo; portanto, você ficará de fora da condicional de Excelência Operacional do Well-Architected Framework.
  • De acordo com Yan Cui, é difícil implementar o acesso refinado a dados confidenciais.

O que é o AWS Systems Manager Parameter Store (também conhecido como SSM Parameter Store)?

O AWS Systems Manager Parameter Store fornece armazenamento hierárquico seguro para gerenciamento de dados de configuração e gerenciamento de segredos. Você pode armazenar dados como senhas, strings de banco de dados e códigos de licença como valores de parâmetro. Você pode armazenar valores como texto sem formatação ou dados criptografados. Você pode fazer referência a valores usando o nome exclusivo que você especificou ao criar o parâmetro. Altamente escalável, disponível e durável, o Parameter Store é suportado pela nuvem da AWS. -- AWS

Quais são os benefícios?

Há muitos benefícios ao usar o AWS SSM Parameter Store, eu apenas os copiei da documentação da AWS:

  • Use um serviço de gerenciamento de segredos seguro, escalável e hospedado, sem servidores para gerenciar.
  • Melhore sua postura de segurança, separando seus dados do seu código.
  • Armazene dados de configuração e strings de forma segura em hierarquias e com acesso a suas versões.
  • Controlar e auditar o acesso em níveis granulares.
  • Configure notificações de alteração e acione ações automatizadas para parâmetros e políticas de parâmetro.
  • Marque (Tag) os parâmetros individualmente e, em seguida, proteja o acesso de diferentes níveis, incluindo nível operacional, parâmetros, tags do Amazon EC2 e por caminho da chave.
  • Consulte os segredos do AWS Secrets Manager usando os parâmetros do Parameter Store.
  • Use os parâmetros de armazenamento de parâmetros com outros recursos do Systems Manager e serviços da AWS para recuperar segredos e dados de configuração de um armazenamento central.
  • Configure a integração com os serviços da AWS para criptografia, notificação, monitoramento e auditoria.

Agora que você entende (mais ou menos) o que é o repositório de parâmetros do SSM e seus desafios, vamos falar sobre como o usamos, revisando as seguintes práticas recomendadas e dicas.

1 - Organizando parâmetros em hierarquias

A AWS fornece instruções detalhadas sobre como organizar seu armazenamento de parâmetros do SSM para definir e gerenciar parâmetros facilmente. Seguir as melhores práticas pode ajudá-lo a facilitar sua vida. Abaixo estão alguns formatos / convenções que nossa equipe normalmente usa:

nossa convenção é:

/<environment>/<service-name>/<type>/<application-name>/<parameter_name>

ficando:

/prod/billing/databases/invoicing-portal/db_connection_string

Você também pode adicionar o nome do seu departamento, ou seja:

/prod/human-resource/employee/user_list

2 - Use uma convenção de nomenclatura consistente

O uso de uma hierarquia bem definida ajuda a gerenciar e recuperar parâmetros com mais eficiência, mas você também precisa usar uma convenção de nomenclatura consistente em sua conta da AWS, entre departamentos e equipes.

Ao implementar essa prática recomendada, ela reduz seus esforços de revisão, concentrando-se na lógica crítica dos negócios, e não nos padrões de sintaxe e nomeação, e depois, aumenta sua produtividade e qualidade, que pode aumentar a satisfação do cliente.

3 - Restrinja permissões com IAM

O AWS SSM Parameter Store contém suas informações confidenciais; portanto, são necessárias permissões restritas para melhorar sua segurança. Cada repositório de parâmetros possui um ARN de recurso exclusivo por conta e região, para que você possa definir com mais facilidade a função e a base de políticas na hierarquia do repositório de parâmetros.

Abaixo está um código de exemplo da documentação oficial da AWS que mostra como definir uma política para restringir o acesso ao armazenamento de parâmetros

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:*"
            ],
            "Resource": "arn:aws:ssm:us-east-2::parameter/*"
        },
        {
            "Effect": "Deny",
            "Action": [
                "ssm:GetParametersByPath"
            ],
            "Condition": {
                "StringEquals": {
                    "ssm:Recursive": [
                        "true"
                    ]
                }
            },
            "Resource": "arn:aws:ssm:us-east-2:123456789012:parameter/Dev/ERP/Oracle/*"
        },
        {
            "Effect": "Deny",
            "Action": [
                "ssm:PutParameter"
            ],
            "Condition": {
                "StringEquals": {
                    "ssm:Overwrite": [
                        "false"
                    ]
                }
            },
            "Resource": "arn:aws:ssm:us-east-2:123456789012:parameter/*"
        }
    ]
}

4 - Combine em um único parâmetro, como strings de conexão com o banco de dados, e mantenha tudo junto (co-localizados)

Usando hierarquias consistentes e convenção de nomenclatura, você pode implementar essa ideia. Manter todos os parâmetros relacionados juntos facilita a localização e a recuperação. Usar menos parâmetros pode reduzir sua fatura.

Ao invés de usar 4 parâmetros separados para a cadeia de conexão do banco de dados, como abaixo:

/{env}/{service}/databases/master/host = db.domain.com
                               /user = username
                               /password = password
                               /port = 3306

Combinamos em um único parâmetro usando um formato de string de conexão padrão:

/{env}/{service}/databases/master/db_connection = jdbc://username:password@db_host:port/database_name

Usando bibliotecas open-source, como connection-string-parser, você pode facilmente analisar os valores dos parâmetros e usar para abrir a conexão, veja abaixo o trecho de código:

import { createConnection as createConnectionPromise, Connection } from 'promise-mysql';
import { ConnectionStringParser } from 'connection-string-parser';

const parseConnectionString = (dialect: string, connectionUri: string) => {
  const connectionParser = new ConnectionStringParser({
    scheme: dialect || 'mysql',
    hosts: []
  });
  const connectionStrParams = connectionParser.parse(connectionUri);

  return {
    host: connectionStrParams.hosts[0].host,
    port: connectionStrParams.hosts[0].port || 3306,
    database: connectionStrParams.endpoint,
    user: connectionStrParams.username,
    password: connectionStrParams.password
  };
};

export const createConnection = (connectionUri: string): Promise<Connection> => {
  return createConnectionPromise(parseConnectionString('mysql', connectionUri));
};

5 - Use uma ferramenta/biblioteca para buscar, armazenar em cache e exportar para variáveis ​​de ambiente em tempo de execução

Você é cobrado pela utilização da API do Parameter Store, sempre que recuperar um parâmetro, você aumentará sua fatura. O que você poderia fazer para reduzir esse custo?

Por padrão, o limite máximo para recuperar parâmetros pela API é de 1000 requisições por segundo, como você gerencia e evita atingir esse limite?

Yan Cui escreveu um artigo descrevendo os motivos pelos quais você deve usar AWS SSM Parameter Store ao invés de variáveis de ambiente na AWS Lambda, ele também mencionou abordagens para armazenamento em cache e expiração de cache usando uma biblioteca de cliente personalizada.

Nossa equipe está usando o middleware middy para lidar com algumas preocupações fora da nossa lógica de negócios, como análise e validação de entradas, serialização de saída, tratamento de erros. A configuração do aplicativo também é um aspecto que todo desenvolvedor precisa elaborar e gerenciar para executar a lógica de negócios. Pronto para uso, o middy fornece parâmetros de busca e suporte a cache com o middleware ssm do AWS SSM Parameter Store, além de atribuir valores de parâmetro a variáveis ​​de ambiente.

Aqui está um código de exemplo sobre como usar o middy para buscar e armazenar em cache os parâmetros:

const middy = require('middy');
const { ssm } = require('middy/middlewares');

export const handler = middy((event, context, cb) => {
  // Você pode acessar os parâmetros na sua função
  console.log(process.env.HARVESTAR_PCMSS_DB_CONNECTION);

  // Sua lógica de negócio aqui
}).use(
  ssm({
    cache: true,
    names: {
      // Nomenclatura incluindo o prefíxo desse serviço "pcmss"
      HARVESTAR_PCMSS_DB_CONNECTION: '/dev/harvestar/pcmss/db_connection'
    }
  })
);

Existem algumas bibliotecas alternativas de código aberto por aí:

Você realmente confia no pacote da comunidade?

Ouvi de algumas pessoas, basicamente, que elas não querem atribuir variáveis ​​a variáveis ​​de ambiente (ou seja, variáveis ​​que você pode acessar através do objeto global process.env em tempo de execução do Node.js.). Se você fizer isso, tenho alguns conselhos, como abaixo:

  • Ao invés de atribuir variáveis ​​a variáveis ​​de ambiente, você tem outra opção que é atribuir o objeto de contexto do AWS Lambda ao usar o middleware middy/ssm.
  • Para evitar o envio de informações confidenciais como credenciais, acesso ao diretório /tmp ou a execução de um processo filho ao usar funções serverless. Você pode usar a biblioteca @puresec/function-shield. Também estamos usando-a em nosso ambiente de produção.

Evite buscar parâmetros na hora de build/deploy, busque-os em tempo de execução. Se você buscar em tempo de build/deploy, precisará realizar um build/deploy sempre que um parâmetro for alterado.

6 - Usando hardcoded variáveis ​​de ambiente para o seu desenvolvimento local

Você precisa executar sua função localmente e ela chama diretamente o AWS SSM Parameter Store? A resposta é opcional, mas para o seu ambiente local, talvez você não precise usar o AWS SSM Parameter Store, você pode usar um arquivo .env para manter suas variáveis ​​locais. Abaixo estão algumas abordagens que você pode usar para usar essa ideia. Observe que você ainda precisa testar sua função no ambiente da AWS:

  • Use a biblioteca env-cmd para carregar, extrair e atribuir ao objeto global process.env. Executando o comando env-cmd serverless offline, você pode acessar todas as variáveis ​​definidas no seu arquivo .env.
  • Usando o plugin serverless-secrets-plugin para definir a variável de ambiente de maneira segura, você pode compartilhar mais facilmente com a equipe e comitar o arquivo criptografado.

Usando o mesmo código com uma pequena modificação, você pode pular a busca de parâmetros no AWS e reduzir sua fatura:

const middy = require('middy');
const { ssm } = require('middy/middlewares');

const isLocalEnv = process.env.IS_OFFLINE || process.env.IS_LOCAL;

export const handler = middy((event, context, cb) => {
  // Você pode acessar os parâmetros na sua função
  console.log(process.env.HARVESTAR_PCMSS_DB_CONNECTION);

  // Sua lógica de negócio aqui
}).use(
  ssm({
    cache: true,
    // Ou usar o "paramsLoaded", você diz ao middleware para
    // não buscar os parâmetros no AWS SSM
    paramsLoaded: isLocalEnv,
    names: {
      // Nomenclatura incluindo o prefíxo desse serviço "pcmss"
      HARVESTAR_PCMSS_DB_CONNECTION: '/dev/harvestar/pcmss/db_connection'
    }
  })
);

7 - Preste atenção aos limites de serviços

Assim como outros serviços da AWS, o AWS SSM Parameter Store também possui alguns limites, como o número máximo de parâmetros por conta e região, tamanho máximo do valor do parâmetro e histórico máximo. Entender seus limites nos ajuda a projetar e construir aplicativos com alta confiabilidade. Por exemplo, evite armazenar itens grandes no parâmetro SSM devido aos limites de tamanho (4KB para o padrão e 8KB para o parâmetro avançado). Consulte a documentação dos limites de serviço da AWS para saber mais.

Finalizando

Ao aplicar as práticas recomendadas, você pode implementar seus aplicativos de modo mais confiável, seguro, eficiente e econômico na nuvem.

Espero que este artigo traga algumas idéias para você e economize seu tempo. Existem artigos mais interessantes e úteis, recomendo a leitura para obter mais informações. Compartilhe suas recomendações ou sugestões nos comentários abaixo.

Obrigado pela leitura! 🥳


Créditos

Top comments (0)