Cómo administrar el estado de Terraform en un bucket S3 de AWS

En este artículo, veremos qué es un estado Terraform y cómo gestionarlo en un S3 Bucket. También veremos qué es un «bloqueo» en Terraform y cómo implementarlo. Para implementarlo, necesitamos crear un Bucket S3 y una Tabla DynamoDB en AWS.

Antes de continuar, vamos a entender los conceptos básicos de Terraform state y Lock.

  • Estado deTerraform (archivo terraform.tstate):
    El archivo de estado contiene información sobre qué recursos existen definidos en los archivos de configuración de terraform. Por ejemplo, si has creado una Instancia EC2 utilizando terraform config, entonces el archivo de estado contiene información sobre el recurso real que se ha creado en AWS.
  • S3 como Backend para almacenar el archivo de Estado:
    Si estamos trabajando en equipo, entonces es bueno almacenar el archivo de estado de terraform remotamente para que las personas del equipo puedan acceder a él. Para almacenar el estado de forma remota necesitamos dos cosas: un bucket s3 para almacenar el archivo de estado y un recurso backend s3 de terraform.
  • Bloqueo:
    Si almacenamos el archivo de estado de forma remota para que muchas personas puedan acceder a él, corremos el riesgo de que varias personas intenten realizar cambios en el mismo archivo exactamente al mismo tiempo. Así que necesitamos un mecanismo que «bloquee» el estado si está siendo utilizado por otros usuarios. Podemos conseguirlo creando una tabla dynamoDB para que la utilice terraform.

Aquí veremos todos los pasos, desde crear manualmente un Bucket de S3, añadirle la política necesaria, crear la Tabla DynamoDB utilizando Terraform y configurar Terraform para que utilice S3 como Backend y DynamoDB para almacenar el bloqueo.

Requisitos previos

  1. Conocimientos básicos de Terraform.
  2. Conocimientos básicos de S3 Bucket.
  3. Terraform instalado en tu sistema.
  4. Cuenta de AWS(Créala si no tienes una).
  5. ‘access_key’ & ‘secret_key’ de un Usuario IAM de AWS. (Haz clic aquí para aprender a crear un usuario IAM con ‘access_key’ & ‘secret_key’ en AWS, )

Qué vamos a hacer

  1. Crear un Bucket de S3 y adjuntarle una Política.
  2. Crear una Tabla DynamoDB utilizando Terraform
  3. Crear una instancia EC2 utilizando los archivos de configuración de Terraform.
  4. Eliminar la instancia EC2 creada utilizando Terraform.

Crea un Bucket S3 y adjúntale una Política.

Haz clic aquí para aprender a crear un Bucket S3 en una cuenta AWS. Una vez que hayas creado un Bucket, adjúntale la siguiente Política.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1560164441598",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:PutObject*",
                "s3:List*",
                "s3:Get*",
                "s3:Delete*"
            ],
            "Resource": [
                "arn:aws:s3:::state-lock-rahul",
                "arn:aws:s3:::state-lock-rahul/*"
            ]
        }
    ]
}

Configura «AWS_ACCESS_KEY_ID» y «AWS_SECRET_ACCESS_KEY» para que puedas acceder a tu cuenta desde la CLI.

Utiliza el siguiente comando para exportar los valores de «AWS_ACCESS_KEY_ID» y «AWS_SECRET_ACCESS_KEY

export AWS_ACCESS_KEY_ID=AKIAQ6GAIA5XC2XMMM7W
export AWS_SECRET_ACCESS_KEY=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
echo $AWS_ACCESS_KEY_ID
echo $AWS_SECRET_ACCESS_KEY

Una vez que hayas configurado tus credenciales, puedes simplemente probarlas listando los buckets mediante el siguiente comando.

aws s3 ls

Crea una tabla DynamoDB utilizando Terraform

Crea ‘variables.tf’ que contiene las variables necesarias para la declaración.

vim variables.tf

variable "region" {
     description = "Region of AWS VPC"
}

Crea ‘main.tf’ que se encargará de crear una Tabla DynamoDB. Este main.tf leerá los valores de las variables desde variables.tf. Esta tabla se utilizará para almacenar el bloqueo.

provider "aws" {
      region     = "${var.region}"
}
resource "aws_dynamodb_table" "terraform_locks" {
  name         = "rahul-test-dynamodb-table"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"
  attribute {
    name = "LockID"
    type = "S"
  }
}

El primer comando a utilizar es ‘terraform init’. Este comando descarga e instala los plugins de los proveedores utilizados en la configuración. En nuestro caso es AWS.

