Install a released binary with the Installation guide, then continue with the Quickstart. The Quickstart validates the project before showing the plan, apply, and teardown lifecycle.
This is the multi-page printable view of this section. Click here to print.
Getting started
- 1: Installation
- 2: Quickstart
1 - Installation
The supported installer downloads only from the canonical GitHub release,
verifies the release checksum before extraction, and installs to
$HOME/.local/bin by default. It never invokes sudo.
curl --proto '=https' --tlsv1.2 --fail --location \
--proto-redir '=https' \
https://github.com/projectious-work/ainfra/releases/latest/download/install.sh \
-o /tmp/ainfra-install.sh
sh /tmp/ainfra-install.sh
Review a downloaded installer before running it when that is required by your local security policy.
To install a specific stable version:
AINFRA_VERSION=0.1.0 sh /tmp/ainfra-install.sh
To select another unprivileged destination:
AINFRA_INSTALL_DIR="$HOME/bin" sh /tmp/ainfra-install.sh
The installer supports these release targets:
| Operating system | Architecture | Release target |
|---|---|---|
| Linux | x86_64 | x86_64-unknown-linux-gnu |
| Linux | ARM64 | aarch64-unknown-linux-gnu |
| macOS | Intel | x86_64-apple-darwin |
| macOS | Apple Silicon | aarch64-apple-darwin |
After installation, the script runs both ainfra --version and
ainfra --help. If the destination is not already on PATH, it prints the
directory that must be added.
For development from a source checkout, use the pinned Rust toolchain:
cargo build
./target/debug/ainfra --version
2 - Quickstart
This guide takes you from an installed binary to a reviewed disposable- infrastructure plan. Applying the plan creates billable Hetzner resources, so the final apply and destroy commands remain explicit.
Prerequisites
- A verified
ainfrarelease from the installation guide - OpenTofu
- Ansible
- A Hetzner Cloud project token for live operations
- An existing SSH public key
Install and validate
Check local readiness without changing infrastructure:
ainfra --version
Initialize a disposable project
Create a separate project and initialize it:
mkdir ../my-infrastructure
cd ../my-infrastructure
ainfra init \
--name my-infrastructure \
--environment development
ainfra validate
ainfra doctor --environment development
Commit ainfra.yaml, ainfra.lock, and the environment input. Keep
.ainfra/ ignored; it contains operational run state. Edit
environments/development.yaml with the location, SSH public key, topology,
and network policy. Export the token; never place it in a project file:
export HCLOUD_TOKEN='...'
Plan and review
ainfra plan \
--environment development
Review the resource count, networking, public-address choices, and ownership scope. The command returns a plan identifier. Apply requires that exact identifier:
ainfra apply \
--environment development \
--approve PLAN_ID
Apply creates billable resources. Keep the input, state, ownership scope, and destroy command available throughout the test. Do not end a disposable test until Hetzner and the local state both confirm that no managed resources remain.
Read outputs and configure hosts
ainfra outputs \
--environment development \
--run PLAN_ID \
--format json
ainfra configure \
--environment development \
--run PLAN_ID \
--known-hosts .ainfra/known_hosts
ainfra status --environment development
Verify SSH host-key fingerprints through the Hetzner console or another
trusted out-of-band channel before the first Ansible connection. Never treat
ssh-keyscan as a source of trust.
Tear down
Create and review a destroy plan:
ainfra plan \
--environment development \
--destroy
Then use the exact destroy-plan ID returned by the lifecycle:
ainfra down \
--environment development \
--approve-destroy PLAN_ID
ainfra status --environment development
Confirm zero project-owned servers, networks, firewalls, and SSH keys in Hetzner, then verify that local OpenTofu state contains no resources.
Next steps
- Review lifecycle operations.
- Understand the security model.
- Learn how the Hetzner baseline is assembled.