Back to Blog

Deploying Azure SQL Server with Terraform

Complete tutorial about azurerm_sql_server in Terraform. Learn SQL server, databases, firewall rules, elastic pools.

Deploying Azure SQL Server with Terraform

Deploying Azure SQL Server with Terraform

Introduction

Azure SQL Server is a fully managed relational database service that allows developers to run SQL Server databases in the cloud without the overhead of managing the underlying infrastructure. Utilizing Terraform to provision Azure SQL Server resources promotes Infrastructure as Code (IaC), which enhances consistency, repeatability, and collaboration among development teams. With IaC, you can define your infrastructure in configuration files, making it easier to manage changes, version control, and automate deployments.

The main use cases for deploying Azure SQL Server with Terraform include setting up a robust database environment for applications, automating the deployment of development and production databases, and managing firewall rules and elastic pools for better performance and cost-efficiency. This tutorial will guide you through creating an Azure SQL Server, databases, firewall rules, and elastic pools using Terraform.

Prerequisites

Before we begin, ensure you have the following prerequisites:

  1. Terraform CLI installed on your local machine. Follow the official installation guide.
  2. An Azure subscription to create and manage Azure resources. Sign up for a free account here.
  3. Azure CLI installed and configured. You can install it from this link.
  4. An Azure service principal with sufficient permissions to create and manage resources in your subscription. You can create one using the following command:
    az ad sp create-for-rbac --name "myServicePrincipal" --role Contributor --scopes /subscriptions/<your-subscription-id>
    

Fundamental Concepts

Key Terminology

  • Azure SQL Server: A logical container for databases in Azure SQL.
  • Firewall Rules: Rules that control access to the Azure SQL Server.
  • Elastic Pools: A collection of databases that share resources, allowing for cost-effective scaling.
  • HCL: HashiCorp Configuration Language, used to write Terraform configuration files.

Resource Dependencies

Terraform manages dependencies automatically. For instance, databases can only exist after the Azure SQL Server is created. When you define your resources in a .tf file, Terraform determines the order in which to create them based on dependencies.

State Management

Terraform maintains a state file that maps your configuration to the real infrastructure. This state file is crucial for tracking resource changes and ensuring that your Terraform operations are accurate.

Resource Syntax

The primary resource for deploying Azure SQL Server in Terraform is azurerm_sql_server. Below is the basic syntax along with its attributes:

resource "azurerm_sql_server" "example" {
  name                         = var.sql_server_name
  resource_group_name          = azurerm_resource_group.example.name
  location                     = azurerm_resource_group.example.location
  version                      = "12.0"
  administrator_login          = var.admin_username
  administrator_login_password = var.admin_password
  tags                         = var.tags
}

Arguments Table

Argument Description
name The name of the SQL Server.
resource_group_name The name of the resource group to which the SQL Server belongs.
location The Azure region where the SQL Server will be created.
version The version of SQL Server (e.g., "12.0", "13.0", "14.0").
administrator_login The admin username for the SQL Server.
administrator_login_password Password for the SQL Server admin user.
tags A map of tags for the SQL Server resource.

Practical Examples

Example 1: Basic SQL Server Deployment

resource "azurerm_resource_group" "example" {
  name     = "example-resources"
  location = "East US"
}

resource "azurerm_sql_server" "example" {
  name                         = "example-sql-server-001"
  resource_group_name          = azurerm_resource_group.example.name
  location                     = azurerm_resource_group.example.location
  version                      = "12.0"
  administrator_login          = "sqladmin"
  administrator_login_password = "Password123!"
}

Example 2: Adding a SQL Database

resource "azurerm_sql_database" "example" {
  name                = "exampledb"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location
  server_name         = azurerm_sql_server.example.name
  requested_service_objective_name = "S0"
}

Example 3: Creating Firewall Rules

resource "azurerm_sql_firewall_rule" "allow_my_ip" {
  name                = "AllowMyIP"
  resource_group_name = azurerm_resource_group.example.name
  server_name         = azurerm_sql_server.example.name
  start_ip_address    = "203.0.113.0"
  end_ip_address      = "203.0.113.0"
}

Example 4: Configuring Elastic Pools

resource "azurerm_sql_elastic_pool" "example" {
  name                = "example-elastic-pool"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location
  server_name         = azurerm_sql_server.example.name

  edition             = "Standard"
  requested_dtu       = 50

  per_database_settings {
    database_name = azurerm_sql_database.example.name
    min_dtu      = 5
    max_dtu      = 20
  }
}

Example 5: Database in Elastic Pool

resource "azurerm_sql_database" "elastic_db" {
  name                = "elasticdb"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location
  server_name         = azurerm_sql_server.example.name
  elastic_pool_id     = azurerm_sql_elastic_pool.example.id
}

Example 6: Applying Changes with Terraform

To apply the changes you made in the configuration, use the following commands in your terminal:

terraform init  # Initializes the Terraform configuration
terraform plan  # Creates an execution plan
terraform apply # Applies the changes to your Azure account

