Creación de una Base de datos AWS RDS con Terraform (4/5)

RDS MariaDB Base de datos y etiquetas de recurso

Tutorial 4 de 5 acerca del uso de Terraform y Ansible para AWS. Tras finalizar el tutorial habrá creado mediante Terraform un VPC en AWS con una instancia EC2 conectadas a una base de datos MariaDB ejecutándose sobre RDS. Posteriormente se usa Ansible para configurar e instalar el software necesario.

Prerequisitos y código fuente:

Configuración de una base de datos RDS MariaDB con Terraform

Las bases de datos AWS RDS aprovechan toda la experiencia de AWS, están listas para usar y disponen de herramientas de administración sencillas.

Buenas prácticas: Utilice servicios cloud siempre que sea posible

Enfoque sus recursos y energía en configurar y desarrollador aquello que es realmente único y disruptivo. Los servidores de base de datos, e-mail, DNS o colas,… son actualmente una commodity (producto o servicio estándar que no requiere nada específico).

En la mayoría de las ocasiones si necesita control total de esos servicios y su empresa no tienen millones de usuarios, existe una alta probabilidad de que su diseño cloud sea incorrecto.

La base de datos AWS RDS se configura completamente en el fichero terraform.tfvars.

Siguiendo las buenas prácticas de IT Wonder Lab, se nombrarán los elementos de RDS siguiendo un patrón:

  • Cloud: un prefijo que especifica un nombre único para este cloud y proveedor. En este caso se utiliza ditwl que se obtiene de las iniciales de Demo IT Wonder Lab en minúscula.
  • Recurso: un nombre corto que identifica el tipo de recurso, en este caso usamos:
    • rds-mariadb: para RDS MariaDB
    • sg-rds-mariadb: para los security group de RDS MariaBD
    • sr-rds-mariadb: para los security rule de RDS MariaBD
  • Environment: para recursos que no están compartidos en varios entornos, se utiliza un acrónimo del entorno:
    • pro: producción
    • pre: preproducción
    • dev: desarrollo
  • Visibilidad: para recursos que pueden ser públicos o privados, se utilizan 3 letras para indicar su visibilidad:
    • pub: para recursos públicos
    • pri: par recursos privados
  • Nombre/ID: nombre o identificador que describe el uso del recurso o el número de instancia del mismo, por ejemplo para RDS:
    • Número de BD : el número de base de datos RDS para esta zona. En un futuro podríamos tener más de una base de datos por lo que añadir desde el principio un número permite crecer de forma ordenada.
    • Número de grupo de seguridad de BD: el número de grupo de seguridad. Al crecer tendremos mas grupos por lo que es conveniente identificarlos y diferenciarlos desde el principio.
    • Descripción del objetivo de la regla: utilizando una descripción que nos indique el objetivo de la regla. Por ejemplo instances_to_db_port nos indica que es la regla de acceso desde las instancias EC2 a la base de datos.

Atención a la contraseña de acceso a la base de datos RDS en texto claro del fichero terraform.tfvars. No es una buena práctica, por lo que se recomienda cambiarla de forma externa a Terraform, por ejemplo vía AWS cli o AWS console una vez creado el recurso con Terraform. Un cambio en contraseña no modifica el plan por lo que Terraform no la volverá a cambiar.

