También estoy en un estado de migración de la infraestructura de AWS existente a Terraform, por lo que intentaré actualizar la respuesta a medida que la desarrolle.
Me he basado en gran medida en los ejemplos oficiales de Terraform y en múltiples pruebas y errores para desarrollar áreas en las que no estaba seguro.
.tfstate
archivos
La configuración de Terraform se puede utilizar para aprovisionar muchas cajas en diferentes infraestructuras, cada una de las cuales podría tener un estado diferente. Como también puede ser ejecutado por varias personas, este estado debe estar en una ubicación centralizada (como S3) pero no en git.
Esto se puede confirmar mirando el Terraform .gitignore
.
Control del desarrollador
Nuestro objetivo es proporcionar un mayor control de la infraestructura a los desarrolladores al tiempo que mantenemos una auditoría completa (git log) y la capacidad de verificar los cambios (solicitudes de extracción). Con eso en mente, el nuevo flujo de trabajo de infraestructura al que apunto es:
- Base de base de AMI comunes que incluyen módulos reutilizables, por ejemplo, títeres.
- Infraestructura central provista por DevOps usando Terraform.
- Los desarrolladores cambian la configuración de Terraform en Git según sea necesario (número de instancias; nueva VPC; adición de región / zona de disponibilidad, etc.).
- Se envió la configuración de Git y se envió una solicitud de extracción para que un miembro del equipo de DevOps verificara la cordura.
- Si se aprueba, llama al webhook a CI para compilar e implementar (no está seguro de cómo particionar múltiples entornos en este momento)
Edición 1: actualización del estado actual
Desde que comencé esta respuesta, he escrito mucho código TF y me siento más cómodo en nuestro estado de cosas. Hemos encontrado errores y restricciones en el camino, pero acepto que esta es una característica del uso de software nuevo que cambia rápidamente.
Diseño
Tenemos una infraestructura de AWS complicada con varias VPC, cada una con varias subredes. La clave para gestionar esto fácilmente fue definir una taxonomía flexible que abarque la región, el medio ambiente, el servicio y el propietario, que podamos utilizar para organizar nuestro código de infraestructura (tanto terraform como títere).
Módulos
El siguiente paso fue crear un único repositorio de git para almacenar nuestros módulos terraform. Nuestra estructura de directorios de nivel superior para los módulos se ve así:
tree -L 1 .
Resultado:
├── README.md
├── aws-asg
├── aws-ec2
├── aws-elb
├── aws-rds
├── aws-sg
├── aws-vpc
└── templates
Cada uno establece algunos valores por defecto sensatos pero los expone como variables que pueden ser sobrescritas por nuestro "pegamento".
pegamento
Tenemos un segundo repositorio con nuestro glue
que hace uso de los módulos mencionados anteriormente. Se presenta de acuerdo con nuestro documento de taxonomía:
.
├── 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 del nivel de cliente, tenemos .tf
archivos específicos de la cuenta de AWS que proporcionan recursos globales (como roles de IAM); el siguiente es el nivel de región con claves públicas EC2 SSH; Por último, en nuestro entorno ( dev
, stg
, prod
etc.) son nuestra configuraciones de VPC, la creación de instancias y mirando uniones y conexiones están almacenados.
Nota al margen: Como puede ver, voy en contra de mi propio consejo anterior de mantenerme terraform.tfstate
en git. Esta es una medida temporal hasta que me cambie a S3, pero me conviene ya que actualmente soy el único desarrollador.
Próximos pasos
Este sigue siendo un proceso manual y aún no está en Jenkins, pero estamos portando una infraestructura bastante grande y complicada y hasta ahora todo va bien. Como dije, ¡pocos errores pero van bien!
Edición 2 - Cambios
Ha pasado casi un año desde que escribí esta respuesta inicial y el estado de Terraform y yo hemos cambiado significativamente. Ahora estoy en una nueva posición usando Terraform para administrar un clúster de Azure y Terraform ahora v0.10.7
.
Estado
La gente me ha dicho repetidamente que el estado no debería entrar en Git, y tienen razón. Usamos esto como una medida provisional con un equipo de dos personas que se basó en la comunicación y la disciplina de los desarrolladores. Con un equipo distribuido más grande, ahora estamos aprovechando por completo el estado remoto en S3 con el bloqueo proporcionado por DynamoDB. Idealmente, esto se migrará a consul ahora es v1.0 para cortar proveedores de nube cruzada.
Módulos
Anteriormente creamos y usamos módulos internos. Este sigue siendo el caso, pero con la llegada y el crecimiento del registro de Terraform , intentamos utilizarlos como al menos una base.
Estructura de archivo
La nueva posición tiene una taxonomía mucho más simple con solo dos entornos infx: dev
y prod
. Cada uno tiene sus propias variables y salidas, reutilizando nuestros módulos creados anteriormente. El remote_state
proveedor también ayuda a compartir los resultados de los recursos creados entre entornos. Nuestro escenario son los subdominios en diferentes grupos de recursos de Azure para un TLD administrado globalmente.
├── main.tf
├── dev
│ ├── main.tf
│ ├── output.tf
│ └── variables.tf
└── prod
├── main.tf
├── output.tf
└── variables.tf
Planificación
Nuevamente, con los desafíos adicionales de un equipo distribuido, ahora siempre guardamos nuestra salida del terraform plan
comando. Podemos inspeccionar y saber qué se ejecutará sin el riesgo de algunos cambios entre la etapa plan
y apply
(aunque el bloqueo ayuda con esto). Recuerde eliminar este archivo de plan, ya que podría contener variables "secretas" de texto sin formato.
En general, estamos muy contentos con Terraform y seguimos aprendiendo y mejorando con las nuevas funciones agregadas.
Usamos Terraform en gran medida y nuestra configuración recomendada es la siguiente:
Diseño de archivo
Recomendamos encarecidamente almacenar el código de Terraform para cada uno de sus entornos (por ejemplo, stage, prod, qa) en conjuntos separados de plantillas (y por lo tanto,
.tfstate
archivos separados ). Esto es importante para que sus entornos separados estén realmente aislados entre sí al realizar cambios. De lo contrario, mientras se juega con algo de código en la puesta en escena, también es muy fácil hacer estallar algo en la producción. Consulte Terraform, VPC y por qué desea un archivo tfstate por env para una explicación detallada de por qué.Por lo tanto, nuestro diseño de archivo típico se ve así:
Todo el código de Terraform para la VPC de etapa va a la
stage
carpeta, todo el código de la VPC de producción va a laprod
carpeta y todo el código que vive fuera de una VPC (por ejemplo, usuarios de IAM, temas de SNS, depósitos de S3) va a laglobal
carpeta .Tenga en cuenta que, por convención, normalmente dividimos nuestro código Terraform en 3 archivos:
vars.tf
: Variables de entrada.outputs.tf
: Variables de salida.main.tf
: Los recursos reales.Módulos
Normalmente, definimos nuestra infraestructura en dos carpetas:
infrastructure-modules
: Esta carpeta contiene módulos pequeños, reutilizables y con versiones. Piense en cada módulo como un modelo de cómo crear una única pieza de infraestructura, como una VPC o una base de datos.infrastructure-live
: Esta carpeta contiene la infraestructura real en ejecución, que crea combinando los módulos eninfrastructure-modules
. Piense en el código de esta carpeta como las casas reales que construyó a partir de sus planos.Un módulo de Terraform es cualquier conjunto de plantillas de Terraform en una carpeta. Por ejemplo, podríamos tener una carpeta llamada
vpc
eninfrastructure-modules
que define todas las tablas de enrutamiento, subredes, puertas de enlace, ACL, etc. para una sola VPC:Luego, podemos usar ese módulo en
infrastructure-live/stage
yinfrastructure-live/prod
para crear las VPC de etapa y producción. Por ejemplo, esto es lo queinfrastructure-live/stage/main.tf
podría parecer:Para usar un módulo, use el
module
recurso y apunte susource
campo a una ruta local en su disco duro (por ejemplosource = "../infrastructure-modules/vpc"
) o, como en el ejemplo anterior, una URL de Git (vea las fuentes del módulo ). La ventaja de la URL de Git es que podemos especificar un git sha1 o tag (ref=v0.0.4
) específico . Ahora, no solo definimos nuestra infraestructura como un grupo de pequeños módulos, sino que podemos versionar esos módulos y actualizarlos o deshacerlos cuidadosamente según sea necesario.Hemos creado una serie de paquetes de infraestructura reutilizables, probados y documentados para crear VPC, clústeres de Docker, bases de datos, etc., y bajo el capó, la mayoría de ellos son solo módulos Terraform versionados.
Estado
Cuando usa Terraform para crear recursos (por ejemplo, instancias EC2, bases de datos, VPC), registra información sobre lo que creó en un
.tfstate
archivo. Para realizar cambios en esos recursos, todos los miembros de su equipo necesitan acceso a este mismo.tfstate
archivo, pero NO debe registrarlo en Git (consulte aquí para obtener una explicación del motivo ).En su lugar, recomendamos almacenar
.tfstate
archivos en S3 habilitando Terraform Remote State , que automáticamente empujará / extraerá los archivos más recientes cada vez que ejecute Terraform. Asegúrese de habilitar el control de versiones en su bucket de S3 para que pueda volver a.tfstate
archivos más antiguos en caso de que de alguna manera corrompa la última versión. Sin embargo, una nota importante: Terraform no proporciona bloqueo . Entonces, si dos miembros del equipo se ejecutanterraform apply
al mismo tiempo en el mismo.tfstate
archivo, es posible que terminen sobrescribiendo los cambios del otro.Para resolver este problema, creamos una herramienta de código abierto llamada Terragrunt , que es un contenedor delgado para Terraform que usa Amazon DynamoDB para proporcionar bloqueo (que debería ser completamente gratuito para la mayoría de los equipos). Consulte Agregar configuración y bloqueo de estado remoto automático a Terraform con Terragrunt para obtener más información.
Otras lecturas
Acabamos de comenzar una serie de publicaciones de blog llamadas Una guía completa de Terraform que describe en detalle todas las mejores prácticas que hemos aprendido para usar Terraform en el mundo real.
Actualización: la serie de publicaciones de blog de la Guía completa de Terraform se hizo tan popular que la expandimos a un libro llamado Terraform: Up & Running !
fuente
remote config
si acaba de verificar sus configuraciones de Terraform o si desea cambiar una configuración remota anterior. Terraform 0.9 introducirá el concepto debackends
, que simplificará mucho esto. Vea este PR para más detalles.remote config
comando para apuntar al estado de prod. Suponiendo un estado diferente por entorno. ¿Está bien? Espero la v0.9..tf
archivos en dos entornos diferentes, sí, necesitaría ejecutarloremote config
cada vez que cambiara. Obviamente, esto es muy propenso a errores, por lo que no recomiendo usar esta técnica. En su lugar, consulte el diseño de archivo de Terraform recomendado en esta publicación de blog junto con cómo usar los módulos de Terraform en esta publicación de blog .Anteriormente
remote config
permitía esto, pero ahora ha sido reemplazado por " backends ", por lo que terraform remote ya no está disponible.Consulte los documentos para obtener más detalles.
fuente
Cubierto con más profundidad por @Yevgeny Brikman pero respondiendo específicamente a las preguntas del OP:
Utilice git para archivos TF. Pero no registre los archivos de estado (es decir, tfstate). En su lugar, utilice
Terragrunt
para sincronizar / bloquear archivos de estado en S3.No.
si
fuente
Sé que hay muchas respuestas aquí, pero mi enfoque es bastante diferente.
Módulos
Gestión medioambiental
IaC ha hecho que el proceso SDLC sea relevante para la gestión de la infraestructura y no es normal esperar tener una infraestructura de desarrollo y entornos de aplicaciones de desarrollo.
Separación de tareas
Si está en una organización pequeña o está ejecutando una infraestructura personal, esto realmente no se aplica, pero lo ayudará a administrar sus operaciones.
Esto también ayuda con las preocupaciones de liberación, ya que encontrará que algunos recursos rara vez cambian, mientras que otros cambian todo el tiempo. La separación elimina el riesgo y la complejidad.
Esta estrategia establece un paralelismo con la estrategia de cuentas múltiples de AWS. Lea para obtener más información.
CI / CD
Este es un tema en sí mismo, pero Terraform funciona muy bien dentro de una buena canalización. El error más común aquí es tratar la IC como una solución milagrosa. Técnicamente, Terraform solo debería aprovisionar infraestructura durante las etapas de una tubería de ensamblaje. Esto sería independiente de lo que sucede en las etapas de CI, donde normalmente se validan y prueban las plantillas.
NB Escrito en el móvil, así que disculpe cualquier error.
fuente
Recomendaciones comunes para estructurar código
Es más fácil y rápido trabajar con una menor cantidad de recursos:
terraform plan
yterraform
apply hacen llamadas a la API en la nube para verificar el estado de los recursos.El radio de explosión es más pequeño con menos recursos:
Inicie su proyecto usando el estado remoto:
tfstate
archivo en git es una pesadilla.Intente practicar una estructura coherente y una convención de nomenclatura:
Mantenga los módulos de recursos lo más sencillos posible.
No codifique valores que puedan pasarse como variables o descubrirse utilizando fuentes de datos.
Utilice
data
fuentes yterraform_remote_state
específicamente como un pegamento entre los módulos de infraestructura dentro de la composición.( artículo de referencia: https://www.terraform-best-practices.com/code-structure )
Ejemplo:
NOTA: solo como referencia no se debe seguir estrictamente ya que cada proyecto tiene sus propias características específicas
fuente
Creo que es necesario seguir algunas prácticas recomendadas al utilizar terraform para orquestar la infraestructura.
Manejar múltiples entornos
La mayoría de las veces, la forma recomendada es usar terraform 'espacio de trabajo' para manejar los múltiples entornos, pero creo que el uso del espacio de trabajo podría variar según la forma de trabajo en una organización. Otro es almacenar el código de Terraform para cada uno de sus entornos (por ejemplo, etapa, prod, QA) para separar los estados del entorno. Sin embargo, en este caso solo estamos copiando el mismo código en muchos lugares.
Seguí un enfoque diferente para manejar y evitar la duplicación del mismo código de terraform manteniéndolo en cada carpeta de entorno, ya que creo que la mayoría de las veces todos los entornos serían 90% iguales.
Configuración relacionada con los entornos
Mantenga la configuración y los parámetros relacionados con el entorno separados en un archivo variable y transfiera ese valor para configurar la infraestructura. por ejemplo, como a continuación
dev.backend.tfvar
dev.variable.tfvar
Omisión condicional de la parte de infraestructura
Cree una configuración en un archivo de variable específico de env y, en función de esa variable, decida crear u omitir esa parte. De esta manera, según la necesidad, se puede omitir la parte específica de la infraestructura.
Se requiere el siguiente comando para inicializar y ejecutar los cambios de infraestructura para cada entorno, cd a la carpeta de entorno requerida.
fuente
No me gusta la idea de subcarpetas porque esto dará como resultado diferentes fuentes por entorno y esto tiende a desviarse.
El mejor enfoque es tener una sola pila para todos los entornos (digamos dev, preprod y prod). Para trabajar en un solo uso ambiental
terraform workspace
.Esto crea un nuevo espacio de trabajo. Esto incluye un archivo de estado dedicado y la variable
terraform.workspace
que puede usar en su código.De esta manera obtendrá cubos llamados
después de aplicar a los espacios de trabajo anteriores (se usa
terraform workspace select <WORKSPACE>
para cambiar de entorno). Para hacer que el código sea incluso a prueba de múltiples regiones, hágalo así:to get (para la región us-east-1)
fuente
Algunas mejores prácticas de Terraform a seguir:
Evite la codificación rígida: a veces, los desarrolladores crean recursos manualmente directamente. Debe marcar estos recursos y utilizar terraform import para incluirlos en los códigos. Una muestra:
account_number = “123456789012" account_alias = "mycompany"
Ejecute Terraform desde un contenedor Docker: Terraform lanza un contenedor Docker oficial que le permite controlar fácilmente qué versión puede ejecutar.
Se recomienda ejecutar el contenedor Terraform Docker cuando configure su trabajo de compilación en la canalización de CI / CD.
Para obtener más información, consulte mi blog: https://medium.com/tech-darwinbox/how-darwinbox-manages-infrastructure-at-scale-with-terraform-371e2c5f04d3
fuente
Me gustaría contribuir a este hilo.
En algunos casos especiales, se requerirá acceso manual a los archivos de estado de Terraform. Cosas como refactorizar, romper cambios o arreglar defectos requerirán que el personal de operaciones ejecute las operaciones estatales de Terraform. Para tales ocasiones, planifique un acceso controlado extraordinario al estado de Terraform utilizando un host bastión, VPN, etc.
Consulte un blog de mejores prácticas más extenso que cubre esto en detalle, incluidas las pautas para las canalizaciones de CI / CD.
fuente
Si todavía está buscando la mejor solución, eche un vistazo a los espacios de trabajo que pueden reemplazar el mantenimiento de una estructura de carpetas de entorno diferente que puede tener variables específicas del espacio de trabajo.
Como mencionó Yevgeniy Brikman , es mejor tener una estructura de módulos.
fuente
Utilice terraform cloud para administrar y guardar estados, junto con los consejos anteriores.
fuente