Best practice per l'utilizzo di Terraform [closed]


111

Sto trasferendo la nostra infrastruttura in terraform. Qual è la migliore pratica per gestire effettivamente i file terraform e lo stato? Mi rendo conto che è infrastruttura come codice e invierò i miei file .tf in git, ma effettuo anche il commit tfstate? Dovrebbe risiedere da qualche parte come S3? Alla fine vorrei che CI gestisse tutto questo, ma è molto complicato e mi richiede di capire i pezzi in movimento per i file.

Sto solo cercando di vedere come le persone là fuori utilizzano effettivamente questo tipo di cose nella produzione

Risposte:


85

Sono anche in uno stato di migrazione dell'infrastruttura AWS esistente a Terraform, quindi cercherò di aggiornare la risposta durante lo sviluppo.

Ho fatto molto affidamento sugli esempi ufficiali di Terraform e su molteplici tentativi ed errori per rimpolpare aree in cui ero incerto.

.tfstate File

La configurazione di Terraform può essere utilizzata per eseguire il provisioning di molte scatole su infrastrutture diverse, ognuna delle quali potrebbe avere uno stato diverso. Poiché può essere eseguito anche da più persone, questo stato dovrebbe trovarsi in una posizione centralizzata (come S3) ma non in git.

Questo può essere confermato guardando la Terraform .gitignore.

Controllo dello sviluppatore

Il nostro scopo è fornire un maggiore controllo dell'infrastruttura agli sviluppatori mantenendo un controllo completo (log git) e la capacità di controllare l'integrità delle modifiche (richieste pull). Con questo in mente, il nuovo flusso di lavoro dell'infrastruttura a cui sto mirando è:

  1. Base di base di AMI comuni che includono moduli riutilizzabili, ad esempio fantoccio.
  2. Infrastruttura principale fornita da DevOps utilizzando Terraform.
  3. Gli sviluppatori modificano la configurazione di Terraform in Git secondo necessità (numero di istanze; nuovo VPC; aggiunta di regione / zona di disponibilità ecc.).
  4. Configurazione di Git inviata e richiesta di pull inviata per essere verificata da un membro della squadra DevOps.
  5. Se approvato, chiama il webhook a CI per creare e distribuire (non è sicuro come partizionare più ambienti in questo momento)

Modifica 1 - Aggiorna allo stato attuale

Da quando ho iniziato questa risposta ho scritto molto codice TF e mi sento più a mio agio nel nostro stato di cose. Abbiamo riscontrato bug e restrizioni lungo il percorso, ma accetto che questa sia una caratteristica dell'utilizzo di software nuovo e in rapida evoluzione.

disposizione

Abbiamo una complessa infrastruttura AWS con più VPC, ciascuno con più sottoreti. La chiave per gestirlo facilmente è stata definire una tassonomia flessibile che comprenda regione, ambiente, servizio e proprietario che possiamo utilizzare per organizzare il nostro codice infrastrutturale (sia terraform che fantoccio).

moduli

Il passo successivo è stato creare un unico repository git per memorizzare i nostri moduli terraform. La nostra struttura dir di primo livello per i moduli è simile a questa:

tree -L 1 .

Risultato:

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

Ognuno imposta alcuni valori predefiniti sani, ma li espone come variabili che possono essere sovrascritte dalla nostra "colla".

Colla

Abbiamo un secondo repository con il nostro glueche utilizza i moduli sopra menzionati. È strutturato in linea con il nostro documento di tassonomia:

.
├── 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

All'interno del livello client abbiamo .tffile specifici dell'account AWS che forniscono risorse globali (come i ruoli IAM); il prossimo è il livello regionale con le chiavi pubbliche EC2 SSH; Finalmente nel nostro ambiente ( dev, stg, prodecc) sono il nostro setup VPC, creazione dell'istanza e scrutando le connessioni ecc, sono memorizzati.

Nota a margine: come puoi vedere, vado contro il mio stesso consiglio di mantenere terraform.tfstatein git. Questa è una misura temporanea fino al passaggio a S3, ma mi va bene perché sono attualmente l'unico sviluppatore.

Prossimi passi

Questo è ancora un processo manuale e non in Jenkins ancora, ma stiamo portando un'infrastruttura piuttosto grande e complicata e finora tutto bene. Come ho detto, pochi bug ma stanno andando bene!

Modifica 2 - Modifiche

È passato quasi un anno da quando ho scritto questa risposta iniziale e lo stato sia di Terraform che di me è cambiato in modo significativo. Ora sono in una nuova posizione che utilizza Terraform per gestire un cluster Azure e Terraform lo è ora v0.10.7.

Stato

Le persone mi hanno ripetutamente detto che lo stato non dovrebbe andare in Git - e hanno ragione. Lo abbiamo utilizzato come misura provvisoria con un team di due persone che faceva affidamento sulla comunicazione e sulla disciplina degli sviluppatori. Con un team più ampio e distribuito, ora stiamo sfruttando appieno lo stato remoto in S3 con il blocco fornito da DynamoDB. Idealmente questo verrà migrato a console ora che è v1.0 per tagliare i provider di cloud incrociati.

moduli

In precedenza abbiamo creato e utilizzato moduli interni. Questo è ancora il caso, ma con l'avvento e la crescita del registro Terraform cerchiamo di usarli almeno come base.

Struttura dei file

La nuova posizione ha una tassonomia molto più semplice con solo due ambienti infx - deve prod. Ognuno ha le proprie variabili e output, riutilizzando i nostri moduli creati sopra. Il remote_stateprovider aiuta anche a condividere gli output delle risorse create tra gli ambienti. Il nostro scenario è costituito da sottodomini in diversi gruppi di risorse di Azure in un TLD gestito a livello globale.

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

Pianificazione

Di nuovo con le sfide extra di un team distribuito, ora salviamo sempre il nostro output del terraform plancomando. Possiamo ispezionare e sapere cosa verrà eseguito senza il rischio di alcune modifiche tra lo stadio plane apply(sebbene il blocco aiuti in questo). Ricordarsi di eliminare questo file del piano in quanto potrebbe contenere variabili "segrete" di testo semplice.

Nel complesso siamo molto soddisfatti di Terraform e continuiamo a imparare e migliorare con le nuove funzionalità aggiunte.


Hai avuto fortuna / problemi dopo questa risposta? Il tuo sembra molto simile a quello che intendo fare, ma potresti essere più avanti di me.
Marc Young

3
Sono curioso di sapere perché pensi che i file tfstate non dovrebbero essere archiviati in git? È semplicemente perché non vale la pena salvare il vecchio stato o ci sono altri problemi?
agbodike

3
@agbodike - Quando si lavora come singolo sviluppatore o parte di un team molto piccolo, tfstate può essere mantenuto in git fintanto che viene regolarmente impegnato e spinto per evitare conflitti. Il mio prossimo passo è impostarlo secondo i loro documenti sullo stato remoto in S3 (che dicono anche: "rende complicato lavorare con Terraform in un team poiché è una fonte frequente di conflitti di unione. Lo stato remoto aiuta ad alleviare questi problemi.") . Come con la maggior parte delle cose, anche se una buona comunicazione di squadra può aiutare ad alleviare la maggior parte / tutti i problemi indipendentemente dalla tattica da tenere :-)
Ewan

1
@ the0ther - Temo che il mio repository principale sia proprietario, ma attualmente sto lavorando a uno personale che renderò disponibile pubblicamente in un futuro molto prossimo.
Ewan

2
Hai avuto fortuna con un repository Git @Ewan? Mi piacerebbe vedere cosa stai facendo.
David

85

Usiamo molto Terraform e la nostra configurazione consigliata è la seguente:

Layout del file

Consigliamo vivamente di memorizzare il codice Terraform per ciascuno dei tuoi ambienti (ad esempio stage, prod, qa) in set separati di modelli (e quindi, .tfstatefile separati ). Questo è importante in modo che i tuoi ambienti separati siano effettivamente isolati l'uno dall'altro durante le modifiche. Altrimenti, mentre si scherza con un po 'di codice in fase di staging, è troppo facile far saltare in aria qualcosa anche in prod. Vedi Terraform, VPC e perché vuoi un file tfstate per env per una discussione colorata sul perché.

Pertanto, il nostro layout di file tipico è simile a questo:

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

Tutto il codice Terraform per lo stage VPC va nella stagecartella, tutto il codice per il prod VPC va nella prodcartella e tutto il codice che risiede al di fuori di un VPC (es. Utenti IAM, argomenti SNS, bucket S3) va nella globalcartella .

Nota che, per convenzione, in genere suddividiamo il nostro codice Terraform in 3 file:

  • vars.tf: Variabili di input.
  • outputs.tf: Variabili di output.
  • main.tf: Le risorse effettive.

