Práticas recomendadas ao usar o Terraform [fechado]

111

Estou no processo de trocar nossa infraestrutura por terraforma. Qual é a melhor prática para realmente gerenciar os arquivos e estado do terrenoform? Percebi que é uma infraestrutura como código e vou comprometer meus arquivos .tf no git, mas também comprometo tfstate? Isso deve residir em algum lugar como S3? Gostaria que, eventualmente, o CI gerencie tudo isso, mas isso é muito complicado e exige que eu descubra as partes móveis dos arquivos.

Estou apenas procurando ver como as pessoas realmente utilizam esse tipo de coisa na produção

Marc Young
fonte

Respostas:

85

Também estou em um estado de migração da infraestrutura existente da AWS para o Terraform, então terei como objetivo atualizar a resposta à medida que desenvolvo.

Tenho confiado muito nos exemplos oficiais do Terraform e em várias tentativas e erros para detalhar áreas nas quais não tenho certeza.

.tfstate arquivos

A configuração do Terraform pode ser usada para provisionar muitas caixas em diferentes infraestruturas, cada uma delas com um estado diferente. Como também pode ser executado por várias pessoas, esse estado deve estar em um local centralizado (como S3), mas não git.

Isso pode ser confirmado olhando para o Terraform .gitignore.

Controle do desenvolvedor

Nosso objetivo é fornecer mais controle da infraestrutura aos desenvolvedores, mantendo uma auditoria completa (git log) e a capacidade de verificar a integridade das alterações (solicitações pull). Com isso em mente, o novo fluxo de trabalho de infraestrutura que pretendo é:

  1. Base básica de AMIs comuns que incluem módulos reutilizáveis, por exemplo, fantoches.
  2. Infraestrutura central provisionada pelo DevOps usando Terraform.
  3. Os desenvolvedores alteram a configuração do Terraform no Git conforme necessário (número de instâncias; novo VPC; adição de região / zona de disponibilidade etc.).
  4. A configuração Git foi enviada por push e uma solicitação de pull foi enviada para ser verificada por um membro do esquadrão DevOps.
  5. Se aprovado, chama webhook para CI para construir e implantar (sem saber como particionar vários ambientes neste momento)

Edição 1 - Atualização do estado atual

Desde que comecei esta resposta, escrevi muito código TF e me sinto mais confortável em nosso estado de coisas. Encontramos bugs e restrições ao longo do caminho, mas eu aceito que essa é uma característica de usar um software novo que muda rapidamente.

Layout

Temos uma infraestrutura AWS complicada com vários VPCs, cada um com várias sub-redes. A chave para gerenciar isso facilmente foi definir uma taxonomia flexível que engloba região, ambiente, serviço e proprietário, que podemos usar para organizar nosso código de infraestrutura (terraform e fantoche).

Módulos

O próximo passo foi criar um único repositório git para armazenar nossos módulos de terraform. Nossa estrutura de diretório de nível superior para os módulos se parece com isto:

tree -L 1 .

Resultado:

├── README.md
├── aws-asg
├── aws-ec2
├── aws-elb
├── aws-rds
├── aws-sg
├── aws-vpc
└── templates

Cada um define alguns padrões lógicos, mas os expõe como variáveis ​​que podem ser substituídas por nossa "cola".

Cola

Temos um segundo repositório com o nosso glueque faz uso dos módulos mencionados acima. Ele é apresentado de acordo com nosso documento de taxonomia:

.
├── README.md
├── clientA
   ├── eu-west-1
      └── dev
   └── us-east-1
       └── dev
├── clientB
   ├── eu-west-1
      ├── dev
      ├── ec2-keys.tf
      ├── prod
      └── terraform.tfstate
   ├── iam.tf
   ├── terraform.tfstate
   └── terraform.tfstate.backup
└── clientC
    ├── eu-west-1
       ├── aws.tf
       ├── dev
       ├── iam-roles.tf
       ├── ec2-keys.tf
       ├── prod
       ├── stg
       └── terraform.tfstate
    └── iam.tf

