Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.3.0] - 2022-12-14

### Added

- Resource `mssql_role` to manipulate role of a SQL Server.

## [0.2.6] - 2022-11-25

### Added
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ HOSTNAME=betr.io
NAMESPACE=betr
NAME=mssql
BINARY=terraform-provider-${NAME}
VERSION=0.2.6
VERSION=0.3.0
OS_ARCH=linux_amd64
TERRAFORM=terraform

Expand Down
55 changes: 55 additions & 0 deletions docs/resources/role.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# mssql_role

The `mssql_role` resource creates and manages a role on a SQL Server database.

## Example Usage

### Basic usage

```hcl
resource "mssql_role" "example" {
server {
host = "example-sql-server.database.windows.net"
azure_login {
tenant_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
client_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
client_secret = "terriblySecretSecret"
}
}
database = "master"
role_name = "example-role-name"
}
```

## Argument Reference

The following arguments are supported:

* `server` - (Required) Server and login details for the SQL Server. The attributes supported in the `server` block is detailed below.
* `role_name` - (Required) The name of the role. Changing this resource property modifies the existing resource.
* `database` - (Optional) The user will be created in this database. Defaults to `master`. Changing this forces a new resource to be created.

The `server` block supports the following arguments:

* `host` - (Required) The host of the SQL Server. Changing this forces a new resource to be created.
* `port` - (Optional) The port of the SQL Server. Defaults to `1433`. Changing this forces a new resource to be created.
* `login` - (Optional) SQL Server login for managing the database resources. The attributes supported in the `login` block is detailed below.

The `login` block supports the following arguments:

* `username` - (Required) The username of the SQL Server login. Can also be sourced from the `MSSQL_USERNAME` environment variable.
* `password` - (Required) The password of the SQL Server login. Can also be sourced from the `MSSQL_PASSWORD` environment variable.
* `object_id` - (Optional) The object id of the external username. Only used in azure_login auth context when AAD role delegation to sql server identity is not possible.

## Import

Before importing `mssql_role`, you must to configure the authentication to your sql server:

1. Using Azure AD authentication, you must set the following environment variables: `MSSQL_TENANT_ID`, `MSSQL_CLIENT_ID` and `MSSQL_CLIENT_SECRET`.
2. Using SQL authentication, you must set the following environment variables: `MSSQL_USERNAME` and `MSSQL_PASSWORD`.

After that you can import the SQL Server database role using the server URL and `role name`, e.g.

