Creating AWS RDS Database with Terraform (4/5)

Tutorial and source code explaining how to create and manage MariaDB (or MySQL) RDS database with Terraform in AWS.

RDS MariaDB Database and Resource Tags

This is the continuation of a Terraform demo to create a VPC in AWS with an EC2 instance connected to MariaDB database running in RDS (Amazon Relational Database Service) using a single Terraform plan.

Operating System and software configuration is done using Ansible after the infrastructure has been created.

Prerequisites and source code:

Configuring an RDS MariaDB Database with Terraform

AWS RDS databases are ready-to-use databases backed by AWS experience and with easy-to-use administration tools.

Best Practice: Use Cloud Services When Possible
Focus all your resources and energy on configuring and developing what is really disruptive and unique. Databases, Email servers, DNS servers, and Queues are now a commodity.

Most of the time if you need full control of those services and If you don’t have millions of customers there is a big probability that you have a wrong design.

The AWS RDS database is fully configured in the terraform.tfvars file.

Be aware of the password in clear text in terraform.tfvars. It will also show in terraform.tftstate and terraform.tfstate.backup.  Currently, the recommended action for passwords in Terraform files is to change them after resource creation using a different tool (AWS CLI, AWS Console, Ansible, DB Client …). A changed password in Terraform doesn’t trigger a resource property change.

#------------------------
# 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 is used to create the security group, assign the security rule, and launch the database.

#----------------------
# 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"]
}

A workaround is used to create a dependency between the RDS subnet group and the RDS database. See RDS subnet group creation in part II (VPC/RDS Sub Nets).

db_subnet_group_name = module.aws_rds_sn_pub_pro_01.id

In order to launch the RDS database the subnet needs to exist, we provide the name of the RDS subnet using the output ID of the RDS subnet as source, this way Terraform is forced to create the RDS subnet first in order to evaluate the output ID.

Tag the RDS instance with all the needed identifiers.

Best Practice: Tag all your AWS Resources
Tags can be used to identify resources, split costs between cost centers, and for further configuration, provisioning, and monitoring with dynamic inventories using Ansible or other tools. See AWS Tagging best practices.

Continue the Terraform and Ansible demo, see:

terraform-aws-ec2-rds-basic-free - ITWL_AWS_Terraform_VPC_WP_RDS_tags.png
Table of Contents
Primary Item (H2)Sub Item 1 (H3)Sub Item 2 (H4)
Sub Item 3 (H5)
Sub Item 4 (H6)

Related Cloud Tutorials

AWS Security Groups’ Best Practices
AWS Security Groups are virtual firewalls that control inbound and outbound traffic to and from Amazon Web Services (AWS) resources, such as EC2 and RDS instances.
AWS and Terraform Naming Best Practices
Terraform and AWS resource naming should follow a company standard. Each company has different requirements and the standard should be adjusted.
How To Debug Terraform
Enable Terraform debug Terraform uses the value from the environment variable TF_LOG to define the LOG level. Available values are TRACE, DEBUG, INFO, WARN or ERROR. Additionally, you can specify a destination file for the log by setting the environment variable TF_LOG_PATH to the full path of the desired destination. Set the debug variables and […]
AWS Tagging Best Practices
Effective infrastructure resource tagging can greatly improve management, IaC, monitoring and cost visibility in AWS.
How to Deploy Applications in Kubernetes using Terraform
How to publish multiple replicas of an Application (from the Docker Registry) and create a NodePort in Kubernetes using Terraform (in 10 seconds)
Terraform logo
HCL
HashiCorp Configuration Language HCL is a domain-specific language developed by HashiCorp, a company known for its infrastructure automation tools such as Terraform, Vault, Consul, and Nomad. HCL is designed specifically for writing configuration files that define infrastructure components and their settings. It is used in HashiCorp’s suite of tools to create and manage infrastructure as […]
AWS Terraform module
IaC
Infrastructure as Code IaC is an approach to managing and provisioning computing infrastructure through machine-readable code and automation, rather than manual processes. In IaC, infrastructure is defined, configured, and managed using code, which can be version-controlled and treated like any other software application. IaC involves: IaC provides several benefits, including improved efficiency, reduced manual errors, […]
AWS S3
AWS S3, is a highly scalable and durable object storage used for data storage, backup, content distribution, data archiving, and as a foundation for building cloud-native applications.
AWS EC2
Amazon Elastic Compute Cloud, is a web service offered by Amazon Web Services (AWS) that provides resizable and scalable compute capacity in the cloud. In simple terms, AWS EC2 allows you to launch and manage virtual machines, known as instances, in the AWS cloud.
AWS AMI
AWS AMI, or Amazon Machine Image, is a pre-configured virtual machine image used to create and launch Amazon Elastic Compute Cloud (EC2) instances
1 2 3

Javier Ruiz

IT Wonder Lab tutorials are based on the rich and diverse experience of Javier Ruiz, who founded and bootstrapped a SaaS company in the energy sector. His company, which was later acquired by a NASDAQ traded company, managed over €2 billion per year of electricity for prominent energy producers across Europe and America. Javier has more than 20 years of experience in building and managing IT companies, developing cloud infrastructure, leading cross-functional teams, and transitioning his own company from on-premises, consulting, and custom software development to a successful SaaS model that scaled globally.

2 comments on “Creating AWS RDS Database with Terraform (4/5)”

Leave a Reply

Your email address will not be published. Required fields are marked *


linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram