# 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.

- Source: https://www.itwonderlab.com/terraform-aws-mariadb-rds-database/
- Published: 2020-06-26
- Updated: 2026-10-05
- Author: Javier Ruiz Jiménez (https://www.javierruizjimenez.com/)
- Site: IT Wonder Lab (https://www.itwonderlab.com/)

---

## 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.

> [!NOTE]
> This is one of the original IT Wonder Lab tutorials, written for Terraform 0.12 (2018-2020) with the AWS provider of that time. The ideas and the structure are still valid, but some arguments and versions have changed. For a current, step-by-step version see [AWS with Terraform: The Essential Guide](https://www.itwonderlab.com/aws-terraform-tutorial-terraform-basics/), and use OpenTofu or a recent Terraform with the commands `tofu` or `terraform`.

### Prerequisites and source code

-   [Terraform Setup and AWS VPC Subnet Creation (1/5)](https://www.itwonderlab.com/terraform-ansible-aws-howto/)
-   [VPC Subnet Routing and Internet Access with Terraform (2/5)](https://www.itwonderlab.com/using-terraform-to-create-an-aws-vpc-with-an-ec2-instance-and-a-mariadb-rds-data-base-ii/)
-   [AWS Route 53, AMI Lookup and EC2 Creation with Terraform (3/5)](https://www.itwonderlab.com/terraform-route-53-ami-lookup/)

### 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 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.tfstate 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. Today the better option is `manage_master_user_password = true`, which keeps the password out of the code and the state (see [AWS RDS](https://www.itwonderlab.com/aws-terraform-tutorial-aws-rds/)).

```json title="terraform.tfvars"
#------------------------
# 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.

```json title="aws_rds_pro_mariadb_01.tf"
#----------------------
# 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)](https://www.itwonderlab.com/using-terraform-to-create-an-aws-vpc-with-an-ec2-instance-and-a-mariadb-rds-data-base-ii/#rds-subnet-group).

`db_subnet_group_name = module.aws_rds_sn_pub_pro_01.id`

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 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](https://www.itwonderlab.com/aws-resource-tagging/).

### Next Steps

-   [AWS Terraform Essential Guide, a comprehensive tutorial that guides you step-by-step through creating infrastructure in AWS using Terraform](https://www.itwonderlab.com/tag/aws-terraform-essential-guide/)
-   Terraform AWS Tutorials
    -   [Terraform Setup and AWS VPC Subnet Creation (1/5)](https://www.itwonderlab.com/terraform-ansible-aws-howto/)
    -   [VPC Subnet Routing and Internet Access with Terraform (2/5)](https://www.itwonderlab.com/using-terraform-to-create-an-aws-vpc-with-an-ec2-instance-and-a-mariadb-rds-data-base-ii/)
    -   [AWS Route 53, AMI Lookup and EC2 Creation with Terraform (3/5)](https://www.itwonderlab.com/terraform-route-53-ami-lookup/)
    -   [AWS RDS MariaDB Database and Resource Tags with Terraform (4/5)](https://www.itwonderlab.com/terraform-aws-mariadb-rds-database/)
    -   [EC2 Instances and Resource Security with Terraform (5/5)](https://www.itwonderlab.com/terraform-aws-ec2-security-rules/)
-   Ansible Tutorials
    -   [Using Ansible for Terraform Managed AWS Infrastructure](https://www.itwonderlab.com/terraform-aws-ansible/)
