Pipeline CI/CD con Terraform y AWS CodePipeline

published on 13 February 2025

¿Quieres automatizar tus despliegues en AWS de forma eficiente y segura? Configurar un pipeline CI/CD con Terraform y AWS CodePipeline es la solución. Este enfoque combina infraestructura como código y servicios administrados para acelerar el desarrollo.

Resumen rápido:

  • Herramientas necesarias: AWS CLI (≥2.0), Terraform (≥1.0.0), Git (2.x).
  • Componentes clave:
    • Terraform: Gestiona la infraestructura.
    • AWS CodePipeline: Orquesta el flujo de despliegue.
    • AWS CodeBuild: Valida y aplica cambios de Terraform.
  • Etapas del pipeline:
    1. Origen: Detecta cambios en el repositorio.
    2. Validación: Ejecuta terraform validate y terraform fmt.
    3. Planificación: Genera un plan con terraform plan.
    4. Aprobación: Paso manual para entornos críticos.
    5. Aplicación: Implementa cambios con terraform apply.

Beneficios:

  • Automatización: Menos errores y despliegues más rápidos.
  • Seguridad: Uso de KMS, IAM, y MFA.
  • Escalabilidad: Modularidad y soporte multi-cuenta.

Con esta guía, aprenderás a configurar y optimizar un pipeline CI/CD paso a paso, integrando validaciones, seguridad y pruebas automatizadas. ¡Comienza a transformar tus procesos de despliegue hoy!

Configuración del Entorno

Prepara tu entorno con las herramientas y configuraciones necesarias para garantizar un flujo de trabajo eficiente.

Herramientas y Accesos Requeridos

Asegúrate de contar con las siguientes herramientas instaladas:

Herramienta Versión
AWS CLI ≥2.0
Terraform ≥1.0.0
Git 2.x

Si usas AWS CloudShell, estas herramientas ya vienen preinstaladas.

Además, necesitarás acceso a un repositorio en AWS CodeCommit o GitHub. Una vez que tengas todo listo, el siguiente paso será configurar los permisos IAM.

Configuración de Roles IAM

Para cumplir con las prácticas de seguridad recomendadas, deberás crear un rol IAM específico para CodePipeline:

  • Paso 1: Crea un rol IAM para CodePipeline.
  • Paso 2: Adjunta las políticas necesarias: AWSCodePipelineFullAccess y AWSCodeBuildAdminAccess.
  • Paso 3: Agrega una política personalizada para gestionar el acceso a S3 y KMS:
data "aws_iam_policy_document" "pipeline_policy" {
  statement {
    effect = "Allow"
    actions = [
      "s3:GetObject",
      "s3:GetObjectVersion",
      "s3:PutObject"
    ]
    resources = ["${aws_s3_bucket.artifacts.arn}/*"]
  }

  statement {
    effect = "Allow"
    actions = [
      "kms:Decrypt",
      "kms:GenerateDataKey"
    ]
    resources = [aws_kms_key.pipeline_key.arn]
  }
}

No olvides habilitar la autenticación multifactor (MFA) para añadir una capa adicional de seguridad [1].

Configuración de Terraform

Terraform

Terraform será clave para gestionar la infraestructura. A continuación, te mostramos cómo configurarlo:

  1. Estructura del Proyecto

Organiza los archivos de tu proyecto de la siguiente manera:

terraform-pipeline/
├── main.tf
├── variables.tf
├── outputs.tf
└── backend.tf
  1. Backend de Terraform

Configura el backend para almacenar el estado de Terraform en S3:

terraform {
  backend "s3" {
    bucket = "${var.project_name}-terraform-state"
    key    = "pipeline/terraform.tfstate"
    region = "us-west-2"
    encrypt = true
  }
}
  1. Credenciales AWS

Define las credenciales de AWS usando variables de entorno o configura AWS Single Sign-On (SSO). Para entornos de producción, es recomendable usar roles IAM con credenciales temporales para mayor seguridad [1].

Arquitectura del Pipeline

Después de configurar el entorno, diseñamos una arquitectura que combina servicios de AWS con flujos de trabajo de Terraform.

Componentes Principales

La arquitectura se basa en servicios de AWS que trabajan en conjunto con Terraform:

Componente Función Principal Relación con Terraform
AWS CodePipeline Orquestador del pipeline Coordina la ejecución de comandos de Terraform
AWS CodeCommit Repositorio de código Almacena y versiona archivos .tf
AWS CodeBuild Motor de ejecución de builds Ejecuta terraform validate, plan y apply

Etapas del Pipeline

El pipeline está organizado en pasos secuenciales que aseguran calidad y control en los despliegues:

  • Origen: El pipeline se activa automáticamente cuando hay cambios en la rama principal del repositorio.
  • Validación: En esta etapa, CodeBuild ejecuta:
    • terraform validate
    • terraform fmt -check
  • Planificación: Genera un plan de ejecución utilizando terraform plan.
  • Aprobación: Paso crucial para entornos de producción, que requiere una aprobación manual antes de proceder.
  • Aplicación: Aplica los cambios con el comando terraform apply --auto-approve.

