-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0c616f1
commit b34bba6
Showing
2 changed files
with
277 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
|
||
# PIM Assignment Script | ||
|
||
This script automates the process of making Privileged Identity Management (PIM) assignments in Azure. It leverages `fzf` for fuzzy searching subscription names and resource group names for user convenience. | ||
|
||
## Features | ||
|
||
- Fuzzy search for subscription names and resource group names using `fzf` | ||
- Customizable role assignments with duration and justification messages | ||
- Supports verbose output for detailed operation logs | ||
|
||
## Prerequisites | ||
|
||
Ensure the following commands are installed and accessible in your environment: | ||
|
||
- `curl` | ||
- `az` (Azure CLI) | ||
- `jq` | ||
- `fzf` | ||
|
||
## Usage | ||
|
||
```bash | ||
./pim.sh [OPTIONS] | ||
``` | ||
|
||
### Required Parameters | ||
|
||
- `--subscription, -s`: Subscription ID or name (fuzzy search enabled) | ||
- `--resource-group, -g`: Resource group name (fuzzy search enabled) | ||
|
||
### Optional Parameters | ||
|
||
- `--message, -m`: Justification message | ||
- `--role, -r`: Role name (default: Contributor) | ||
- `--time, -t`: Duration (default: 8H). Format: 8H (hours) or 8M (minutes) | ||
- `--verbose, -v`: Enable verbose output | ||
- `--help`: Show help message | ||
|
||
### Example | ||
|
||
```bash | ||
./pim.sh --subscription "My Subscription" --resource-group "MyResourceGroup" --message "Access required for deployment" --role "Contributor" --time "4H" --verbose | ||
``` | ||
|
||
### Fuzzy Search | ||
|
||
If you do not provide `--subscription` or `--resource-group`, the script will invoke `fzf` to let you select from available options. | ||
|
||
### Running Without Parameters | ||
|
||
You can run the script without specifying `--subscription` or `--resource-group`, and you will be prompted to select them using `fzf`. | ||
|
||
```bash | ||
./pim.sh | ||
``` | ||
|
||
## Example Workflow | ||
|
||
1. Ensure you are logged into Azure CLI: | ||
```bash | ||
az login | ||
``` | ||
2. Run the script: | ||
```bash | ||
./pim.sh --verbose | ||
``` | ||
3. Select the subscription and resource group using `fzf`. | ||
4. Provide the required justification message when prompted. | ||
|
||
## Error Handling | ||
|
||
The script performs various checks and provides meaningful error messages for missing dependencies, invalid input formats, and operational errors. | ||
|
||
## Contribution | ||
|
||
Contributions are welcome! Please fork the repository and create a pull request with your changes. | ||
|
||
## License | ||
|
||
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
#!/bin/bash | ||
# This script is used to make PIM assignments | ||
|
||
print_help() { | ||
cat <<EOF | ||
Usage: $(basename "$0") [OPTIONS] | ||
Required parameters: | ||
--subscription, -s Subscription ID or name (fuzzy search enabled) | ||
--resource-group, -g Resource group name (fuzzy search enabled) | ||
Optional parameters: | ||
--message, -m Justification message | ||
--role, -r Role name (default: Contributor) | ||
--time, -t Duration (default: 8H). Format: 8H (hours) or 8M (minutes) | ||
--verbose, -v Enable verbose output | ||
--help Show this help message | ||
EOF | ||
exit 1 | ||
} | ||
|
||
check_dependencies() { | ||
for cmd in curl az jq fzf; do | ||
if ! command -v $cmd &>/dev/null; then | ||
echo "$cmd is required but not installed. Exiting." | ||
exit 1 | ||
fi | ||
done | ||
} | ||
|
||
validate_time() { | ||
if [[ ! $time =~ ^[0-9]+[HM]$ ]]; then | ||
echo "Invalid time format. Use nH (hours, max 8) or nM (minutes, min 5, max 60)" | ||
exit 1 | ||
fi | ||
if [[ $time == *H ]]; then | ||
local hours=${time%H} | ||
if ((hours < 1 || hours > 8)); then | ||
echo "Invalid hour format. Use 1-8H." | ||
exit 1 | ||
fi | ||
elif [[ $time == *M ]]; then | ||
local minutes=${time%M} | ||
if ((minutes < 5 || minutes > 60)); then | ||
echo "Invalid minute format. Use 5-60M." | ||
exit 1 | ||
fi | ||
fi | ||
} | ||
|
||
parse_arguments() { | ||
while [[ "$#" -gt 0 ]]; do | ||
case $1 in | ||
-s|--subscription) | ||
subscription="$2" | ||
shift | ||
;; | ||
-g|--resource-group) | ||
resource_group="$2" | ||
shift | ||
;; | ||
-m|--message) | ||
message="$2" | ||
shift | ||
;; | ||
-r|--role) | ||
role="$2" | ||
shift | ||
;; | ||
-t|--time) | ||
time="$2" | ||
shift | ||
;; | ||
-v|--verbose) | ||
verbose=true | ||
;; | ||
--help) | ||
print_help | ||
;; | ||
*) | ||
echo "Unknown parameter passed: $1" | ||
print_help | ||
;; | ||
esac | ||
shift | ||
done | ||
} | ||
|
||
set_defaults() { | ||
role=${role:-"Contributor"} | ||
time=${time:-"8H"} | ||
verbose=${verbose:-false} | ||
} | ||
|
||
fuzzy_select_subscription() { | ||
subscription=$(az account list --query "[].{name:name, id:id}" -o tsv | fzf --prompt="Select Subscription: " | awk '{print $1}') | ||
if [[ -z "$subscription" ]]; then | ||
echo "No subscription selected. Exiting." | ||
exit 1 | ||
fi | ||
} | ||
|
||
fuzzy_select_resource_group() { | ||
resource_group=$(az group list --query "[].name" -o tsv | fzf --prompt="Select Resource Group: ") | ||
if [[ -z "$resource_group" ]]; then | ||
echo "No resource group selected. Exiting." | ||
exit 1 | ||
fi | ||
} | ||
|
||
convert_date() { | ||
local date="$1" | ||
local format="$2" | ||
if [[ $(uname) == "Darwin" ]]; then | ||
date -j -f "%Y-%m-%dT%H:%M:%S" "$date" +"$format" | ||
else | ||
date -d "$date" +"$format" | ||
fi | ||
} | ||
|
||
main() { | ||
check_dependencies | ||
parse_arguments "$@" | ||
set_defaults | ||
|
||
if [[ -z "$subscription" ]]; then | ||
fuzzy_select_subscription | ||
fi | ||
|
||
if [[ -z "$resource_group" ]]; then | ||
fuzzy_select_resource_group | ||
fi | ||
|
||
validate_time | ||
|
||
if [[ -z "$message" ]]; then | ||
read -p "Please provide a justification message: " message | ||
if [[ -z "$message" ]]; then | ||
echo "Justification message cannot be empty" | ||
exit 1 | ||
fi | ||
fi | ||
|
||
user_object_id=$(az ad user list --filter "mail eq '$(az account show --query user.name -o tsv)'" --query "[0].id" -o tsv) | ||
start_date=$(date -u +"%Y-%m-%dT%H:%M:%S.%3NZ") | ||
guid=$(uuidgen | tr '[:upper:]' '[:lower:]') | ||
token=$(az account get-access-token --query accessToken -o tsv) | ||
subscription_id=$(az account list --query "[?id=='$subscription' || name=='$subscription'].id" -o tsv) | ||
|
||
role_eligibility_schedule_instances=$(curl -s -H "Authorization: Bearer $token" -X GET \ | ||
"https://management.azure.com/subscriptions/${subscription_id}/resourceGroups/${resource_group}/providers/Microsoft.Authorization/roleEligibilityScheduleInstances?api-version=2020-10-01&\$filter=asTarget()") | ||
|
||
role_definition_id=$(jq -r --arg resource_group "$resource_group" --arg role "$role" \ | ||
'.value[] | select(.properties.scope | endswith($resource_group)) | select(.properties.expandedProperties.roleDefinition.displayName == $role) | .properties.expandedProperties.roleDefinition.id' <<<"$role_eligibility_schedule_instances" | awk -F'/' '{print $NF}') | ||
|
||
justification="${message// /_}" | ||
data=$(cat <<EOF | ||
{ | ||
"Properties": { | ||
"RoleDefinitionId": "/subscriptions/${subscription_id}/providers/Microsoft.Authorization/roleDefinitions/${role_definition_id}", | ||
"PrincipalId": "${user_object_id}", | ||
"RequestType": "SelfActivate", | ||
"Justification": "${justification}", | ||
"ScheduleInfo": { | ||
"StartDateTime": "${start_date}", | ||
"Expiration": { | ||
"Type": "AfterDuration", | ||
"EndDateTime": null, | ||
"Duration": "PT${time}" | ||
} | ||
} | ||
} | ||
} | ||
EOF | ||
) | ||
|
||
response=$(curl -s -H "Authorization: Bearer $token" -X PUT -H "Content-Type: application/json" -d "$data" \ | ||
"https://management.azure.com/subscriptions/${subscription_id}/resourceGroups/${resource_group}/providers/Microsoft.Authorization/roleAssignmentScheduleRequests/${guid}?api-version=2020-10-01") | ||
|
||
if [[ $(echo "$response" | jq -r '.error') != "null" ]]; then | ||
echo "Error: $(echo "$response" | jq -r '.error.message')" | ||
exit 1 | ||
fi | ||
|
||
if [[ $(echo "$response" | jq -r '.properties.status') == "Provisioned" ]]; then | ||
start_date_time=$(echo "$response" | jq -r '.properties.scheduleInfo.startDateTime') | ||
end_date_time=$(convert_date "$start_date_time" +"%Y-%m-%dT%H:%M:%S.%3NZ + ${time//H/h} ${time//M/m} minutes") | ||
end_date_formatted=$(convert_date "$end_date_time" "%d.%m.%Y - %H:%M") | ||
start_date_formatted=$(convert_date "$start_date_time" "%d.%m.%Y - %H:%M") | ||
echo "PIM assignment active from $start_date_formatted to $end_date_formatted" | ||
else | ||
echo "An unknown error occurred." | ||
fi | ||
} | ||
|
||
main "$@" |