moduli

Tipicamente, definiamo la nostra infrastruttura in due cartelle:

  1. infrastructure-modules: Questa cartella contiene piccoli moduli riutilizzabili con versione. Pensa a ogni modulo come a un modello per come creare un singolo pezzo di infrastruttura, come un VPC o un database.
  2. infrastructure-live: Questa cartella contiene l'effettiva infrastruttura live in esecuzione, che crea combinando i moduli in infrastructure-modules. Pensa al codice in questa cartella come alle case reali che hai costruito dai tuoi progetti.

Un modulo Terraform è un qualsiasi insieme di modelli Terraform in una cartella. Ad esempio, potremmo avere una cartella chiamata vpcin infrastructure-modulesche definisce tutte le tabelle di route, le sottoreti, i gateway, gli ACL e così via per un singolo VPC:

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

Possiamo quindi utilizzare quel modulo in infrastructure-live/stagee infrastructure-live/prodper creare lo stage e produrre VPC. Ad esempio, ecco come infrastructure-live/stage/main.tfpotrebbe apparire:

module "stage_vpc" {
  source = "git::git@github.com: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"
}

Per usare un modulo, usate la modulerisorsa e puntate il suo sourcecampo su un percorso locale sul vostro disco rigido (es. source = "../infrastructure-modules/vpc") O, come nell'esempio sopra, su un URL Git (vedi sorgenti del modulo ). Il vantaggio dell'URL Git è che possiamo specificare uno specifico git sha1 o tag ( ref=v0.0.4). Ora, non solo definiamo la nostra infrastruttura come un gruppo di piccoli moduli, ma possiamo anche aggiornare tali moduli e aggiornarli o ripristinarli con cura, se necessario.

Abbiamo creato una serie di pacchetti di infrastruttura riutilizzabili, testati e documentati per la creazione di VPC, cluster Docker, database e così via, e sotto il cofano, la maggior parte di essi sono solo moduli Terraform con versione.

Stato

Quando utilizzi Terraform per creare risorse (ad esempio istanze EC2, database, VPC), registra le informazioni su ciò che ha creato in un .tfstatefile. Per apportare modifiche a queste risorse, tutti i membri del tuo team devono accedere a questo stesso .tfstatefile, ma NON dovresti archiviarlo in Git (vedi qui per una spiegazione del motivo ).

Consigliamo invece di archiviare i .tfstatefile in S3 abilitando Terraform Remote State , che automaticamente spinge / estrae i file più recenti ogni volta che esegui Terraform. Assicurati di abilitare il controllo delle versioni nel tuo bucket S3 in modo da poter ripristinare i .tfstatefile più vecchi nel caso in cui tu abbia in qualche modo corrotto l'ultima versione. Tuttavia, una nota importante: Terraform non fornisce il blocco . Quindi, se due membri del team vengono eseguiti terraform applycontemporaneamente sullo stesso .tfstatefile, potrebbero finire per sovrascrivere le modifiche a vicenda.

Per risolvere questo problema, abbiamo creato uno strumento open source chiamato Terragrunt , che è un wrapper sottile per Terraform che utilizza Amazon DynamoDB per fornire il blocco (che dovrebbe essere completamente gratuito per la maggior parte dei team). Controlla Aggiungi blocco automatico dello stato remoto e configurazione a Terraform con Terragrunt per maggiori informazioni.

Ulteriore lettura

Abbiamo appena iniziato una serie di post sul blog chiamati A Comprehensive Guide to Terraform che descrive in dettaglio tutte le migliori pratiche che abbiamo imparato per l'utilizzo di Terraform nel mondo reale.

Aggiornamento: la serie di post del blog Guida completa a Terraform è diventata così popolare che l'abbiamo espansa in un libro chiamato Terraform: Up & Running !


Penso che questa sia la risposta corretta. Usa i moduli, creane una versione e mantieni gli ambienti separati.
wrangler

Il passaggio di configurazione remota deve essere rieseguito ogni volta che si desidera lavorare su un diverso componente terraform / ambiente / modulo / qualunque cosa se non si utilizza terragrunt o qualche altro wrapper?
jmreicha

@jmreicha: devi eseguire remote configse hai appena controllato le configurazioni di Terraform o se desideri modificare una configurazione remota precedente. Terraform 0.9 introdurrà il concetto di backends, che semplificherà molto questo. Vedi questo PR per maggiori dettagli.
Yevgeniy Brikman,