Dentro do nível do cliente, temos .tfarquivos específicos da conta da AWS que provisionam recursos globais (como funções de IAM); a seguir está o nível de região com as chaves públicas SSH EC2; Finalmente, em nosso ambiente ( dev, stg, prodetc) são a nossa setups VPC, a criação da instância e olhando conexões etc, são armazenados.

Nota lateral: Como você pode ver, estou indo contra meu próprio conselho acima de manter o terraform.tfstategit. Esta é uma medida temporária até que eu mude para o S3, mas é adequado para mim, pois sou atualmente o único desenvolvedor.

Próximos passos

Este ainda é um processo manual e não está no Jenkins, mas estamos portando uma infraestrutura bastante grande e complicada e até agora tudo bem. Como eu disse, poucos bugs mas indo bem!

Editar 2 - Mudanças

Já se passou quase um ano desde que escrevi esta resposta inicial e o estado do Terraform e de mim mudou significativamente. Agora estou em uma nova posição usando o Terraform para gerenciar um cluster do Azure e o Terraform está agora v0.10.7.

Estado

As pessoas me disseram repetidamente que o estado não deve ser usado no Git - e estão corretas. Usamos isso como uma medida provisória com uma equipe de duas pessoas que dependia da comunicação e disciplina do desenvolvedor. Com uma equipe maior e distribuída, agora estamos aproveitando totalmente o estado remoto no S3 com bloqueio fornecido pelo DynamoDB. Idealmente, isso será migrado para o cônsul agora que é v1.0 para cortar provedores de nuvem cruzada.

Módulos

Anteriormente, criamos e usamos módulos internos. Esse ainda é o caso, mas com o advento e crescimento do registro Terraform , tentamos usá-lo como pelo menos uma base.

Estrutura de arquivo

A nova posição tem uma taxonomia muito mais simples com apenas dois ambientes infx - deve prod. Cada um tem suas próprias variáveis ​​e saídas, reutilizando nossos módulos criados acima. O remote_stateprovedor também ajuda no compartilhamento de saídas de recursos criados entre ambientes. Nosso cenário é de subdomínios em diferentes grupos de recursos do Azure para um TLD gerenciado globalmente.

├── main.tf
├── dev
   ├── main.tf
   ├── output.tf
   └── variables.tf
└── prod
    ├── main.tf
    ├── output.tf
    └── variables.tf

Planejamento

Novamente com os desafios extras de uma equipe distribuída, agora sempre salvamos nossa saída do terraform plancomando. Podemos inspecionar e saber o que será executado sem o risco de algumas alterações entre o estágio plane apply(embora o bloqueio ajude nisso). Lembre-se de excluir este arquivo de plano, pois ele pode conter variáveis ​​"secretas" de texto simples.

No geral, estamos muito felizes com o Terraform e continuamos a aprender e melhorar com os novos recursos adicionados.

Ewan
fonte
Você teve alguma sorte / problemas desde esta resposta? O seu parece muito com o que pretendo fazer, mas você pode estar mais longe do que eu.
Marc Young
3
Estou curioso para saber por que você acha que os arquivos tfstate não devem ser armazenados no git? É simplesmente porque não vale a pena salvar o antigo estado ou há outros problemas?
agbodike
3
@agbodike - Ao trabalhar como um único desenvolvedor ou parte de uma equipe muito pequena, tfstate pode ser mantido em git contanto que seja regularmente submetido a commit e push para evitar conflitos. Minha próxima etapa é configurar isso de acordo com seus documentos de estado remoto no S3 (que também dizem: "isso torna o trabalho com o Terraform em uma equipe complicado, pois é uma fonte frequente de conflitos de mesclagem. O estado remoto ajuda a aliviar esses problemas.") . Como acontece com a maioria das coisas, embora uma boa comunicação de equipe possa ajudar a aliviar a maioria / todos os problemas, independentemente da tática para manter o estado :-)
Ewan
1
@ the0ther - Receio que meu repositório principal seja proprietário, no entanto, estou trabalhando em um pessoal que disponibilizarei publicamente em um futuro muito próximo.
Ewan de
2
Teve sorte em um repositório Git @Ewan? Adoraria ver o que você está fazendo.
David
85

Usamos muito o Terraform e nossa configuração recomendada é a seguinte:

Layout de arquivo

É altamente recomendável armazenar o código do Terraform para cada um de seus ambientes (por exemplo, stage, prod, qa) em conjuntos separados de modelos (e, portanto, .tfstatearquivos separados ). Isso é importante para que seus ambientes separados fiquem realmente isolados uns dos outros durante as alterações. Caso contrário, ao mexer com algum código na preparação, é muito fácil explodir algo na produção também. Consulte Terraform, VPC e por que você deseja um arquivo tfstate por env para uma discussão colorida sobre o motivo.

Portanto, nosso layout de arquivo típico é assim:

stage
   main.tf
   vars.tf
   outputs.tf
prod
   main.tf
   vars.tf
   outputs.tf
global
   main.tf
   vars.tf
   outputs.tf

Todo o código do Terraform para o VPC de estágio vai para a stagepasta, todo o código para o VPC do produto vai para a prodpasta e todo o código que reside fora de um VPC (por exemplo, usuários IAM, tópicos SNS, buckets S3) vai para a globalpasta .

Observe que, por convenção, normalmente dividimos nosso código Terraform em três arquivos:

  • vars.tf: Variáveis ​​de entrada.
  • outputs.tf: Variáveis ​​de saída.
  • main.tf: Os recursos reais.

Módulos

Normalmente, definimos nossa infraestrutura em duas pastas:

  1. infrastructure-modules: Esta pasta contém módulos pequenos e reutilizáveis ​​com versão. Pense em cada módulo como um plano de como criar uma única peça de infraestrutura, como um VPC ou um banco de dados.
  2. infrastructure-live: Esta pasta contém a infraestrutura real em execução, que ele cria combinando os módulos em infrastructure-modules. Pense no código nesta pasta como as casas reais que você construiu a partir de seus projetos.

Um módulo Terraform é qualquer conjunto de modelos Terraform em uma pasta. Por exemplo, podemos ter uma pasta chamada vpcem infrastructure-modulesque define todas as tabelas de rota, sub-redes, gateways, ACLs, etc. para um único VPC:

infrastructure-modules
   vpc
     main.tf
     vars.tf
     outputs.tf

Podemos, então, usar esse módulo em infrastructure-live/stagee infrastructure-live/prodpara criar as VPCs palco e prod. Por exemplo, infrastructure-live/stage/main.tfpode ser assim:

module "stage_vpc" {
  source = "git::[email protected]:gruntwork-io/module-vpc.git//modules/vpc-app?ref=v0.0.4"

  vpc_name         = "stage"
  aws_region       = "us-east-1"
  num_nat_gateways = 3
  cidr_block       = "10.2.0.0/18"
}

Para usar um módulo, você usa o modulerecurso e aponta seu sourcecampo para um caminho local em seu disco rígido (por exemplo source = "../infrastructure-modules/vpc") ou, como no exemplo acima, uma URL Git (consulte as fontes do módulo ). A vantagem da URL Git é que podemos especificar um git sha1 ou tag ( ref=v0.0.4) específico. Agora, não apenas definimos nossa infraestrutura como um monte de pequenos módulos, mas podemos criar uma versão desses módulos e atualizar ou reverter com cuidado, conforme necessário.

Criamos uma série de pacotes de infraestrutura reutilizáveis, testados e documentados para a criação de VPCs, clusters Docker, bancos de dados e assim por diante, e nos bastidores, a maioria deles são apenas módulos do Terraform com versão.

Estado

