An evidence-backed record of deploying and administering an ARM64 Ubuntu virtual machine on Oracle Cloud Infrastructure. It helps cloud and security learners reproduce the build, understand every traffic and privilege boundary, and distinguish what is verified, partially verified, or still pending.
Security notice: public IP addresses, OCIDs and credentials are redacted. No private key is stored in this repository.
Cloud deployments are easy to complete once and difficult to explain later. Console clicks, networking corrections, firewall rules and validation commands often become scattered across screenshots and terminal history. This repository turns that work into a reproducible, reviewable engineering record for hiring teams, peer reviewers and my future self.
A public-subnet OCI compute deployment with key-based SSH administration, a routed Internet Gateway, host firewall controls and evidence-driven operational documentation.
| Area | Verified configuration |
|---|---|
| Instance | oci-vm01 |
| OS | Ubuntu 24.04.4 LTS, kernel 6.17.0-1018-oracle |
| Shape | VM.Standard.A1.Flex, ARM64 / aarch64 |
| Compute | 2 OCPUs, 12 GB provisioned memory |
| Storage | 50 GB boot volume, Balanced, in-transit encryption |
| VCN / subnet | oci-vcn / oci-public-subnet, subnet 10.0.0.0/24 |
| VNIC | oci-vm01-vnic, private IP 10.0.0.64 |
| Internet access | Ephemeral public IP, Internet Gateway, 0.0.0.0/0 route |
| Administration | SSH key → ubuntu → passwordless sudo |
| Host firewall | UFW active; required TCP/UDP ports allowed |
| Capability | Status | Evidence |
|---|---|---|
| Compute, storage and operating system | ✅ Verified | Command output, screenshots |
| Public IP, Internet Gateway and default route | ✅ Verified | Network evidence |
| Successful SSH login | ✅ Verified | Access validation |
| UFW rules for five requested ports | ✅ Verified | Firewall output |
| OCI NSG/security-list ingress for application ports | No uploaded evidence confirms the final OCI ingress rules | |
| Service on TCP/22 | ✅ Verified | sshd listening on IPv4 and IPv6 sockets |
| Services on 80, 443, 51820 and 21820 | ⏳ Not implemented | Firewall rules exist, but no process was listening |
| Automated monitoring | ⏳ Not implemented | Documented as future work |
| Infrastructure as Code | ⏳ Not implemented | Manual console deployment only |
Detailed explanation: Architecture.
The deployment is demonstrated through sanitized OCI Console screenshots and captured terminal validation. Each screenshot is mapped to a precise claim and labelled as verified, historical or troubleshooting evidence.
Run on the OCI instance:
bash scripts/validate-instance.sh
bash scripts/validate-firewall.sh
bash scripts/validate-services.shExpected current result: the instance and UFW validate successfully; only TCP/22 has a listening service.
chmod 400 ~/.ssh/oci-vm01.key
ssh -i ~/.ssh/oci-vm01.key ubuntu@<PUBLIC_IP>The ubuntu account has unrestricted passwordless sudo. Treat the private key as a root-equivalent credential. See Access and administration.
| Port | Purpose | UFW | Listener at validation time |
|---|---|---|---|
| 22/TCP | SSH administration | Allowed | sshd |
| 80/TCP | HTTP | Allowed | None |
| 443/TCP | HTTPS | Allowed | None |
| 51820/UDP | Planned UDP service | Allowed | None |
| 21820/UDP | Planned UDP service | Allowed | None |
End-to-end reachability additionally requires matching OCI ingress rules. See Networking and firewalls.
oci-deployments/
├── .github/workflows/ Documentation and shell quality checks
├── config/ Safe examples and port inventory
├── diagrams/ Editable SVG architecture diagrams
├── docs/ Runbooks and technical explanations
├── evidence/ Sanitized screenshots and command output
├── scripts/ Repeatable validation scripts
├── README.md Reader-first project landing page
└── PUBLISHING.md Exact GitHub publication steps
- ARM64 A1 Flex was selected to use the available OCI A1 entitlement efficiently. The trade-off is that all installed software must support
aarch64. - Ephemeral public IP was accepted for this learning deployment. The trade-off is that the address is not a durable identity for production use.
- UFW plus OCI filtering provides defense in depth. At present, only the UFW evidence is complete for the requested application ports.
- Manual console deployment made each resource visible while learning, but it is less repeatable than Terraform/OpenTofu.
Full rationale: Decisions and trade-offs.
The repository includes shell validation scripts and a GitHub Actions workflow that checks shell syntax, runs ShellCheck and lints Markdown. The workflow becomes active after publication to GitHub. It does not test live OCI resources because no cloud credentials are stored in CI.
Current operations are command-line based: system status, disk/memory checks, UFW inspection and listening-port validation. OCI Monitoring alarms, centralized logs and automated backups are not yet configured. See Operations and monitoring.
The documentation preserves two useful corrections:
- The instance initially had no public IP.
- A gateway route-table association was attempted in the wrong place; the correct design uses a
0.0.0.0/0route rule in the subnet route table.
See Troubleshooting.
- OCI ingress rules for 80/TCP, 443/TCP, 51820/UDP and 21820/UDP are not evidenced yet.
- No web, TLS or UDP application is currently listening on the planned application ports.
- The deployment is a single VM with no high availability.
- The public IP is ephemeral.
- There is no Terraform/OpenTofu, backup validation, monitoring dashboard or automated disaster recovery.
Priority order:
- Capture evidence of the final OCI NSG/security-list rules.
- Restrict SSH source CIDRs where practical.
- Deploy and validate the intended web and UDP services.
- Add TLS and a stable DNS name.
- Rebuild the environment with Terraform/OpenTofu.
- Add OCI Monitoring alarms, backups and recovery testing.
This README is structured for three readers at once: reviewers, hiring teams and my future self. It surfaces the problem, working evidence, reproduction path, architecture, decisions, limitations and future work without describing planned work as already implemented. See Documentation method.
