Skip to content

Commit 7c79826

Browse files
authored
Merge 8bf6142 into 2a85c3c
2 parents 2a85c3c + 8bf6142 commit 7c79826

File tree

10 files changed

+487
-2
lines changed

10 files changed

+487
-2
lines changed

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Costa Rica
55
[![GitHub](https://img.shields.io/badge/--181717?logo=github&logoColor=ffffff)](https://github.com/)
66
[brown9804](https://github.com/brown9804)
77

8-
Last updated: 2025-02-21
8+
Last updated: 2025-04-15
99

1010
------------------------------------------
1111

@@ -27,8 +27,24 @@ Last updated: 2025-02-21
2727

2828
</details>
2929

30+
## Prerequisites
31+
32+
- An `Azure subscription is required`. All other resources, including instructions for creating a Resource Group, are provided in this workshop.
33+
- `Contributor role assigned or any custom role that allows`: access to manage all resources, and the ability to deploy resources within subscription.
34+
- If you choose to use a Terraform approach, please ensure that:
35+
- [Terraform is installed on your local machine](https://developer.hashicorp.com/terraform/tutorials/azure-get-started/install-cli#install-terraform).
36+
- [Install the Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) to work with both Terraform and Azure commands.
3037

3138
<div align="center">
3239
<h3 style="color: #4CAF50;">Total Visitors</h3>
3340
<img src="https://profile-counter.glitch.me/brown9804/count.svg" alt="Visitor Count" style="border: 2px solid #4CAF50; border-radius: 5px; padding: 5px;"/>
3441
</div>
42+
43+
## Infrastructure as Code (IaC)
44+
45+
46+
47+
<div align="center">
48+
<img src="https://github.com/user-attachments/assets/16640052-7f57-443a-9efd-30855de5e231" alt="Centered Image" style="border: 2px solid #4CAF50; border-radius: 5px; padding: 5px;"/>
49+
</div>
50+

Terraform/README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Costa Rica
55
[![GitHub](https://img.shields.io/badge/--181717?logo=github&logoColor=ffffff)](https://github.com/)
66
[brown9804](https://github.com/brown9804)
77

8-
Last updated: 2025-03-13
8+
Last updated: 2025-04-15
99

1010
------------------------------------------
1111

@@ -34,6 +34,7 @@ Last updated: 2025-03-13
3434

3535
- [Overview](#overview)
3636
- [Finding admin_principal_id Using Azure CLI](#finding-admin_principal_id-using-azure-cli)
37+
- [Configure Remote Storage for a Terraform deployment](#configure-remote-storage-for-a-terraform-deployment)
3738
- [How to execute it](#how-to-execute-it)
3839

3940
</details>
@@ -78,6 +79,16 @@ Here is an example value for `admin_principal_id` which is Object ID you retriev
7879
admin_principal_id = "12345678-1234-1234-1234-1234567890ab"
7980
```
8081

82+
## Configure Remote Storage for a Terraform deployment
83+
84+
> To configure remote storage for a Terraform deployment, you need to set up a backend configuration in your Terraform files. This backend configuration specifies where Terraform should store the state file, which keeps track of the resources it manages.
85+
86+
> 1. Create an Azure Storage Account: <br/>
87+
> - Go to the Azure portal and create a new storage account (if you don't have one already). <br/>
88+
> - Note down the storage account name and the access key. <br/>
89+
> 2. Create a Storage Container: Within the storage account, create a new container to store the Terraform state file.
90+
> 3. Configure Terraform Backend: In your Terraform configuration file (e.g., [remote-storage.tf](./src/remote-storage.tf), add the backend configuration for Azure Blob Storage.
91+
8192
## How to execute it
8293

8394
```mermaid

Terraform/src/main.tf

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Retrieve the client configuration of the AzureRM provider
2+
data "azurerm_client_config" "example" {}
3+
4+
# Check the directory object type
5+
data "azuread_directory_object" "example" {
6+
object_id = data.azurerm_client_config.example.object_id
7+
}
8+
9+
# Get information about the Entra user
10+
data "azuread_user" "example" {
11+
object_id = data.azurerm_client_config.example.object_id
12+
}
13+
14+
# Local value to determine if the client is a user or not
15+
locals {
16+
fabric_admin = can(data.azuread_directory_object.example.type == "User") ? data.azuread_user.example.user_principal_name : data.azurerm_client_config.example.object_id
17+
}
18+
19+
# Create a resource group
20+
resource "azurerm_resource_group" "example" {
21+
name = var.resource_group_name # Name of the resource group
22+
location = var.location # Location of the resource group
23+
}
24+
25+
# Create a storage account for remote state
26+
resource "azurerm_storage_account" "example" {
27+
name = var.storage_account_name
28+
resource_group_name = azurerm_resource_group.example.name
29+
location = azurerm_resource_group.example.location
30+
account_tier = "Standard"
31+
account_replication_type = "LRS"
32+
depends_on = [azurerm_resource_group.example] # Ensure resource group is created first
33+
}
34+
35+
# Create a storage container for remote state
36+
resource "azurerm_storage_container" "example" {
37+
name = var.container_name
38+
storage_account_name = azurerm_storage_account.example.name
39+
container_access_type = "private"
40+
depends_on = [azurerm_storage_account.example] # Ensure storage account is created first
41+
}
42+
43+
# Create an MSSQL Server
44+
resource "azurerm_mssql_server" "example" {
45+
name = var.sql_server_name # Name of the SQL Server
46+
resource_group_name = azurerm_resource_group.example.name # Resource group name
47+
location = azurerm_resource_group.example.location # Location of the SQL Server
48+
version = "12.0" # SQL Server version
49+
administrator_login = var.admin_username # Administrator username
50+
administrator_login_password = var.admin_password # Administrator password
51+
depends_on = [azurerm_resource_group.example] # Ensure resource group is created first
52+
}
53+
54+
# Add a null resource to introduce a delay
55+
resource "null_resource" "wait_for_sql_server" {
56+
depends_on = [azurerm_mssql_server.example]
57+
58+
provisioner "local-exec" {
59+
command = "Start-Sleep -Seconds 60"
60+
interpreter = ["PowerShell", "-Command"]
61+
}
62+
}
63+
64+
# Create an MSSQL Database
65+
resource "azurerm_mssql_database" "example" {
66+
name = var.sql_database_name # Name of the SQL Database
67+
server_id = azurerm_mssql_server.example.id # ID of the SQL Server
68+
sku_name = "Basic" # SKU name for the SQL Database
69+
depends_on = [null_resource.wait_for_sql_server] # Ensure SQL Server is fully provisioned first
70+
}
71+
72+
# Create Microsoft Fabric Capacity
73+
resource "azurerm_fabric_capacity" "example" {
74+
name = "fc${var.solution_name}"
75+
resource_group_name = azurerm_resource_group.example.name
76+
location = var.location
77+
78+
administration_members = setunion([local.fabric_admin], var.fabric_capacity_admin_upns)
79+
80+
sku {
81+
name = var.fabric_capacity_sku
82+
tier = "Fabric"
83+
}
84+
depends_on = [azurerm_resource_group.example] # Ensure resource group is created first
85+
}
86+
87+
# Get the Fabric Capacity details
88+
data "fabric_capacity" "example" {
89+
display_name = azurerm_fabric_capacity.example.name
90+
91+
lifecycle {
92+
postcondition {
93+
condition = self.state == "Active"
94+
error_message = "Fabric Capacity is not in Active state. Please check the Fabric Capacity status."
95+
}
96+
}
97+
}
98+
99+
# Create a Fabric Workspace
100+
resource "fabric_workspace" "example" {
101+
capacity_id = data.fabric_capacity.example.id
102+
display_name = "ws-${var.solution_name}"
103+
depends_on = [data.fabric_capacity.example] # Ensure Fabric Capacity data source is available first
104+
}

Terraform/src/outputs.tf

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Output the name of the resource group
2+
output "resource_group_name" {
3+
value = azurerm_resource_group.example.name # The name of the resource group
4+
}
5+
6+
# Output the name of the storage account
7+
output "storage_account_name" {
8+
value = azurerm_storage_account.example.name # The name of the storage account
9+
}
10+
11+
# Output the name of the storage container
12+
output "storage_container_name" {
13+
value = azurerm_storage_container.example.name # The name of the storage container
14+
}
15+
16+
# Output the name of the MSSQL Server
17+
output "sql_server_name" {
18+
value = azurerm_mssql_server.example.name # The name of the SQL Server
19+
}
20+
21+
# Output the name of the MSSQL Database
22+
output "sql_database_name" {
23+
value = azurerm_mssql_database.example.name # The name of the SQL Database
24+
}
25+
26+
# Output the name of the Microsoft Fabric Capacity
27+
output "fabric_capacity_name" {
28+
value = azurerm_fabric_capacity.example.name
29+
}
30+
31+
output "fabric_workspace_name" {
32+
value = fabric_workspace.example.display_name
33+
}

Terraform/src/provider.tf

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
terraform {
2+
required_version = ">= 1.8, < 2.0"
3+
# Specify the required providers and their versions
4+
required_providers {
5+
azurerm = {
6+
source = "hashicorp/azurerm" # Source of the AzureRM provider
7+
version = "~> 4.16.0" # Version of the AzureRM provider
8+
}
9+
fabric = {
10+
source = "microsoft/fabric"
11+
version = "0.1.0-beta.7"
12+
}
13+
}
14+
}
15+
16+
provider "azurerm" {
17+
features {} # Enable all features for the AzureRM provider
18+
subscription_id = var.subscription_id # Add your subscription ID here
19+
}
20+
21+
provider "fabric" {}

Terraform/src/remote-storage.tf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
terraform {
2+
backend "azurerm" {
3+
resource_group_name = "RGWorkshopUserName" # The name of the resource group for remote state storage
4+
storage_account_name = "examplestorageacctworkshop" # The name of the storage account for remote state storage
5+
container_name = "tfstate" # The name of the container for remote state storage
6+
key = "terraform.tfstate" # The key for the remote state file
7+
}
8+
}

Terraform/src/terraform.tfvars

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# ----------------------------------
2+
### Here is some sample data. Please make any necessary modifications. 
3+
# ----------------------------------
4+
5+
# Variable for subscription ID
6+
subscription_id = "" # Add your subscription id number
7+
8+
# Resource group name
9+
resource_group_name = "" # Add your desired RG name
10+
11+
# Location of the resources
12+
location = "Central US"
13+
14+
# SQL Server configuration
15+
sql_server_name = "usernamesqlserver" # replace username with your name
16+
admin_username = "adminuser" # replace with your desired user name
17+
admin_password = "P@ssw0rd1234" # Make sure to use a strong password
18+
19+
# SQL Database name
20+
sql_database_name = "workshopdbusername" # replace username with your name
21+
22+
# Variables for remote state storage
23+
storage_account_name = "storageacctworkshop01"
24+
container_name = "tfstate"
25+
26+
# Variable for administrator principal ID
27+
admin_principal_id = ""
28+
29+
# Microsoft Fabric Capacity configuration
30+
solution_name = "capacitynamews" # choose your capacity name
31+
fabric_capacity_admin_upns = ["user-email-here", "another-user-email-here"]
32+
fabric_capacity_sku = "F64" # Choose your SKU like F64

Terraform/src/variables.tf

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Variable for the resource group name
2+
variable "resource_group_name" {
3+
description = "The name of the resource group"
4+
type = string
5+
}
6+
7+
# Variable for the location of the resources
8+
variable "location" {
9+
description = "The location of the resources"
10+
type = string
11+
default = "East US" # Default location
12+
}
13+
14+
# Variable for the SQL Server name
15+
variable "sql_server_name" {
16+
description = "The name of the SQL Server"
17+
type = string
18+
}
19+
20+
# Variable for the administrator username for the SQL Server
21+
variable "admin_username" {
22+
description = "The administrator username for the SQL Server"
23+
type = string
24+
}
25+
26+
# Variable for the administrator password for the SQL Server
27+
variable "admin_password" {
28+
description = "The administrator password for the SQL Server"
29+
type = string
30+
sensitive = true # Mark this variable as sensitive
31+
}
32+
33+
# Variable for the SQL Database name
34+
variable "sql_database_name" {
35+
description = "The name of the SQL Database"
36+
type = string
37+
}
38+
39+
# Variable for the storage account name
40+
variable "storage_account_name" {
41+
description = "The name of the storage account for remote state storage"
42+
type = string
43+
}
44+
45+
# Variable for the container name
46+
variable "container_name" {
47+
description = "The name of the container for remote state storage"
48+
type = string
49+
}
50+
51+
# Variable for the subscription ID
52+
variable "subscription_id" {
53+
description = "The subscription ID for the Azure account"
54+
type = string
55+
}
56+
57+
# Variable for the administrator principal ID
58+
variable "admin_principal_id" {
59+
description = "The principal ID of the capacity administrator"
60+
type = string
61+
}
62+
63+
# Variable for the SKU name for the Microsoft Fabric Capacity
64+
variable "fabric_capacity_sku" {
65+
description = "The SKU for the Fabric Capacity."
66+
type = string
67+
}
68+
69+
# Variable for the solution name
70+
variable "solution_name" {
71+
description = "The name of the solution."
72+
type = string
73+
}
74+
75+
# Variable for additional UPNs to be added as Fabric Capacity administrators
76+
variable "fabric_capacity_admin_upns" {
77+
description = "Additional UPNs to be added as Fabric Capacity administrators."
78+
type = list(string)
79+
default = []
80+
}

0 commit comments

Comments
 (0)