Quando você usa o Terraform para criar recursos (por exemplo, instâncias EC2, bancos de dados, VPCs), ele registra informações sobre o que foi criado em um .tfstatearquivo. Para fazer alterações nesses recursos, todos em sua equipe precisam acessar este mesmo .tfstatearquivo, mas você NÃO deve verificá-lo no Git (veja aqui uma explicação do porquê ).

Em vez disso, recomendamos armazenar .tfstatearquivos no S3 ativando o Terraform Remote State , que enviará / extrairá automaticamente os arquivos mais recentes sempre que você executar o Terraform. Certifique-se de habilitar o controle de versão em seu balde S3 para que você possa reverter para .tfstatearquivos mais antigos no caso de de alguma forma corromper a versão mais recente. No entanto, uma observação importante: o Terraform não fornece bloqueio . Portanto, se dois membros da equipe executam terraform applyao mesmo tempo no mesmo .tfstatearquivo, eles podem acabar substituindo as alterações um do outro.

Para resolver esse problema, criamos uma ferramenta de código aberto chamada Terragrunt , que é um wrapper fino para Terraform que usa o Amazon DynamoDB para fornecer bloqueio (que deve ser totalmente gratuito para a maioria das equipes). Confira Adicionar bloqueio automático de estado remoto e configuração ao Terraform com Terragrunt para obter mais informações.

Leitura adicional

Acabamos de começar uma série de postagens no blog chamada A Comprehensive Guide to Terraform que descreve em detalhes todas as melhores práticas que aprendemos para usar o Terraform no mundo real.

Atualização: a série de postagens do blog Guia abrangente para o Terraform se tornou tão popular que a expandimos em um livro chamado Terraform: Up & Running !

Yevgeniy Brikman
fonte
Acho que essa é a resposta correta. Use módulos, crie uma versão deles e mantenha os ambientes separados.
Wrangler
A etapa de configuração remota precisa ser executada novamente toda vez que você quiser trabalhar em um componente / ambiente / módulo / qualquer outro terraform diferente, se não estiver usando terragrunt ou algum outro wrapper?
jmreicha
@jmreicha: Você precisa executar remote configse acabou de verificar as configurações do Terraform ou se deseja alterar uma configuração remota anterior. O Terraform 0.9 apresentará o conceito de backends, o que simplificará muito isso. Veja este PR para mais detalhes.
Yevgeniy Brikman
Só para que eu entenda - estou trabalhando em um 'estágio' de ambiente, mas depois começo a trabalhar em 'prod'. Precisarei executar novamente o remote configcomando para apontar para o estado de produção. Supondo um estado diferente por ambiente. Isso está certo? Estou ansioso para v0.9.
jmreicha
Se você fosse implantar exatamente o mesmo conjunto de .tfarquivos em dois ambientes diferentes, sim, você precisaria executar remote configcada vez que alternasse. Obviamente, isso é muito sujeito a erros, portanto, não recomendo o uso dessa técnica. Em vez disso, verifique o layout do arquivo Terraform recomendado nesta postagem do blog, juntamente com como usar os módulos do Terraform nesta postagem do blog .
Yevgeniy Brikman
9

remote configPermitido anteriormente, mas agora foi substituído por " backends ", então o terraform remote não está mais disponível.

terraform remote config -backend-config="bucket=<s3_bucket_to_store_tfstate>" -backend-config="key=terraform.tfstate" -backend=s3
terraform remote pull
terraform apply
terraform remote push

Veja a documentação para detalhes.

Shantanu
fonte
A fonte remota precisa ser reconfigurada toda vez que você quiser trabalhar em um componente / ambiente / módulo / qualquer outro terrenoform?
jmreicha
6

Abordado com mais detalhes por @Yevgeny Brikman, mas respondendo especificamente às perguntas do OP:

Qual é a melhor prática para realmente gerenciar os arquivos e estado do terrenoform?

