avm-tf-module-repository-creation
Skill3 starsChanged 9 days agoMITView on GitHub
Use when asked to create, set up, or finish setting up a new Azure Verified Modules (AVM) Terraform module repository in the Azure GitHub organization, or to resume or troubleshoot repository setup with `avm init -Ecosystem terraform`. Covers the inputs to ask the user for, the Open Source Portal and just-in-time (JIT) steps, verification, recovery, and the final step of leaving jaredholgate and jatracey as the only Direct Owners. Trigger on "create a Terraform module repository", "new AVM module repo", "avm init terraform", "terraform-azure-avm-", "module proposal approved", "app installation request", "JIT tie", and "Direct Owners".
- Reads credentials
In this repositoryOne other file it gives its agents.
- .github/copilot-instructions.mdCopilot instructions
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 7 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈7
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 16
Use only approved values from the module proposal, confirmed by the user.
- Distinctive: line 18
Ask the user one question at a time, and offer the values you found as choices.
- Distinctive: line 22
Run these read-only checks and resolve any gaps first:
- Very specific: line 47
Run avm upgrade instead when an older release is already installed.
- Distinctive: line 54
Ask the user for each value, offering what you found:
- Very specific: line 73
If your shell cannot answer prompts, avm init cannot ask for missing values, so pass them all with -InputObject.
- Distinctive: line 115
Ask the user to do this. Only with their explicit approval, do it for them through browser automation in their signed-in browser.
- Distinctive: line 119
Run these read-only checks:
- Distinctive: line 147
Keep the fallback security group, then select Save.
- Distinctive: line 162
Run the same command again from the same machine after fixing the cause.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Create an AVM Terraform Module Repository
avm init -Ecosystem terraform from the Avm.Authoring PowerShell module creates and sets up the repository. Each stage checks GitHub and the local folder first, so running the same command again continues an interrupted setup. Your job is to collect approved inputs, run the command, relay the manual steps to the user, and verify the result.
The operator guide is https://azure.github.io/Azure-Verified-Modules/contributing/terraform/repository-setup/, and each stage is described in the Avm.Authoring README.
Rules
- This changes production systems: a public repository in the
Azureorganization, team access, a push tomain, a pull request inmicrosoft/github-operations, and Open Source Portal settings. Get the user's explicit approval before the first run without-WhatIf, and again before you change anything in the portal for them. - Let
avm initmake every GitHub change. Do not push tomain, change theglobal-rulesets-opt-outcustom property, grant team access, or open the app installation pull request yourself. Never edit or delete the records in therepository-initfolder of the Avm state directory. - Use only approved values from the module proposal, confirmed by the user. Never infer
canonicalTypefrom the module name, and never choose atelemetryIdPrefix;avm initmints one. - The setup is not complete until
jaredholgateandjatraceyare the only individual Direct Owners in the Open Source Portal. This is always the last step (step 7), done once everything else is finished. - Ask the user one question at a time, and offer the values you found as choices.
1. Check the prerequisites
Run these read-only checks and resolve any gaps first:
$PSVersionTable.PSVersion # 7.4 or later
git --version
git config --global user.name
git config --global user.email
gh auth status --hostname github.comghmust be signed in to github.com with therepo,read:org(orwrite:orgoradmin:org), andworkflowscopes. If any are missing, ask the user to rungh auth refresh --hostname github.com --scopes read:org,workflow. It opens a browser, so the user must run it.If
GH_TOKENorGITHUB_TOKENis set,ghandavm inituse that token instead of the signed-in account, and agent environments often set one without these scopes. Whengh auth statusshows that the token lacks the scopes but the user's signed-in account has them, clear both in the PowerShell session that runsavm init:$env:GH_TOKEN = $null $env:GITHUB_TOKEN = $nullInstall or update the module, then import it:
Install-PSResource -Name Avm.Authoring -Repository PSGallery -TrustRepository Import-Module Avm.AuthoringRun
avm upgradeinstead when an older release is already installed.- The user needs AVM core team approval to create the repository, a GitHub account linked in the Open Source Portal, and membership of the
Azureorganization. They also need to be able to forkmicrosoft/github-operations, because the app installation pull request is opened from their fork.
2. Collect the inputs
Find the approved module proposal with gh search issues --repo Azure/Azure-Verified-Modules "<module name>", or ask the user for the issue number, and read it with gh issue view <number> --repo Azure/Azure-Verified-Modules. The proposal form gives the module name, its classification, the resource type under Module Details, and the owner handles. Confirm with the user that the proposal is approved before continuing.
Ask the user for each value, offering what you found:
| Input | Rule | Example |
| Module name | avm-<type>-<name>, where <type> is res, ptn, or utl; lowercase with hyphens | avm-res-signalrservice-webpubsub |
| Repository name | terraform-azure- followed by the module name | terraform-azure-avm-res-signalrservice-webpubsub |
| Module type | resource, pattern, or utility, matching res, ptn, or utl | resource |
Display name (moduleDisplayName) | The approved display name | SignalR Service Web PubSub |
Description (moduleDescription) | The approved one-sentence description | AVM Terraform resource module for SignalR Service Web PubSub. |
Canonical type (canonicalType) | The ARM resource type for a resource module, or the approved taxonomy for a pattern or utility module | Microsoft.SignalRService/webPubSub |
Owners (owners) | Approved GitHub handles or @Azure/<team> entries | sujaypillai |
Telemetry ID prefix (telemetryIdPrefix) | Only when the proposal assigned one; otherwise leave it out | |
Alternative names (alternativeNames) | Optional | |
| Parent folder | An existing folder for the local clone | C:\code |
The values become metadata.json in the first commit, and the display name and description start the module's _header.md and README.
3. Preview the run and get approval
If your shell cannot answer prompts, avm init cannot ask for missing values, so pass them all with -InputObject. The local folder's name must be the repository name. Preview first:
$metadata = @{
moduleDisplayName = '<display name>'
moduleDescription = '<description>'
canonicalType = '<canonical type>'
owners = @('<owner>')
}
$path = Join-Path '<parent folder>' '<repository name>'
avm init -Ecosystem terraform -ModuleType resource -Path $path -InputObject $metadata -WhatIfExpect planned steps for metadata and repository when the repository does not exist yet. Show the user the repository URL and the values, and ask for approval to create the repository.
4. Run avm init and relay the manual steps
Run the same command without -WhatIf. When a stage needs the user, the run stops and prints instructions. avm then lists the steps and throws avm init reported Status 'fail', so wrap the call in try/catch and read the failed step. Relay it to the user, and run the same command again once they confirm. Later runs read the values from the local metadata.json and ignore -InputObject.
A new repository normally takes two runs:
- The first run writes
metadata.json, creates the repository, and stops atopen source portal setup. Give the user the portal link and the answers it printed. The guide also asks them to add themselves,jaredholgate, andjatraceyas Direct Owners, withazure-verified-modules-module-ownersas the fallback security group. They need to be a Direct Owner until the setup is finished, and step 7 removes them. They uncheck Repository template and Add .gitignore, finish the setup, then select Elevate your access. Wait for the user to confirm. - The second run grants the contributors and readers teams, publishes the first commit, opens the app installation pull request, clones the repository, and ends with two
manualportal steps: the JIT tie, then the Direct Owners check. If it stops atadministrator accessinstead, ask the user to select Elevate your access on the repository's portal page.
Elevation can take a minute to reach GitHub. Before running again, poll until GitHub shows the repository as public and the user as an administrator:
gh api 'repos/Azure/<repository name>' --jq '"visibility=\(.visibility) admin=\(.permissions.admin)"'The first commit runs avm pre-commit, which downloads Terraform and other tools on first use, so allow a few minutes.
5. Tie the repository to the shared JIT rule
The Open Source Portal offers no API that avm init could use to check this, so every completed run lists it as manual. Do it after the second run, because it changes how elevation works.
- Open
https://repos.opensource.microsoft.com/orgs/Azure/repos/<repository name>. - Select Advanced JIT options, then Propose a new tie.
- Enter the rule ID
service-AVM-azure-verified-modules-module-owners, then select Review and Create tie.
The result page says whether the tie is active or waiting for an owner of the rule to approve it. On a JIT v1 repository, a tie proposed by a Direct Owner can become active at once. Once active, the repository overview shows JIT version: JIT v2 and the rule. A user who does not have permission skips this step and emails avm@microsoft.com with the repository name.
Ask the user to do this. Only with their explicit approval, do it for them through browser automation in their signed-in browser.
6. Verify the setup
Run these read-only checks:
$repo = 'Azure/<repository name>'
gh api "repos/$repo/commits?per_page=3" --jq '.[].commit.message'
gh api "repos/$repo/properties/values" --jq '.[] | "\(.property_name)=\(.value)"'
foreach ($team in 'azure-verified-modules-module-contributors', 'azure-verified-modules-module-readers') {
gh api -H 'Accept: application/vnd.github.v3.repository+json' "orgs/Azure/teams/$team/repos/$repo" --jq '.permissions'
}
git -C $path status --shortmainholdschore: initialize module repositoryon top of the portal's README commit.global-rulesets-opt-outis back to its original value, normallyfalse.- The contributors team has push access and the readers team has triage access.
- The local clone is clean, and
_header.mdstarts with the display name and description.
Running avm init again should change nothing. Every step passes except app installation, which stays pending until the request is approved, and the two manual portal steps.
7. Last step: leave only jaredholgate and jatracey as Direct Owners
Do this last, once everything else is done: avm init has completed, the JIT tie is in place, and the checks above pass. The app installation request can still be awaiting approval, because it does not need Direct Owner access. After this step, jaredholgate and jatracey must be the only individual Direct Owners. Remove everyone else, including the user and whoever created the repository, and keep the azure-verified-modules-module-owners fallback security group.
Changing owners is an access change, so ask the user to do it, or get their explicit approval before doing it for them through browser automation:
- Elevate to administrator. On the repository's Just-in-time Access tab, select Next, enter a justification, and select the button that elevates the user's GitHub login to Administrator. Wait until
admin=true(see step 4). - On the repository overview, select Change owners under Direct Owners. The button only appears while elevated, and the Compliance tab does not show the editor.
- Remove every individual owner other than
jaredholgateandjatracey. The first two owner slots are required, and Save stays disabled while either is empty. If removing someone empties a required slot, removejaredholgateorjatraceyfrom a later slot and search for them in the empty required slot instead. - Keep the fallback security group, then select Save.
- Reload the overview and check that Individual Direct Owners lists only Jack Tracey and Jared Holgate.
A user who cannot change the owners emails avm@microsoft.com with the repository name.
Report to the user
- the repository URL;
- the app installation pull request link. The
microsoft/github-operationsmaintainers approve it, and repository sync then applies the shared configuration and managed files; - whether the JIT tie is active or still pending;
- whether
jaredholgateandjatraceyare now the only individual Direct Owners; and - the local clone path.
Recovery
Run the same command again from the same machine after fixing the cause.
| Message | What to do |
The GitHub CLI is not signed in to github.com | Ask the user to run gh auth login --hostname github.com --web --git-protocol https --scopes workflow. |
The GitHub CLI token is missing the ... scope(s) | Ask the user to run the printed gh auth refresh command, or clear GH_TOKEN and GITHUB_TOKEN. |
Configure a Git commit identity | Ask the user for the name and email to set with git config --global user.name and git config --global user.email. |
Missing required metadata fields | Add the missing values to -InputObject. |
The -Path folder name must be the repository name or is not an AVM Terraform repository name | Use <parent folder>/<repository name> with a valid repository name. |
Complete the open source portal setup | Relay the portal steps, as for the first run. |
Elevate your access to ... with JIT | Ask the user to elevate, wait until admin=true, then run again. |
avm pre-commit failed | Read the issues in that step's result, fix the cause (often a failed tool download), then run again. |
Could not restore global-rulesets-opt-out or has not been restored | Run again on the same machine; it restores the recorded value. |
global-rulesets-opt-out is true, but ... no record or global-rulesets-opt-out is already true | Stop and tell the user. If avm init was interrupted on another machine, run it there. Otherwise a repository administrator sets the property back to its original value, normally false. |
Repository sync already protects main, main already contains files without metadata.json, main has metadata.json but is missing, or metadata.json on main is invalid | The repository needs its files through a pull request. Tell the user; do not push to main. |
local clone is skipped | The folder holds other files, which avm init never overwrites. Ask the user where to clone instead. |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