Solo per farmi capire: sto lavorando su un "palco" ambientale, ma poi inizio a lavorare su "prod". Avrò bisogno di rieseguire il remote configcomando per puntare allo stato prod. Supponendo stato diverso per ambiente. È giusto? Attendo con ansia la v0.9.
jmreicha

Se avessi intenzione di distribuire lo stesso identico set di .tffile in due ambienti diversi, sì, dovresti eseguire remote configogni volta che cambi. Questo è ovviamente molto soggetto a errori, quindi non consiglio di utilizzare effettivamente questa tecnica. Invece, controlla il layout del file Terraform consigliato in questo post del blog insieme a come utilizzare i moduli Terraform in questo post del blog .
Yevgeniy Brikman,

9

In precedenza lo remote configconsentiva, ma ora è stato sostituito da " backend ", quindi terraform remote non è più disponibile.

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

Vedere i documenti per i dettagli.


La sorgente remota deve essere riconfigurata ogni volta che si desidera lavorare su un diverso componente / ambiente / modulo / altro terraform?
jmreicha

6

Coperto in modo più approfondito da @Yevgeny Brikman ma rispondendo specificamente alle domande dell'OP:

Qual è la migliore pratica per gestire effettivamente i file terraform e lo stato?

Usa git per i file TF. Ma non controllare i file di stato in (es. Tfstate). Utilizzare invece Terragruntper la sincronizzazione / blocco dei file di stato su S3.

ma mi impegno anche tfstate?

No.

Dovrebbe risiedere da qualche parte come S3?


2

So che ci sono molte risposte qui, ma il mio approccio è abbastanza diverso.

   Modules
   Environment management 
   Separation of duties

moduli

  1. Crea moduli per raccolte logiche di risorse. Esempio: se il tuo obiettivo è distribuire un'API, che richiede un database, macchine virtuali ad alta disponibilità, scalabilità automatica, DNS, PubSub e archiviazione di oggetti, tutte queste risorse dovrebbero essere basate su modelli in un singolo modulo.
  2. Evita di creare moduli che utilizzano una singola risorsa. Questo può ed è stato fatto e molti moduli nel registro lo fanno, ma è una pratica che aiuta con l'accessibilità delle risorse piuttosto che con l'orchestrazione dell'infrastruttura. Esempio: un modulo per AWS EC2 aiuta l'utente ad accedere a EC2 rendendo le configurazioni complesse più semplici da richiamare, ma un modulo come l'esempio in 1. assiste l'utente durante l'orchestrazione di applicazioni, componenti o infrastrutture guidate dai servizi.
    1. Evita le dichiarazioni di risorse nel tuo spazio di lavoro. Si tratta più di mantenere il codice ordinato e organizzato. Poiché i moduli possono essere facilmente controllati, hai un maggiore controllo sulle tue versioni.

Gestione dell'ambiente

IaC ha reso il processo SDLC rilevante per la gestione dell'infrastruttura e non è normale aspettarsi di avere un'infrastruttura di sviluppo e ambienti applicativi di sviluppo.

  1. Non utilizzare cartelle per gestire i tuoi ambienti IaC. Ciò porta alla deriva poiché non esiste un modello comune per la tua infrastruttura.
  2. Utilizzare un unico spazio di lavoro e variabili per controllare le specifiche dell'ambiente. Esempio: scrivi i tuoi moduli in modo che quando cambi la variabile d'ambiente (var.stage è popolare) il piano si modifica per soddisfare le tue esigenze. In genere gli ambienti dovrebbero variare il meno possibile con quantità, esposizione e capacità che di solito sono le configurazioni variabili. Dev potrebbe distribuire 1 VM con 1 core e 1 GB di RAM in topologia privata, ma la produzione potrebbe essere 3 VM con 2 core e 4 GB di RAM con topologia pubblica aggiuntiva. Ovviamente puoi avere più variazioni: dev può eseguire il processo di database sullo stesso server dell'applicazione per risparmiare sui costi, ma la produzione potrebbe avere un'istanza database dedicata. Tutto questo può essere gestito modificando una singola variabile, istruzioni ternarie e interpolazione.

Separazione dei compiti