Use git para arquivos TF. Mas não verifique os arquivos de estado em (ou seja, tfstate). Em vez disso, use Terragruntpara sincronização / bloqueio de arquivos de estado para S3.

mas eu comprometo tfstate também?

Não.

Isso deve residir em algum lugar como S3?

sim

Snowcrash
fonte
2

Eu sei que há muitas respostas aqui, mas minha abordagem é bem diferente.

   Modules
   Environment management 
   Separation of duties

Módulos

  1. Crie módulos para coleções lógicas de recursos. Exemplo: se sua meta é implantar uma API, que requer um banco de dados, VMs HA, escalonamento automático, DNS, PubSub e armazenamento de objetos, todos esses recursos devem ser modelados em um único módulo.
  2. Evite criar módulos que utilizem um único recurso. Isso pode e tem sido feito e muitos módulos no registro fazem isso, mas é uma prática que ajuda na acessibilidade dos recursos, em vez da orquestração da infraestrutura. Exemplo: um módulo para AWS EC2 ajuda o usuário a acessar o EC2 tornando as configurações complexas mais simples de invocar, mas um módulo como o exemplo em 1. auxilia o usuário na orquestração de aplicativos, componentes ou infraestrutura orientada a serviços.
    1. Evite declarações de recursos em seu espaço de trabalho. Trata-se mais de manter seu código organizado e organizado. Como os módulos têm controle de versão facilmente, você tem mais controle sobre suas versões.

Gestão ambiental

IaC tornou o processo SDLC relevante para o gerenciamento de infraestrutura e não é normal esperar ter infraestrutura de desenvolvimento, bem como ambientes de aplicativos de desenvolvimento.

  1. Não use pastas para gerenciar seus ambientes IaC. Isso leva a um desvio, pois não há um modelo comum para sua infraestrutura.
  2. Use um único espaço de trabalho e variáveis ​​para controlar as especificações do ambiente. Exemplo: Escreva seus módulos de forma que, quando você alterar a variável de ambiente (var.stage é popular), o plano seja alterado para se adequar aos seus requisitos. Normalmente, os ambientes devem variar o mínimo possível, sendo a quantidade, a exposição e a capacidade normalmente as configurações variáveis. Dev pode implantar 1 VM com 1 núcleo e 1 GB de RAM em topologia privada, mas a produção pode ser de 3 VMs com 2 núcleos e 4 GB de RAM com topologia pública adicional. É claro que você pode ter mais variação: dev pode executar o processo de banco de dados no mesmo servidor que o aplicativo para economizar custos, mas a produção pode ter uma instância de banco de dados dedicada. Tudo isso pode ser gerenciado alterando uma única variável, declarações ternárias e interpolação.

Separação de deveres

Se você estiver em uma pequena organização ou administrando uma infraestrutura pessoal, isso não se aplica realmente, mas o ajudará a gerenciar suas operações.

  1. Divida sua infraestrutura por deveres, responsabilidades ou equipes. Exemplo: controle de TI central de serviços compartilhados subjacentes (redes virtuais, sub-redes, endereços IP públicos, grupos de registros, recursos de governança, bancos de dados multilocatários, chaves compartilhadas etc.), enquanto a equipe de API controla apenas os recursos necessários para seu serviço (VMs, LBs , PubSub etc.) e consumir serviços centrais de TI por meio de fontes de dados e pesquisas de estado remoto.
    1. Controle o acesso da equipe. Exemplo: a TI central pode ter direitos de administrador, mas a equipe da API só tem acesso a um conjunto restrito de APIs de nuvem pública.

Isso também ajuda com as questões de liberação, pois você descobrirá que alguns recursos raramente mudam, enquanto outros mudam o tempo todo. A separação remove o risco e a complexidade.

Essa estratégia traça paralelos com a estratégia de várias contas da AWS. Leia para mais informações.

CI / CD

