providers - Diferentes entornos para Terraform(Hashicorp).
terraform vs ansible (5)
He estado utilizando Terraform para construir mi pila de AWS y lo he estado disfrutando. Si se utilizara en un entorno comercial, la configuración tendría que reutilizarse para diferentes entornos (por ejemplo, control de calidad, STAGING, PROD).
¿Cómo podría lograr esto? ¿Necesitaría crear un script de envoltorio que haga llamadas a cli de terraform mientras se pasan diferentes archivos de estado por entorno como se muestra a continuación? Me pregunto si hay una solución más nativa provista por Terraform.
terraform apply -state=qa.tfstate
A medida que amplíe su uso de Terraform, deberá compartir el estado (entre desarrolladores, procesos de compilación y diferentes proyectos), soportar múltiples entornos y regiones. Para esto necesitas usar el estado remoto. Antes de ejecutar su terraform necesita configurar su estado. (Estoy usando PowerShell)
$environment="devtestexample"
$region ="eu-west-1"
$remote_state_bucket = "${environment}-terraform-state"
$bucket_key = "yoursharedobject.$region.tfstate"
aws s3 ls "s3://$remote_state_bucket"|out-null
if ($lastexitcode)
{
aws s3 mb "s3://$remote_state_bucket"
}
terraform remote config -backend S3 -backend-config="bucket=$remote_state_bucket" -backend-config="key=$bucket_key" -backend-config="region=$region"
#(see here: https://www.terraform.io/docs/commands/remote-config.html)
terraform apply -var=''environment=$environment'' -var=''region=$region''
Su estado ahora está almacenado en S3, por región, por entorno, y luego puede acceder a este estado en otros proyectos tf.
La solución de Paul con módulos es la idea correcta. Sin embargo, recomendaría encarecidamente que no se definan todos sus entornos (por ejemplo, control de calidad, puesta en escena, producción) en el mismo archivo Terraform. Si lo hace, entonces siempre que realice un cambio en la puesta en escena, corre el riesgo de romper la producción accidentalmente, ¡lo que anula parcialmente el punto de mantener esos entornos aislados en primer lugar! Consulte https://charity.wtf/2016/03/30/terraform-vpc-and-why-you-want-a-tfstate-file-per-env/ para una discusión colorida de lo que puede salir mal.
Siempre recomiendo almacenar el código de Terraform para cada entorno en una carpeta separada. De hecho, es posible que incluso desee almacenar el código de Terraform para cada "componente" (por ejemplo, una base de datos, una VPC, una aplicación única) en carpetas separadas. Nuevamente, la razón es el aislamiento: cuando realiza cambios en una sola aplicación (lo que podría hacer 10 veces al día), no quiere poner en riesgo su VPC completo (que probablemente nunca cambie).
Por lo tanto, mi diseño de archivo típico se ve algo como esto:
stage
└ vpc
└ main.tf
└ vars.tf
└ outputs.tf
└ app
└ db
prod
└ vpc
└ app
└ db
global
└ s3
└ iam
Todo el código de Terraform para el entorno de prueba entra en la carpeta de la stage
, todo el código para el entorno de producción entra en la carpeta de prod
, y todo el código que vive fuera de un entorno (por ejemplo, usuarios de IAM, depósitos de S3) entra en la carpeta global
.
Para obtener más información, consulte Cómo administrar el estado de Terraform . Para conocer más a fondo las mejores prácticas de Terraform, consulte el libro Terraform: Up & Running .
Le sugiero que eche un vistazo al repo de mejores prácticas de hashicorp , que tiene una buena configuración para tratar con diferentes entornos (similar a lo que sugirió James Woolfenden).
Estamos usando una configuración similar, y funciona bastante bien. Sin embargo, este repo de mejores prácticas supone que estás usando Atlas, pero no lo estamos haciendo. Hemos creado un Rakefile bastante elaborado, que básicamente (siguiendo el repo de mejores prácticas) obtiene todas las subcarpetas de / terraform / suppliers / aws, y las expone como diferentes compilaciones utilizando espacios de nombres. Así que nuestra salida rake -T
las siguientes tareas:
us_east_1_prod:init
us_east_1_prod:plan
us_east_1_prod:apply
us_east_1_staging:init
us_east_1_staging:plan
us_east_1_staging:apply
Esta separación evita que los cambios que podrían ser exclusivos de dev afecten accidentalmente (o, peor aún, destruyan) algo, como un archivo de estado diferente. También permite probar un cambio en dev / staging antes de aplicarlo a prod.
Además, recientemente me topé con este pequeño artículo, que básicamente muestra lo que podría pasar si mantienes todo junto: https://charity.wtf/2016/03/30/terraform-vpc-and-why-you-want-a-tfstate-file-per-env/
No hay necesidad de hacer un script envoltorio. Lo que hacemos es dividir nuestra env en un módulo y luego tener un archivo terraform de nivel superior donde solo importamos ese módulo para cada entorno. Siempre y cuando tengas la configuración de tu módulo para tomar suficientes variables, generalmente env_name y algunas otras, eres bueno. Como ejemplo
# project/main.tf
module "dev" {
source "./env"
env = "dev"
aws_ssh_keyname = "dev_ssh"
}
module "stage" {
source "./env"
env = "stage"
aws_ssh_keyname = "stage_ssh"
}
# Then in project/env/main.tf
# All the resources would be defined in here
# along with variables for env and aws_ssh_keyname, etc.
Tenga en cuenta que a partir de la versión 0.10.0, ahora Terraform admite el concepto de áreas de trabajo (entornos en 0.9.x).
Un espacio de trabajo es un contenedor con nombre para el estado Terraform. Con múltiples espacios de trabajo, se puede usar un solo directorio de configuración de Terraform para administrar múltiples conjuntos distintos de recursos de infraestructura.
Ver más información aquí: Workspaces