Bootstrap the ac-cicd-infra Repository from Windows 11
This page creates the initial private Aspireclan infrastructure repository from a Windows 11 workstation. The supplied ZIP contains the PowerShell scripts that create the cleaned repository scaffold, commit it to main, create and push the local, dev, qa, and prod branches, keep main as the GitHub default branch, and clone a clean local working copy.
The expected result is:
GitHub organization: ASPIRECLAN-LLC-Org
Repository: ac-cicd-infra
Visibility: private
Default branch: main
Branches: main, local, dev, qa, prod
Clean clone: D:\code\ASPIRECLAN-LLC-Org\ac-cicd-infra
Checked-out branch: mainThe current infrastructure execution path is:
feature/* → dev validation → prod apply/configuration → main baselineThis bootstrap creates the repository structure only. It does not provision Proxmox VMs, configure Kubernetes, install ARC, or deploy applications.
1. Keep the ZIP in the Docusaurus static directory
Docusaurus copies files from its default static directory directly into the generated site. Keep the downloadable ZIP here:
acdocs/
├── docs/
│ └── <your-documentation-folder>/
│ └── bootstrap-ac-cicd-infra-repository.mdx
└── static/
└── downloads/
└── ac-cicd-infra-windows-bootstrap-v4.zipThe page uses Docusaurus useBaseUrl, so the public download link resolves correctly even when the site is deployed with a non-root baseUrl.
The public site path is:
/downloads/ac-cicd-infra-windows-bootstrap-v4.zipFrom the Docusaurus project root, copy the ZIP into static/downloads:
cd D:\code\AC-Documentation-Org\acdocs
New-Item \`
-ItemType Directory \`
-Path ".\static\downloads" \`
-Force | Out-Null
Copy-Item \`
-Path "C:\Users\Manoj\Downloads\ac-cicd-infra-windows-bootstrap-v4.zip" \`
-Destination ".\static\downloads\ac-cicd-infra-windows-bootstrap-v4.zip" \`
-Force
Get-Item ".\static\downloads\ac-cicd-infra-windows-bootstrap-v4.zip"
Get-FileHash \`
".\static\downloads\ac-cicd-infra-windows-bootstrap-v4.zip" \`
-Algorithm SHA256The SHA-256 hash of the attached ZIP is:
SHA256
C8EA2C074103E9B4BFC6775FC347F20D74D2C058891CBABA70AD5BE25712F30EIf your local copy produces a different hash, confirm that you intentionally replaced the ZIP with a newer version before publishing the documentation.
2. Contents of the bootstrap ZIP
00-Prepare-AcCicdInfraWindows.ps1
01-New-AcCicdInfraRepository.ps1
02-Clone-AcCicdInfraRepository.ps1
99-Test-PowerShellScripts.ps1
README.md| File | Purpose |
|---|---|
99-Test-PowerShellScripts.ps1 | Parses the three operational scripts with the local Windows PowerShell parser before anything is executed. |
00-Prepare-AcCicdInfraWindows.ps1 | Checks Windows, installs Git and GitHub CLI when missing, configures Git identity, and authenticates GitHub CLI. |
01-New-AcCicdInfraRepository.ps1 | Builds the repository in a temporary staging directory, creates the private GitHub repository, commits the scaffold, and pushes all five branches. |
02-Clone-AcCicdInfraRepository.ps1 | Clones a clean working copy, creates local tracking branches, and returns the working copy to main. |
README.md | Provides the short command sequence and expected result. |
The v4 scripts retain the Windows PowerShell 5.1 compatibility fixes and update the generated scaffold to match the cleaned repository structure. They do not recreate removed placeholder trees or the obsolete 07-join-workers.yml filename.
3. Prerequisites
Before running the scripts, confirm:
- Windows 11 is available.
- The signed-in GitHub account can create private repositories in
ASPIRECLAN-LLC-Org. - The repository
ASPIRECLAN-LLC-Org/ac-cicd-infradoes not already exist. - The intended Git identity is known.
- WinGet is available if Git or GitHub CLI must be installed.
- The target working-copy parent directory is available.
The documented working-copy location is:
D:\code\ASPIRECLAN-LLC-Org\ac-cicd-infra4. Download and extract the ZIP
Download the ZIP using the button at the top of this page. From Windows PowerShell:
cd C:\Users\Manoj\Downloads
Expand-Archive \`
-Path ".\ac-cicd-infra-windows-bootstrap-v4.zip" \`
-DestinationPath ".\ac-cicd-infra-windows-bootstrap-v4" \`
-Force
cd .\ac-cicd-infra-windows-bootstrap-v4
Get-ChildItem
Get-ChildItem -Filter "*.ps1" | Unblock-FileVerify the ZIP and display its contents when needed:
Get-FileHash \`
".\ac-cicd-infra-windows-bootstrap-v4.zip" \`
-Algorithm SHA256
Add-Type -AssemblyName System.IO.Compression.FileSystem
$zipPath = Resolve-Path ".\ac-cicd-infra-windows-bootstrap-v4.zip"
$archive = [System.IO.Compression.ZipFile]::OpenRead($zipPath)
try {
$archive.Entries |
Select-Object FullName, Length |
Format-Table -AutoSize
}
finally {
$archive.Dispose()
}5. Allow the scripts for the current PowerShell session
The execution-policy change below applies only to the current PowerShell process. It does not permanently weaken the workstation policy.
Set-ExecutionPolicy \`
-Scope Process \`
-ExecutionPolicy Bypass
Get-ExecutionPolicy -List6. Parse-test all operational PowerShell scripts
Run this before any repository operation:
.\99-Test-PowerShellScripts.ps1Expected result:
PASS: 00-Prepare-AcCicdInfraWindows.ps1
PASS: 01-New-AcCicdInfraRepository.ps1
PASS: 02-Clone-AcCicdInfraRepository.ps1
All PowerShell scripts passed parser validation.Do not continue if any script reports FAIL.
7. Prepare Git and GitHub CLI
Run:
.\00-Prepare-AcCicdInfraWindows.ps1 \`
-GitUserName "Manoj Nair" \`
-GitUserEmail "aspireclan1208@gmail.com"The script:
- Confirms it is running on Windows.
- Uses WinGet to install Git when missing.
- Uses WinGet to install GitHub CLI when missing.
- Configures the supplied Git name and email.
- Starts browser-based GitHub authentication when required.
- Configures GitHub CLI to use HTTPS for Git operations.
- Verifies the final authentication state.
When Git and GitHub CLI are already installed and must not be changed, use:
.\00-Prepare-AcCicdInfraWindows.ps1 \`
-GitUserName "Manoj Nair" \`
-GitUserEmail "aspireclan1208@gmail.com" \`
-SkipToolInstallationVerify the completed preparation:
git --version
gh --version
gh auth status
git config --global user.name
git config --global user.emailThe GitHub account should be the account that has permission to create the organization repository.
8. Confirm that the repository does not already exist
Run:
gh repo view ASPIRECLAN-LLC-Org/ac-cicd-infraA repository-not-found response is expected before the first creation. The repository-creation script deliberately stops when the repository already exists.
Also check the temporary staging path:
$stagingPath = Join-Path $env:TEMP "ac-cicd-infra-bootstrap"
Write-Host "Staging path: $stagingPath"
Test-Path $stagingPathExpected before a clean first run:
FalseIf a failed earlier attempt left the staging directory behind and its contents are no longer needed, remove it:
Remove-Item \`
-LiteralPath (Join-Path $env:TEMP "ac-cicd-infra-bootstrap") \`
-Recurse \`
-Force \`
-ErrorAction SilentlyContinue9. Create the private GitHub repository
Run the repository-creation script with its approved defaults:
.\01-New-AcCicdInfraRepository.ps1The defaults are:
- Organization:
ASPIRECLAN-LLC-Org - Repository:
ac-cicd-infra - Visibility: private
- Default branch:
main - Additional branches:
local,dev,qa,prod - Temporary staging directory:
%TEMP%\ac-cicd-infra-bootstrap
When a known disposable staging directory remains, run:
.\01-New-AcCicdInfraRepository.ps1 \`
-ForceStagingCleanupThe parameters can also be supplied explicitly:
.\01-New-AcCicdInfraRepository.ps1 \`
-GitHubOrganization "ASPIRECLAN-LLC-Org" \`
-RepositoryName "ac-cicd-infra" \`
-RepositoryDescription "Shared Proxmox, Terraform, Ansible, Kubernetes and ARC CI/CD infrastructure for Aspireclan applications."Expected completion:
Repository creation completed successfully.
Repository: ASPIRECLAN-LLC-Org/ac-cicd-infra
Default: main
Branches: main, local, dev, qa, prodThe script creates the first commit on main, pushes main, creates the other four branches from the same commit, pushes them, explicitly sets GitHub's default branch to main, and removes the temporary staging directory after success.
10. Repository structure created by the script
The bootstrap creates this cleaned initial scaffold:
ac-cicd-infra/
├── terraform/
│ ├── modules/
│ │ ├── proxmox-vm/
│ │ └── proxmox-vm-group/
│ └── stacks/
│ └── shared-k8s/
├── ansible/
│ ├── ansible.cfg
│ ├── inventories/
│ │ └── shared-k8s/
│ │ ├── hosts.ini
│ │ └── group_vars/
│ ├── playbooks/
│ │ ├── shared-k8s/
│ │ └── tenants/
│ │ └── fp/{dev,qa,prod}/
│ └── roles/
│ ├── common/
│ ├── haproxy/
│ ├── keepalived/
│ ├── containerd/
│ ├── kubernetes-common/
│ ├── kubernetes-control-plane/
│ ├── kubernetes-worker/
│ ├── arc-controller/
│ └── arc-runner-scale-set/
├── kubernetes/
│ ├── common/
│ │ └── cni/
│ └── tenants/
│ └── fp/
│ ├── organization/
│ ├── dev/{namespace,runner-scale-sets}/
│ ├── qa/{namespace,runner-scale-sets}/
│ └── prod/{namespace,runner-scale-sets}/
├── helm/
│ ├── common/
│ │ └── arc-controller/
│ └── tenants/
│ └── fp/{dev,qa,prod}/
├── .github/
│ ├── workflows/
│ │ ├── terraform-plan-shared-k8s.yml
│ │ ├── terraform-apply-shared-k8s.yml
│ │ ├── ansible-configure-shared-k8s.yml
│ │ ├── ansible-configure-load-balancer.yml
│ │ ├── ansible-configure-control-planes.yml
│ │ ├── ansible-configure-dev-workers.yml
│ │ ├── ansible-configure-qa-workers.yml
│ │ ├── ansible-configure-prod-workers.yml
│ │ ├── ansible-install-arc-controller.yml
│ │ ├── onboard-fp-github-org.yml
│ │ ├── arc-fp-web-ui-001-dev.yml
│ │ ├── arc-fp-web-ui-001-qa.yml
│ │ └── arc-fp-web-ui-001-prod.yml
│ └── CODEOWNERS
├── .editorconfig
├── .gitattributes
├── .gitignore
└── README.mdConsistency status: this tree matches the cleaned source repository and intentionally excludes the folders and files removed during cleanup.
Important characteristics:
- Terraform manages Proxmox infrastructure definitions.
- Ansible contains only the shared-cluster, ARC, and FP runner paths used by the current source.
- Kubernetes and Helm contain the active shared CNI, ARC controller, FP organization, namespace, and repository scale-set paths.
- Removed application-VM, scripts, docs, Shelvera, future-product, and separate build/deploy placeholder trees are not recreated.
- The development worker playbook is created as
07-join-dev-workers.yml. - Workflow files use the active cleaned-source filenames, remain safe manual placeholders, and do not provision anything.
- Proxmox credentials, SSH private keys, Terraform state, kubeconfig, and other secrets are not generated or committed.
11. Verify the GitHub repository and branches
Run:
gh repo view ASPIRECLAN-LLC-Org/ac-cicd-infra \`
--json nameWithOwner,visibility,defaultBranchRef,url
gh api \`
repos/ASPIRECLAN-LLC-Org/ac-cicd-infra/branches \`
--jq '.[].name' Expected branch names, in any display order:
main
local
dev
qa
prodConfirm that the repository visibility is PRIVATE and defaultBranchRef.name is main.
12. Clone a clean working copy
Clone into the approved Aspireclan source folder:
.\02-Clone-AcCicdInfraRepository.ps1 \`
-CloneParent "D:\code\ASPIRECLAN-LLC-Org"The script defaults to C:\code when -CloneParent is omitted:
.\02-Clone-AcCicdInfraRepository.ps1If the destination already exists, the script stops rather than overwriting it. Use the force option only when the existing destination is definitely disposable:
.\02-Clone-AcCicdInfraRepository.ps1 \`
-CloneParent "D:\code\ASPIRECLAN-LLC-Org" \`
-ForceRemoveExistingDestination13. Verify the cloned repository
Run:
cd D:\code\ASPIRECLAN-LLC-Org\ac-cicd-infra
git branch --show-current
git branch -vv
git branch -r
git remote -v
git statusExpected result:
Current branch: main
Local branches:
dev
local
* main
prod
qa
Working tree: clean
Remote: https://github.com/ASPIRECLAN-LLC-Org/ac-cicd-infra.gitThe clone intentionally ends on main. Day-to-day infrastructure work begins by switching to dev and creating a feature branch. The retained local and qa branches are not targeted by the current shared-cluster workflows.
14. Verify the Visual Studio ignore rules
The v4 bootstrap creates the Visual Studio ignore rules from the first commit:
# Visual Studio
.vs/
*.suo
*.user
*.userosscache
*.sln.docstates
*.VC.db
*.VC.VC.opendbVerify the committed rules and confirm that a local .vs file is ignored:
cd D:\code\ASPIRECLAN-LLC-Org\ac-cicd-infra
Select-String \`
-Path .gitignore \`
-Pattern '^\.vs/$','^\*\.suo$','^\*\.user$','^\*\.VC\.db$'
git check-ignore -v .vs\VSWorkspaceState.jsonExpected result:
Expected:
.gitignore contains the Visual Studio rules.
git check-ignore reports that .vs/ is ignored.
No pull request is required because v4 creates these rules during bootstrap.The ignore rules are part of the initial scaffold, so no follow-up commit or pull request is required.
15. Confirm that sensitive files are not tracked
From the cloned repository:
$sensitiveMatches = git ls-files | Select-String -Pattern \`
'(\.tfstate|terraform\.tfvars$|kubeconfig|admin\.conf|id_ed25519|\.pem$|\.key$)'
if ($sensitiveMatches) {
$sensitiveMatches
throw "A sensitive file may be tracked. Review before continuing."
}
Write-Host "PASS: No known sensitive files are tracked." -ForegroundColor GreenNever commit:
- Proxmox API tokens
- Terraform state or plan files
- SSH private keys
- GitHub App private keys
- Kubernetes kubeconfig or
admin.conf - Ansible vault passwords
- Deployment credentials
16. Day-to-day branch usage
Start implementation work from dev:
cd D:\code\ASPIRECLAN-LLC-Org\ac-cicd-infra
git switch dev
git pull --ff-only origin dev
git switch -c feature/<change-name>Branch purposes:
| Branch | Purpose |
|---|---|
local | Retained local-only branch; not targeted by the current shared-cluster workflows. |
dev | Active validation and Terraform-plan branch. |
qa | Retained promotion branch; not targeted by the current newer shared-cluster workflows. |
prod | Approved infrastructure apply and configuration branch. |
main | Protected approved baseline. |
The bootstrap does not create separate local or QA Kubernetes clusters. The active automation path is dev validation followed by prod apply/configuration.
17. Recommended GitHub repository protections
After bootstrap, configure branch rulesets:
- Block deletion and force pushes on all five long-lived branches.
- Require pull requests for the protected long-lived branches after the initial bootstrap.
- Require validation checks on
devafter the real workflows have run and their exact check names are visible. - Restrict direct pushes to
prodandmain. - Protect the GitHub Environments used by shared Kubernetes and ARC changes.
- Require approval for production infrastructure changes.
- Keep
mainas the default branch.
Do not require placeholder workflow check names. Replace placeholder workflows first, run them once, and then select their real status-check names in the ruleset.
18. Failure handling
Repository already exists
The script stops by design. Confirm whether the existing repository is the desired repository. Do not overwrite it blindly.
Temporary staging directory exists
Inspect it first:
Get-ChildItem \`
-Force \`
(Join-Path $env:TEMP "ac-cicd-infra-bootstrap")
Remove-Item \`
-LiteralPath (Join-Path $env:TEMP "ac-cicd-infra-bootstrap") \`
-Recurse \`
-ForceUse -ForceStagingCleanup only when those files are disposable.
Clone destination exists
Preserve unknown work by renaming the folder before cloning again:
Rename-Item \`
-Path "D:\code\ASPIRECLAN-LLC-Org\ac-cicd-infra" \`
-NewName "ac-cicd-infra-backup-$(Get-Date -Format yyyyMMdd-HHmmss)"Authentication fails
Run:
gh auth logout
gh auth login --hostname github.com --git-protocol https --web
gh auth setup-git
gh auth statusOrganization repository creation is denied
Confirm that the authenticated GitHub account is allowed to create repositories in ASPIRECLAN-LLC-Org. Organization policy may restrict repository creation to owners.
PowerShell parser test fails
Stop and replace the local extracted ZIP with the published v4 ZIP. Do not edit around a parser failure without reviewing the exact script difference.
19. Test the Docusaurus download link
From the Docusaurus project root:
cd D:\code\AC-Documentation-Org\acdocs
npm install
npm run startOpen this documentation page and click the download button. A direct local-development test can also use:
$downloadUrl = "http://localhost:3000/downloads/ac-cicd-infra-windows-bootstrap-v4.zip"
$testFile = Join-Path $env:TEMP "ac-cicd-infra-windows-bootstrap-v4-test.zip"
Invoke-WebRequest \`
-Uri $downloadUrl \`
-OutFile $testFile
Get-FileHash $testFile -Algorithm SHA256
Remove-Item $testFileThe downloaded test ZIP should produce the same SHA-256 hash shown earlier.
20. Successful completion state
Private repository created: ASPIRECLAN-LLC-Org/ac-cicd-infra
Default GitHub branch: main
Branches pushed: main, local, dev, qa, prod
Working copy cloned to: D:\code\ASPIRECLAN-LLC-Org\ac-cicd-infra
Working copy checked out on: main
Initial repository content: cleaned implementation scaffold only
Scaffold consistency: aligned with the cleaned ac-cicd-infra source structure
Development worker playbook: 07-join-dev-workers.yml
Unused application-vm, scripts, docs, Shelvera, and future-product placeholders: not created
Infrastructure provisioned by bootstrap: none
Secrets committed: none
Terraform state committed: noneThe next implementation page can now replace the scaffolded Terraform and Ansible placeholders with the approved shared Kubernetes infrastructure, starting from a feature branch created from dev.