{"id":21929186,"url":"https://github.com/achetronic/metal-cloud","last_synced_at":"2025-09-03T10:36:21.824Z","repository":{"id":46102126,"uuid":"409401512","full_name":"achetronic/metal-cloud","owner":"achetronic","description":"Terraform your VMs on bare metal","archived":false,"fork":false,"pushed_at":"2023-10-06T07:39:15.000Z","size":21642,"stargazers_count":23,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-19T19:51:01.017Z","etag":null,"topics":["kvm","libvirt","qemu","terraform"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/achetronic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-09-23T00:57:33.000Z","updated_at":"2024-09-26T15:40:40.000Z","dependencies_parsed_at":"2024-11-28T22:40:09.609Z","dependency_job_id":null,"html_url":"https://github.com/achetronic/metal-cloud","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/achetronic/metal-cloud","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/achetronic%2Fmetal-cloud","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/achetronic%2Fmetal-cloud/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/achetronic%2Fmetal-cloud/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/achetronic%2Fmetal-cloud/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/achetronic","download_url":"https://codeload.github.com/achetronic/metal-cloud/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/achetronic%2Fmetal-cloud/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273431176,"owners_count":25104487,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-03T02:00:09.631Z","response_time":76,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kvm","libvirt","qemu","terraform"],"created_at":"2024-11-28T22:29:59.068Z","updated_at":"2025-09-03T10:36:21.344Z","avatar_url":"https://github.com/achetronic.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Metal Cloud\n\n## Description\n\nTerraform module to provision VMs (and their resources, included networks) on a bare metal Linux, \nusing Terraform on top of opensource tools such as Libvirt, QEMU and KVM.\n\n## Requirements\n\n- OpenSSH `vx.x.x`\n- Terraform `v1.2.5+`\n\n## How to use\n\n\u003e All the following commands are executed from the root path of the repository\n\n### 1. Declare environment vars with the SSH connection parameters.\n\nThese can be declared as input vars inside a `.tfvars` file too\n\n```bash\nexport TF_VAR_SSH_HOST=\"XXX.XXX.XXX.XXX\"\nexport TF_VAR_SSH_USERNAME=\"yourUsername\"\nexport TF_VAR_SSH_PASSWORD=\"yourPassword\"\nexport TF_VAR_SSH_KEY_PATH=\"~/.ssh/id_ed25519\"\n ```\n\n### 2. Install some REQUIRED dependencies in local machine\n\n\u003e To build the ISOs we need to have installed `mkisofs`.\n\n```bash\nsudo apt install mkisofs\n```\n\n### 3. Execute some REQUIRED previous scripts to bootstrap the host\n\n\u003e By the moment, only recent Ubuntu versions are supported.\n\u003e Feel free to extend the OS support by pushing your code to this repository.\n\n```bash\n# Copy current SSH key into the target host\necho ${TF_VAR_SSH_PASSWORD} | ssh-copy-id -f ${TF_VAR_SSH_USERNAME}@${TF_VAR_SSH_HOST}\n\n# Give execution permissions to the helper scripts\nchmod -R +x ./scripts\n\n# Connect to the host machine by SSH and install the dependencies using passwordless authentication \n# (user with sudo privileges required) \nscp ./scripts/prepare-host-ubuntu.sh ${TF_VAR_SSH_USERNAME}@${TF_VAR_SSH_HOST}:/tmp\nssh ${TF_VAR_SSH_USERNAME}@${TF_VAR_SSH_HOST} \"sudo bash ./tmp/prepare-host-ubuntu.sh ${TF_VAR_SSH_USERNAME}\"\n```\n   \n### 4. Include the module with VMs definition in your code\n\nUsing this module is pretty simple. It's only about including the module from git and passing data structures\nwith the definition of your VMs composition\n\n```terraform\nmodule \"arm-virtual-machines\" {\n\n  source = \"git@github.com:achetronic/metal-cloud.git//terraform?ref=v1.0.0\"\n\n  # Global configuration\n  globals   = local.globals\n\n  # Configuration related to VMs directly\n  networks  = local.networks\n  instances = local.instances\n}\n```\n\n\u003e This module can be used to bootstrap VMs for any purpose, but we prepared a complete example for Kubernetes to show\n\u003e the most difficult scenario. The examples can be found inside [examples](./examples/bootstrap-kubernetes-vms) directory\n\n#### 4.1. Define some global aspects\n\n`globals` structure is there for those variables that affects general aspects of your VMs composition:\n\n```terraform\nlocals {\n  # Globals definition\n  globals = {\n\n    # Configuration for SSH connection parameters\n    ssh_connection = {\n      host     = var.SSH_HOST\n      username = var.SSH_USERNAME\n\n      password = var.SSH_PASSWORD\n      key_path = var.SSH_KEY_PATH\n      mode     = \"password\"\n    }\n\n    # Parameters related to those files used/thrown at some point on VM creation\n    io_files = {\n\n      # Path to the folder containing SSH keys authorized in all the VMs\n      external_ssh_keys_path = \"./files/input/external-ssh-keys\"\n\n      # Path to the folder where instances' autogenerated SSH keys will be stored\n      instances_ssh_keys_path = \"./files/output\"\n    }\n\n    # Parameters related to the installable OS on VMs creation\n    os = {\n\n      # Distro version to use\n      # ATM, only ubuntu is supported, so the version is something like: 23.04\n      version = \"23.04\"\n    }\n  }\n}\n```\n\n#### 4.2. Networking devices\n\nVMs are useless if they are not connected to anything. For this, you can include network \ndevices that can be invoked by VMs later. There are two type of devices supported by the module: `nat` and `macvtap`\n\nLet's see a `macvtap` configuration. \n\n\u003e Remember `macvtap` is intended to connect network interfaces from VMs, directly to some physical interface of the host\n\n```terraform\nlocals {\n  # Networks definition\n  networks = {\n\n    # Configuration for a macvtap device\n    external0 = {\n      mode = \"macvtap\"\n\n      # Host physical interface to attach\n      # the autogenerated virtual interface\n      interface = \"eth0\"\n\n      # Assignable IP address blocks in CIDR notation\n      dhcp_address_blocks = [\"192.168.2.40/28\"]\n\n      # Address to the gateway\n      gateway_address = \"192.168.2.1\"\n    }\n  }\n}\n```\n\nWhat about crafting a `NAT` device?\n\n```terraform\nlocals {\n  networks = {\n    \n    # Configuration for a NAT\n    virnat0 = {\n      mode = \"nat\"\n\n      # Assignable IP address blocks in CIDR notation\n      dhcp_address_blocks = [\"10.10.10.0/24\"]\n\n      # Address to the gateway\n      gateway_address = \"10.10.10.1\"\n    }\n  }\n}\n```\n\n#### 4.3. Creating some VMs\n\nThe goal of this module is creating VMs, so let's create one of them:\n\n```terraform\nlocals {\n\n  instances = {\n    \n    my-wonderful-vm-name = {\n      vcpu     = 2\n      memory   = 6144\n      disk     = 20000000000\n      networks = [\n        {\n          name    = \"external0\"\n          address = \"192.168.2.41/24\"\n          \n          # Yes, MAC definition is mandatory\n          mac     = \"DA:C8:20:7A:37:BF\"\n        }\n      ]\n    }\n  }\n}\n```\n\nHey, I have a different architecture or a well known machine. Ok, let's define both fields:\n\n\u003e hey, listen! At this moment, only `aarch64` and `x86_64` architectures are supported. \n\u003e However, on ARM64 environments, the boards are not so standard as in x86_64. \n\u003e Because of that, it's possible you don't find the right value for `machine` field.\n\u003e In that case, just set `virt` and some tweaks will be automatically applied under \n\u003e the hood to improve the support for them\n\n```terraform\nlocals {\n  \n  instances = {\n\n    kube-master-0 = {\n      # Using 'OrangePi 5' as hypervisor. This SBC is quite new, so there is no specific machine type for it\n      # Use generic 'virt' to apply all needed patches for this kind of environments\n      # Ref: https://www.qemu.org/docs/master/system/target-arm.html\n      arch    = \"aarch64\"\n      machine = \"virt\"\n\n      vcpu     = 2\n      memory   = 6144\n      disk     = 20000000000\n      networks = [\n        {\n          name    = \"external0\"\n          address = \"192.168.2.41/24\"\n          mac     = \"DA:C8:20:7A:37:BF\"\n        }\n      ]\n    }\n  }\n}\n```\n   \n### 5. Create your VMs.\n\nOnce you have defined them, just push the red button and create the chaos\n\n```bash\nterraform init \u0026\u0026 terraform apply\n```\n\n## Security considerations\n\nFor security reasons, a random password and an SSH key-pair are auto-generated per instance.\nThis means that each instance has a different password and a different authorized SSH key.\nThey are stored in the `tfstate` so execute a `terraform state list` and then show the resource you need\nby using `terraform state show ···`\n\nWhen the `terraform apply` is complete, all the SSH private key files are exported in order\nto allow you to access or manage them.\n\nThere is a special directory located in the path defined with value `globals.io_files.external_ssh_keys_path`.\nThis was created for the special case that several well-known SSH keys must be authorized\nin all the instances at the same time.\nThis can be risky and must be used under your own responsibility. If you need it, place some `.pub` key files\ninside, and they will be directly configured and authorized in all the instances.\n\n## How to collaborate\n\nOf course, I'm open to external collaborations for this project. For doing it you must:\n\n* Fork the repository\n* Make your changes to the code\n* Open a PR. \n\nAs an advise, the code will be reviewed and tested (always)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fachetronic%2Fmetal-cloud","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fachetronic%2Fmetal-cloud","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fachetronic%2Fmetal-cloud/lists"}