Skip to content
Merged
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 Readme.MD
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ export MPF_SPOBJECTID=YOUR_SP_OBJECT_ID
make test-e2e-arm
```



### End to End Bicep Tests

To run the end-to-end tests for Bicep, you need to have the following environment variables set, and then execute `make test-e2e-bicep`:
Expand All @@ -85,6 +87,8 @@ export MPF_BICEPEXECPATH="/opt/homebrew/bin/bicep" # Path to the Bicep executabl
make test-e2e-bicep
```



### End to End Terraform Tests

The Terraform end-to-end tests can take a long time to execute, depending on the resources being created. To run the end-to-end tests for Terraform, you need to have the following environment variables set, and then execute `make test-e2e-terraform`:
Expand All @@ -100,6 +104,8 @@ export MPF_TFPATH=$(which terraform) # Path to the Terraform executable
make test-e2e-terraform
```



## Permissions required by default Azure CLI credentials

The default Azure CLI credentials used by the utility need to have the following permissions:
Expand Down
2 changes: 2 additions & 0 deletions docs/commandline-flags-and-env-variables.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# MPF command line flags and environment variables

**Note**: Environment variables can be set using bash/shell syntax (e.g., `export MPF_SUBSCRIPTIONID=value`) on Linux/macOS, or using PowerShell syntax (e.g., `$env:MPF_SUBSCRIPTIONID = "value"`) on Windows.

## Global Flags (Common to all providers)

| Flag | Environment Variable | Required / Optional | Description |
Expand Down
75 changes: 69 additions & 6 deletions docs/display-options.MD
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,27 @@ export MPF_SPCLIENTSECRET=YOUR_SP_CLIENT_SECRET
export MPF_SPOBJECTID=YOUR_SP_OBJECT_ID

$ ./azmpf arm --templateFilePath ./samples/templates/aks-private-subnet.json --parametersFilePath ./samples/templates/aks-private-subnet-parameters.json --showDetailedOutput --verbose
```

Or using PowerShell on Windows:

```powershell
# Detailed Text output
$env:MPF_SUBSCRIPTIONID = "YOUR_SUBSCRIPTION_ID"
$env:MPF_TENANTID = "YOUR_TENANT_ID"
$env:MPF_SPCLIENTID = "YOUR_SP_CLIENT_ID"
$env:MPF_SPCLIENTSECRET = "YOUR_SP_CLIENT_SECRET"
$env:MPF_SPOBJECTID = "YOUR_SP_OBJECT_ID"

.\azmpf.exe arm --templateFilePath .\samples\templates\aks-private-subnet.json --parametersFilePath .\samples\templates\aks-private-subnet-parameters.json --showDetailedOutput --verbose
```

Output:

```
INFO[0000] Executing MPF for ARM
INFO[0000] TemplateFilePath: ./samples/templates/aks-private-subnet.json
INFO[0000] ParametersFilePath: ./samples/templates/aks-private-subnet-parameters.json
INFO[0000] TemplateFilePath: .\samples\templates\aks-private-subnet.json
INFO[0000] ParametersFilePath: .\samples\templates\aks-private-subnet-parameters.json
INFO[0000] Location: eastus2
INFO[0001] Creating Resource Group: testdeployrg-OJ2zCNA
INFO[0007] Resource Group: testdeployrg-OJ2zCNA created successfully
Expand Down Expand Up @@ -101,10 +118,26 @@ export MPF_SPCLIENTSECRET=YOUR_SP_CLIENT_SECRET
export MPF_SPOBJECTID=YOUR_SP_OBJECT_ID

$ ./azmpf arm --templateFilePath ./samples/templates/aks-private-subnet.json --parametersFilePath ./samples/templates/aks-private-subnet-parameters.json --outputFormat json --verbose
```

Or using PowerShell on Windows:

```powershell
$env:MPF_SUBSCRIPTIONID = "YOUR_SUBSCRIPTION_ID"
$env:MPF_TENANTID = "YOUR_TENANT_ID"
$env:MPF_SPCLIENTID = "YOUR_SP_CLIENT_ID"
$env:MPF_SPCLIENTSECRET = "YOUR_SP_CLIENT_SECRET"
$env:MPF_SPOBJECTID = "YOUR_SP_OBJECT_ID"

.\azmpf.exe arm --templateFilePath .\samples\templates\aks-private-subnet.json --parametersFilePath .\samples\templates\aks-private-subnet-parameters.json --outputFormat json --verbose
```

Output:

