Add azure SQL Server login using terraform - sql-server

Is it possible to add an user as active directory admin for an azure sql server using terraform?
https://learn.microsoft.com/pt-br/azure/sql-database/sql-database-aad-authentication
I need this to be enable users to authenticate through their company logins to a sql server created using Terraform.
I've found this question:
Add azure SQL user with terraform
But it is not what I need, it creates a new user for a login. Terraform docs regarding azure do not document this action.
https://www.terraform.io/docs/providers/azurerm/r/sql_server.html

Please reference this link: Active Directory Admin for azurerm_sql_server:
Support for configuring Azure Active Directory Administrators for a SQL Server Database can be found in the azurerm_sql_active_directory_administrator resource.
azurerm_sql_active_directory_administrator:
Allows you to set a user or group as the AD administrator for an Azure SQL server.
Example useage:
data "azurerm_client_config" "current" {}
resource "azurerm_resource_group" "example" {
name = "acceptanceTestResourceGroup1"
location = "West US"
}
resource "azurerm_sql_server" "example" {
name = "mysqlserver"
resource_group_name = "${azurerm_resource_group.example.name}"
location = "${azurerm_resource_group.example.location}"
version = "12.0"
administrator_login = "4dm1n157r470r"
administrator_login_password = "4-v3ry-53cr37-p455w0rd"
}
resource "azurerm_sql_active_directory_administrator" "example" {
server_name = "${azurerm_sql_server.example.name}"
resource_group_name = "${azurerm_resource_group.example.name}"
login = "sqladmin"
tenant_id = "${data.azurerm_client_config.current.tenant_id}"
object_id = "${data.azurerm_client_config.current.object_id}"
}
Hope this helps.

Related

Unable to find a management group - terraform

