{"id":19267491,"url":"https://github.com/lunarlogic/ansible-elixir-playbooks","last_synced_at":"2025-04-21T19:32:56.870Z","repository":{"id":66543018,"uuid":"97747364","full_name":"LunarLogic/ansible-elixir-playbooks","owner":"LunarLogic","description":"Ansible playbooks for Elixir build server and Phoenix Website. Sample app here: https://github.com/LunarLogic/phoenix_website","archived":true,"fork":false,"pushed_at":"2020-04-07T11:18:42.000Z","size":22,"stargazers_count":40,"open_issues_count":0,"forks_count":16,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-03-12T20:48:27.797Z","etag":null,"topics":["ansible","app-server","build-server","elixir-lang","mysql","phoenix","postgresql"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LunarLogic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2017-07-19T18:12:20.000Z","updated_at":"2024-11-08T11:23:27.000Z","dependencies_parsed_at":null,"dependency_job_id":"4cced86c-9efd-45b5-8eb5-88608ea9d7ac","html_url":"https://github.com/LunarLogic/ansible-elixir-playbooks","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LunarLogic%2Fansible-elixir-playbooks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LunarLogic%2Fansible-elixir-playbooks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LunarLogic%2Fansible-elixir-playbooks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LunarLogic%2Fansible-elixir-playbooks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LunarLogic","download_url":"https://codeload.github.com/LunarLogic/ansible-elixir-playbooks/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250120127,"owners_count":21378140,"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":["ansible","app-server","build-server","elixir-lang","mysql","phoenix","postgresql"],"created_at":"2024-11-09T20:12:52.280Z","updated_at":"2025-04-21T19:32:56.864Z","avatar_url":"https://github.com/LunarLogic.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ansible Elixir Playbooks\n\nThis project has ansible playbooks for:\n\n* Elixr Build Server - it has installed Erlang, Elixir and nodejs. Basically, all what is required to compile the Phoenix Framework application.\n* Phoenix Website - it is a playbook to provision server with installed PostgreSQL and configured nginx and Let's Encrypt for SSL. There is no Erlang/Elixir on this server because we will deploy there only compiled Phoenix application.\n\n__You can learn more about the project from this blog post__\nhttps://blog.lunarlogic.io/2017/phoenix-app-deployment-with-ansible-playbooks-for-elixir/\n\nHere you will find an example [Phoenix Framework app configured for deployment](https://github.com/LunarLogic/phoenix_website).\n\n## Requirements\n\n### Control machine (your computer)\n\n* Install [Ansible](https://www.ansible.com/)\n\n* Download roles:\n\n  ```shell\n  $ ansible-galaxy install -r requirements.yml\n  ```\n\n* Generate `vault_pass.txt` file into this repository. You need it to be able to encrypt/decrypt secrets.\n\n  :warning: For security reasons, the `vault_pass.txt` file should not be committed into the repository. It's ignored in `.gitignore`.\n\n  ```shell\n  $ openssl rand -base64 256 \u003e vault_pass.txt\n  ```\n\n* Generate your DB password and put output to `apps/phoenix-website/host_vars/phoenix-website.lunarlogic.io`\n\n  ```shell\n  $ ansible-vault encrypt_string --name db_password \"YOUR_DB_PASSWORD\"\n  ```\n\n### Target machine (server)\n\n* Server with [Ubuntu](https://www.ubuntu.com/) 16.04 LTS.\n\n## Public keys\n\nWe keep our public keys in [public_keys/] directory. This set of keys is uploaded to the server during each provisioning\nand overwrites the list of authorized keys, so proper people have access to the server. It is important to keep\nthe list of keys up to date.\n\nIf you don't know how to generate a key for yourself,\n[read this article](https://help.github.com/articles/connecting-to-github-with-ssh/).\n\n## App deployement\n\n### CircleCI deployment\n\nIf you want to deploy app from CI to the staging/production host then you must generate RSA keys for CircleCI.\n\n```shell\n$ ssh-keygen -t rsa -b 4096 -N \"\" -C \"circle_ci\" -f ./apps/elixir-build-server/circle_ci\n$ ssh-keygen -t rsa -b 4096 -N \"\" -C \"circle_ci\" -f ./apps/phoenix-website/circle_ci\n```\n\nAdd `circle_ci.pub` public key to your app playbook for the role `user`:\n\n```\n- role: user/0.0.1\n  username: phoenix\n  authorized_key_paths:\n    - ../../public_keys/*.pub\n    - ./circle_ci.pub # add this line\n```\n\nGo to CircleCI and find your project, open settings and find `SSH Permissions`. Click `Add an SSH key` button and paste there private key `apps/YOUR_APP_NAME/circle_ci`.\n\nNow you can remove private key `apps/YOUR_APP_NAME/circle_ci` from local machine. It should not be commited into repo!\n\nCommit into repo only public key `apps/YOUR_APP_NAME/circle_ci.pub`.\n\nYou can always generate a new fresh keys if you need it hence no reason to backup private key. You already added it to CircleCI.\n\n## Run playbooks\n\n__Warning:__ This command will provision all servers listed in inventory file for particular app `apps/app_name`.\n\n```shell\n$ ./play apps/app_name\n```\n\nIf you want to provision only specific machine do (it's useful if your app is deployed to multiple servers like staging and production):\n\n```shell\n# Warning: There must be comma and the end of the hosts list!\n$ ansible-playbook -i 'example-staging.lunarlogic.io,' apps/app_name/playbook.yml\n```\n\n## Provisioning logs\n\nYou can check when and with what git commit the host was provisioned in log file: `/var/log/provision.log` (stored on the target machine).\n\n## System users\n\nThere are 3 types of users on the server:\n\n* `root` - for provisioning\n* `admin` - user has the sudo access\n* `app_name_user` - for instance `phoenix` user for Phoenix Website application. The user has no sudo access. The application is running under this user.\n\n## Add playbook for new app\n\n* create new app directory in the `app` directory\n* in this new directory create `playbook.yml` and `inventory` files\n* in the `inventory` file put host names to provision (see [Ansible docs](http://docs.ansible.com/ansible/intro_inventory.html))\n* implement `playbook.yml`\n\n## Secrets\n\nWe store secrets in encrypted version using [Vault]. If you are adding new secrets, make sure you commit them to the repository in the encrypted form.\n\n* Encrypting single values (that can be placed inside a \"clear text\" YAML file, using the `!vault` tag):\n\n  ```shell\n  $ ansible-vault encrypt_string --name pass_to_some_service \"secret\"  # stdout encrypted string\n  ```\n\n* Encrypting whole YAML files:\n\n  ```shell\n  $ ansible-vault encrypt secret.yml   # encrypt unencrypted file\n  $ ansible-vault edit secret.yml      # edit encrypted file\n  $ ansible-vault decrypt secret.yml   # decrypt encrypted file\n  ```\n\n## Roles\n\n### Role versioning\n\nWe use roles versioning the simplest possible way, we just add version subdirectories under every role directory.\n\n```shell\nroles/role-name/role-version/ # e.g. roles/webserver/0.3.2/\n```\n\nTo create a new version just copy an existing one, bump the role version and modify it.\nPlease, respect [Semantic Versioning 2.0.0].\n\n### Community developed roles\n\nInclude the roles in [requirements.yml] and download them using the following command:\n\n```shell\n$ ansible-galaxy install -r requirements.yml\n```\n\n### SSL with Let's Encrypt\n\nYou can use `lets_encrypt` role to generate free SSL certificate thanks to https://letsencrypt.org\n\n#### Rate Limits\n\nThe main limit is Certificates per Registered Domain (20 per week).\n\nhttps://letsencrypt.org/docs/rate-limits/\n\nIf you are testing Let's Encrypt then use `staging` environment with higher limits!\n\n```\n- role: lets_encrypt/0.0.1\n  app_name: myapp\n  lets_encrypt_contact_email: admin@lunarlogic.io\n  lets_encrypt_environment: staging # you can change it to production once ready\n```\n\n#### If you want to change main domain for your certificate\n\nIf you want to change main domain for your certificate then you need to generate a new certificate.\n\nHere is example file for [Phoenix Website project with multiple domains](apps/phoenix-website/host_vars/phoenix-website.lunarlogic.io).\n\nIn order to generate a new certificate please remove first the old files generated by `lets_encrypt` role on the server:\n\n```shell\n$ rm -rf /etc/letsencrypt/accounts/*\n$ rm -rf /etc/letsencrypt/archive/*\n$ rm -rf /etc/letsencrypt/csr/*\n$ rm -rf /etc/letsencrypt/keys/*\n$ rm -rf /etc/letsencrypt/live/*\n$ rm -rf /etc/letsencrypt/renewal/*\n\n# remove the snippents that load SSL certificate\n$ rm -rf /etc/nginx/snippets/project_name\n```\n\nEnsure the nginx is running. It's required so Let's Encrypt can do request to our domain.\nProvision server again.\n\nNote: If you would like to add a new subdomain to domain list then you can just provision server and a new subdomain will be added to the certificate. You need to generate certificate from scrach only if you change the main domain (the first domain on the list of domains).\n\n\n[Vault]: http://docs.ansible.com/ansible/playbooks_vault.html\n[public_keys/]: public_keys/\n[requirements.yml]: requirements.yml\n[Semantic Versioning 2.0.0]: http://semver.org/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flunarlogic%2Fansible-elixir-playbooks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flunarlogic%2Fansible-elixir-playbooks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flunarlogic%2Fansible-elixir-playbooks/lists"}