```
INFO[0000] Executing MPF for ARM
INFO[0000] TemplateFilePath: ./samples/templates/aks-private-subnet.json
INFO[0000] ParametersFilePath: ./samples/templates/aks-private-subnet-parameters.json
INFO[0000] TemplateFilePath: .\samples\templates\aks-private-subnet.json
INFO[0000] ParametersFilePath: .\samples\templates\aks-private-subnet-parameters.json
INFO[0000] Location: eastus2
INFO[0001] Creating Resource Group: testdeployrg-Uqc4z3E
INFO[0007] Resource Group: testdeployrg-Uqc4z3E created successfully
Expand Down Expand Up @@ -181,8 +214,23 @@ export MPF_SPCLIENTSECRET=YOUR_SP_CLIENT_SECRET
export MPF_SPOBJECTID=YOUR_SP_OBJECT_ID

$ ./azmpf arm --templateFilePath ./samples/templates/aks-private-subnet.json --parametersFilePath ./samples/templates/aks-private-subnet-parameters.json
```

------------------------------------------------------------------------------------------------------------------------------------------
Or using PowerShell on Windows:

```powershell
$env:MPF_SUBSCRIPTIONID = "YOUR_SUBSCRIPTION_ID"
$env:MPF_TENANTID = "YOUR_TENANT_ID"
$env:MPF_SPCLIENTID = "YOUR_SP_CLIENT_ID"
$env:MPF_SPCLIENTSECRET = "YOUR_SP_CLIENT_SECRET"
$env:MPF_SPOBJECTID = "YOUR_SP_OBJECT_ID"

.\azmpf.exe arm --templateFilePath .\samples\templates\aks-private-subnet.json --parametersFilePath .\samples\templates\aks-private-subnet-parameters.json
```

Output:

```
Permissions Required:
------------------------------------------------------------------------------------------------------------------------------------------
Microsoft.ContainerService/managedClusters/read
Expand All @@ -209,8 +257,23 @@ export MPF_SPCLIENTSECRET=YOUR_SP_CLIENT_SECRET
export MPF_SPOBJECTID=YOUR_SP_OBJECT_ID

$ ./azmpf arm --templateFilePath ./samples/templates/multi-resource-template.json --parametersFilePath ./samples/templates/multi-resource-parameters.json --showDetailedOutput
```

------------------------------------------------------------------------------------------------------------------------------------------
Or using PowerShell on Windows:

```powershell
$env:MPF_SUBSCRIPTIONID = "YOUR_SUBSCRIPTION_ID"
$env:MPF_TENANTID = "YOUR_TENANT_ID"
$env:MPF_SPCLIENTID = "YOUR_SP_CLIENT_ID"
$env:MPF_SPCLIENTSECRET = "YOUR_SP_CLIENT_SECRET"
$env:MPF_SPOBJECTID = "YOUR_SP_OBJECT_ID"

.\azmpf.exe arm --templateFilePath .\samples\templates\multi-resource-template.json --parametersFilePath .\samples\templates\multi-resource-parameters.json --showDetailedOutput
```

Output:

```
Permissions Required:
------------------------------------------------------------------------------------------------------------------------------------------
Microsoft.Authorization/roleAssignments/read
Expand Down
82 changes: 79 additions & 3 deletions docs/installation-and-quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ mv azmpf_v0.15.0 azmpf
chmod +x ./azmpf
```

And for Mac Arm64:
For Mac Arm64:

```shell
# Please change the version in the URL to the latest version
Expand All @@ -24,10 +24,20 @@ mv azmpf_v0.15.0 azmpf
chmod +x ./azmpf
```

And for Windows:

```powershell
# Please change the version in the URL to the latest version
Invoke-WebRequest -Uri "https://github.com/Azure/mpf/releases/download/v0.15.0/azmpf_0.15.0_windows_amd64.zip" -OutFile "azmpf_0.15.0_windows_amd64.zip"
Expand-Archive -Path "azmpf_0.15.0_windows_amd64.zip" -DestinationPath "."
Rename-Item -Path "azmpf_v0.15.0.exe" -NewName "azmpf.exe"
```

## Creating a service principal for MPF

To use MPF, you need to create a service principal in your Azure Active Directory tenant. You can create a service principal using the Azure CLI or the Azure portal. The service principal needs no roles assigned to it, as the MPF utility will as it is remove any assigned roles each time it executes.
Here is an example of how to create a service principal using the Azure CLI:

Here is an example of how to create a service principal using the Azure CLI on Linux/macOS:

```shell
# az login
Expand All @@ -38,6 +48,17 @@ MPF_SPCLIENTSECRET=$(echo $MPF_SP | jq -r .password)
MPF_SPOBJECTID=$(az ad sp show --id $MPF_SPCLIENTID --query id -o tsv)
```

And here is the equivalent example using Azure CLI on Windows PowerShell:

```powershell
# az login

$MPF_SP = az ad sp create-for-rbac --name "MPF_SP" --skip-assignment | ConvertFrom-Json
$env:MPF_SPCLIENTID = $MPF_SP.appId
$env:MPF_SPCLIENTSECRET = $MPF_SP.password
$env:MPF_SPOBJECTID = (az ad sp show --id $MPF_SP.appId --query id -o tsv)
```