Any advice on additional troubleshooting steps for the below error?
Error: Management Group "00000000-0000-0000-0000-000000000000" was not found
with data.azurerm_management_group.current
on main.tf line 40, in data "azurerm_management_group" "current":
data "azurerm_management_group" "current" {
I am using a service principal with the Contributor role assigned to authenticate to azure.
I have ensured the management group UUID set in the terraform config points to the correct ID.
I have ensured that access management for Azure resources in the azure active directory is enabled so that my user account can manage access to all Azure subscriptions and management groups in this tenant.
I know that the GET Management REST API throws errors when calls are made to azure ad tenants with large resource hierarchies that would return a payload greater than 15 MB. However, I only have 1 root tenant management group in my tenant that I want to reference.
The data source is configured as:
data "azurerm_management_group" "current" {
# parent management group ID pulled in as a variable from terraform cloud using interpolation
name = var.parent_mg_id
}
The management group resource which will be created once the data source can be referenced is currently set as follows:
resource "azurerm_management_group" "az104-02-mg1" {
display_name = "az104-02-mg1"
# current subscription associated with existing tenant assigned to this management group
subscription_ids = [data.azurerm_subscription.current.subscription_id]
# existing root management group within AAD tenant set as parent mg of az-104 lab 2 management group
parent_management_group_id = data.azurerm_management_group.current.parent_management_group_id
}
Thanks in advance!
I tried to reproduce the same issue in my environment and got the below results
I have used the following script for the management groups it worked for me
vi vm.tf
provider "azurerm" {
features {}
}
data "azurerm_subscription" "current" {
}
resource "azurerm_management_group" "example_parent" {
display_name = "ParentGroup"
subscription_ids = [
data.azurerm_subscription.current.subscription_id,
]
}
resource "azurerm_management_group" "example_child" {
display_name = "ChildGroup"
parent_management_group_id = azurerm_management_group.example_parent.id
subscription_ids = [
data.azurerm_subscription.current.subscription_id,
]
}
Follow the below steps to execute the file
Terraform init
It will initialize the file
terraform plan
This will creates an execution plan and it will preview the changes that terraform plans to make the infrastructure
terraform apply
This will creates or updates the infrastructure depending on the configuration

How to connect database to data files in Azure Blob?

This resource states that a Azure SQL database may be attached to a database by using the following command:
WITH IDENTITY='SHARED ACCESS SIGNATURE',
SECRET = '<your SAS key>'
CREATE DATABASE testdb
ON
( NAME = testdb_dat,
FILENAME = 'https://testdb.blob.core.windows.net/data/TestData.mdf' )
LOG ON
( NAME = testdb_log,
FILENAME = 'https://testdb.blob.core.windows.net/data/TestLog.ldf')
This results in Syntax Error near "ON". What is the issue here?
To connect Azure SQL Database to Azure blob storage, you need to create an external data source with the database scoped credentials.
CREATE DATABASE SCOPED CREDENTIAL BlobCred
WITH
IDENTITY = 'SHARED ACCESS SIGNATURE',
SECRET = 'SAS token' ;
CREATE EXTERNAL DATA SOURCE BlobStg
WITH
( LOCATION =‘https://storagename.blob.core.windows.net’,
CREDENTIAL = BlobCred,
TYPE = BLOB_STORAGE
) ;
Refer to official documents this & this for more details.

Terraform - Azure Service Principal deployment - insufficient permissions

I am trying to create azure service principal. I am connection to azure from my laptop using service principal, I have added required permissions, service principal (which I am using to connect to azure) is a member of global administrators, sp is a member of an application developer and application administrator role in azure AD. In order to connect to Azure I am using following PowerShell commands.
$ApplicationId = "aaa"
$AppPassword = "bbb"
$TenantId = "ccc"
$SecuredPassword = ConvertTo-SecureString -String $AppPassword -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList
$ApplicationId, $SecuredPassword
Connect-AzAccount -ServicePrincipal -TenantId $TenantId -Credential $Credential
When I try run - terraform apply -var-file="variables.tfvars" I am getting an error:
with azuread_application.azuread_app,
│ on service-principal.tf line 3, in resource "azuread_application" "azuread_app":
│ 3: resource "azuread_application" "azuread_app" {
│
│ ApplicationsClient.BaseClient.Post(): unexpected status 403 with OData error: Authorization_RequestDenied: Insufficient privileges to complete the operation.
I was able to deploy other resources without any problems. I am using remote backend state file, located on Azure Container.
terraform code below:
data "azuread_client_config" "client_config" {}
resource "azuread_application" "azuread_app" {
display_name = "sp_name"
owners = [data.azuread_client_config.client_config.object_id]
}
resource "azuread_service_principal" "azuread_sp" {
application_id = azuread_application.azuread_app.application_id
app_role_assignment_required = false
owners = [data.azuread_client_config.client_config.object_id]
}
resource "azuread_service_principal_password" "azuread_sp_password" {
service_principal_id = azuread_service_principal.azuread_sp.object_id
}
I tested the same scenario in my environment using the below code and the Service Principal was successfully created from terraform.
terraform {
backend "azurerm" {
storage_account_name = "cloudshellansuman123" # replace with your storage account name
container_name = "test" #replace with your container name
key = "terraform.tfstate"
access_key = "ukyaH/Jxxxxxxxxxxxxxxxxx="#replace with your storage account access key
}
}
provider "azurerm" {
features{}
client_id="de398e56-xxxxxxxxxxxxxxxxxx-20d07416ecb0"#replace with your service principal client ID which you are using to connect with Azure
client_secret= "-IP7Q~uDLoxxxxxxxxxxxxRGtHMMXj7-.-lA"#replace with your service principal client Secret which you are using to connect with Azure
tenant_id = "ab07xxxxxxxxxxxxxxx--xxx-620b694ded30"#replace with your AzureAD tenant ID which the subscription is a part of
subscription_id="8xxxxxxxxxxx-xxxxxxx-xxxxxxxxx-xxae"#replace with your Subscription ID on Which the Service Principal has Owner/Contributor access
}
provider "azuread" {
client_id="de398e-xx-x-x-x-x-x-x-x416ecb0"#replace with your service principal client ID which you are using to connect with Azure AD
client_secret= "-IP7Q~uDLoxxxxxxxxxxxxxxGtHMMXj7-.-lA"#replace with your service principal client Secret which you are using to connect with Azure AD
tenant_id = "ab0xxxxxxxxxxxxxxx-xxxxxxxxx-xxxxxxxx30"#replace with your AzureAD tenant ID which the subscription is a part of
}
data "azuread_client_config" "current" {}
resource "azuread_application" "terraform" {
display_name = "Ansumantest"
owners = [data.azuread_client_config.current.object_id]
}
resource "azuread_application_password" "terraform" {
application_object_id = azuread_application.terraform.object_id
}
resource "azuread_service_principal" "terraform" {
application_id = azuread_application.terraform.application_id
owners = [data.azuread_client_config.current.object_id]
}
For Testing I created a Service Principal which I am using to connect with Azure and granted all the same permissions that you have granted and also added a Owner access on the subscription like below :
Output:
Note: Using the above code , you don't need again to connect to Azure using PowerShell. It will get authenticated directly using the .tf configuration. Also make sure to use Latest AzureRM and AzureAD provider Versions in terraform i.e. 2.95.0 & 2.17.0 respectively.

Azure VM SQL Server connection string

*** Apologies folks - I appended wrong code ---now replaced below here
I have a simple Visual Studio .NET web forms app. I run it on my Azure VM called dexram (Windows 10) and I also created a SQL Server on the Azure VM. There is a user on the VM called 5001211 that has admin authority in Windows. It can use SSMS to access the database no problems.
All my connection string attempts fail in the C# code. This is strange as the VS web app and the SQL Server are both running on the Azure VM.
Here are the strings I tried and the messages I got underneath:
string Server = "Data Source = dexram; Initial Catalog = FruitNVeg; User ID=5001211;Password=Fitsh3ly;";
This connection string throws an error:
Login failed for user '5001211'
string Server = "Data Source = tcp:dexram,1433; Database = FruitNVeg; User ID = 5001211#dexram; Password = Fitsh3ly; Trusted_Connection = False; Encrypt = True;";
The certificate chain was issued by an authority that is not trusted
string Server = "Data Source = tcp:dexram,1433; Authentication = Active Directory Integrated; Database = FruitNVeg;";
The certificate chain was issued by an authority that is not trusted
string Server = "Data Source = tcp:dexram,1433; Authentication = Active Directory Password; Database = FruitNVeg; UID=5001211#dexram;PWD=Fitsh3ly;";
The certificate chain was issued by an authority that is not trusted
Thanks Dan - no luck - I created as per your suggestion and made 5001211 sysadmin and got following results:
string Server = "Data Source = dexram; Initial Catalog = FruitNVeg; User ID=5001211;Password=Fitsh3ly;";
Gives -- > Login failed for user '5001211'
string Server = "Data Source = tcp:dexram,1433; Database = FruitNVeg; User ID = 5001211#dexram; Password = Fitsh3ly; Trusted_Connection = True; Encrypt = True;";
Gives -- > The certificate chain was issued by an authority that is not trusted
I am thinking I need to get a cert. created as I think (?) my SQL calls from my VS app are going out over the internet (even though the 2 tools (VS and SQL Svr) are on the same VM machine) ?
you must first create a user in sql server after use from string format below
Data Source=instanse name or use .;Initial Catalog=database bame;User ID=created user in sql server;Password=your password
and do setting below for user
User dexram\5001211 is a Windows account. Your app connection string specifies a SQL login named 5001211. You need to create a SQL login named 5001211 and an associated database user:
USE FruitNVeg;
CREATE LOGIN [5001211] WITH PASSWORD = 'Fitsh3ly';
CREATE USER [5001211];
The user will also need permissions on the objects the application uses in the FruitNVeg database. Although you could add the login to a privileged role like sysadmin to avoid granting these permissions, the best practice is to use a minimally privileged account for routine application database access that has only the required permissions:
USE FruitNVeg;
GRANT SELECT ON dbo.Apples TO [5001211];
As per this URL --> https://blog.greglow.com/2020/01/16/sql-sql-server-the-certificate-chain-was-issued-by-an-authority-that-is-not-trusted/
I used the sql config manager and set "Trust Server Cert" to yes and that fixed the problem it seems

Principal 'xyz' could not be resolved: how can I add a managed identity to Azure SQL Server when running under a Service Principal?

I want to add a managed identity (coming from an App Service) to Azure SQL Server.
I created an AAD group where a group of my team and the Service Principal is part of.
AzureSqlAdminGroup = TeamGroup + Service Principal
This AAD group is added as an Azure SQL admin during the provisioning of the Azure SQL Server.
When I run CreateSqlUserFromManagedIdentity under my personal account everything works fine. Whereas when I run the code under a service principal, SQL Server tells me that it can not resolve the managed identity of my app service and that the service principal doesn't have the permissions to do so.
System.Data.SqlClient.SqlException (0x80131904): Principal 'xyz' could not be resolved. Error message: ''
2020-06-10T16:34:12.6605990Z Cannot add the principal 'xyz', because it does not exist or you do not have permission.
2020-06-10T16:34:12.6606728Z Cannot add the principal 'xyz', because it does not exist or you do not have permission.
2020-06-10T16:34:12.6607420Z Cannot add the principal 'xyz', because it does not exist or you do not have permission.
Code:
public async Task CreateSqlUserFromManagedIdentity(string managedIdentityName, params string[] roles)
{
var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions
{
ExcludeVisualStudioCredential = true,
ExcludeVisualStudioCodeCredential = true
});
var accessToken = await credential.GetTokenAsync(new TokenRequestContext(new[] { "https://database.windows.net/.default" }));
var sqlConnectionStringBuilder = new SqlConnectionStringBuilder(_connectionString);
var stringBuilder = new StringBuilder();
stringBuilder.AppendLine($"IF DATABASE_PRINCIPAL_ID('{managedIdentityName}') IS NULL");
stringBuilder.AppendLine("BEGIN");
stringBuilder.AppendLine($"\tCREATE USER [{managedIdentityName}] FROM EXTERNAL PROVIDER;");
stringBuilder.AppendLine("END");
Console.WriteLine($"Adding Managed Identity '{managedIdentityName}' to '{sqlConnectionStringBuilder.DataSource}\\{sqlConnectionStringBuilder.InitialCatalog}' with roles ...");
foreach (var role in roles)
{
Console.WriteLine($"\t{role}");
stringBuilder.AppendLine($"ALTER ROLE {role} ADD MEMBER [{managedIdentityName}];");
}
await using var sqlConnection = new SqlConnection(_connectionString) { AccessToken = accessToken.Token };
await sqlConnection.OpenAsync();
var sqlCommand = sqlConnection.CreateCommand();
sqlCommand.CommandText = stringBuilder.ToString();
await sqlCommand.ExecuteNonQueryAsync();
ConsoleEx.WriteSuccessLine("successfully");
}
How can I add a Managed Identity to Azure SQL Server when running under a Service Principal?
Clarification:
xyz is the Managed Identity I want to add as a user in Azure SQL. I am running the code under a service principal (which fails).

Resources