Microsoft SQL Role Usage Guide
Requirements
- Outbound access to cdn.powershellgallery.com and www.powershellgallery.com to download required PowerShell modules. If outbound access is not available, the required modules can be manually installed. The required modules are:
- SqlServer
- SqlServerDsc
- ServerManager
- StorageDsc
- dbatools
- xNetworking
Prerequisites
- Storage must be provisioned on the host(s) Microsoft SQL will be installed on. This can be done using the storage roles. If ephemeral storage is being used for tempdb, it must be manually configured using AWS/Azure best practices.
- Required AD accounts (e.g. GMSAs) must be created. The create-gmsa.yml playbook can be used to create GMSAs in Active Directory.
- Either a customer provided ISO or a copy of Microsoft SQL Server Developer Edition (e.g. SQLServer2022-x64-ENU-Dev.iso).
- The following variables must be defined. Use a secure password generator to create strong passwords. The variables should be all uppercase when defined as environment variables, but all lowercase when defined in
host_varsorgroup_varsfiles or an ansible vault.
Usage
- Create a file in
host_varsfor each host Microsoft SQL will be installed on if it doesn't already exist. The file should be named after the host's inventory name (e.g.host_vars/abcmsql01.yml). - A SQL ISO is required to install Microsoft SQL Server. The playbook supports delivering it via HTTP(S) (e.g. storage account, S3 bucket, caddy file server, etc.) or by uploading it from the Ansible control node.
- When uploading files from the Ansible control node, place the ISO in a "shared files" directory on the ansible control node (usually a location on the container's persistent storage in
/home/ansible/source/files) and setshared_files_directoryingroup_varsto the path of the directory. If themicrosoft_sql_install_source_dirvariable is defined inhost_vars, it will overrideshared_files_directoryfor that host. - If the value of
shared_files_directoryormicrosoft_sql_install_source_diris a URL, the playbook will attempt to download the ISO from that location. If it's a local file path, the playbook will attempt to upload the ISO from the Ansible control node.microsoft_sql_install_source_fileshould be set to the name of the ISO file (e.g. 'SQLServer2019.iso').
- When uploading files from the Ansible control node, place the ISO in a "shared files" directory on the ansible control node (usually a location on the container's persistent storage in
-
Update each hosts
host_varswith the necessary variables using the sample variables below or navigate totemplatesto see more examples.SQL Template Variables
If you are deploying a multipurpose SQL server for Kuiper/System Pulse, ensure variables in the template are configured to grant database permissions to both the user account running the Kuiper installation Ansible role and the Kuiper GMSA.
-
Run the
playbooks/deploy-microsoft-sql.ymlplaybook. This playbook calls themicrosoft-sqlrole to install Microsoft SQL and dependencies, configure databases, users, permissions, firewall rules, etc. It also contains some tasks specific to Kuiper/System Pulse deployments.
Sample Variables
SQL Template Variables
The sample below is for a Kuiper/System Pulse multipurpose SQL Deployment. Be sure to customize environment specific variables in the template. Many of the lines containing environment specific values are highlighted in the code block below. See comments for more information.
Azure SQL Database (SaaS)
The microsoft_sql role targets a SQL Server instance it installs and manages
locally, so it does not apply to Azure SQL Database. That platform has no
Windows or Kerberos integrated authentication, which means an AADDS-joined VM
cannot connect as its machine account or as a gMSA — applications authenticate
with a contained SQL user instead.
playbooks/ire/configure-azure-sql-db-user.yml provisions those users. It is
idempotent: if a user can already log in and holds the roles it is meant to
hold, it changes nothing; otherwise it creates or re-keys the user as the server
admin, grants the requested database roles, and then verifies both the login and
the role membership.
The SQL work is delegated to azure_sql_management_host — a Windows host with
network line of sight to the server's private endpoint, defaulting to the first
Kuiper server — because the Ansible controller is not on that VNet.
Each application declares its own databases in its group's group_vars, next to
the vaulted credentials it references. azure_sql_databases has the same shape
as microsoft_sql_databases — a list of databases, each
with its users and its roles, whose members are drawn from those users — so
both SQL platforms are declared the same way:
azure_sql_server: sph-ire-epicsql-centralus-sql.database.windows.net
azure_sql_databases:
- name: Kuiper
users:
- name: "{{ kuiper_sql_user }}"
password: "{{ kuiper_sql_password }}"
roles:
- name: db_owner
members:
- "{{ kuiper_sql_user }}"
| Variable | Description |
|---|---|
azure_sql_server |
FQDN of the Azure SQL server. |
azure_sql_admin_user |
Server admin login, used only to create or re-key users. |
azure_sql_admin_password |
Server admin password. Falls back to the AZURE_SQL_ADMIN_PASSWORD environment variable. |
azure_sql_databases |
Databases to provision, each with name, users, and roles. |
azure_sql_management_host |
Windows host the SQL work runs from. Defaults to the first host in app_kuiper. |
A users entry is either a bare login name or a mapping with a name and an
optional password. Password precedence matches the microsoft_sql role: the
user's own password attribute, then the azure_sql_<user>_password Ansible
variable, then the AZURE_SQL_<USER>_PASSWORD environment variable.
Roles are additive — like the role's MembersToInclude, the playbook grants
missing memberships and never revokes one. Every role member must be one of that
database's declared users; the playbook asserts this before it connects.
azure_sql_admin_user / azure_sql_admin_password are the server admin
credentials and are set once per environment — on Azure IRE they come from
group_vars/ire_copier_azure_platform/vault.yml (see
Secret Management).
Hosts that do not define azure_sql_databases are skipped, so a single run
covers every application in the inventory:
The databases themselves are created by Terraform, not by this playbook.