## Quickstart / Usage

**Important**: ARM and Bicep deployments now use **Full Deployment mode** exclusively with Incremental deployment mode, which creates and deploys resources (then cleans them up automatically) to determine the required permissions. This provides the most accurate permission detection but takes longer than the previous what-if mode - expect execution times of several minutes to longer depending on template complexity and the resources being deployed. The previous what-if analysis mode (which completed in ~90 seconds) has been deprecated due to incomplete permission detection in some scenarios.
Expand All @@ -54,7 +75,23 @@ export MPF_SPCLIENTSECRET=YOUR_SP_CLIENT_SECRET
export MPF_SPOBJECTID=YOUR_SP_OBJECT_ID

$ ./azmpf arm --templateFilePath ./samples/templates/aks-private-subnet.json --parametersFilePath ./samples/templates/aks-private-subnet-parameters.json --verbose
```

Or using PowerShell on Windows:

```powershell
$env:MPF_SUBSCRIPTIONID = "YOUR_SUBSCRIPTION_ID"
$env:MPF_TENANTID = "YOUR_TENANT_ID"
$env:MPF_SPCLIENTID = "YOUR_SP_CLIENT_ID"
$env:MPF_SPCLIENTSECRET = "YOUR_SP_CLIENT_SECRET"
$env:MPF_SPOBJECTID = "YOUR_SP_OBJECT_ID"

.\azmpf.exe arm --templateFilePath .\samples\templates\aks-private-subnet.json --parametersFilePath .\samples\templates\aks-private-subnet-parameters.json --verbose
```

Output:

```text
INFO[0000] Executing MPF for ARM
INFO[0000] TemplateFilePath: ./samples/templates/aks-private-subnet.json
INFO[0000] ParametersFilePath: ./samples/templates/aks-private-subnet-parameters.json
Expand Down Expand Up @@ -109,8 +146,24 @@ export MPF_SPOBJECTID=YOUR_SP_OBJECT_ID
export MPF_BICEPEXECPATH="/usr/local/bin/bicep" # Path to the Bicep executable

$ ./azmpf bicep --bicepFilePath ./samples/bicep/aks-private-subnet.bicep --parametersFilePath ./samples/bicep/aks-private-subnet-params.json --verbose
```

Or using PowerShell on Windows:

```powershell
$env:MPF_SUBSCRIPTIONID = "YOUR_SUBSCRIPTION_ID"
$env:MPF_TENANTID = "YOUR_TENANT_ID"
$env:MPF_SPCLIENTID = "YOUR_SP_CLIENT_ID"
$env:MPF_SPCLIENTSECRET = "YOUR_SP_CLIENT_SECRET"
$env:MPF_SPOBJECTID = "YOUR_SP_OBJECT_ID"
$env:MPF_BICEPEXECPATH = "C:\Program Files\Azure Bicep CLI\bicep.exe" # Path to the Bicep executable

INFO[0000] Executing MPF for Bicep
.\azmpf.exe bicep --bicepFilePath .\samples\bicep\aks-private-subnet.bicep --parametersFilePath .\samples\bicep\aks-private-subnet-params.json --verbose
```

Output:

```text
INFO[0000] BicepFilePath: ./samples/bicep/aks-private-subnet.bicep
INFO[0000] ParametersFilePath: ./samples/bicep/aks-private-subnet-params.json
INFO[0000] Location: eastus2
Expand Down Expand Up @@ -170,6 +223,29 @@ export MPF_TFPATH=TERRAFORM_EXECUTABLE_PATH
# popd

$ ./azmpf terraform --workingDir `pwd`/samples/terraform/aci --varFilePath `pwd`/samples/terraform/aci/dev.vars.tfvars --debug
```

Or using PowerShell on Windows:

```powershell
$env:MPF_SUBSCRIPTIONID = "YOUR_SUBSCRIPTION_ID"
$env:MPF_TENANTID = "YOUR_TENANT_ID"
$env:MPF_SPCLIENTID = "YOUR_SP_CLIENT_ID"
$env:MPF_SPCLIENTSECRET = "YOUR_SP_CLIENT_SECRET"
$env:MPF_SPOBJECTID = "YOUR_SP_OBJECT_ID"
$env:MPF_TFPATH = "C:\Program Files\Terraform\terraform.exe" # Path to the Terraform executable

# Push-Location
# Set-Location .\samples\terraform\aci\
# & $env:MPF_TFPATH init
# Pop-Location

.\azmpf.exe terraform --workingDir "$PWD\samples\terraform\aci" --varFilePath "$PWD\samples\terraform\aci\dev.vars.tfvars" --debug
```

Output:

```text
.
# debug information
.
Expand Down
Loading