[TOC]
- Python 3: MacOs requires python 3.9
- Pip
- Virtualenv
-
Activate the python venv in order to run ansible.
$ cd ansible $ bin/activate
-
Edit the Ansible inventory file and primero variables. Refer to the Deploy section for more info. Create a copy of the template file and modify to get started quickly.
(venv) $ cp inventory/inventory.yml.temnplate inventory/inventory.yml (venv) $ vim inventory/inventory.yml
The inventory file should include the Primero server you want to deploy to. You can refer to this sample for further documentation.
Note: If you want to use SOLR, ensure that
SOLR_ENABLED: 'true'
is set in the inventory file. To disable SOLR, set it tofalse
. -
Create the
secrets.yml
. Refer to the Deploy section for more info.$ cd ansible $ vim secrets.yml
The
secrets.yml
file will contain secrets necessary to run Primero. To generate a secure random secret you can use the commandLC_ALL=C < /dev/urandom tr -dc '_A-Z-a-z-0-9' | head -c"${1:-32}"
. If you are deploying Primero or a custom Primero configuration from a private Git repository, you will need to include the private SSH deployment key. If you are using a public Primero configuration,you may leave the variablessh_private_key
out of the secrets.yml file.--- primero_secret_key_base: 'generated_secret' primero_message_secret: 'generated_secret' postgres_password: 'generated_secret' devise_secret_key: 'generated_secret' ssh_private_key: | -----BEGIN RSA PRIVATE KEY----- klkdl;fk;lskdflkds;kf;kdsl;afkldsakf;kasd;f afdnfdsnfjkndsfdsjkfjkdsjkfjdskljflajdfjdsl -----END RSA PRIVATE KEY-----
-
Run the bootstrap playbook in order to install the basic system requirements. This can be run once.
(venv) $ ansible-playbook bootstrap.yml
-
Install Docker using the
install-docker.yml
playbook. This can be run once.(venv) $ ansible-playbook install-docker.yml
-
Stage secrets and instance specific environment variables. This can be run once, or whenever you are rotating secrets or changing other environment variables.
(venv) $ ansible-playbook application-primero.yml --tags "local-env" -e @secrets.yml
-
Deploy the Primero application. There are many options here. You can build, configure, and start the containers. This is done using Ansible tags. If you run this playbook with no
--tags
then none these options will run by default.For building locally use tag
build
. This is optional, and should not be used on Production environments. If you do not have locally built images, they will be pulled from Dockerhub.(venv) $ ansible-playbook application-primero.yml --tags "build"
Configure Primero and apply the database schema using tag
configure
. Before running, if you would like to run primero with the default seeds remove and setprimero_configuration_path
to '' andRUN_DEFAULT_PRIMERO_SEEDS
to 'true' in your inventory file under environment_variables.(venv) $ ansible-playbook application-primero.yml --tags "configure"
To (re)start the Primero service use tag
start
.(venv) $ ansible-playbook application-primero.yml --tags "start"
You can also provide a combination. For example, to build, configure, deploy, and run the latest code:
(venv) $ ansible-playbook application-primero.yml --tags build,configure,start
-
Don't forget that you now have a
secrets.yml
file! Make sure that it's safely stored. Secret management is out of scope for the core Primero application devops. -
If using Certbot run the
certbot.yml
playbook. Sometimes Certbot won't work right away when the application is first deployed. If Certbot does fail, wait a couple minutes and then just run thecertbot.yml
playbook again.(venv) $ ansible-playbook certbot.yml
As a convenience for Bash users, there is an activate
script which will setup the virtualenv, activate it in a subshell, add the bin
directory to the PATH
, and set the ANSIBLE_CONFIG
environment variable.
$ cd ansible
$ bin/activate
You can deactivate this subshell virtualenv by exiting the shell.
(venv) $ exit
The server infrastructure is managed by Ansible. The general form of an Ansible command is as follows:
(virtualenv) $ cd ansible
(virtualenv) $ ansible-playbook -i <inventory> <playbook> [-l <server>]
Each ansible-playbook
command will require an inventory and a playbook.
The inventory is the set of hosts managed by Ansible.
The playbook is the "script" that is run against the hosts in the inventory.
When new machines are added to the inventory they must first be provisioned with the "boostrap" playbook. Refer to the Bootstrap section for more details.
Unless the -l <server>
parameter is used, the playbook will be applied to all servers in the inventory.
bootstrap.yml : This playbook is used to install the basic system requirements on servers in the inventory. See the Bootstrap section for more details.
install-docker.yml : This playbook will install new users to map to docker containers, install docker, create a users.env file, and synchronize the primero app files to the host machine
application-primero.yml : Deploy and run (and optionally, first build) the Primero Docker containers.
certbot.yml : Configure Certbot to run on the Primero site.
In order to deploy primero using Ansible you will first need to create an ansible inventory.yml
file located at ansible/inventory/inventory.yml
.
Below is example of what the file should look like. There is also a sample template file provided in the repo, ansible/inventory/inventory.yml.template
.
Note: You can enable or disable the SOLR service by setting the
SOLR_ENABLED
variable to true or false in your inventory file.
---
all:
hosts:
primero.example.com:
ansible_user: 'ubuntu'
primero_host: 'primero.example.com'
certbot_domain:
- '{{ primero_host }}'
certbot_email: '[email protected]'
primero_repo_branch: 'main'
build_docker_tag: ''
build_docker_container_registry: ''
primero_tag: 'latest'
lets_encrypt_domain: '{{ primero_host }}'
lets_encrypt_email: '{{ certbot_email }}'
use_lets_encrypt: 'true'
nginx_ssl_cert_path: '/etc/letsencrypt/live/primero/fullchain.pem'
nginx_ssl_key_path: '/etc/letsencrypt/live/primero/privkey.pem'
# If you want to seed from a private configuration repo
primero_configuration_repo: '[email protected]:quoin/primero-x-configuration.git'
primero_configuration_repo_branch: 'main'
primero_configuration_path: 'directory/of/config/loader/script.rb'
environment_variables
RUN_DEFAULT_PRIMERO_SEEDS: 'false'
SOLR_ENABLED: 'true'
All these variables are required with the exception of certbot_domain
and certbot_email
. These certbot variables are required only when using certbot.
The build_docker_tag
and build_docker_container_registry
can be left as ''
, which default to latest. If you require a specific build_docker_tag
and/or build_docker_container_registry
,
then enter those values for these variables.
The bootstrap process installs the basic system requirements onto the inventory. It only needs to be run once against any piece of inventory (although it is safe, but unnecessary, to run again.)
-
Run the Ansible "bootstrap" playbook.
If the inventory is configured to use SSH keys for authentication you do not need to specify any special arguments to the
ansible-playbook
command. This is the default for cloud images.(virtualenv) $ cd ansible (virtualenv) $ ansible-playbook -i <inventory> bootstrap.yml
If the inventory is configured to use password use password authentication you must pass the
-k
and-K
arguments to theansible-playbook
command so that Ansible will prompt for passwords. (Disable password authentication in favor of SSH keys as soon as possible.)(virtualenv) $ cd ansible (virtualenv) $ ansible-playbook -i <inventory> bootstrap.yml -k -K
You may also wish to limit the inventory against which the playbook runs by using
ansible-playbook
's-l
argument.The bootstrap playbook disables SSH host key checking due to an unresolved bug in Ansible (#25068).
Solving secret management is left up to the implementing team.
One naive way, is to create an environment file per server and keep it separate from your inventory file. DO NOT CHECK THIS FILE INTO SOURCE CONTROL! The developer can make a file called secrets.yml
in the ansible
directory.
$ cd ansible
$ vim secrets.yml
The secrets.yml
file will contain secrets for Primero. The following variables are required in the is file. The secrets in this file require a secure random number. To generate, can use the command
LC_ALL=C < /dev/urandom tr -dc '_A-Z-a-z-0-9' | head -c"${1:-32}"
You also have the option of creating a variable for a private ssh key in order to clone configuration files from a private repo. If you will not be including the private ssh
key just leave the variable ssh_private_key
out of the secrets.yml file.
---
primero_secret_key_base: 'generated_secret'
primero_message_secret: 'generated_secret'
postgres_password: 'generated_secret'
devise_secret_key: 'generated_secret'
secret_environment_variables:
SMTP_USER: 'secret'
SMTP_PASSWORD: 'secret'
PRIMERO_WEBPUSH_VAPID_PRIVATE: 'secret'
PRIMERO_WEBPUSH_VAPID_PUBLIC: 'secret'
ssh_private_key: |
-----BEGIN RSA PRIVATE KEY-----
klkdl;fk;lskdflkds;kf;kdsl;afkldsakf;kasd;f
afdnfdsnfjkndsfdsjkfjkdsjkfjdskljflajdfjdsl
-----END RSA PRIVATE KEY-----
nginx_ssl_key: |
-----BEGIN PRIVATE KEY-----
klkdl;fk;lskdflkds;kf;kdsl;afkldsakf;kasd;f
afdnfdsnfjkndsfdsjkfjkdsjkfjdskljflajdfjdsl
-----END PRIVATE KEY-----
nginx_ssl_cert: |
-----BEGIN CERTIFICATE-----
klkdl;fk;lskdflkds;kf;kdsl;afkldsakf;kasd;f
afdnfdsnfjkndsfdsjkfjkdsjkfjdskljflajdfjdsl
-----END CERTIFICATE-----
The variables in the inventory.yml
along with the secrets.yml
will also be used to make the local.env
file for the dokcer-compose files.
The optional dictionary secret_environment_variables
can contain key/value pairs of secret environment variables. It can be used in conjuunction with the optional environment_variables
dictionary in the inventory file, and will override those values. A good use of this dictionary is to specify SMTP settings. Here we can add PRIMERO_WEBPUSH_VAPID_PRIVATE and PRIMERO_WEBPUSH_VAPID_PUBLIC, these keys together with PRIMERO_WEBPUSH allow us to enable webpush notifications. To generate VAPID keys follow the instruction in README.md file. if we are enabling Webpush on an existing server, we must modify the inventory.yml
and secrets.yml
with the 3 variables, then re-execute the ansible command local-env
In order to enable configuration promotion between two servers handled by ansible, you have to set some environment variables on the demo server, the one responsible to handle and send the configuration to the production server.
PRIMERO_SANDBOX_UI: 'true'
PRIMERO_PROMOTE_CONFIG_PROD_TLS: 'true'
PRIMERO_PROMOTE_CONFIG_PROD_PORT: '443'
PRIMERO_PROMOTE_CONFIG_PROD_HOST: 'example.production.org'
PRIMERO_PROMOTE_CONFIG_PROD_BASIC_AUTH: 'configuration_promotion:strongPassword1!'
-
PRIMERO_SANDBOX_UI
Show the UI in Sandbox mode, this enable the config promotion option. -
PRIMERO_PROMOTE_CONFIG_PROD_TLS
andPRIMERO_PROMOTE_CONFIG_PROD_PORT
variables required to stablish the connection between the current implementation and the production site -
PRIMERO_PROMOTE_CONFIG_PROD_HOST
Target implementation, where the configuration will be applied -
PRIMERO_PROMOTE_CONFIG_PROD_BASIC_AUTH
This is a combination(separated by:
) between a user production and its password. The exact environment variable, the user and the password needs to exist on the production implementation. To generate a strong password using:LC_ALL=C < /dev/urandom tr -dc '_A-Z-a-z-0-9' | head -c"${1:-32}"
To use an external cert on a primero deploy you need to add on the secret.yml
file the follow entries:
nginx_ssl_key
nginx_ssl_cert
Also set on your inventory file the follow entries:
use_lets_encrypt: 'false'
use_external_certs: 'true'
nginx_ssl_cert_path: '/external-certs/primero.crt'
nginx_ssl_key_path: '/external-certs/primero.key'
Then recreate the local env file:
(venv) $ ansible-playbook application-primero.yml --tags "local-env" -e @secrets.yml
Copy the certs to the host using:
(venv) $ ansible-playbook external-certs.yml -e @secrets.yml
Finally restart the docker containers:
(venv) $ ansible-playbook application-primero.yml --tags start
If nginx is already using external certs, to update the certs follow the next steps:
- Copy over target server in the
/srv/external-certs/
folder, the new key and cert. - Replace the existing key an cert with the new files.
- Restart nginx docker container:
sudo docker restart primero_nginx_1
If you change your hostname and you want to update your letsencrypt certificate, you need to:
- Update your
primero_host
on the inventory file. - Update your environment variables running
(venv) $ ansible-playbook application-primero.yml --tags "local-env" -e @secrets.yml
- Run the certbot playbook
(venv) $ ansible-playbook certbot.yml
- Restart all the containers
(venv) $ ansible-playbook application-primero.yml --tags "start"
Database migrations are only present in major and minor version updates (2.7, 2.8) never in patch versions (v2.7.1).
Make sure to execute the migrations every time you upgrade Primero.
To execute the migrations, run:
(venv) $ ansible-playbook application-primero.yml --tags "configure,start"
This command will execute migrations and also attempt to run the configuration indicated in primero_configuration_repo_branch
.
Please be cautious as this could overwrite the current system configuration. if you want to prevent a configuration from being applied, make sure to set the configuration version that is applied to the system.
Also in your inventory file you can add RUN_DEFAULT_PRIMERO_SEEDS: 'false'
to the variables and remove primero_configuration_path
keys to prevent that the configuration will not be applied