#------------------------
# RDS INSTANCES
#------------------------

  #------------------------
  # MariaDB PRO 01
  #------------------------
  aws_rds_mariadb_pro_pub_01 = {
    identifier              = "ditwl-rds-mariadb-pro-pub-01"
    allocated_storage       = 20 #GB
    storage_type            = "gp2"
    final_snapshot_id       = "ditwl-rds-mariadb-pro-pub-01-final"
    skip_final_snapshot     = false
    engine                  = "mariadb"
    engine_version          = "10.2.11"
    instance_class          = "db.t2.micro"
    password                = "**************"
    username                = "ditwlRDSPROdb01" #Start with a letter. Only numbers, letters, and _ accepted, 1 to 16 characters long
    availability_zone       = "us-east-1a"
    backup_retention_period = 5
    #db_subnet_group_name   = See var aws_rds_sn_pro_01["name"]
    multi_az                = false
    vpc_security_group_ids  = ""
    parameter_group_name    = ""
    allow_major_version_up  = false
    publicly_accessible     = true
    tag_private_name        = "ditwl-rds-mariadb-pro-pub-01"
    tag_public_name         = "ditwl-rds-mariadb-pro-pub-01"
    tag_app                 = "mariadb"
    tag_app_id              = "mariadb-01"
    tag_os                  = "rds"
    tags_environment        = "pro"
    tag_cost_center         = "ditwl-permanent"
  }

  #------------------------
  # RDS Security Group
  #------------------------
  aws_sg_rds_mariadb_pro_pub_01 = {
    sec_name        = "ditwl-aws-sg-rds-mariadb-pro-pub-01"
    sec_description = "ditwl - MariaDb server access rules - Pub, Env: PRO"
    allow_all_outbound = false
  }
    #------------------------
    # Allow access from my Instances to DB port
    #------------------------
    aws_sr_rds_mariadb_pro_pub_01_instances_to_db_port = {
      type              = "ingress"
      from_port         = "3306"
      to_port           = "3306"
      protocol          = "tcp"
      #source_security_group_id module.aws_sec_group_ec2_default.id
      description       = "Access from Instances to DB port"
    }

aws_rds_pro_mariadb_01.tf se utiliza para crear el grupo de seguridad, asignar la regla de seguridad y crear la base de datos.

#----------------------
# RDS MariaDB
#----------------------

# SECURITY
  # Group
  module "aws_sg_rds_mariadb_pro_pub_01" {
    source      = "./modules/aws/security/group"
    vpc_id      = module.aws_network_vpc.id
    name        = var.aws_sg_rds_mariadb_pro_pub_01["sec_name"]
    description = var.aws_sg_rds_mariadb_pro_pub_01["sec_description"]
  }

  # Rules
  # Access from instances in group aws_sec_group_ec2_default to DB Port
  module "aws_sr_rds_mariadb_pro_pub_01_instances_to_db_port" {
    source            = "./modules/aws/security/rule/source_group"
    security_group_id = module.aws_sg_rds_mariadb_pro_pub_01.id
    type              = var.aws_sr_rds_mariadb_pro_pub_01_instances_to_db_port["type"]
    from_port         = var.aws_sr_rds_mariadb_pro_pub_01_instances_to_db_port["from_port"]
    to_port           = var.aws_sr_rds_mariadb_pro_pub_01_instances_to_db_port["to_port"]
    protocol          = var.aws_sr_rds_mariadb_pro_pub_01_instances_to_db_port["protocol"]
    source_security_group_id = module.aws_sg_ec2_default.id
    description       = var.aws_sr_rds_mariadb_pro_pub_01_instances_to_db_port["description"]
  }

module "aws_rds_mariadb_pro_pub_01" {
  source = "./modules/aws/rds/instance"

  identifier              = var.aws_rds_mariadb_pro_pub_01["identifier"]
  allocated_storage       = var.aws_rds_mariadb_pro_pub_01["allocated_storage"]
  storage_type            = var.aws_rds_mariadb_pro_pub_01["storage_type"]
  final_snapshot_id       = var.aws_rds_mariadb_pro_pub_01["final_snapshot_id"]
  skip_final_snapshot     = var.aws_rds_mariadb_pro_pub_01["skip_final_snapshot"]
  engine                  = var.aws_rds_mariadb_pro_pub_01["engine"]
  engine_version          = var.aws_rds_mariadb_pro_pub_01["engine_version"]
  instance_class          = var.aws_rds_mariadb_pro_pub_01["instance_class"]
  password                = var.aws_rds_mariadb_pro_pub_01["password"]
  username                = var.aws_rds_mariadb_pro_pub_01["username"]
  availability_zone       = var.aws_rds_mariadb_pro_pub_01["availability_zone"]
  backup_retention_period = var.aws_rds_mariadb_pro_pub_01["backup_retention_period"]