Este é um tópico à parte, mas o Terraform funciona muito bem dentro de um bom pipeline. O erro mais comum aqui é tratar o IC como uma solução mágica. Tecnicamente, o Terraform deve provisionar infraestrutura apenas durante os estágios de um pipeline de montagem. Isso seria diferente do que acontece nos estágios de CI, onde normalmente se valida e testa os modelos.

NB escrito no celular, desculpe quaisquer erros.

Henry Dobson
fonte
0

Antes que as respostas tenham sido muito sólidas e informativas, tentarei adicionar meus 2 centavos aqui

Recomendações comuns para estruturar código

  1. É mais fácil e rápido trabalhar com menor número de recursos:

    • Os cmds terraform plane o terraformapply fazem chamadas de API em nuvem para verificar o status dos recursos.
    • Se você tem toda a sua infraestrutura em uma única composição, isso pode levar vários minutos (mesmo se você tiver vários arquivos na mesma pasta).
  2. O raio da explosão é menor com menos recursos:

    • Isolar recursos não relacionados uns dos outros, colocando-os em composições (pastas) separadas, reduz o risco de algo dar errado.
  3. Comece seu projeto usando o estado remoto:

  4. Tente praticar uma estrutura consistente e convenção de nomenclatura:

    • Como o código procedural, o código Terraform deve ser escrito para que as pessoas leiam primeiro. A consistência ajudará quando as mudanças acontecerem daqui a seis meses.
    • É possível mover recursos no arquivo de estado do Terraform, mas pode ser mais difícil de fazer se você tiver estrutura e nomenclatura inconsistentes.
  5. Mantenha os módulos de recursos o mais simples possível.

  6. Não codifique valores que podem ser passados ​​como variáveis ​​ou descobertos usando fontes de dados.

  7. Use datafontes e, terraform_remote_stateespecificamente, como uma cola entre os módulos de infraestrutura dentro da composição.

