Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Azure Database for MySQL - Flexible Server #1245

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion examples/azure/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Let's make sure [go.mod](https://github.com/gruntwork-io/terratest/blob/master/g
```go
require (
...
github.com/Azure/azure-sdk-for-go v46.1.0+incompatible
github.com/Azure/azure-sdk-for-go v57.1.0+incompatible
...
)
```
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Terraform Azure Database for MySQL - Flexible Server Example

This folder contains a Terraform module that deploys resources in [Azure](https://azure.microsoft.com/) to demonstrate how you can use Terratest to write automated tests for your Azure Terraform code.
This module deploy a [Azure Database for MySQL - Flexible Server](https://learn.microsoft.com/en-gb/azure/mysql/flexible-server/overview) with default values defined in [variables.tf](variables.tf).

Check out [test/azure/terraform_azure_mysqldb_flexible_example_test.go](./../../../test/azure/terraform_azure_mysqldb_flexible_example_test.go) to see how you can write automated tests for this module and validate the configuration of the parameters and options.

**WARNING**: This module and the automated tests for it deploy real resources into your Azure account which can cost you money. The resources are all part of the [Azure Free Tier](https://azure.microsoft.com/en-us/pricing/free-services/), so if you haven't used that up,
it should be free, but you are completely responsible for all Azure charges.

## Running this module manually
1. Sign up for [Azure](https://azure.microsoft.com/).
1. Configure your Azure credentials using one of the [supported methods for Azure CLI
tools](https://docs.microsoft.com/en-us/cli/azure/azure-cli-configuration?view=azure-cli-latest)
1. Install [Terraform](https://www.terraform.io/) and make sure it's on your `PATH`.
1. Ensure [environment variables](../README.md#review-environment-variables) are available
1. Run `terraform init`
1. Run `terraform apply`
1. When you're done, run `terraform destroy`.


## Running automated tests against this module
1. Sign up for [Azure](https://azure.microsoft.com/)
1. Configure your Azure credentials using one of the [supported methods for Azure CLI
tools](https://docs.microsoft.com/en-us/cli/azure/azure-cli-configuration?view=azure-cli-latest)
1. Install [Terraform](https://www.terraform.io/) and make sure it's on your `PATH`
1. Configure your Terratest [Go test environment](../README.md)
1. `cd test/azure`
1. `go build terraform_azure_mysqldb_flexible_example_test.go`
1. `go test -v -timeout 60m -tags azure -run TestTerraformAzureMySqlFlexibleServerDBExample`

96 changes: 96 additions & 0 deletions examples/azure/terraform-azure-mysqldb-flexible-example/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# ---------------------------------------------------------------------------------------------------------------------
# DEPLOY AN AZURE Database For MySQL - Flexible Server
# This is an example of how to deploy an Azure Database Mysql - Flexible Server .
# See test/terraform_azure_mysqldb_flexible_example_test.go for how to write automated tests for this code.
# ---------------------------------------------------------------------------------------------------------------------

# ---------------------------------------------------------------------------------------------------------------------
# PIN TERRAFORM VERSION TO >= 0.12
# The examples have been upgraded to 0.12 syntax
# ---------------------------------------------------------------------------------------------------------------------

terraform {
# This module is now only being tested with Terraform 0.13.x. However, to make upgrading easier, we are setting
# 0.12.26 as the minimum version, as that version added support for required_providers with source URLs, making it
# forwards compatible with 0.13.x code.
required_version = ">= 0.12.26"

required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.41.0"
}

random = {
source = "hashicorp/random"
version = "~> 3.4.3"
}
}
}

# ---------------------------------------------------------------------------------------------------------------------
# CONFIGURE OUR AZURE CONNECTION
# ---------------------------------------------------------------------------------------------------------------------

provider "azurerm" {
features {}
}

# ---------------------------------------------------------------------------------------------------------------------
# DEPLOY A RESOURCE GROUP
# ---------------------------------------------------------------------------------------------------------------------

resource "azurerm_resource_group" "example" {
location = var.location
name = "rg-flexible-${var.postfix}"
}

# ---------------------------------------------------------------------------------------------------------------------
# DEPLOY AZURE MySQL FLEXIBLE SERVER
# ---------------------------------------------------------------------------------------------------------------------

# Random password is used as an example to simplify the deployment and improve the security of the database.
# This is not as a production recommendation as the password is stored in the Terraform state file.
resource "random_password" "password" {
length = 16
override_special = "_%@"
min_upper = "1"
min_lower = "1"
min_numeric = "1"
min_special = "1"
}

resource "azurerm_mysql_flexible_server" "example" {
name = "mysql-flexible-${var.postfix}"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name

administrator_login = var.mysql_flexible_server_administrator_login
administrator_password = random_password.password.result

backup_retention_days = var.mysql_flexible_server_backup_retention_days
sku_name = var.mysql_flexible_server_sku_name
version = var.mysql_version
# Azure automatically deploy the instance in an Availability Zone.
# By providing this, when updating your configuration, you avoid error:
# Error: `zone` cannot be changed independently.
zone = var.mysql_flexible_server_zone

storage {
auto_grow_enabled = false
size_gb = var.mysql_flexible_server_storage_size_gb
}
}

# ---------------------------------------------------------------------------------------------------------------------
# DEPLOY AZURE MySQL DATABASE
# ---------------------------------------------------------------------------------------------------------------------

resource "azurerm_mysql_flexible_database" "example" {
name = "mysqldb-flexible-${var.postfix}"
resource_group_name = azurerm_resource_group.example.name
server_name = azurerm_mysql_flexible_server.example.name

charset = var.mysql_flexible_server_db_charset
collation = var.mysql_flexible_server_db_collation
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
output "resource_group_name" {
value = azurerm_resource_group.example.name
}

output "mysql_flexible_server_name" {
value = azurerm_mysql_flexible_server.example.name
}

output "mysql_flexible_server_full_domain_name" {
value = azurerm_mysql_flexible_server.example.fqdn
}

output "mysql_flexible_server_admin_login" {
value = azurerm_mysql_flexible_server.example.administrator_login
}

output "mysql_flexible_server_admin_login_pass" {
value = azurerm_mysql_flexible_server.example.administrator_password
sensitive = true
}

output "mysql_flexible_server_db_name" {
value = azurerm_mysql_flexible_database.example.name
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# ---------------------------------------------------------------------------------------------------------------------
# ENVIRONMENT VARIABLES
# Define these secrets as environment variables
# ---------------------------------------------------------------------------------------------------------------------

# ARM_CLIENT_ID
# ARM_CLIENT_SECRET
# ARM_SUBSCRIPTION_ID
# ARM_TENANT_ID

# ---------------------------------------------------------------------------------------------------------------------
# REQUIRED PARAMETERS
# You must provide a value for each of these parameters.
# ---------------------------------------------------------------------------------------------------------------------

# ---------------------------------------------------------------------------------------------------------------------
# OPTIONAL PARAMETERS
# These parameters have reasonable defaults.
# ---------------------------------------------------------------------------------------------------------------------

variable "postfix" {
description = "A postfix string to centrally mitigate resource name collisions."
type = string
default = "example"
}

variable "location" {
description = "The Azure Region where the MySQL Flexible Server should exist."
type = string
default = "West Europe"
}

variable "mysql_flexible_server_administrator_login" {
description = "The Administrator login for the MySQL Flexible Server."
type = string
default = "mysqladmin"
}

variable "mysql_flexible_server_backup_retention_days" {
description = "The backup retention days for the MySQL Flexible Server."
type = number
default = 7

validation {
condition = var.mysql_flexible_server_backup_retention_days >= 1 && var.mysql_flexible_server_backup_retention_days <= 35
error_message = "MySQL Flexible Server retention days should be between 1 and 35."
}
}

variable "mysql_flexible_server_sku_name" {
description = "The SKU Name for the MySQL Flexible Server."
type = string
default = "B_Standard_B1ms"
}

variable "mysql_flexible_server_storage_size_gb" {
description = "The max storage allowed for the MySQL Flexible Server."
type = number
default = 32

validation {
condition = var.mysql_flexible_server_storage_size_gb >= 20 && var.mysql_flexible_server_storage_size_gb <= 16384
error_message = "MySQL Flexible Server storage size (GB) should be a value between 20 and 16384."
}
}

variable "mysql_flexible_server_zone" {
description = "Specifies the Availability Zone in which this MySQL Flexible Server should be located."
type = number
default = 1

validation {
condition = var.mysql_flexible_server_zone == 1 || var.mysql_flexible_server_zone == 2 || var.mysql_flexible_server_zone == 3
error_message = "MySQL Flexible Server possible Availability Zone are 1, 2 or 3."
}
}

variable "mysql_version" {
description = "The version of the MySQL Flexible Server to use."
type = string
default = "5.7"

validation {
condition = var.mysql_version == "5.7" || var.mysql_version == "8.0.21"
error_message = "MySQL version for Flexbile Server instance should be 5.7 or 8.0.21."
}
}

variable "mysql_flexible_server_db_charset" {
description = "Specifies the Charset for the MySQL Database, which needs to be a valid MySQL Charset."
type = string
default = "utf8"
}

variable "mysql_flexible_server_db_collation" {
description = "Specifies the Collation for the MySQL Database, which needs to be a valid MySQL Collation."
type = string
default = "utf8_unicode_ci"
}
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.19
require (
cloud.google.com/go v0.105.0 // indirect
cloud.google.com/go/storage v1.27.0
github.com/Azure/azure-sdk-for-go v51.0.0+incompatible
github.com/Azure/azure-sdk-for-go v57.1.0+incompatible
github.com/Azure/go-autorest/autorest v0.11.20
github.com/Azure/go-autorest/autorest/azure/auth v0.5.8
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
Expand Down Expand Up @@ -109,7 +109,6 @@ require (
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/satori/go.uuid v1.2.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/ulikunitz/xz v0.5.10 // indirect
go.opencensus.io v0.24.0 // indirect
Expand Down
7 changes: 4 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,8 @@ cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1V
cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-sdk-for-go v51.0.0+incompatible h1:p7blnyJSjJqf5jflHbSGhIhEpXIgIFmYZNg5uwqweso=
github.com/Azure/azure-sdk-for-go v51.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-sdk-for-go v57.1.0+incompatible h1:TKQ3ieyB0vVKkF6t9dsWbMjq56O1xU3eh3Ec09v6ajM=
github.com/Azure/azure-sdk-for-go v57.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
Expand Down Expand Up @@ -525,6 +525,8 @@ github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblf
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=
github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
Expand Down Expand Up @@ -923,7 +925,6 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4=
Expand Down
59 changes: 59 additions & 0 deletions modules/azure/client_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (

"github.com/Azure/azure-sdk-for-go/profiles/latest/frontdoor/mgmt/frontdoor"
"github.com/Azure/azure-sdk-for-go/profiles/latest/mysql/mgmt/mysql"
"github.com/Azure/azure-sdk-for-go/profiles/latest/mysql/mgmt/mysqlflexibleservers"
"github.com/Azure/azure-sdk-for-go/profiles/latest/resources/mgmt/resources"
"github.com/Azure/azure-sdk-for-go/profiles/latest/sql/mgmt/sql"
"github.com/Azure/azure-sdk-for-go/profiles/preview/cosmos-db/mgmt/documentdb"
Expand Down Expand Up @@ -438,6 +439,64 @@ func CreateMySQLServerClientE(subscriptionID string) (*mysql.ServersClient, erro
return &mysqlClient, nil
}

// CreateMySqlFlexibleServerClientE is a helper function that will setup a mysql flexible server client.
func CreateMySqlFlexibleServerClientE(subscriptionID string) (*mysqlflexibleservers.ServersClient, error) {
// Validate Azure subscription ID
subscriptionID, err := getTargetAzureSubscription(subscriptionID)
if err != nil {
return nil, err
}

// Lookup environment URI
baseURI, err := getBaseURI()
if err != nil {
return nil, err
}

// Create a mysql server client
flexibleMySqlClient := mysqlflexibleservers.NewServersClientWithBaseURI(baseURI, subscriptionID)

// Create an authorizer
authorizer, err := NewAuthorizer()
if err != nil {
return nil, err
}

// Attach authorizer to the client
flexibleMySqlClient.Authorizer = *authorizer

return &flexibleMySqlClient, nil
}

// CreateMySqlFlexibleServerDBClientE is a helper function that will setup a mysql db flexible server client.
func CreateMySqlFlexibleServerDBClientE(subscriptionID string) (*mysqlflexibleservers.DatabasesClient, error) {
// Validate Azure subscription ID
subscriptionID, err := getTargetAzureSubscription(subscriptionID)
if err != nil {
return nil, err
}

// Lookup environment URI
baseURI, err := getBaseURI()
if err != nil {
return nil, err
}

// Create a mysql server client
flexibleMySqlDBClient := mysqlflexibleservers.NewDatabasesClientWithBaseURI(baseURI, subscriptionID)

// Create an authorizer
authorizer, err := NewAuthorizer()
if err != nil {
return nil, err
}

// Attach authorizer to the client
flexibleMySqlDBClient.Authorizer = *authorizer

return &flexibleMySqlDBClient, nil
}

// CreateDisksClientE returns a new Disks client in the specified Azure Subscription
func CreateDisksClientE(subscriptionID string) (*compute.DisksClient, error) {
// Validate Azure subscription ID
Expand Down