Se fai parte di una piccola organizzazione o gestisci un'infrastruttura personale, ciò non si applica realmente, ma ti aiuterà a gestire le tue operazioni.

  1. Suddividi la tua infrastruttura in base a compiti, responsabilità o team. Esempio: controllo IT centrale sottostante ai servizi condivisi (reti virtuali, sottoreti, indirizzi IP pubblici, gruppi di log, risorse di governance, DB multi-tenant, chiavi condivise, ecc.) Mentre il team API controlla solo le risorse necessarie per il loro servizio (VM, LB , PubSub ecc.) E utilizzano i servizi IT centrali tramite l'origine dati e le ricerche di stato remote.
    1. Governare l'accesso del team. Esempio: l'IT centrale può disporre dei diritti di amministratore ma il team API ha accesso solo a un set limitato di API del cloud pubblico.

Questo aiuta anche con i problemi di rilascio poiché troverai alcune risorse raramente cambiate mentre altre cambiano continuamente. La separazione elimina rischi e complessità.

Questa strategia traccia paralleli con la strategia multi account di AWS. Dai una lettura per maggiori informazioni.

CI / CD

Questo è un argomento a sé stante, ma Terraform funziona molto bene all'interno di una buona pipeline. L'errore più comune qui è trattare CI come un proiettile d'argento. Tecnicamente Terraform dovrebbe fornire l'infrastruttura solo durante le fasi di una pipeline di assemblaggio. Questo sarebbe separato da ciò che accade nelle fasi CI in cui in genere si convalidano e si testano i modelli.

NB Scritto su cellulare quindi si prega di scusare eventuali errori.


0

Prima che le risposte siano state molto solide e istruttive, cercherò di aggiungere i miei 2 centesimi qui

Consigli comuni per strutturare il codice

  1. È più facile e veloce lavorare con un numero minore di risorse:

    • Cmds terraform plane terraformapply effettuano entrambi chiamate API cloud per verificare lo stato delle risorse.
    • Se hai l'intera infrastruttura in una singola composizione, questo può richiedere molti minuti (anche se hai più file nella stessa cartella).
  2. Il raggio dell'esplosione è più piccolo con meno risorse:

    • Isolare le risorse non correlate l'una dall'altra mettendole in composizioni separate (cartelle) riduce il rischio se qualcosa va storto.
  3. Inizia il tuo progetto utilizzando lo stato remoto:

  4. Prova a praticare una struttura coerente e una convenzione di denominazione:

    • Come il codice procedurale, il codice Terraform dovrebbe essere scritto in modo che le persone lo leggano per primo, la coerenza aiuterà quando le modifiche avvengono tra sei mesi.
    • È possibile spostare le risorse nel file di stato Terraform, ma potrebbe essere più difficile se si dispone di una struttura e di nomi incoerenti.
  5. Mantieni i moduli delle risorse il più semplici possibile.

  6. Non codificare valori che possono essere passati come variabili o scoperti utilizzando origini dati.

  7. Usa le datafonti e in terraform_remote_stateparticolare come collante tra i moduli infrastrutturali all'interno della composizione.

( articolo di riferimento: https://www.terraform-best-practices.com/code-structure )


Esempio:

È più facile e veloce lavorare con un numero inferiore di risorse, quindi di seguito presentiamo un layout di codice consigliato.

NOTA: solo come riferimento da non seguire rigorosamente poiché ogni progetto ha le sue caratteristiche specifiche

.
├── 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

0

Credo che ci siano poche best practice da seguire durante l'utilizzo di terraform per orchestrare l'infrastruttura

  1. Non scrivere più lo stesso codice (Riusabilità)
  2. Mantieni separata la configurazione dell'ambiente per mantenerla facilmente.
  3. Utilizza il backend remoto s3 (crittografato) e Dynamo DB per gestire il blocco della concorrenza
  4. Crea un modulo e usa quel modulo nell'infrastruttura principale più volte, è come una funzione riutilizzabile che può essere chiamata più volte passando un parametro diverso.

Gestisci più ambienti

La maggior parte delle volte il modo consigliato è utilizzare lo "spazio di lavoro" terraform per gestire più ambienti, ma credo che l'utilizzo dello spazio di lavoro possa variare in base al modo di lavorare in un'organizzazione. Altro è memorizzare il codice Terraform per ciascuno dei tuoi ambienti (ad esempio stage, prod, QA) per separare gli stati dell'ambiente. Tuttavia, in questo caso stiamo solo copiando lo stesso codice in molti posti.

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

Ho seguito un approccio diverso per gestire ed evitare la duplicazione dello stesso codice terraform mantenendolo in ogni cartella dell'ambiente poiché credo che la maggior parte delle volte tutto l'ambiente sarebbe uguale al 90%.

├── 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

Configurazione relativa agli ambienti

Mantieni la configurazione ei parametri relativi all'ambiente separati in un file variabile e trasferisci quel valore per configurare l'infrastruttura. ad esempio come sotto

  • 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"

Salto condizionale della parte dell'infrastruttura

Crea una configurazione in un file variabile specifico env e in base a quella variabile decidi di creare o saltare quella parte. In questo modo in base alle necessità è possibile saltare la parte specifica dell'infrastruttura.

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"
}