Esta estructura establece los fundamentos necesarios para la implementación detallada que se desarrollará en la próxima sección.

Construcción del Pipeline

Después de definir la arquitectura, el siguiente paso es implementar el pipeline utilizando recursos de Terraform.

Despliegue de Recursos

El recurso principal del pipeline, CodePipeline, se configura con Terraform de la siguiente manera:

resource "aws_codepipeline" "pipeline" {
  name     = "terraform-pipeline"
  role_arn = aws_iam_role.codepipeline_role.arn

  artifact_store {
    location = aws_s3_bucket.artifact_store.bucket
    type     = "S3"

    encryption_key {
      id   = aws_kms_key.artifact_key.arn
      type = "KMS"
    }
  }
}

Este recurso se complementa con las etapas detalladas en la arquitectura previamente definida.

Configuración de Etapas

Cada etapa del pipeline utiliza un archivo buildspec para definir los comandos necesarios. Aquí tienes un ejemplo:

version: 0.2

phases:
  pre_build:
    commands:
      - wget https://releases.hashicorp.com/terraform/1.0.0/terraform_1.0.0_linux_amd64.zip
      - unzip terraform_1.0.0_linux_amd64.zip
      - mv terraform /usr/local/bin/
  build:
    commands:
      - terraform init
      - terraform validate

Este archivo asegura que las herramientas necesarias estén disponibles antes de ejecutar las validaciones y otros procesos de construcción.

Implementación de Seguridad

La seguridad del pipeline se gestiona mediante encriptación con KMS y políticas IAM específicas. Aquí tienes un ejemplo de configuración:

resource "aws_kms_key" "artifact_key" {
  description             = "Clave KMS para artefactos del pipeline"
  deletion_window_in_days = 10
  enable_key_rotation     = true
}

resource "aws_iam_role_policy" "codepipeline_kms_policy" {
  role = aws_iam_role.codepipeline_role.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Action = [
          "kms:Decrypt",
          "kms:DescribeKey",
          "kms:Encrypt",
          "kms:ReEncrypt*",
          "kms:GenerateDataKey*"
        ]
        Resource = aws_kms_key.artifact_key.arn
      }
    ]
  })
}

Estas configuraciones refuerzan el principio de privilegios mínimos, asegurando que el pipeline solo tenga acceso a los recursos necesarios para su operación. Además, la rotación automática de claves KMS agrega una capa adicional de seguridad.

sbb-itb-03dc61e

Pruebas del Pipeline

Después de configurar la infraestructura del pipeline, realizamos pruebas automatizadas en tres niveles para asegurar su correcto funcionamiento.

Validación de Código

Usamos herramientas como TFLint (para análisis de Terraform) y Checkov (para seguridad). Aquí tienes un ejemplo de configuración en YAML:

version: 0.2
phases:
  install:
    commands:
      - curl -s https://raw.githubusercontent.com/terraform-linters/tflint/master/install_linux.sh | bash
      - pip install checkov
  build:
    commands:
      - tflint --format=compact
      - checkov -d . --framework terraform --output cli

Además, personalizamos reglas específicas en el archivo .tflint.hcl para ajustar las validaciones a nuestras necesidades:

plugin "aws" {
  enabled = true
  version = "0.21.1"
  source  = "github.com/terraform-linters/tflint-ruleset-aws"
}

rule "aws_instance_invalid_type" {
  enabled = true
}

Verificación del Despliegue

Para validar la infraestructura implementada, integramos pruebas que abarcan tres áreas clave:

Nivel de Prueba Herramienta Propósito
Infraestructura AWS Config Rules Revisión de conformidad y configuración
Funcional Scripts de prueba Validación de operaciones básicas
Monitoreo CloudWatch Alarms Seguimiento de métricas importantes

En el pipeline, incluimos scripts que automatizan esta verificación:

post_build: # Verificación automatizada
  commands:
    - python scripts/verify_infrastructure.py
    - aws cloudwatch put-metric-alarm --alarm-name PipelineHealth --metric-name DeploymentStatus --namespace AWS/CodePipeline --statistic Average --period 300 --threshold 1 --comparison-operator GreaterThanThreshold

Si ocurre un fallo durante el despliegue, ejecutamos un rollback automático:

on_failure:
  commands:
    - terraform destroy -auto-approve -var-file="rollback.tfvars"
    - aws sns publish --topic-arn ${SNS_TOPIC} --message "Despliegue fallido - Rollback ejecutado"

Este enfoque combina validaciones de código y pruebas de despliegue, garantizando que cada implementación cumpla con los estándares de calidad y seguridad necesarios. Esto reduce el riesgo de problemas en producción y refuerza el control de calidad en el pipeline CI/CD.

Configuración Avanzada