```shell
terraform import mssql_role.example 'mssql://example-sql-server.database.windows.net/master/testrole'
```
20 changes: 16 additions & 4 deletions examples/azure/main.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
terraform {
required_version = "~> 0.13"
required_version = "~> 1.3.6"
required_providers {
azuread = {
source = "hashicorp/azuread"
Expand All @@ -11,15 +11,15 @@ terraform {
}
mssql = {
source = "betr-io/mssql"
version = "0.1.0"
version = "0.2.6"
}
random = {
source = "hashicorp/random"
version = "~> 3.0.0"
version = "~> 3.4.3"
}
time = {
source = "hashicorp/time"
version = "0.6.0"
version = "0.9.0"
}
}
}
Expand Down Expand Up @@ -225,6 +225,18 @@ resource "mssql_user" "server" {
login_name = mssql_login.server.login_name
}

resource "mssql_role" "server" {
server {
host = azurerm_mssql_server.sql_server.fully_qualified_domain_name
login {
username = azurerm_mssql_server.sql_server.administrator_login
password = azurerm_mssql_server.sql_server.administrator_login_password
}
}
database = azurerm_mssql_database.db.name
role_name = "testrole"
}

output "instance" {
value = {
login_name = mssql_login.server.login_name,
Expand Down
19 changes: 14 additions & 5 deletions examples/fedauth/main.tf
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
terraform {
required_version = "~> 0.13"
required_version = "~> 1.3.6"
required_providers {
azuread = {
source = "hashicorp/azuread"
version = "~> 1.0"
version = "~> 2.22.0"
}
azurerm = {
source = "hashicorp/azurerm"
version = "~> 2.99.0"
version = "~> 3.8.0"
}
mssql = {
source = "betr.io/betr/mssql"
version = "0.2.6"
}
random = {
source = "hashicorp/random"
version = "~> 3.0.0"
version = "~> 3.4.3"
}
time = {
source = "hashicorp/time"
version = "0.6.0"
version = "0.9.0"
}
}
}
Expand Down Expand Up @@ -134,3 +134,12 @@ resource "mssql_user" "external" {
database = azurerm_mssql_database.db.name
username = "[email protected]"
}

resource "mssql_role" "external" {
server {
host = azurerm_mssql_server.sql_server.fully_qualified_domain_name
azuread_default_chain_auth {}
}
database = azurerm_mssql_database.db.name
role_name = "testrole"
}
29 changes: 23 additions & 6 deletions examples/local/main.tf
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
terraform {
required_version = "~> 0.13"
required_version = "~> 1.3.6"
required_providers {
docker = {
source = "terraform-providers/docker"
version = "~> 2.7.2"
source = "kreuzwerker/docker"
version = "~> 2.23.1"
}
mssql = {
source = "betr-io/mssql"
version = "~> 0.1.0"
version = "~> 0.2.6"
}
random = {
source = "hashicorp/random"
version = "~> 2.3"
version = "~> 3.4.3"
}
time = {
source = "hashicorp/time"
version = "0.6.0"
version = "0.9.0"
}
}
}
Expand Down Expand Up @@ -45,6 +45,10 @@ resource "docker_container" "mssql" {
name = "mssql"
image = docker_image.mssql.latest
env = ["ACCEPT_EULA=Y", "SA_PASSWORD=${local.local_password}"]
ports {
internal = 1433
external = 1433
}
}

resource "time_sleep" "wait_5_seconds" {
Expand Down Expand Up @@ -91,7 +95,20 @@ resource "mssql_user" "example" {
login_name = mssql_login.example.login_name
}

resource "mssql_role" "example" {
server {
host = docker_container.mssql.ip_address
login {
username = local.local_username
password = local.local_password
}
}
database = "master"
role_name = "testrole"
}

output "login" {
sensitive = true
value = {
login_name = mssql_login.example.login_name,
password = mssql_login.example.password
Expand Down
17 changes: 14 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package main

import (
"github.com/hashicorp/terraform-plugin-sdk/v2/plugin"
"flag"

"github.com/betr-io/terraform-provider-mssql/mssql"
"github.com/hashicorp/terraform-plugin-sdk/v2/plugin"
)

// These will be set by goreleaser to appropriate values for the compiled binary
Expand All @@ -12,7 +14,16 @@ var (
)

func main() {
plugin.Serve(&plugin.ServeOpts{
var debug bool

flag.BoolVar(&debug, "debug", false, "set to true to run the provider with support for debuggers like delve")
flag.Parse()

opts := &plugin.ServeOpts{
Debug: debug,
ProviderAddr: "registry.terraform.io/betr-io/mssql",
ProviderFunc: mssql.New(version, commit),
})
}

plugin.Serve(opts)
}
1 change: 1 addition & 0 deletions mssql/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const (
passwordProp = "password"
sidStrProp = "sid"
clientIdProp = "client_id"
roleNameProp = "role_name"
authenticationTypeProp = "authentication_type"
defaultSchemaProp = "default_schema"
defaultSchemaPropDefault = "dbo"
Expand Down
7 changes: 7 additions & 0 deletions mssql/model/role.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package model

// Role represents a SQL Server role
type Role struct {
RoleID int64
RoleName string
}
12 changes: 7 additions & 5 deletions mssql/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ package mssql
import (
"context"
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"io"
"os"
"time"

"github.com/betr-io/terraform-provider-mssql/mssql/model"
"github.com/betr-io/terraform-provider-mssql/sql"
"time"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)

type mssqlProvider struct {
Expand Down Expand Up @@ -46,6 +47,7 @@ func Provider(factory model.ConnectorFactory) *schema.Provider {
ResourcesMap: map[string]*schema.Resource{
"mssql_login": resourceLogin(),
"mssql_user": resourceUser(),
"mssql_role": resourceRole(),
},
DataSourcesMap: map[string]*schema.Resource{},
ConfigureContextFunc: func(ctx context.Context, data *schema.ResourceData) (interface{}, diag.Diagnostics) {
Expand Down
19 changes: 12 additions & 7 deletions mssql/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import (
"context"
sql2 "database/sql"
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"os"
"strconv"
"github.com/betr-io/terraform-provider-mssql/mssql/model"
"github.com/betr-io/terraform-provider-mssql/sql"
"testing"
"text/template"
"time"

"github.com/betr-io/terraform-provider-mssql/mssql/model"
"github.com/betr-io/terraform-provider-mssql/sql"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

var runLocalAccTests bool
Expand Down Expand Up @@ -61,6 +61,7 @@ type Check struct {
type TestConnector interface {
GetLogin(name string) (*model.Login, error)
GetUser(database, name string) (*model.User, error)
GetRole(database, name string) (*model.Role, error)
GetSystemUser() (string, error)
GetCurrentUser(database string) (string, string, error)
}
Expand Down Expand Up @@ -158,6 +159,10 @@ func (t testConnector) GetUser(database, name string) (*model.User, error) {
return t.c.(UserConnector).GetUser(context.Background(), database, name)
}

func (t testConnector) GetRole(database string, roleName string) (*model.Role, error) {
return t.c.(RoleConnector).GetRole(context.Background(), database, roleName)
}

func (t testConnector) GetSystemUser() (string, error) {
var user string
err := t.c.(*sql.Connector).QueryRowContext(context.Background(), "SELECT SYSTEM_USER;", func(row *sql2.Row) error {
Expand Down Expand Up @@ -190,7 +195,7 @@ func templateToString(name, text string, data interface{}) (string, error) {
return doc.String(), nil
}

func testAccImportStateId(resource string, azure bool) func(state *terraform.State) (string, error) {
func testResourceTryGetStateId(resource string) func(state *terraform.State) (string, error) {
return func(state *terraform.State) (string, error) {
rs, ok := state.RootModule().Resources[resource]
if !ok {
Expand All @@ -199,6 +204,6 @@ func testAccImportStateId(resource string, azure bool) func(state *terraform.Sta
if rs.Primary.ID == "" {
return "", fmt.Errorf("no record ID is set")
}
return rs.Primary.ID + "?azure=" + strconv.FormatBool(azure), nil
return rs.Primary.ID, nil
}
}
5 changes: 3 additions & 2 deletions mssql/resource_login_import_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package mssql

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"testing"
)

func TestAccLogin_Local_BasicImport(t *testing.T) {
Expand All @@ -24,7 +25,7 @@ func TestAccLogin_Local_BasicImport(t *testing.T) {
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"password"},
ImportStateIdFunc: testAccImportStateId("mssql_login.test_import", false),
ImportStateIdFunc: testResourceTryGetStateId("mssql_login.test_import"),
},
},
})
Expand Down
Loading