Conceptos

Fundamentos

Para iniciar hay algunos conceptos que hay que tener claros al momento de trabajar con templates de cloudformation, se pueden escribir templates en dos diferentes lenguajes:

  • YAML: este es un lenguaje utilizado para serializar datos y se hace uso de la identación para poder indicar diferentes jerarquías dentro del archivo. Es más común encontrar templates escritos en YAML ya que tienen una estrctura más legible y sencilla de entender.
# Extracto de ejemplo de template en cloudformation escrito en YAML
Resources:

  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      IpAddressType: ipv4
      Name: !Sub ${Identifier}-${Environment}-alb
      Scheme: internet-facing
      SecurityGroups:
      - !Ref AlbSecurityGroup
      Subnets: !Ref SubnetIds
      Type: application
      Tags:
      - Key: Name
        Value: !Sub ${Identifier}-${Environment}-alb
      - Key: Owner
        Value: !Ref OwnerName
      - Key: ProjectName
        Value: !Ref ProjectName
      - Key: Environment
        Value: !Ref Environment
  • JSON: lenguaje utilizado para poder definir objetos, es bastante utilizado para el uso de APIs. Los templates de cloudformation pueden ser escritos utilizando JSON pero en mi opinion es un poco menos legible con templates más grandes.
{
    "Resources": {
        "Ec2Instance": {
            "Type": "AWS::EC2::Instance",
            "Properties": {
                "SecurityGroups": [
                    {
                        "Ref": "InstanceSecurityGroup"
                    }
                ],
                "KeyName": "mykey",
                "ImageId": ""
            }
        },
        "InstanceSecurityGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "Enable SSH access via port 22",
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "FromPort": 22,
                        "ToPort": 22,
                        "CidrIp": "0.0.0.0/0"
                    }
                ]
            }
        }
    }
}

Partes de un Template

Para efectos prácticos de los ejemplos se utilizará YAML para la definición de los templates, ya que es un formato más legible. Un tmplate cuenta con los siguientes bloques principales que son de utilidad:

  • Sección de “Parameters”: como el nombre lo indica, podemos definir parametros que necesitemos para definir los recursos:
...
Parameters:

  # definiendo parametros que puede utilizarse dentro del template
  Identifier:
    Type: String
    Description: A name identifier to tag the networking resources

  SshIp:
    Type: String
    Default: 0.0.0.0/0
    Description: IP allowed to ssh into instances

  VpcId:
    Type: String
    Description: VPC In which SecurityGroups will be created
...
  • Sección de “Resources”: Esta sección se pueden definir todos los recursos que se desean crear en un template de cloudformation.
...
Resources:

  # definicion de una vpc
  Vpc:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCidr
      InstanceTenancy: default
      EnableDnsHostnames: true
      EnableDnsSupport: true
      Tags:
      - Key: Name
        Value: !Sub ${Identifier}-${Environment}
      - Key: Owner
        Value: !Ref OwnerName
      - Key: ProjectName
        Value: !Ref ProjectName
      - Key: Environment
        Value: !Ref Environment

  # definicion de una subnet
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: !Select [ 0, !Ref PublicSubnetsCidr ]
      MapPublicIpOnLaunch: true
      AvailabilityZone: !Select [ 0, !GetAZs '' ]
      Tags:
      - Key: Name
        Value: !Sub ${Identifier}-${Environment}-public-subnet-1
      - Key: Owner
        Value: !Ref OwnerName
      - Key: ProjectName
        Value: !Ref ProjectName
      - Key: Environment
        Value: !Ref Environment

  # definicion de otra subnet
  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: !Select [ 1, !Ref PublicSubnetsCidr ]
      MapPublicIpOnLaunch: true
      AvailabilityZone: !Select [ 1, !GetAZs '' ]
      Tags:
      - Key: Name
        Value: !Sub ${Identifier}-${Environment}-public-subnet-2
      - Key: Owner
        Value: !Ref OwnerName
      - Key: ProjectName
        Value: !Ref ProjectName
      - Key: Environment
        Value: !Ref Environment
...
  • Sección de “Outputs”: esta sección contiene todas las propiedades que queremos exponer de nuestro template de cloudformation. Estos outputs pueden ser nombres de recursos, comandos a utilizar, etc. Estos pueden ser exportados y utilizados en otras “Stacks” de cloudformation.
...
Outputs:

  # exportando el ID de la vpc que crea el template de cloudformation  
  VpcId:
    Value: !Ref Vpc
    Export:
      Name: !Sub ${ProjectName}:${Identifier}-vpc

  # exportando el id de la subnet 1
  PublicSubnet1Id:
    Value: !Ref PublicSubnet1
    Export:
      Name: !Sub ${ProjectName}:${Identifier}-public-subnet-1

  # exportando el id de la subnet 2
  PublicSubnet2Id:
    Value: !Ref PublicSubnet2
    Export:
      Name: !Sub ${ProjectName}:${Identifier}-public-subnet-2
...

Template básico

---
AWSTemplateFormatVersion: 2010-09-09
Description: >-
    Esqueleto de template de cloudformation

Parameters:
# Definicion de los parametros

Resources:
# Definicion de los recursos

Outputs:
# Definicion de los outputs

Documentacion de referencia

Puedes consultar los siguientes recursos para explorar un poco mas lo que hemos hablado en este apartado: