Sync from dev @ 252c1cf

Source: main (252c1cf)
Excluded: live tenant exports, generated artifacts, and dev-only tooling.
This commit is contained in:
2026-04-17 15:57:35 +02:00
commit 17d745bdac
52 changed files with 15601 additions and 0 deletions

View File

@@ -0,0 +1,150 @@
# ASTRAL Onboarding Runbook
This guide walks through deploying ASTRAL into a new Azure DevOps organization and Microsoft 365 tenant.
## Prerequisites
- Azure DevOps organization and project created.
- Owner or Contributor access to the target Microsoft 365 tenant.
- Permission to create app registrations and grant admin consent in Entra ID.
- PowerShell 7+ or Windows PowerShell 5.1 with the `Microsoft.Graph` module (for the bootstrap script).
## Step 1: Import the repository
1. In Azure DevOps, create a new Git repository in your project.
2. Push the contents of this repository into it, or use **Import repository** from a public Git URL.
## Step 2: Create the tenant variable group
1. In Azure DevOps, go to **Pipelines > Library** and create a new Variable Group.
2. Recommended name: `vg-astral-tenant` (you can choose any name).
3. Add the variables from `templates/variables-tenant.yml`. Use your real tenant values:
| Variable | Example value | Notes |
| --- | --- | --- |
| `TENANT_NAME` | `contoso.onmicrosoft.com` | Your M365 tenant domain |
| `SERVICE_CONNECTION_NAME` | `sc-astral-backup` | Name you will use for the service connection |
| `USER_NAME` | `ASTRAL Backup Service` | Git committer name |
| `USER_EMAIL` | `astral-backup@contoso.com` | Git committer email |
| `AGENT_POOL_NAME` | `Azure Pipelines` | Change if using a self-hosted pool |
| `BACKUP_TIMEZONE` | `Europe/Prague` | Valid tz database name |
| `FULL_RUN_HOUR` | `00` | Hour that triggers full export |
| `AUTO_REMEDIATE_RESTORE_PIPELINE_ID` | *(leave empty)* | Filled in Step 8 |
4. If you plan to use Azure OpenAI summaries, also add:
- `ENABLE_PR_AI_SUMMARY` = `true`
- `AZURE_OPENAI_ENDPOINT`
- `AZURE_OPENAI_DEPLOYMENT`
- `AZURE_OPENAI_API_KEY` *(mark as secret)*
## Step 3: Link the variable group to the pipelines
Open each pipeline YAML and uncomment the variable group line near the top:
```yaml
variables:
- group: vg-astral-tenant # <-- uncomment this line
- template: templates/variables-common.yml
```
Do this for:
- `azure-pipelines.yml`
- `azure-pipelines-review-sync.yml`
- `azure-pipelines-restore.yml`
Commit and push the changes.
## Step 4: Run the tenant bootstrap script
Run `deploy/bootstrap-tenant.ps1` in a PowerShell session authenticated to your target tenant.
```powershell
# Example
.\deploy\bootstrap-tenant.ps1 -TenantName "contoso.onmicrosoft.com" -ServiceConnectionName "sc-astral-backup"
```
The script will:
1. Create a single-tenant app registration.
2. Add required Microsoft Graph application permissions.
3. Grant admin consent.
4. Create a workload federated credential for Azure DevOps.
5. Print the App ID and instructions for creating the Azure DevOps service connection.
## Step 5: Create the Azure DevOps service connection
1. In Azure DevOps, go to **Project settings > Service connections**.
2. Click **New service connection > Azure Resource Manager > Workload identity federation (manual)**.
3. Fill in:
- **Subscription**: leave blank or select if you also want ARM access (not required).
- **Tenant ID**: your Microsoft 365 tenant ID.
- **Service Connection Name**: the same value you set in `SERVICE_CONNECTION_NAME` (e.g. `sc-astral-backup`).
- **App ID**: from the bootstrap script output.
4. Save the service connection.
## Step 6: Import the pipelines
1. Go to **Pipelines > Create pipeline > Azure Repos Git**.
2. Select your repository.
3. Choose **Existing Azure Pipelines YAML file**.
4. Import each of the three YAMLs one by one:
- `azure-pipelines.yml` (main backup)
- `azure-pipelines-review-sync.yml` (review sync)
- `azure-pipelines-restore.yml` (restore)
## Step 7: Grant repository permissions to the build identity
1. Go to **Project settings > Repositories**.
2. Select your repository.
3. Under **Security**, grant the **Build Service** account:
- Contribute
- Create branch
- Force push
- Create pull request
- Edit pull request
- Tag creation (if you enable tagging)
4. Under **Pipelines**, grant the build service **Queue builds** permission on `azure-pipelines-restore.yml` if you plan to use auto-remediation.
## Step 8: Set the restore pipeline definition ID
After importing `azure-pipelines-restore.yml`, find its definition ID:
1. Open the restore pipeline in Azure DevOps.
2. The URL contains `definitionId=XX`. Note the number.
3. Go back to your variable group (`vg-astral-tenant`) and set:
- `AUTO_REMEDIATE_RESTORE_PIPELINE_ID` = `XX`
## Step 9: Validate the deployment
1. Import `deploy/validate-deployment.yml` as a one-time pipeline.
2. Run it.
3. Verify that all checks pass:
- Graph token acquisition
- Required roles present
- Test read from Graph
- Test PR creation and abandonment
## Step 10: Run the first backup
1. Queue a manual run of `azure-pipelines.yml`.
2. Set `forceFullRun=true` to get a complete initial snapshot.
3. Verify that `tenant-state/` is populated and a rolling PR is created.
## Optional: progressive feature rollout
| Phase | What to enable |
| --- | --- |
| Backup-only | `ENABLE_PR_REVIEW_SUMMARY=false`, `ENABLE_PR_REVIEWER_DECISIONS=false`, `AUTO_REMEDIATE_AFTER_MERGE=false` |
| Review package | `ENABLE_PR_REVIEW_SUMMARY=true`, `ENABLE_PR_REVIEWER_DECISIONS=true` |
| Full package | Also enable restore and set `AUTO_REMEDIATE_AFTER_MERGE=true` if desired |
| AI summaries | `ENABLE_PR_AI_SUMMARY=true` plus Azure OpenAI variables |
## Troubleshooting
| Symptom | Likely cause | Fix |
| --- | --- | --- |
| Pipeline fails at "Get Graph Token" | Wrong service connection name or missing federated credential | Verify `SERVICE_CONNECTION_NAME` matches the service connection exactly |
| "Missing required Graph roles" | Admin consent not granted | Run bootstrap script again or grant consent manually in Entra ID |
| Rolling PR not created | Build identity lacks PR permissions | Add **Create pull request** and **Edit pull request** permissions |
| Restore pipeline queue fails | `AUTO_REMEDIATE_RESTORE_PIPELINE_ID` wrong or missing queue permission | Verify the ID and grant **Queue builds** on the restore pipeline |
| Empty `tenant-state/` after run | First run may have no data if Graph returns nothing; also check `BACKUP_FOLDER` path | Verify Graph permissions and re-run |