  # Workaround for dependency. We need Terraform to wait for aws_rds_sn_pro_01 creation before the RDS DB can use it.
  db_subnet_group_name    = module.aws_rds_sn_pub_pro_01.id #aws_rds_sn_pro_01["name"]

  multi_az                = var.aws_rds_mariadb_pro_pub_01["multi_az"]
  vpc_security_group_ids  = [module.aws_sg_rds_mariadb_default.id,module.aws_sg_rds_mariadb_pro_pub_01.id]
  publicly_accessible     = var.aws_rds_mariadb_pro_pub_01["publicly_accessible"]

  #parameter_group_name    = aws_db_parameter_group.rds_pos_96_db_parameter_group_01.id
  allow_major_version_up  = var.aws_rds_mariadb_pro_pub_01["allow_major_version_up"]
  tag_private_name        = var.aws_rds_mariadb_pro_pub_01["tag_private_name"]
  tag_public_name         = var.aws_rds_mariadb_pro_pub_01["tag_public_name"]
  tag_app                 = var.aws_rds_mariadb_pro_pub_01["tag_app"]
  tag_app_id              = var.aws_rds_mariadb_pro_pub_01["tag_app_id"]
  tag_os                  = var.aws_rds_mariadb_pro_pub_01["tag_os"]
  tags_environment        = var.aws_rds_mariadb_pro_pub_01["tags_environment"]
  tag_cost_center         = var.aws_rds_mariadb_pro_pub_01["tag_cost_center"]
}

Utilizamos un truco para crear una dependencia explícita entre la subred RDS y la base de datos RDS: pasar el ID de la subred RDS a la base de datos, esto obliga a Terraform a crear la subred antes pues debe obtener el ID.

Vea creación de subredes RDS en (VPC/RDS Subredes).

db_subnet_group_name = module.aws_rds_sn_pub_pro_01.id

Etiquetado de bases de datos AWS RDS con Terraform

Etiquete las instancias RDS con todos los identificadores necesarios. Utilice un estándar y el mismo idioma para las etiquetas y sus valores.

Buenas prácticas: Etiquetar todos los recursos de AWS

Las etiquetas se utilizan para identificar los recursos, repartir costes entre centros de coste, configurar y aprovisionar máquinas y monitorización mediante inventarios dinámicos utilizando Ansible y otras herramientas.

Etiquetas recomendadas:

  • private_name (nombre privado): el nombre privado de este elemento, se utiliza para el registro en la zona privada del DNS, debe ser único y seguir el patrón estándar de nombrado de la organización.
  • public_name (nombre público): el nombre público que puede ser utilizado para registrar el servidor en la zona pública del DNS y que podría incluso corresponder a varias instancias si va a estar detrás de una balanceador de carga. En el caso de RDS se usa el mismo nombre para el privado y el público.
  • app: el nombre de la aplicación que usará el recurso.
  • app_id (ID de App): un número o característica única que puede ser utilizada para diferenciar múltiples instancias de la misma aplicación, por ejemplo para diferenciar versiones de la misma aplicación usando su número de entrega.
  • os: El sistema operativo de la instancia, útil para instalar y configurar aplicaciones con Ansible.
  • env (entorno:) para recursos que no están compartidos en varios entornos, se utiliza un acrónimo del entorno:
    • pro: producción
    • pre: preproducción
    • dev: desarrollo
  • cost_center (centro de coste): uno o varios centros de coste a los que se vaya a asignar el coste de este recurso. El centro de coste se utiliza para clasificar los recursos en la facturación. Algunos recursos son compartidos y otros podrían ser específicos de un cliente.

Ejemplo:

Table showing tag keys and values
Etiquetas y sus valores para una instancia RDS AWS

Continúe la demo de Terraform y Ansible para AWS:

Creación de una Base de datos AWS RDS con Terraform (4/5)

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

ansible-aws-ec2-terraform-tags - ansible-aws-ec2-terraform-tags-ec2.png
Tutoriales de Amazon Web Services (AWS)

Integración de Ansible y Terraform

Integración de Ansible y Terraform para configuración de infraestructura en AWS mediante tags e inventario dinámico.