Templates anidados en Cloudformation

Buenas noches!

Uno de los problemas con los que me enfrenté cuando empecé con Cloudformation fue que creaba stacks con recursos demasiado grandes, de manera que si este fallaba en la creación de alguno de esos recursos, automáticamente AWS realiza el rollback, destruyendo todos los creados anteriormente. ¿Qué problemas implica esto? Principalmente pérdida de tiempo,además de tener un stack de recursos poco mantenible.

Una forma práctica y correcta al momento de provisionar recursos con Cloudformation es crear templates atómicos y reutilizables.

Ejemplo: se necesita levantar Grafana en docker, dos containers (distintas AZ) y un load balancer. Se usará ECS Fargate para tal propósito. De la descripción anterior se deduce que se requieren los siguientes recursos:
  • security groups, tanto para el ALB como para la aplicación 
  • un ALB, con su respectivo target group y listener
    una task y un service definition de ECS Fargate y un log group
Cada uno de estos grupos de recursos estarán definidos en templates diferentes, que serán los child.
La estrategia consiste en crear un template al que llamaremos master.yml que lucirá de la siguiente manera:

---
AWSTemplateFormatVersion: '2010-09-09'
Description: >
  Master template for Grafana hosted on Fargate

Parameters:
  S3Location:
    Description: Your S3 location to store cloudformation template
    Type: String
    Default: "https://s3-us-west-2.amazonaws.com/cf-grafana/"
    MinLength: 1

Resources:
  SecurityGroups:
    Type: AWS::CloudFormation::Stack
    Properties:
      Parameters:
        VPCId: ""
        EnvironmentName: ""
        Stage: ""
        ProjectName: ""
      TemplateURL: !Join ["",[!Ref S3Location, "sec-groups.yml"]]

  LoadBalancers:
    Type: AWS::CloudFormation::Stack
    Properties:
      Parameters:
        EnvironmentName: ""
        Stage: ""
        ProjectName: ""
        VPCId: ""
        Subnets: ""
        ALBSecurityGroup: ""
        HealthCheck: /api/health
      TemplateURL: !Join ["",[!Ref S3Location, "load-balancers.yml"]]

  ECS:
    Type: AWS::CloudFormation::Stack
    Properties:
      Parameters:
        Subnets: ""
        #RepositoryURL: ""
        SecurityGroups: ""
        TargetARN: ""
        ClusterName: ""
        LogPrefix: ""
        EnvironmentName: ""
        Stage: ""
        ProjectName: ""
        LogGroupName: "ecs"
      TemplateURL: !Join ["",[!Ref S3Location, "ecs.yml"]]
...
Del template anterior se puede destacar que es necesario disponer de un bucket S3 donde guardar los templates referenciados luego.

Cada Resource es del tipo AWS::CloudFormation::Stack y es allí donde se llaman a los stacks de los recursos que necesitamos crear.

Algo interesante es que desde el archivo master se pueden pasar Parameters a cada child, de manera que esos templates hijos no estarán harcodeados y podrán ser reutilizados en otra implementación. Teniendo todo esto listo, ya se puede realizar el deploy de los recursos ¿Cómo? Comentando cada sección de Stacks. Esto sería, comentar el Stack LoadBalancers y ECS; posteriormente, cuando se actualiza el template master, descomentar lo que corresponde a LoadBalancers (Cloudformation no modificará ni destruirá nada de lo anterior). Por último ECS.

Espero que haya sido de utilidad.

Comentarios

Entradas más populares de este blog

Errores con mirrors de Raspberry Pi

Mis razones para abandonar y no volver IBM Cloud

Me gusta GnuPG