terraform init

El segundo comando a utilizar es ‘terraform plan’. Este comando se utiliza para ver los cambios que se producirán en la infraestructura.

terraform plan

El comando «terraformar aplicar» creará los recursos en AWS mencionados en el archivo main.tf. Se te pedirá que proporciones tus datos para crear los recursos.

terraformar aplicar

Ahora, puedes ir al Panel de DynamoDB en la consola para comprobar si la Tabla se ha creado o no.

Hasta este momento, hemos creado un Bucket S3 manualmente desde la Consola S3 y una Tabla DynamoDB utilizando Terraform. No hemos configurado el Bucket de S3 como Backend para almacenar el estado ni la Tabla DynamoDB para almacenar el bloqueo.

Para lograr nuestro objetivo, tenemos que modificar nuestro archivo main.tf de Terraform. Tras modificar el código y ejecutarlo, nuestro estado local preexistente se copiará en el Backend de S3.

Actualiza nuestro main.tf existente con el siguiente código.

vim main.tf

provider "aws" {
      region     = "${var.region}"
}
 
 
terraform {
  backend "s3" {
    bucket         = "state-lock-rahul"
    key            = "test/terraform.tfstate"
    region         = "eu-west-3"
    dynamodb_table = "rahul-test-dynamodb-table"
  }
}
 
 
resource "aws_dynamodb_table" "terraform_locks" {
  name         = "rahul-test-dynamodb-table"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"
  attribute {
    name = "LockID"
    type = "S"
  }
}

Ahora, si intentas el comando «terraformar plan» para ver qué nuevo recurso se creará, el comando fallará con el siguiente error.

Se te pedirá que reinicies el backend.

Para reinicializar el backend, utiliza el comando «terraform init». En este paso, tu archivo de estado local se copiará en S3 Bucket.

terraform init

Puedes observar la salida como se muestra en la siguiente captura de pantalla después de ejecutar el comando «terraform init», Terraform se ha habilitado para utilizar DynamoDb Table para adquirir el bloqueo. Una vez habilitado el bloqueo, no se pueden realizar dos operaciones iguales en el mismo recurso de forma paralela.

Puedes ir al Panel de S3 desde la consola de AWS para ver si el terraform.tfstate se ha copiado o no.

Ahora, de nuevo puedes crear un nuevo recurso y ver que el estado se almacenará en S3 Bucket. Para crear una nueva tabla DynamoDB Test, actualiza el archivo main.tf con el siguiente código.

vim main.tf

variable "region" {
     description = "Region of AWS VPC"
}

Rahuls-MacBook-Pro:terraform rahul$ cat main.tf 
provider "aws" {
      region     = "${var.region}"
}


terraform {
  backend "s3" {
    bucket         = "state-lock-rahul"
    key            = "test/terraform.tfstate"
    region         = "eu-west-3"
    dynamodb_table = "rahul-test-dynamodb-table"
  }
}

resource "aws_dynamodb_table" "terraform_locks" {
  name         = "rahul-test-dynamodb-table"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"
  attribute {
    name = "LockID"
    type = "S"
  }
}


resource "aws_dynamodb_table" "test-table" {
  name         = "rahul-test-table"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"
  attribute {
    name = "LockID"
    type = "S"
  }
}

Esta vez, no es necesario ejecutar «terraform init» ya que no hay ningún cambio en el Backend del Proveedor.

Puedes utilizar simplemente el comando «terraform plan» para ver qué nuevos recursos se crearán.

terraform plan

Ahora, ejecuta el siguiente comando para crear una nueva Tabla de Prueba DynamoDb.

terraformar aplicar

En la captura de pantalla anterior, puedes ver que se ha activado el Bloqueo y que el archivo .tfstate se está copiando en S3.

Ahora, en la consola puedes ver que se ha creado la nueva tabla

Ahora, si ya no necesitas el recurso que has creado utilizando Terraform, utiliza el siguiente comando para eliminar los recursos.

terraform destroy

En cuanto elimines los recursos, podrás ver que también se ha eliminado la tabla que se estaba utilizando para el bloqueo. Si tampoco necesitas el S3 Bucket, puedes eliminarlo desde la consola.

Conclusión

En este artículo, hemos aprendido sobre la necesidad de utilizar un estado remoto y el bloqueo en Terraform. Vimos los pasos para utilizar S3 Bucket como Backend para almacenar el Estado de Terraform y la Tabla DynamoDb para habilitar el Bloqueo.

Scroll al inicio