Skip to content

Commit dbc1f45

Browse files
committed
docs: rewrite README as a beginner-friendly quickstart guide
Replaces the jargon-heavy overview with a plain-language explanation of what Terraform and Ansible do, a numbered quickstart, a credentials table (oci setup config / aws configure / az login), and a simplified repo structure — scoped to the three supported providers (OCI, AWS, Azure).
1 parent 214a1eb commit dbc1f45

1 file changed

Lines changed: 104 additions & 42 deletions

File tree

README.md

Lines changed: 104 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,130 @@
11
# multi-cloud-infra
22

3-
A production-grade, cloud-agnostic Infrastructure as Code (IaC) blueprint. This repository provides the framework to provision minimal Ubuntu `aarch64` (ARM64) virtual instances across multiple cloud providers and automatically bootstrap them into a standardized, secure base environment.
3+
Spin up a secure, ready-to-use Ubuntu ARM64 server on **Oracle Cloud, AWS, or Azure** with a single command — no cloud console clicking, no manual server setup.
4+
5+
You don't need to be a cloud expert to use this. Follow the steps below in order and you'll have a working server in a few minutes.
46

57
---
68

7-
## 🛠️ Tech Stack & Concepts
8-
* **Declarative Provisioning:** Multi-provider infrastructure orchestration (modular architecture).
9-
* **Configuration Automation:** Idempotent server state configuration management.
10-
* **Target Operating System:** Ubuntu Minimal `aarch64` (optimized for ARM architectures like Oracle Ampere A1 or AWS Graviton).
9+
## How it works
10+
11+
This repo uses two well-known, free, open-source tools:
12+
13+
- **Terraform** — creates the server and its networking on your chosen cloud provider.
14+
- **Ansible** — connects to that new server and locks it down (firewall, automatic security updates, no password logins, etc).
15+
16+
The `Makefile` runs both for you in the right order, so in practice you only ever type one command.
1117

1218
---
1319

14-
## 📁 Repository Structure
20+
## ☁️ Supported providers
1521

16-
```text
17-
├── .gitignore # Global exclusions for sensitive credentials and state files
18-
├── README.md # Project documentation
19-
├── terraform/ # Declarative provisioning modules
20-
│ ├── oci/ # Oracle Cloud Infrastructure setup
21-
│ │ ├── main.tf
22-
│ │ ├── variables.tf
23-
│ │ └── terraform.tfvars.example
24-
│ ├── aws/ # AWS Graviton setup (Future extension)
25-
│ └── gcp/ # GCP ARM64 setup (Future extension)
26-
└── ansible/ # Configuration management automation
27-
├── playbook.yml # Base configuration entrypoint
28-
├── group_vars/
29-
│ └── all.yml # Global setup variables
30-
└── roles/
31-
└── ubuntu_minimal/ # Baseline optimization tasks for minimal OS
32-
```
22+
| Provider | Free-tier ARM64 offer | Default server size |
23+
|---|---|---|
24+
| **Oracle Cloud (OCI)** | Best free tier — 4 OCPU / 24GB, always free | `VM.Standard.A1.Flex` |
25+
| **AWS** | 750 hrs/month of `t4g.micro` for 12 months | `t4g.micro` |
26+
| **Azure** | Free credits cover Ampere Altra ARM VMs for 12 months | `Standard_D2ps_v5` |
27+
28+
Pick whichever one you already have an account with. Oracle Cloud has been tested end-to-end; AWS and Azure follow the identical setup process.
3329

3430
---
3531

36-
## 🚀 Getting Started
32+
## ✅ Prerequisites
3733

38-
### 1. Provision Infrastructure
39-
Navigate to your targeted cloud provider directory, set up your credentials using the provided example template, and initialize the declarative configuration:
34+
Install these once on your own computer (macOS example shown):
4035