sotto il comando è necessario per inizializzare ed eseguire le modifiche di infra per ogni ambiente, cd nella cartella dell'ambiente richiesta.

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

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

Per riferimento: https://github.com/mattyait/devops_terraform


0

Non mi piace l'idea delle sottocartelle perché questo si tradurrà in fonti diverse per ambiente e questo tende a spostarsi.

L'approccio migliore è avere un unico stack per tutti gli ambienti (diciamo dev, preprod e prod). Per lavorare su un unico ambiente usa terraform workspace.

terraform workspace new dev

Questo crea un nuovo spazio di lavoro. Questo include un file di stato dedicato e la variabile terraform.workspaceche puoi usare nel tuo codice.

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

In questo modo verranno chiamati i bucket

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

dopo l'applicazione alle aree di lavoro sopra (utilizzare terraform workspace select <WORKSPACE>per modificare gli ambienti). Per rendere il codice anche a prova di multi-regione, fallo in questo modo:

data "aws_region" "current" {}

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

da ottenere (per la regione us-east-1)

  • my-tf-test-bucket noi-est-1-dev
  • my-tf-test-bucket noi-est-1-preprod
  • my-tf-test-bucket noi-est-1-prod

0

Alcune best practice di Terraform da seguire:

  1. Evita l'hard coding: a volte gli sviluppatori creano manualmente le risorse direttamente. È necessario contrassegnare queste risorse e utilizzare l'importazione di terraform per includerle nei codici. Un campione:

    account_number = "123456789012" account_alias = "mycompany"

  2. Esegui Terraform da un container Docker: Terraform rilascia un container Docker ufficiale che ti consente di controllare facilmente quale versione puoi eseguire.

Si consiglia di eseguire il container Docker Terraform quando si imposta il lavoro di compilazione nella pipeline 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"

Per ulteriori informazioni, fare riferimento al mio blog: https://medium.com/tech-darwinbox/how-darwinbox-manages-infrastructure-at-scale-with-terraform-371e2c5f04d3


0

Mi piacerebbe contribuire a questo thread.

  • Molto probabilmente sarà AWS S3 + DynamoDB a meno che non si utilizzi Terraform Cloud.
  • Infrastruttura separata (rete + RBAC) di backend di produzione e non di produzione.
  • Pianificare la disabilitazione dell'accesso ai file di stato (accesso alla rete e RBAC) dall'esterno di una rete designata (ad es. Pool di agenti di distribuzione).
  • Non mantenere l'infrastruttura di backend Terraform con l'ambiente di runtime. Usa un account separato.
  • Abilita il controllo delle versioni degli oggetti sui tuoi backend Terraform per evitare di perdere modifiche e file di stato e per mantenere la cronologia dello stato di Terraform.

In alcuni casi speciali, sarà richiesto l'accesso manuale ai file di stato Terraform. Cose come il refactoring, la rottura delle modifiche o la correzione di difetti richiederanno l'esecuzione di operazioni di stato Terraform da parte del personale operativo. Per tali occasioni, pianifica un accesso controllato straordinario allo stato Terraform utilizzando bastion host, VPN ecc.

Consulta un blog di best practice più lungo che copre questo aspetto in dettaglio, comprese le linee guida per le pipeline CI / CD.


-1

Se stai ancora cercando la soluzione migliore, dai un'occhiata alle aree di lavoro che possono sostituire il mantenimento di una struttura di cartelle di ambiente diversa che può avere variabili specifiche dell'area di lavoro.

Come Yevgeniy Brikman menzionato è meglio avere una struttura moduli.


-1

Usa terraform cloud per gestire e salvare stati, insieme ai consigli sopra.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.