This repository provides a simple and efficient way for users to provision AzureStack HCI clusters in a bunch of locations using Terraform. By forking this repository and modifying the parameters, you can quickly and easily deploy AzureStack HCI to your environment.
Check deployment checklist and install AzureStack HCI OS on your servers to be deployed as AzureStack HCI clusters. Complete the step 2 (Download the software) & 3 (Install the OS) in this doc. Step 1 (Prepare Active Directory) & 4 (Register with Arc and set up permissions) are covered in the project. Follow the guidance in this repository to start HCI deployments.
To get started, follow these steps:
- Create a repository base on this template.
- Setup pipeline.
- Create a branch from
main
. - Rename
dev/sample
to<your location>
. Edit the variables in thedev/<your location>/main.tf
commit and push. - Create a pull request to
main
. After approval, changes will be applied automatically. After the successful deployment, following resources will be created:- A resource group name
<site>-rg
- A KeyVault named
<site>-kv
: Contains secrets that used for deploy - Arc servers that make up the HCI cluster
- A storage account used for HCI cloud witness
- An HCI cluster name
<site>-cl
- Arc Resource Bridge named
<site>-cl-arcbridge
- Custom location of ARB named
<site>-customLocation
- Two storage paths named
UserStorage1
,UserStorage2
- A resource group name
- Add new sites by copy and paste your first site folder to others. Commit and create a pull request for new sites. After the pull request is merged, new sites will be applied.
-
Setup OIDC service principle to allow your repository terraform environment authenticate as the service principle. The detailed steps are described in Azure documentation. Here's the steps:
- Create
terraform
environment in your GitHub repository. Creating an environment - Create a service principal in Microsoft Entra ID Application and service principal objects in Microsoft Entra ID.
- Add Federated credential to the service principal. Use
Environment
as entity type and inputterraform
toBased on selection
input box. - Add a secret and save it to
servicePrincipalSecret
in the repo secrets described in the next step. - Grant the following permissions to the service principle in your subscription:
- Contributor (to create resource group / KeyVault / HCI cluster...)
- Key Vault Secrets Officer (to create secret in azure KeyVault)
- User Access Administrator (to grant role for arc-enabled servers)
- Create
-
Setup repository secret following Managing secrets for your repository and organization for GitHub Codespaces:
- Pipeline secrets:
- AZURE_CLIENT_ID: The client ID of the service principle in step 1.
- AZURE_SUBSCRIPTION_ID: The subscription ID of the service principle in step 1.
- AZURE_TENANT_ID: The tenant ID of the service principle in step 1.
- HCI secrets:
- domainAdminUser
- domainAdminPassword
- localAdminUser
- localAdminPassword
- servicePrincipalId
- servicePrincipalSecret
- Pipeline secrets:
-
Setup Terraform backend:
- Create a storage account in your Azure subscription (the same subscription as AZURE_SUBSCRIPTION_ID). Create a container in it.
- Open
.azure/backendTemplate.tf
in this repository. Replace\<ResourceGroupName\>
,\<StorageAccountName\>
,\<StorageContainerName\>
to the storage account and container you just created. - Commit
.azure/backendTemplate.tf
and push.
-
Setup git hooks:
Run
git config --local core.hooksPath ./.azure/hooks/
. This hook will generate the pipeline definitiondeploy-infra.yml
when you commit changes to this repository. -
Setup GitHub runners.
- If the remote PowerShell port(5985) of HCI is exposed to the Internet. Open
.github/workflows/site-cd-workflow.yml
. Modifyruns-on
section to
runs-on: [ubuntu-latest] # runs-on: [self-hosted]
- If your HCI nodes can be remote managed inside your CorpNet. You can setup self-host runner. Runner hosts must setup the following tools.
- Install Git. Add
Git
to path. Rungit --version
to validate. - Add
<Git installation root>\usr\bin
to path. The default path isC:\Program Files\Git\usr\bin
. - Install Az CLI. Run
az --version
to validate installation. - Follow the first answer in PowerShell Remoting - stackoverflow, finish client side settings to allow remote PowerShell HCI servers from runners.
- Register self-hosted runners. Make sure that the runner process is running as Administrator.
- Install Git. Add
- If the remote PowerShell port(5985) of HCI is exposed to the Internet. Open
After the first HCI deployment succeeds, you may want to scale the deployment to more sites. You can simply copy and paste your first site folder. Edit main.tf
for each newly copied sites to the site specific values. Commit and create a pull request for the changes. Deployment pipeline and backend settings will be set during the commit. Once the pull request is merged into main
branch, pipeline will be triggered and deploy new sites accordingly. An example could be
├───dev
│ └───firstsite
│ main.tf
│ ...
│
├───prod
│ ├───prod1
│ │ main.tf
│ │ ...
│ │
│ ├───prod2
│ │ main.tf
│ │ ...
│ │
│ └───prod3
│ main.tf
│ ...
│
└───qa
├───qa1
│ main.tf
│ ...
│
└───qa2
main.tf
...
Microsoft collects deployment pipeline telemetry. If you do not want to send telemetry, edit .github/workflows/site-cd-workflow.yml
, remove all steps starts with Telemetry
.
Removing one folder will not remove the resources created by this folder previously.
You have 2 ways to cleanup if you do want to remove the resources.
- Before removing the folder, run
terraform destroy
to destroy the resources created by this Terraform configuration. Then remove this folder. - Go to Azure portal or use CLI to remove
${siteId}-rg
resource group and remove this folder.
PROJECT_ROOT
│
├───.azure
│ │ backendTemplate.tf // Backend storage account config file
│ │
│ └───hooks
│ pre-commit // Git hook to generate deployment workflow and set backend
│
├───.github
│ └───workflows
│ site-cd-workflow.yml // Steps to deploy a single site
│
├───dev // The first stage to deploy
│ └───sample
│ backend.tf
│ main.tf // Main configuration file for the site
│ provider.tf
│ terraform.tf
│ variables.tf
│
├───modules
│ ├───base // Base module of all sites
│ │ main.tf
│ │ variables.tf
│ │
│ ├───hci // Module to manage HCI clusters
│ │ │
│ │ └───hciserver
│ │
│ ├───hci-extensions // Module to manage HCI extensions
│ │
│ └───hci-vm // Module to manage HCI VMs
│
├───prod // prod stage sites are deployed after qa stage
│ │
│ └───prod1
│
└───qa // qa stage sites are deployed after dev stage
│
└───qa1
You may create new folders to represent a stage. Put new sites under the folder. Then, open .stages
file to add the stage into your deployment workflow. Commit the changes, the deployment pipeline will change accordingly.
Edit modules/base/naming.tf
for your naming conventions. The default naming for resources are
Resource | Naming |
---|---|
Resource group | {siteId}-rg |
Witness storage account | {siteId}wit |
KeyVault | {siteId}-kv |
cluster | {siteId}-cl |
custom location | {siteId}-customlocation |
Log analytics workspace | {siteId}-workspace |
Log analytics data collection endpoint | {siteId}-dce |
Log analytics data collection rule | AzureStackHCI-{siteId}-dcr |
You may toggle whether to append random suffix for storage account and KeyVault by with randomSuffix
local variable. If randomSuffix
is set to true, it can avoid conflicts when storage account and KeyVault soft deletion is enabled. randomSuffix
is a random integer from 10 to 99. The naming will changed to
Resource | Naming |
---|---|
Resource group | {siteId}-rg |
Witness storage account | {siteId}wit{randomSuffix} |
KeyVault | {siteId}-kv-{randomSuffix} |
You may edit modules/base
to customize your deployment template for all sites. You may add default values for your sites in modules/base/variables.tf
. For example, tenant name is likely to be the same for all sites. You can add a default value for tenant
variable.
variable "tenant" {
type = string
description = "The tenant ID for the Azure account."
default = "<your tennat ID>"
}
If you want to deploy locally:
- Create a repository base on this template.
- Clone the forked repository to your local machine.
- Install Terraform if not already installed.
- Make sure you have the following permissions to the subscription you want to deploy HCI clusters.
- Contributor (to create resource group / KeyVault / HCI cluster...)
- Key Vault Secrets Officer (to create secret in azure KeyVault)
- User Access Administrator (to grant role for arc-enabled servers)
- Edit
.azure/backendTemplate.tf
to use local backend.terraform { backend "local" {} }
- Modify the variables in the
dev/sample/main.tf
file to fit your environment's requirements. - Open a PowerShell as administrator,
az login
with your credentials. - Go to the site folder
cd dev/sample
. - Add
sample.tfvars
to assign values for variables.subscriptionId = "<your subscription id>" localAdminUser = "<local admin user name>" localAdminPassword = "<local admin password>" domainAdminUser = "<domain admin user name>" domainAdminPassword = "<domain admin user password>" servicePrincipalId = "<service principal id created in the first step of setting pipeline>" servicePrincipalSecret = "<service principal secret created in the first step of setting pipeline>"
- Initialize the Terraform working directory by running
terraform init
. - Apply the Terraform configuration and create the resources by running
terraform apply -var-file="sample.tfvars"
.
The above commands will provision an AzureStack HCI cluster in your Azure subscription.
Name | Description | Type | Default | Required |
---|---|---|---|---|
adouPath | The Active Directory OU path. | string |
n/a | yes |
defaultGateway | The default gateway for the network. | string |
n/a | yes |
dnsServers | A list of DNS server IP addresses. | list(string) |
n/a | yes |
domainAdminPassword | The password for the domain administrator account. | string |
n/a | yes |
domainAdminUser | The username for the domain administrator account. | string |
n/a | yes |
domainFqdn | The domain FQDN. | string |
n/a | yes |
domainName | The domain name for the environment. | string |
n/a | yes |
domainServerIP | The ip of the domain server. | string |
n/a | yes |
endingAddress | The ending IP address of the IP address range. | string |
n/a | yes |
localAdminPassword | The password for the local administrator account. | string |
n/a | yes |
localAdminUser | The username for the local administrator account. | string |
n/a | yes |
servers | A list of servers with their names and IPv4 addresses. | list(object({ |
n/a | yes |
servicePrincipalId | The service principal ID for the Azure account. | string |
n/a | yes |
servicePrincipalSecret | The service principal secret for the Azure account. | string |
n/a | yes |
siteId | A unique identifier for the site. | string |
n/a | yes |
startingAddress | The starting IP address of the IP address range. | string |
n/a | yes |
subId | The subscription ID for the Azure account. | string |
n/a | yes |
tenant | The tenant ID for the Azure account. | string |
n/a | yes |
destory_adou | whether destroy previous adou | bool |
false |
no |
location | The Azure region where the resources will be deployed. | string |
"eastus" |
no |
rp_principal_id | The principal ID of the resource provider. | string |
"f0e0e122-3f80-44ed-95d2-f56e6fdc514c" |
no |
subnetMask | The subnet mask for the network. | string |
"255.255.255.0" |
no |
This project is licensed under the MIT License. See the LICENSE file for more information.
This repository is provided "as-is" without any warranties or support. Use at your own risk. Always test in a non-production environment before deploying to production.
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.