|
1 | | -# Deploys an Ubuntu Minimal OS Virtual Machine with Docker-ce and Docker Compose installed in GCP using Terraform |
2 | | -Using the below instructions and supplied .tf files you will be able to deploy an e2-micro instance into GCP using Terraform, this is the free tier so shouldnt cost you a thing. This version comes with docker installed and will inject a compose file into the app data drive in /mnt/disks/docker/projects/app my example contains an Uptime Kuma and Healthchecks container. |
| 1 | +<div align="center"> |
| 2 | +<img src="docs/assets/logo.png" align="center" width="144px" height="144px"/> |
3 | 3 |
|
4 | | -# 🔧 IMPORTANT |
5 | | -I have moved all the installation instructions for this project over to my doc's site at [sudo-kraken Docs](https://sudo-kraken.github.io/docs/gcp-free-forever/) This contains everything you need to know and more to deploy this project. |
| 4 | +### Terraform GCP Ubuntu e2-micro VM |
6 | 5 |
|
7 | | -<p align="center"> |
8 | | - <a href="https://www.buymeacoffee.com/jharrison94" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="60px" width="217px" > |
| 6 | +_Deploys an Ubuntu Minimal VM on Google Cloud’s free tier with Docker CE and Docker Compose preinstalled. Injects a sample Compose project to an attached data disk for quick app bring-up._ |
| 7 | +</div> |
9 | 8 |
|
10 | | -Everything from this point down is deprecated in favor of the doc's page, I am leaving it in however for those of you who do not require a long and in-depth guide. |
| 9 | +<div align="center"> |
11 | 10 |
|
12 | | -____ |
| 11 | +[](https://www.terraform.io/) |
| 12 | +[](https://www.terraform.io/) |
13 | 13 |
|
14 | | -## Instructions |
15 | | -Firstly you will need to have a GCP account you can read more on this [here](https://cloud.google.com/free/docs/gcp-free-tier). Once this is done, go ahead and create yourself a blank project, name it whatever you like. Then enable the Compute Engine API, finally proceed to open up the google cloud shell from within that project. |
| 14 | +</div> |
16 | 15 |
|
17 | | -Once in the cloud shell, make sure you are in /home/USERHERE |
18 | | -Create the folders required for your auth, tf, and docker compose files. (You should automatically be in your home folder feel free to put these wherever you choose.) |
| 16 | +<div align="center"> |
19 | 17 |
|
20 | | -- I made the folders in /home/USER. |
21 | | - - All TF files go in the terraform folder. |
22 | | - - docker-compose.yaml goes into compose_files |
23 | | - - The auth command auto outputs into the /home/USER/auth folder |
24 | | - - Finally the startup.sh goes into the startup folder. |
| 18 | +[](https://scorecard.dev/viewer/?uri=github.com/sudo-kraken/terraform-gcp-ubuntu-container-ready-e2-micro-vm) |
25 | 19 |
|
26 | | -``` |
27 | | -cd ~/ |
| 20 | +</div> |
28 | 21 |
|
29 | | -mkdir terraform |
| 22 | +## Contents |
30 | 23 |
|
31 | | -mkdir auth |
| 24 | +- [Overview](#overview) |
| 25 | +- [Architecture at a glance](#architecture-at-a-glance) |
| 26 | +- [Features](#features) |
| 27 | +- [Prerequisites](#prerequisites) |
| 28 | +- [Quick start](#quick-start) |
| 29 | +- [Repository structure](#repository-structure) |
| 30 | +- [Google Free Tier information](#google-free-tier-information) |
| 31 | +- [Troubleshooting](#troubleshooting) |
| 32 | +- [Infrastructure model](#infrastructure-model) |
| 33 | +- [Licence](#licence) |
| 34 | +- [Security](#security) |
| 35 | +- [Contributing](#contributing) |
| 36 | +- [Support](#support) |
32 | 37 |
|
33 | | -mkdir compose_files |
| 38 | +## Overview |
34 | 39 |
|
35 | | -mkdir startup |
| 40 | +Using the supplied Terraform configuration, this project deploys a free-tier eligible **e2-micro** VM running Ubuntu Minimal, with **Docker CE** and **Docker Compose** installed automatically. A sample Compose file is injected onto a data disk at `/mnt/disks/docker/projects/app` that runs **Uptime Kuma** and **Healthchecks** as examples. |
36 | 41 |
|
37 | | -mkdir .ssh |
38 | | -``` |
39 | | -Git clone this repo into the terraform folder and move the compose file into the compose_files folder, startup.sh into the startup folder. |
| 42 | +> [!NOTE] |
| 43 | +> The full, step-by-step installation guide lives in my docs site: **[sudo-kraken Docs](https://sudo-kraken.github.io/docs/gcp-free-forever/)**. The sections below summarise the essentials for quick use. |
| 44 | +
|
| 45 | +## Architecture at a glance |
| 46 | + |
| 47 | +- Terraform Google provider provisions: |
| 48 | + - **Compute Engine e2-micro** instance based on **Ubuntu Minimal** |
| 49 | + - Optional **secondary persistent disk** for container data, mounted at `/mnt/disks/docker` |
| 50 | + - **Firewall rules** for required ingress such as SSH and web ports as defined in `network-firewall.tf` |
| 51 | +- **Startup script** installs Docker CE and Docker Compose then places a sample `docker-compose.yaml` under `/mnt/disks/docker/projects/app` |
| 52 | +- **SSH key injection** from `~/.ssh/sshkey.pub` |
| 53 | +- Outputs expose VM details including external IP |
| 54 | + |
| 55 | +## Features |
| 56 | + |
| 57 | +- Free-tier friendly deployment targeting eligible US regions |
| 58 | +- Automatic install of Docker CE and Docker Compose |
| 59 | +- Sample Compose project seeded to a mounted data disk |
| 60 | +- Separate Terraform files for provider, network, VM and variables for clarity |
| 61 | +- Opinionated defaults you can customise via `terraform.tfvars` |
| 62 | + |
| 63 | +## Prerequisites |
| 64 | + |
| 65 | +- A Google Cloud account with Free Tier enabled |
| 66 | +- A new or existing GCP project with **Compute Engine API** enabled |
| 67 | +- A **service account** with keys and the following roles at project scope: |
| 68 | + - `roles/viewer` |
| 69 | + - `roles/storage.admin` |
| 70 | + - `roles/compute.instanceAdmin.v1` |
| 71 | + - `roles/compute.networkAdmin` |
| 72 | + - `roles/compute.securityAdmin` |
| 73 | +- SSH keypair in `~/.ssh/sshkey` and `~/.ssh/sshkey.pub` in OpenSSH format |
| 74 | +- Terraform 1.6 or newer |
| 75 | + |
| 76 | +> [!NOTE] |
| 77 | +> Google defaults VM network service tier to Premium. Switch to **Standard** to stay aligned with free-tier usage. See the screenshot below. |
40 | 78 |
|
41 | | -You will also need to store a private and public key in your ~/.ssh folder and name them "sshkey" and "sshkey.pub", these should container your OpenSSH format keys, this will be what is added to the VM so that you can SSH in on the public interface to manage it. |
| 79 | +## Quick start |
42 | 80 |
|
43 | | -Now you will need to create a service account to use Terraform with and give it all the required permissions necessary to provision the VM. |
| 81 | +Create basic folders in Cloud Shell or your workstation: |
44 | 82 |
|
| 83 | +```bash |
| 84 | +cd ~ |
| 85 | +mkdir -p terraform auth compose_files startup .ssh |
45 | 86 | ``` |
46 | | -# Creates a service account named tf-serviceaccount |
47 | | -gcloud iam service-accounts create tf-serviceaccount --description="service account for terraform" --display-name="terraform_service_account" |
48 | 87 |
|
49 | | -# List accounts to ensure it was created |
50 | | -gcloud iam service-accounts list |
| 88 | +Clone and copy files: |
51 | 89 |
|
52 | | -# Create keys for the service account to use when provisioning and store them in the auth folder. |
53 | | -**Ensure that you update PROJECT-ID-HERE with your project ID.** |
54 | | -gcloud iam service-accounts keys create ~/auth/google-key.json --iam-account [email protected] |
| 90 | +```bash |
| 91 | +git clone https://github.com/sudo-kraken/terraform-gcp-ubuntu-container-ready-e2-micro-vm.git ~/terraform |
| 92 | +# Place your docker-compose.yaml into ~/compose_files |
| 93 | +# Place startup.sh into ~/startup |
55 | 94 | ``` |
56 | 95 |
|
57 | | -With this done we will now add the following permissions to the service account. |
| 96 | +Create a service account and key: |
58 | 97 |
|
| 98 | +```bash |
| 99 | +# Replace PROJECT-ID-HERE with your project id |
| 100 | +gcloud iam service-accounts create tf-serviceaccount \ |
| 101 | + --description="service account for terraform" \ |
| 102 | + --display-name="terraform_service_account" |
| 103 | + |
| 104 | +gcloud iam service-accounts keys create ~/auth/google-key.json \ |
| 105 | + |
59 | 106 | ``` |
60 | | -gcloud services enable cloudresourcemanager.googleapis.com |
61 | | -gcloud services enable cloudbilling.googleapis.com |
62 | | -gcloud services enable iam.googleapis.com |
63 | | -gcloud services enable storage.googleapis.com |
64 | | -gcloud services enable serviceusage.googleapis.com |
65 | 107 |
|
66 | | -# For all of the below commands ensure that you update PROJECT-ID-HERE with your project ID. |
67 | | -gcloud projects add-iam-policy-binding PROJECT-ID-HERE --member serviceAccount:[email protected] --role roles/viewer |
| 108 | +Enable required services and bind roles: |
68 | 109 |
|
69 | | -gcloud projects add-iam-policy-binding PROJECT-ID-HERE --member serviceAccount:[email protected] --role roles/storage.admin |
| 110 | +```bash |
| 111 | +gcloud services enable cloudresourcemanager.googleapis.com cloudbilling.googleapis.com iam.googleapis.com storage.googleapis.com serviceusage.googleapis.com |
70 | 112 |
|
| 113 | +gcloud projects add-iam-policy-binding PROJECT-ID-HERE --member serviceAccount: [email protected] --role roles/viewer |
| 114 | +gcloud projects add-iam-policy-binding PROJECT-ID-HERE --member serviceAccount: [email protected] --role roles/storage.admin |
71 | 115 | gcloud projects add-iam-policy-binding PROJECT-ID-HERE --member serviceAccount: [email protected] --role roles/compute.instanceAdmin.v1 |
72 | | -
|
73 | 116 | gcloud projects add-iam-policy-binding PROJECT-ID-HERE --member serviceAccount: [email protected] --role roles/compute.networkAdmin |
74 | | -
|
75 | 117 | gcloud projects add-iam-policy-binding PROJECT-ID-HERE --member serviceAccount: [email protected] --role roles/compute.securityAdmin |
76 | 118 | ``` |
77 | 119 |
|
78 | | -Now you will want to copy all of the .tf files in this repo into the terraform folder we created earlier, ensure you read all of them carefully and update each one with your own information. |
| 120 | +Copy the `.tf` files from this repo into your `~/terraform` folder, review and update variables to match your project and region, then run: |
79 | 121 |
|
80 | | -You should now be ready to deploy. First you will run the init, to pull all dependancies, then a plan to test the config and finally apply to build the project. |
81 | | -``` |
| 122 | +```bash |
| 123 | +cd ~/terraform |
82 | 124 | terraform init |
83 | | -
|
84 | 125 | terraform plan |
85 | | -
|
86 | 126 | terraform apply |
87 | 127 | ``` |
88 | 128 |
|
89 | | -Voila! if all is well you should be presented with the information of your new vm. You can now SSH in via the public IP or go through the cloud console SSH which can be found in the GCP Compute Engine under VM Instances. It can take a couple of minutes to complete all the installations and file injection once the machine is up so give it a few minutes to process, it will all be there I promise. |
90 | | - |
91 | | -By Default Google sets the VM networking to premium, so dont forget to go and change it to standard, as shown here. |
92 | | - |
93 | | - |
| 129 | +After apply completes, connect via the external IP using your SSH key or use the Cloud Console’s SSH. Allow a few minutes for the startup script to finish installing Docker and placing the Compose project. |
94 | 130 |
|
95 | | -____ |
| 131 | +## Repository structure |
96 | 132 |
|
97 | | -### Notes |
98 | | -``` sh |
| 133 | +```text |
99 | 134 | . |
100 | | -├─ auth/ # Folder to store the API user credentials |
| 135 | +├─ auth/ # API user credentials |
101 | 136 | ├─ compose_files/ |
102 | | -│ └─ docker-compose.yaml # Docker compose configuration file |
| 137 | +│ └─ docker-compose.yaml # Docker Compose configuration |
103 | 138 | ├─ startup/ |
104 | | -│ └─ startup.sh # Startup script to install dependancies |
| 139 | +│ └─ startup.sh # Installs dependencies and seeds files |
105 | 140 | └─ terraform/ |
106 | | - ├─ network-firewall.tf # Network Firewall Rule Definitions |
107 | | - ├─ network-main.tf # Network Definitions |
108 | | - ├─ network-variables.tf # Network Terraform Variable Definitions |
109 | | - ├─ provider-main.tf # GCP Providers Definitions |
110 | | - ├─ provider-variables.tf # GCP Providers Terraform Variable Definitions |
111 | | - ├─ terraform.tfvars # Terraform Variable Definitions |
112 | | - ├─ ubnt-versions.tf # Ubuntu Version Definitions |
113 | | - ├─ ubnt-vm-main.tf # Main VM Configuration Definitions |
114 | | - ├─ ubnt-vm-output.tf # Information To Display When Provisioning Completes |
115 | | - └─ ubnt-vm-variables.tf # Main VM Terraform Variable Definitions |
| 141 | + ├─ network-firewall.tf # Firewall rule definitions |
| 142 | + ├─ network-main.tf # Network definitions |
| 143 | + ├─ network-variables.tf # Network variables |
| 144 | + ├─ provider-main.tf # GCP provider setup |
| 145 | + ├─ provider-variables.tf # Provider variables |
| 146 | + ├─ terraform.tfvars # Your variable values |
| 147 | + ├─ ubnt-versions.tf # Ubuntu version data |
| 148 | + ├─ ubnt-vm-main.tf # VM resource definitions |
| 149 | + ├─ ubnt-vm-output.tf # Outputs post-provision |
| 150 | + └─ ubnt-vm-variables.tf # VM variables |
116 | 151 | ``` |
117 | | -### Google Free Tier Information |
118 | | -I have highlighted the key information in bold below. |
119 | 152 |
|
120 | | -**Compute Engine** |
121 | | -- 1 non-preemptible **e2-micro VM** instance per month in one of the following US regions: |
| 153 | +## Google Free Tier information |
| 154 | + |
| 155 | +Key points highlighted in bold. |
| 156 | + |
| 157 | +- **Compute Engine** |
| 158 | + - 1 non-preemptible **e2-micro VM** per month in one of: |
122 | 159 | - Oregon: **us-west1** |
123 | 160 | - Iowa: us-central1 |
124 | 161 | - South Carolina: us-east1 |
125 | | -- 30 GB-months standard persistent disk** |
126 | | -- 5 GB-month snapshot storage** in the following regions: |
| 162 | + - 30 GB-months standard persistent disk |
| 163 | + - 5 GB-month snapshot storage in: |
127 | 164 | - Oregon: **us-west1** |
128 | 165 | - Iowa: us-central1 |
129 | 166 | - South Carolina: us-east1 |
130 | 167 | - Taiwan: asia-east1 |
131 | 168 | - Belgium: europe-west1 |
132 | | -- **1 GB network egress from North America to all region destinations** (excluding China and Australia) per month |
133 | | -- **Your Free Tier e2-micro instance limit is by time**, not by instance. Each month, eligible use of all of your e2-micro instance is free until you have used a number of hours equal to the total hours in the current month. Usage calculations are combined across the supported regions. |
| 169 | + - **1 GB egress from North America to all regions** per month excluding China and Australia |
| 170 | + - **Usage is time-based for e2-micro** across supported regions |
| 171 | + - **External IP address is not charged** under the free tier |
| 172 | + - GPUs and TPUs are excluded from the free tier |
| 173 | + |
| 174 | +### Network service tier screenshot |
| 175 | + |
| 176 | +By default Google sets the VM networking to Premium. Change it to **Standard** as shown here: |
134 | 177 |
|
135 | | -- **Compute Engine free tier does not charge for an external IP address.** |
| 178 | + |
136 | 179 |
|
137 | | -- GPUs and TPUs are not included in the Free Tier offer. You are always charged for GPUs and TPUs that you add to VM instances. |
| 180 | +## Troubleshooting |
138 | 181 |
|
| 182 | +- **APIs or permissions** |
| 183 | + Errors during plan or apply often indicate a missing enabled API or insufficient IAM roles on the service account. |
| 184 | +- **Startup work still in progress** |
| 185 | + Give the VM a few minutes after first boot for Docker install and file injection. Check serial console logs if needed. |
| 186 | +- **Network service tier charges** |
| 187 | + Switch the VM’s network service tier from Premium to **Standard** to stick to free-tier limits. |
139 | 188 |
|
140 | | -### Infrastructure model |
| 189 | +## Infrastructure model |
141 | 190 |
|
142 | 191 |  |
| 192 | + |
| 193 | +## Licence |
| 194 | + |
| 195 | +This project is licensed under the MIT Licence. See the [LICENCE](LICENCE) file for details. |
| 196 | + |
| 197 | +## Security |
| 198 | + |
| 199 | +If you discover a security issue, please review and follow the guidance in [SECURITY.md](SECURITY.md), or open a private security-focused issue with minimal details and request a secure contact channel. |
| 200 | + |
| 201 | +## Contributing |
| 202 | + |
| 203 | +Feel free to open issues or submit pull requests if you have suggestions or improvements. |
| 204 | +See [CONTRIBUTING.md](CONTRIBUTING.md) |
| 205 | + |
| 206 | +## Support |
| 207 | + |
| 208 | +Open an [issue](/../../issues) with as much detail as possible, including your project id, region and any Terraform output or error logs that help reproduce the problem. |
0 commit comments