En proyectos que necesitan operar en múltiples entornos, es clave implementar ajustes específicos para garantizar escalabilidad y seguridad.

Configuración Multi-Cuenta

Gestionar múltiples cuentas en AWS requiere una arquitectura bien definida. Un elemento esencial es un bucket S3 compartido para almacenar el estado de Terraform de manera centralizada.

Para manejar despliegues entre cuentas, se utilizan roles IAM diseñados bajo el principio de privilegios mínimos:

  • Cuenta de Desarrollo: Rol TerraformDev (para despliegues en el entorno de desarrollo).
  • Cuenta de Pruebas: Rol TerraformTest (para validaciones en staging).
  • Cuenta de Producción: Rol TerraformProd (para implementaciones en producción).

La configuración del proveedor AWS para cada cuenta se define de esta manera:

provider "aws" {
  region = "us-west-2"
  assume_role {
    role_arn = "arn:aws:iam::TARGET_ACCOUNT_ID:role/RolDespliegue"
  }
}

Desarrollo de Módulos

Los módulos reutilizables son clave para mantener el código organizado y fácil de gestionar. Aquí hay un ejemplo de cómo estructurar módulos para componentes comunes en un pipeline:

module "source_pipeline" {
  source = "./modules/pipeline_source"
  repository_name = var.repo_name
  branch_name = var.branch_name
}

module "build_project" {
  source = "./modules/build"
  project_name = var.project_name
  build_spec = var.build_spec
}

Para manejar secretos y configuraciones sensibles, se utiliza AWS Secrets Manager, lo que permite centralizar el acceso a credenciales y tokens necesarios para el pipeline.

Además, se habilitan AWS CloudTrail y AWS Config para auditoría y monitoreo centralizados. Estas herramientas complementan las políticas de cifrado con KMS y las configuraciones IAM ya implementadas, asegurando un entorno seguro y preparado para manejar la complejidad de múltiples entornos.

Resumen

Configurar pipelines CI/CD con Terraform y AWS CodePipeline simplifica y automatiza los procesos de despliegue. Este tutorial práctico mostró cómo llevarlo a cabo de manera eficiente.

Puntos Clave

Integrar Terraform con AWS CodePipeline aporta beneficios claros: automatización confiable usando IaC, mayor seguridad con herramientas como KMS e IAM, y la posibilidad de escalar fácilmente gracias a módulos reutilizables.

Automatización y Consistencia

  • Definir infraestructura como código permite un control de versiones preciso.
  • Los despliegues automatizados agilizan el proceso, como se destacó en las etapas de validación y aplicación.

Seguridad y Cumplimiento

  • Artefactos cifrados con AWS KMS.
  • Supervisión centralizada mediante AWS CloudTrail y Config.

Escalabilidad

  • Uso de módulos reutilizables para componentes comunes.

Consulta más guías prácticas en Dónde Aprendo AWS.

Para mantener tu pipeline funcionando correctamente, recuerda realizar revisiones de configuración (sección 2.2), actualizar dependencias (sección 4.2) y seguir prácticas de seguridad (sección 4.3). Si quieres implementar este flujo en tus proyectos, revisa las configuraciones detalladas en las secciones anteriores y la guía práctica del FAQ.

FAQs

¿Cómo configurar AWS CodePipeline usando código Terraform?

AWS CodePipeline

La configuración básica sigue los pasos descritos en las secciones anteriores. Este proceso implica coordinar tres elementos clave mencionados en la arquitectura (sección 3):

  • Repositorio de código
  • Proyecto de construcción
  • Definición del pipeline

El enfoque principal se divide en dos fases:

  1. Definir los Componentes Principales
    • Configurar el origen del código de acuerdo con la arquitectura establecida.
    • Establecer los parámetros necesarios para la construcción.
    • Implementar políticas de seguridad según lo indicado en la sección 4.3.
  2. Integrar el Pipeline Aquí tienes un ejemplo de cómo se podría definir un pipeline básico usando Terraform:
    resource "aws_codepipeline" "pipeline" {
      name     = "pipeline-aplicacion"
      role_arn = aws_iam_role.rol_pipeline.arn
    
      artifact_store {
        location = aws_s3_bucket.artefactos.bucket
        type     = "S3"
      }
    
      stage {
        name = "Source"
        action {
          name             = "Source"
          category         = "Source"
          owner            = "AWS"
          provider         = "CodeCommit"
          version          = "1"
          output_artifacts = ["codigo_fuente"]
          configuration = {
            RepositoryName = aws_codecommit_repository.repositorio.repository_name
            BranchName     = "main"
          }
        }
      }
    }
    

Es importante complementar estos pasos con las políticas de seguridad detalladas en la sección "Implementación de Seguridad". En implementaciones más complejas, se recomienda usar módulos (sección 6.2) y definir políticas IAM estrictas (sección 2.2) [1][2].

Publicaciones de blog relacionadas

Read more