{"id":16042522,"url":"https://github.com/nylen/infrastructure-template","last_synced_at":"2026-01-21T17:33:26.894Z","repository":{"id":42650908,"uuid":"217769001","full_name":"nylen/infrastructure-template","owner":"nylen","description":"Template for creating and managing Devuan servers on DigitalOcean using Terraform + Ansible.","archived":false,"fork":false,"pushed_at":"2023-01-24T23:19:19.000Z","size":32,"stargazers_count":1,"open_issues_count":5,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-13T17:54:42.695Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","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/nylen.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}},"created_at":"2019-10-26T21:03:34.000Z","updated_at":"2020-08-08T04:27:45.000Z","dependencies_parsed_at":"2023-02-14T02:30:42.533Z","dependency_job_id":null,"html_url":"https://github.com/nylen/infrastructure-template","commit_stats":null,"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nylen%2Finfrastructure-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nylen%2Finfrastructure-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nylen%2Finfrastructure-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nylen%2Finfrastructure-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nylen","download_url":"https://codeload.github.com/nylen/infrastructure-template/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247678382,"owners_count":20977841,"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","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":[],"created_at":"2024-10-09T00:02:27.799Z","updated_at":"2026-01-21T17:33:26.841Z","avatar_url":"https://github.com/nylen.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ProjectName Infrastructure\n\n## What is this?\n\nThis repository controls the names and configurations of the \"ProjectName\"\nservers hosted on DigitalOcean.\n\n(This repository is a _template_ for your own project. You can download/clone\nthe files and use it as-is, or you can run the `scripts/_convert.sh` script to\nrename all the files from \"project name\" to a name you specify.)\n\nServers are currently based on the Debian 10 image, and they are converted to\n[Devuan](https://devuan.org/)\n(a fork of Debian without systemd) on first boot.  The conversion is done using\na cloudinit script that is associated with the server when it is created by\n[Terraform](https://www.terraform.io/).\n\nServer _configuration_, including installed packages and applcations, is\nmanaged by\n[Ansible](https://www.ansible.com/).\n\nThere are also a number of supporting scripts included for tasks such as\nlisting all available servers and updating your SSH config file to point to\nthem correctly.  These scripts are documented below.\n\n## Why this approach?\n\nGenerally, like any kind of\n[DevOps](https://en.wikipedia.org/wiki/DevOps)\ntooling, this approach to managing servers aims to **avoid manual processes**.\nAs software projects and their infrastructure grow, more servers are needed.\nSetting them up manually takes a while and increases the chance of problems,\nwhich could be basic configuration errors or \"drift\" in which different\nservers' configurations diverge over time. This \"drift\" has a tendency to cause\nunexpected problems later on.\n\n**Automating everything** related to server configuration also makes it\npossible to solve a number of related problems more easily, such as **regularly\nrebuilding your servers** and **automatic scaling**.  This template does not\nsolve these problems, rather it aims to serve as a workable base for\nimplementing your own rebuild/scaling strategies later on.\n\nMore specifically, this tempate uses\n[Terraform](https://www.terraform.io/)\nand\n[Ansible](https://www.ansible.com/)\nto manage different steps of the server configuration process.\n\nThe _input_ for each of these tools is a set of code (text files) that\ndescribes the desired server configuration, and the scripts and documentation\nin this repository are designed to help you _execute_ this code, with the end\nresult of creating and updating your servers according to your configuration.\n\nTerraform is\n[designed to create and destroy servers](https://www.terraform.io/intro/vs/chef-puppet.html)\nwhile configuration management tools like Ansible are designed to manage server\nconfiguration.\n\nTerraform was chosen because of its approach of inspecting _existing_ resources\nand _desired_ resources, and then planning and executing the changes to turn\nthe _existing_ state into the _desired_ state.  It always shows you exactly\nwhat it's going to do before it does it, which is a big benefit when performing\npotentially destructive actions.\n\nAnsible was chosen because of its\n[design goals](https://en.wikipedia.org/wiki/Ansible_%28software%29#Design_goals)\nand because it is easy to install into a project without affecting the rest of\nthe computer.\n\nTo bridge these two tools (i.e. feed a list of Terraform-created servers into\nAnsible so that it can manage their configuration), an approach similar to\n[this article](https://nicholasbering.ca/tools/2018/01/08/introducing-terraform-provider-ansible/)\nis used, implemented as a local script stored in this repository\n(`terraform-inventory.py`).\n\n## Prerequisites\n\n- Solid understanding of how to use the Linux command line, including SSH with\n  private/public key authentication.\n- Bonus: familiarity with using `git` to manage sets of code/text files.\n- `terraform` v0.11 installed and available in your `$PATH`.  See the\n  \"Compatibility\" section below for more details.\n- Python 2.7 or higher, or 3.5 or higher, including `pip` and `virtualenv`.\n\n## How it works\n\n### 0. Modify the project template for your project name\n\nRun `scripts/_convert.sh` to change the template files from \"Project Name\" to your project. Your project name should be a single word in CamelCase.  For example:\n\n```sh\nscripts/_convert.sh MyAwesomeProduct\n```\n\nThen you will probably want to `git add` and `git commit` the resulting changes.\n\nAs you make further changes, you should update this Readme so that it serves as\nthe documentation for your project's servers, and continue using `git add` and\n`git commit` to track the history of the project.\n\nAvoid storing _passwords_, _API keys_ and other _secrets_ in this repository!\nThese should be managed separately in a way that allows for _rotation_ and\n_deletion_ as needed (currently outside the scope of this template).\n\n### 1. Create servers\n\nThis part of the process uses\n[terraform](https://www.terraform.io/)\nto create new droplets (servers) on DigitalOcean.\n\nThe following steps need to be done once per computer:\n\n- [Install terraform](https://www.terraform.io/downloads.html)\n  on your local machine.  It is just a single executable file that you can put\n  anywhere in your `$PATH` directory.  **Note** we are not using the latest\n  version of Terraform, see the \"Compatibility\" section below for details!\n\n- Add some **public SSH keys** (including your own) to a file named\n  `keys/ssh_authorized_keys_ROOT.txt` under this directory.  There should be\n  one key per line, and one key for each member of your infrastructure team;\n  ask someone if you don't have their key or you aren't sure what this file\n  should look like.  These are the keys that will be added to any new servers\n  you create.\n\n- Grab a Cloudflare API key from\n  [your profile page](https://dash.cloudflare.com/profile)\n  and create a file in this directory named `cloudflare.tf`:\n\n```\nprovider \"cloudflare\" {\n    email = \"you@example.com\"\n    token = \"your-api-key\"\n    version = \"~\u003e 1.12\"\n}\n```\n\n(If you don't want to use Cloudflare for DNS, then you should remove or comment\nout all the sections in `modules/digitalocean-devuan/main.tf` that have to do\nwith `cloudflare_record` resources.  It will then be your responsibility to set\nthe DNS records for your server(s) correctly.  You probably want to do this\n**after** running `terraform` and **before** running `ansible`.)\n\n- Grab a DigitalOcean API key from\n  [the Applications \u0026 API page](https://cloud.digitalocean.com/account/api/tokens)\n  and create a file in this directory named `digitalocean.tf`:\n\n```\nprovider \"digitalocean\" {\n    token = \"your-api-key\"\n    version = \"~\u003e 1.9\"\n}\n```\n\n- Get a copy of the latest `terraform.tfstate` file from someone on the\n  infrastructure team.\n\n- Change to this directory and run `terraform init`.\n\n- Verify that Terraform would not make any changes to the current state by\n  running `terraform plan`.  The result of this command should be **No changes.\n  Infrastructure is up-to-date.**  If you see otherwise, it probably means you\n  have an **outdated state file** and you need to **contact someone on the\n  infrastructure team** before making any changes.\n\n#### To add a new server\n\n- Add a new `module \"projectname_SERVERNAME\"` block to `projectname.tf`\n  (note, using an underscore instead of a dot here because Terraform module\n  names don't allow dots)\n- Run `terraform get` to refresh the module structure\n- Run `terraform plan` and inspect the execution plan\n- † If everything looks ok, run `terraform apply`\n\n† **Be very careful that no existing servers** (\"resources\" in Terraform\nterminology) **will be deleted by your execution plan.**  With the way our\nservers are currently set up, this **will** cause data loss!\n\nIf you see `(new resource required)` or `(forces new resource)` in the output\nof `terraform plan` or `terraform apply`, **STOP**, press `Ctrl+C` to abort\nwhat you were doing, and ask for help!\n\n#### Compatibility\n\nThis process has been tested with the following `terraform` and plugin\nversions:\n\n```\n$ terraform --version\nTerraform v0.11.14\n+ provider.cloudflare v1.12.0\n+ provider.digitalocean v1.9.1\n+ provider.template v2.1.0\n```\n\nIn particular `terraform` 0.12 is a major upgrade, and our configuration files\nwill need some re-working before we can change to that version.\n\n### 2. Configure servers\n\nThis part of the process uses\n[ansible](https://www.ansible.com/)\nto configure existing servers and change their configuration.\n\nIn addition to completing the `terraform` installation steps from above, you'll\nneed to have `pip` and `virtualenv` installed.  Here is a general\n[guide](https://packaging.python.org/guides/installing-using-pip-and-virtualenv/)\nto installing `pip` (a Python package manager) and using it to install\n`virtualenv`.\n\nOnce you're in the directory for this repository, run the commands to\ninitialize and activate a Python virtual environment:\n\n```sh\nvirtualenv .\n. bin/activate\npip install\n```\n\n`virtualenv .` and `pip install` only need to be run once per computer, and `.\nbin/activate` needs to be run with every new shell session where you're using\nthis directory.\n\n#### To update the configuration of existing servers\n\nRun `scripts/run-ansible-playbooks.sh`.\n\nCurrently this will update all the Devuan servers as follows:\n\n- `apt-get update` and `apt-get upgrade`\n- Install some additional packages common to all servers (usually these are\n  packages that were added after the initial server configuration was written)\n\n## Helper scripts\n\n### `scripts/find-ssh-key.sh`\n\nAfter you have set up a `keys/ssh_authorized_keys_ROOT.txt` file with the\npublic keys of the infrastructure team, this script will look at the keys\nloaded in your `ssh-agent` and find the one that matches.\n\nIf it's not working, run `ssh-add ~/.ssh/my-projectname-key` and type the\npassphrase for your key.\n\n### `scripts/list-servers.sh`\n\nLists the servers known by `terraform state pull` and their public IP\naddresses.\n\nThis will only work after running `terraform init` as described above.\n\n### `scripts/run-ansible-playbooks.sh`\n\nUpdates the configuration of existing servers (pulled from the Terraform\ninventory) using Ansible.\n\n### `scripts/ssh-config.sh`\n\nGenerates a configuration block for your `~/.ssh/config` file that will make\ncommands like the following work as expected:\n\n```\nssh projectname.www_wwwfiles\n```\n\nThe convention is `projectname.SERVERNAME_USERNAME`.  To generate a config\nblock for the `root` user instead, do `scripts/ssh-config.sh ROOT` and then run\ne.g. `ssh projectname.static_ROOT`.\n\n### `scripts/update-ssh-config.sh`\n\nUpdates your `~/.ssh/config` to make commands like\n`ssh projectname.www_wwwfiles`\nwork as expected.  Like `scripts/ssh-config.sh`, it also accepts `ROOT`.\n\n### `scripts/update-everything.sh`\n\nRuns both Terraform and Ansible.  One-stop command for setting up a new server\nafter including its details in the configuration files.\n\nNote, even though this script is a single command, it is not fully automatic\nfrom start to finish.  Terraform will prompt you to apply any changes, and\nAnsible will prompt you to accept SSH host keys for new servers.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnylen%2Finfrastructure-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnylen%2Finfrastructure-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnylen%2Finfrastructure-template/lists"}