For now a space for random thoughts and notes. TODO: Refactor once things have solidified.
Prefer args-based task definitions over string-based.
- name: create redis symlink sudo: yes file: src=/usr/conda/bin/redis-server dest=/usr/local/bin/redis-server state=link
- name: create redis symlink
sudo: yes
file:
src: /usr/conda/bin/redis-server
dest: /usr/local/bin/redis-server
state: link
Use a name directive for every task.
Use sudo on a task-by-task basis. Never apply "sudo: yes" to a whole play, role, or include statement.
Never use command or shell tasks when an ansible module exists that provides the desired behavior. Prefer command over shell.
Individual directories for the application are created as needed within the FHS.
/etc/nginx.conf /etc/nginx.d/ /var/log/nginx.log /var/run/nginx.pid
/etc/nginx/nginx.conf /etc/nginx/conf.d/ /var/log/nginx/nginx.log /var/run/nginx/nginx.pid
/etc/supervisord.conf /etc/supervisord.d/
/etc/supervisord/supervisord.conf /etc/supervisord/conf.d/
A dedicated user is created for each system process. UIDs and GIDs are kept consistent across all environments. The source of truth for UID and GID information is https://bitbucket.org/23andme/ansible/src/develop/pb/roles/local-user/defaults/main.yml.
The shell for the application user is /sbin/nologin.
Application user write permissions are strictly limited to:
/usr/home/$USER//var/run/$USER//tmp/
Note that /var/log/$USER/ is neither readable nor writable by the application user. Instead, the application should simply write log information to stdout and stderr. Then supervisord will collect and write logs appropriately.
The template file in the template directory is named exactly what it will be on the remote (i.e. no .j2 extension). The dest parameter of the template task does not specify the file name–only the src parameter does.
- name: create gunicorn config for you app
template:
src: gunicorn.py
dest: /etc/opt/you/
We override the default convention when the destination is a ".d" directory. Here, the file name in the template directory should indicate which .d directory it'll be dropped into. The dest parameter then specifies the file name and removes the extraneous information.
- name: create nginx config for you app
template:
src: nginx-you.conf
dest: /etc/nginx/conf.d/you.conf
The system time zone is set to America/Los_Angeles.
OS-agnostic package management is preferred to decouple package infrastructure from the variety of base OSes. We use conda. A base conda installation can provide any necessary application-specific runtimes (python, ruby, java, node, etc). Language-native package installers are made available (pip, gem, npm, etc.), but their use has some limitations to be aware of for production environments. #1 Do not assume production environments have access to the outside internet. A dedicated repo/mirror/etc will need to be provisioned within the production environment. #2 Do not assume compilers (e.g. gcc, g++) exist. Language-native installers often invoke a compiler to install a package, and here, prefer building a conda package instead.
Supervisor is the init system used for all conda-installed and application processes. Like Conda for package management, Supervisor abstracts and unifies process startup and monitoring from any OS-specific system (e.g. SysVinit, systemd, Upstart).
- Don't count on
$PATHor$PWDbeing set properly. Use full paths where possible. - Don't count on defaults being set, being set correctly, or not changing out from underneath you. Make settings explicit, even if they're indeed default.
- Prefix ansible variable and environment variable names with the app name that makes the most sense. Examples:
YOU_STATIC_HOSTYOU_REDIS_CACHE_URLPRODUCT_DB_REL
- All keys and other files meant to be immutable should be permissioned
0400or0444as appropriate. - If a variable name ends in
_URL, the url protocol should be prepended.- Example:
https://api.23andme.com
- Example:
- If the variable name ends in
_HOST, it refers to a full-qualified domain name for a machine, and thus should not include a protocol.- Example:
api.23andme.com
- Example:
| tag | use case / description |
|---|---|
| update | attached to tasks necessary to update application code and packages from an old deploy to a new deploy |
| os_update | attached to tasks like `yum update` and `apt-get upgrade` for explicit exclusion of inclusion |