4136
```bash
42-
cd terraform/oci
37+
brew tap hashicorp/tap
38+
brew install hashicorp/tap/terraform ansible jq
39+
ansible-galaxy collection install -r ansible/requirements.yml
40+
```
41+
42+
You'll also need:
43+
- An account with your chosen cloud provider, with billing/free-tier set up.
44+
- An SSH key pair on your computer. If you don't have one: `ssh-keygen -t ed25519`.
45+
46+
---
47+
48+
## 🚀 Quickstart
49+
50+
1. **Pick a provider folder** and copy the example config:
51+
```bash
52+
cd terraform/live/oci # or terraform/live/aws, terraform/live/azure
53+
cp terraform.tfvars.example terraform.tfvars
54+
```
55+
2. **Open `terraform.tfvars`** and fill in the few values it asks for (region, path to your SSH key, etc). Every line has a comment explaining it.
56+
3. **Log in to your cloud provider's CLI** so Terraform can authenticate (one-time per provider — see the Credentials table below).
57+
4. **From the repository root, run:**
58+
```bash
59+
make up PROVIDER=oci # or aws / azure
60+
```
61+
This creates the server and automatically secures it. Takes 2-5 minutes.
62+
5. **When you're done with the server:**
63+
```bash
64+
make down PROVIDER=oci
65+
```
66+
67+
That's it — steps 1-2 only happen once per provider; after that it's just `make up` / `make down`.
68+
69+
---
70+
71+
## 🔑 Credentials (one-time setup per provider)
4372

44-
# Create your local untracked secrets file
45-
cp terraform.tfvars.example terraform.tfvars
73+
No cloud credentials are ever stored in this repo. Each provider reads them from your machine automatically:
4674

47-
# Initialize and apply infrastructure
48-
terraform init
49-
terraform apply
75+
| Provider | How to log in |
76+
|---|---|
77+
| Oracle Cloud | Run `oci setup config` (installs `~/.oci/config`) |
78+
| AWS | Run `aws configure` (installs `~/.aws/credentials`) |
79+
| Azure | Run `az login` |
80+
81+
---
82+
83+
## 📁 Repository structure
84+
85+
```text
86+
├── Makefile # make up / make down / make lint — the commands you'll actually use
87+
├── scripts/generate-inventory.sh
88+
├── terraform/
89+
│ ├── modules/ # Reusable building blocks, one per provider
90+
│ │ ├── oci-instance/
91+
│ │ ├── aws-instance/
92+
│ │ └── azure-instance/
93+
│ └── live/ # Your actual settings live here (terraform.tfvars)
94+
│ ├── oci/
95+
│ ├── aws/
96+
│ └── azure/
97+
└── ansible/
98+
├── playbook.yml
99+
├── group_vars/all.yml # Tweak the admin username, SSH port, swap size, timezone here
100+
└── roles/ubuntu_minimal/ # The security hardening steps
50101
```
51102

52-
### 2. Automate Server Configuration
53-
Once your instance is up and running, trigger the automation scripts to securely provision packages, configure firewalls, and optimize the minimal Ubuntu OS:
103+
---
54104

55-
```bash
56-
cd ../../ansible
105+
## Everyday commands
57106

58-
# Execute configuration against your instance IP
59-
ansible-playbook -i '<INSTANCE_IP>,' playbook.yml --user ubuntu
107+
```bash
108+
make up PROVIDER=oci # create + secure a server
109+
make down PROVIDER=oci # destroy it
110+
make plan PROVIDER=aws # preview changes before applying
111+
make lint # check everything is valid (useful before committing changes)
60112
```
61113

62114
---
63115

64-
## 🔒 Security Best Practices
65-
* **Zero Credential Leaks:** All active `.tfvars`, local states, and sensitive key pairs are strictly blocked from git tracking via `.gitignore`.
66-
* **Example Templates:** Real configurations are substituted with extension `.example` templates for demonstration purposes.
67-
* **Minimalist Footprint:** Server setups enforce strict UFW firewall policies and only inject baseline essential utilities onto the minimal OS layer.
116+
## 🔒 What gets secured automatically
117+
118+
Every server this repo creates gets, out of the box:
119+
- Firewall open to SSH only (port 22)
120+
- Password login disabled — SSH key only
121+
- Root login disabled, non-root admin user created
122+
- Automatic security updates
123+
- fail2ban (blocks repeated failed login attempts)
124+
- A swap file, sized for small free-tier instances
125+
126+
---
68127

128+
## Notes
129+
- State is stored locally (already excluded from git) — fine for personal use. See the comment in each `terraform/live/<provider>/backend.tf` if you later want to move it to shared/remote storage.
130+
- Only Oracle Cloud has been tested against a real account so far. AWS and Azure use the identical, validated structure — if a region/size isn't available on your account, the error message will tell you and the `.tfvars.example` comments point you to how to check.

0 commit comments

Comments
 (0)