Example 7: Output SQL Server Information

output "sql_server_name" {
  value = azurerm_sql_server.example.name
}

output "sql_server_admin" {
  value = azurerm_sql_server.example.administrator_login
}

Example 8: Clean Up Resources

To destroy the resources created by Terraform, run:

terraform destroy

Real-World Use Cases

Scenario 1: Development Environment

You can deploy a SQL Server with multiple databases in an elastic pool to manage costs effectively for a development environment. This setup allows developers to share resources without over-provisioning.

Scenario 2: Production Database Setup

For a production application, you can create a highly available SQL Server with multiple databases, firewall rules, and monitoring configurations. This setup ensures that your application can handle high traffic and maintain security.

Scenario 3: Testing and Staging

Set up separate instances of SQL Servers for testing and staging environments. This practice allows for testing changes in a controlled environment before deploying to production, ensuring quality and performance.

Best Practices

  1. Use Variables: Always use variables for sensitive information like usernames and passwords to avoid hardcoding them in your configurations.
  2. Modularize Your Code: Break your Terraform configuration into modules for better organization and reusability.
  3. Use Tags: Tag your resources for easier management and cost tracking.
  4. Version Control: Store your Terraform files in a version control system (e.g., Git) to track changes over time.
  5. Review State Files: Regularly review and manage your Terraform state files to prevent drift from your infrastructure.

Common Errors

  1. Error: "The resource group does not exist."

    • Cause: The specified resource group has not been created.
    • Solution: Ensure the resource group is created before referencing it in other resources.
  2. Error: "SQL Server name already exists."

    • Cause: The name for the SQL Server must be globally unique.
    • Solution: Choose a different name for the SQL Server.
  3. Error: "Administrator login password must meet complexity requirements."

    • Cause: The password does not meet Azure's complexity requirements.
    • Solution: Ensure the password includes uppercase, lowercase, numbers, and special characters.
  4. Error: "Insufficient permissions to create resources."

    • Cause: The service principal does not have the necessary permissions.
    • Solution: Verify and grant the appropriate role assignments to the service principal.

Related Resources

Resource Name Description
azurerm_sql_database Terraform resource to manage Azure SQL Databases.
azurerm_sql_firewall_rule Terraform resource to manage firewall rules for Azure SQL.
azurerm_sql_elastic_pool Terraform resource to manage elastic pools in Azure SQL.
Terraform Documentation Official Terraform documentation for comprehensive guidance.

Complete Infrastructure Script

Here is a complete Terraform configuration script that includes all the elements we discussed:

provider "azurerm" {
  features {}
}

variable "sql_server_name" {
  default = "example-sql-server-001"
}

variable "admin_username" {
  default = "sqladmin"
}

variable "admin_password" {
  default = "Password123!"
}

variable "tags" {
  default = {
    Environment = "Dev"
    Project     = "SQLServerDeployment"
  }
}

resource "azurerm_resource_group" "example" {
  name     = "example-resources"
  location = "East US"
}

resource "azurerm_sql_server" "example" {
  name                         = var.sql_server_name
  resource_group_name          = azurerm_resource_group.example.name
  location                     = azurerm_resource_group.example.location
  version                      = "12.0"
  administrator_login          = var.admin_username
  administrator_login_password = var.admin_password
  tags                         = var.tags
}

resource "azurerm_sql_database" "example" {
  name                = "exampledb"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location
  server_name         = azurerm_sql_server.example.name
  requested_service_objective_name = "S0"
}

resource "azurerm_sql_firewall_rule" "allow_my_ip" {
  name                = "AllowMyIP"
  resource_group_name = azurerm_resource_group.example.name
  server_name         = azurerm_sql_server.example.name
  start_ip_address    = "203.0.113.0"
  end_ip_address      = "203.0.113.0"
}

resource "azurerm_sql_elastic_pool" "example" {
  name                = "example-elastic-pool"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location
  server_name         = azurerm_sql_server.example.name
  edition             = "Standard"
  requested_dtu       = 50

  per_database_settings {
    database_name = azurerm_sql_database.example.name
    min_dtu      = 5
    max_dtu      = 20
  }
}

output "sql_server_name" {
  value = azurerm_sql_server.example.name
}

output "sql_server_admin" {
  value = azurerm_sql_server.example.administrator_login
}

Conclusion

In this tutorial, we've covered how to deploy Azure SQL Server using Terraform. You learned about the fundamental concepts, syntax, and practical examples, including how to manage firewall rules and elastic pools. By leveraging Terraform for your infrastructure needs, you can ensure a consistent, repeatable, and manageable deployment process for your Azure SQL environments.

Next Steps

  • Explore advanced configurations like geo-replication and scaling.
  • Consider integrating Terraform with CI/CD pipelines for automated deployments.
  • Familiarize yourself with monitoring and diagnostics for your Azure SQL Server resources.

References

With this comprehensive guide, you are now well-equipped to deploy and manage Azure SQL Server using Terraform! 🚀💡