( artigo de referência: https://www.terraform-best-practices.com/code-structure )


Exemplo:

É mais fácil e rápido trabalhar com um número menor de recursos, portanto, a seguir apresentamos um layout de código recomendado.

NOTA: apenas como referência não deve ser seguida à risca visto que cada projeto possui características próprias

.
├── 1_tf-backend #remote AWS S3 + Dynamo Lock tfstate 
   ├── main.tf
   ├── ...
├── 2_secrets
   ├── main.tf
   ├── ...
├── 3_identities
   ├── account.tf
   ├── roles.tf
   ├── group.tf
   ├── users.tf
   ├── ...
├── 4_security
   ├── awscloudtrail.tf
   ├── awsconfig.tf
   ├── awsinspector.tf
   ├── awsguarduty.tf
   ├── awswaf.tf
   └── ...
├── 5_network
   ├── account.tf
   ├── dns_remote_zone_auth.tf
   ├── dns.tf
   ├── network.tf
   ├── network_vpc_peering_dev.tf
   ├── ...
├── 6_notifications
   ├── ...
├── 7_containers
   ├── account.tf
   ├── container_registry.tf
   ├── ...
├── config
   ├── backend.config
   └── main.config
└── readme.md
Exequiel Barrirero
fonte
0

Acredito que haja poucas práticas recomendadas a serem seguidas ao usar o terraform para orquestrar a infraestrutura

  1. Não escreva o mesmo código novamente (capacidade de reutilização)
  2. Mantenha a configuração do ambiente separada para mantê-la facilmente.
  3. Use backend remoto s3 (criptografado) e dínamo DB para lidar com o bloqueio de simultaneidade
  4. Crie um módulo e use esse módulo na infraestrutura principal várias vezes, é como uma função reutilizável que pode ser chamada várias vezes passando um parâmetro diferente.

Lidar com vários ambientes

Na maioria das vezes, a forma recomendada é usar o 'espaço de trabalho' do terraform para lidar com vários ambientes, mas acredito que o uso do espaço de trabalho pode variar de acordo com a forma de trabalho em uma organização. Outra é armazenar o código do Terraform para cada um de seus ambientes (por exemplo, stage, prod, QA) para separar os estados do ambiente. No entanto, neste caso, estamos apenas copiando o mesmo código em muitos lugares.

├── main.tf
├── dev
   ├── main.tf
   ├── output.tf
   └── variables.tf
└── prod
├── main.tf
├── output.tf
└── variables.tf

Eu segui uma abordagem diferente para lidar e evitar a duplicação do mesmo código de terraform, mantendo em cada pasta de ambiente, pois acredito que na maioria das vezes todos os ambientes seriam 90% iguais.

├── deployment
 ├── 01-network.tf
 ├── 02-ecs_cluster.tf
 ├── 03-ecs_service.tf
 ├── 04-eks_infra.tf
 ├── 05-db_infra.tf
 ├── 06-codebuild-k8s.tf
 ├── 07-aws-secret.tf
 ├── backend.tf
 ├── provider.tf
 └── variables.tf
├── env
 ├── dev
  ├── dev.backend.tfvar
  └── dev.variables.tfvar
 └── prod
 ├── prod.backend.tfvar
 └── prod.variables.tfvar
├── modules
 └── aws
 ├── compute
  ├── alb_loadbalancer
  ├── alb_target_grp
  ├── ecs_cluster
  ├── ecs_service
  └── launch_configuration
 ├── database
  ├── db_main
  ├── db_option_group
  ├── db_parameter_group
  └── db_subnet_group
 ├── developertools
 ├── network
  ├── internet_gateway
  ├── nat_gateway
  ├── route_table
  ├── security_group
  ├── subnet
  ├── vpc
 └── security
 ├── iam_role
 └── secret-manager
└── templates

Configuração relacionada a ambientes

Mantenha a configuração e os parâmetros relacionados ao ambiente separados em um arquivo de variável e passe esse valor para configurar a infraestrutura. por exemplo, como abaixo

  • dev.backend.tfvar

      region = "ap-southeast-2"
      bucket = "dev-samplebackendterraform"
      key = "dev/state.tfstate"
      dynamo_db_lock = "dev-terraform-state-lock"
  • dev.variable.tfvar

    environment                     =   "dev"
    vpc_name                        =   "demo"
    vpc_cidr_block                  =   "10.20.0.0/19"
    private_subnet_1a_cidr_block    =   "10.20.0.0/21"
    private_subnet_1b_cidr_block    =   "10.20.8.0/21"
    public_subnet_1a_cidr_block     =   "10.20.16.0/21"
    public_subnet_1b_cidr_block     =   "10.20.24.0/21"

Ignorando condicionalmente a parte da infraestrutura

Crie uma configuração em um arquivo de variável específico de env e com base nessa variável decida criar ou pular essa parte. Desta forma, com base na necessidade, a parte específica da infraestrutura pode ser ignorada.

variable vpc_create {
   default = "true"
}

module "vpc" {
  source = "../modules/aws/network/vpc"
  enable = "${var.vpc_create}"
  vpc_cidr_block = "${var.vpc_cidr_block}"
  name = "${var.vpc_name}"
 }

 resource "aws_vpc" "vpc" {
    count                = "${var.enable == "true" ? 1 : 0}"
    cidr_block           = "${var.vpc_cidr_block}"
    enable_dns_support   = "true"
   enable_dns_hostnames = "true"
}

O comando abaixo é necessário para inicializar e executar as mudanças de infra para cada ambiente, cd para a pasta de ambiente necessária.

  terraform init -var-file=dev.variables.tfvar -backend-config=dev.backend.tfvar ../../deployment/

  terraform apply -var-file=dev.variables.tfvar ../../deployment

Para referência: https://github.com/mattyait/devops_terraform

Mahattam
fonte
0

Não gosto da ideia de subpastas porque isso resultará em fontes diferentes por ambiente e isso tende a se desviar.

A melhor abordagem é ter uma única pilha para todos os ambientes (digamos dev, preprod e prod). Para trabalhar em um único ambiente de uso terraform workspace.

terraform workspace new dev

Isso cria um novo espaço de trabalho. Isso inclui um arquivo de estado dedicado e a variável que terraform.workspacevocê pode usar em seu código.

resource "aws_s3_bucket" "bucket" {
  bucket = "my-tf-test-bucket-${terraform.workspace}"
}

Desta forma, você obterá baldes chamados

  • my-tf-test-bucket-dev
  • my-tf-test-bucket-preprod
  • my-tf-test-bucket-prod

depois de se inscrever nas áreas de trabalho acima (use terraform workspace select <WORKSPACE>para alterar ambientes). Para tornar o código ainda à prova de multirregiões, faça assim:

data "aws_region" "current" {}

resource "aws_s3_bucket" "bucket" {
  bucket = "my-tf-test-bucket-${data.aws_region.current.name}-${terraform.workspace}"
}

obter (para a região us-east-1)

  • my-tf-test-bucket-us-east-1-dev
  • my-tf-test-bucket-us-east-1-preprod
  • my-tf-test-bucket-us-east-1-prod
Magister Halderian
fonte
0

Algumas práticas recomendadas do Terraform a serem seguidas:

  1. Evite a codificação permanente: às vezes, os desenvolvedores criam recursos manualmente de maneira direta. Você precisa marcar esses recursos e usar a importação de terreno para incluí-los nos códigos. Uma amostra:

    account_number = “123456789012" account_alias = "mycompany"

  2. Execute o Terraform de um contêiner do Docker: o Terraform lança um contêiner oficial do Docker que permite controlar facilmente qual versão pode ser executada.

É recomendado executar o contêiner Terraform Docker ao definir seu trabalho de compilação no pipeline de CI / CD.

TERRAFORM_IMAGE=hashicorp/terraform:0.11.7
TERRAFORM_CMD="docker run -ti --rm -w /app -v ${HOME}/.aws:/root/.aws -v ${HOME}/.ssh:/root/.ssh -v `pwd`:/app $TERRAFORM_IMAGE"

Para obter mais informações, consulte meu blog: https://medium.com/tech-darwinbox/how-darwinbox-manages-infrastructure-at-scale-with-terraform-371e2c5f04d3

ND1772
fonte
0

Eu gostaria de contribuir com este tópico.

  • Provavelmente será AWS S3 + DynamoDB, a menos que você esteja usando Terraform Cloud.
  • Infraestrutura separada (rede + RBAC) de back-ends de produção e não-prod.
  • Planeje desabilitar o acesso aos arquivos de estado (acesso à rede e RBAC) de fora de uma rede designada (por exemplo, pool de agentes de implantação).
  • Não mantenha a infraestrutura de back-end do Terraform com o ambiente de tempo de execução. Use uma conta separada.
  • Habilite o controle de versão de objetos em seus back-ends do Terraform para evitar a perda de alterações e arquivos de estado e para manter o histórico de estado do Terraform.

Em alguns casos especiais, será necessário acesso manual aos arquivos de estado do Terraform. Coisas como refatorar, interromper alterações ou corrigir defeitos exigirão a execução de operações de estado do Terraform pelo pessoal de operações. Para tais ocasiões, planeje um acesso controlado extraordinário ao estado do Terraform usando o host bastião, VPN etc.

Verifique um blog de práticas recomendadas mais longo que cobre isso em detalhes, incluindo diretrizes para pipelines de CI / CD.

Piotr Gwiazda
fonte
-1

Se você ainda estiver procurando por uma solução melhor, dê uma olhada nos espaços de trabalho que podem substituir a manutenção de uma estrutura de pasta de ambiente diferente que pode ter variáveis ​​específicas do espaço de trabalho.

Como Yevgeniy Brikman mencionou , é melhor ter uma estrutura de módulos.

Rajendra
fonte
-1

Use a nuvem terraform para gerenciar e salvar estados, juntamente com os conselhos acima.

Den Zalman
fonte