apt-get install
sources.list.d/
apt-get install
againpip install -r requirements.txt
But what if we need to set up a new server?
#!/bin/bash
# Stop immediately if a command fails
set -e
# Add PostgreSQL 9.4 repo
curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
echo 'deb http://apt.postgresql.org/pub/repos/apt/ trusty-pgdg main' |
sudo tee /etc/apt/sources.list.d/postgresql.list
# Install packages
sudo apt-get update
sudo apt-get install -y python postgresql-9.4 redis-server nginx git
# Clone our repo
git clone https://github.com/omarkhan/app.git
cd app/
# Install python dependencies
sudo pip install -r requirements.txt
esac
anyone?)- hosts: all
sudo: true
tasks:
- name: Add postgres apt key
apt_key:
url: https://www.postgresql.org/media/keys/ACCC4CF8.asc
- name: Add postgres apt repo
apt_repository:
repo: deb http://apt.postgresql.org/pub/repos/apt/ trusty-pgdg main
- name: Install packages
apt: name={{ item }}
with_items: [python-pip, postgresql-9.4, redis-server, nginx, git]
- name: Clone git repo
git: repo=https://github.com/omarkhan/app.git dest=/home/user/app/
- name: Install python dependencies
pip: requirements=/home/user/app/requirements.txt
Is it really declarative?
If it's just a list of commands, why not just write the commands yourself?
TASK: [Add postgres apt repo] *************************************************
failed: [default] => {"failed": true, "parsed": false}
BECOME-SUCCESS-fmgfvvftrngmceouxmfppwportjsvwzp
Traceback (most recent call last):
File "/home/vagrant/.ansible/tmp/ansible-tmp-1449127965.5-100195964141677/apt_repository", line 2855, in <module>
main()
File "/home/vagrant/.ansible/tmp/ansible-tmp-1449127965.5-100195964141677/apt_repository", line 464, in main
cache.update()
File "/usr/lib/python2.7/dist-packages/apt/cache.py", line 440, in update
raise FetchFailedException(e)
apt.cache.FetchFailedException: W:Failed to fetch
http://apt.postgresql.org/pub/repos/apt/dists/trusty-pgdg/InRelease
Unable to find expected entry 'maindeb/binary-amd64/Packages' in Release file
(Wrong sources.list entry or malformed file)
, E:Some index files failed to download. They have been ignored, or old ones used instead.
OpenSSH_6.9p1, LibreSSL 2.1.7
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 21: Applying options for *
debug1: auto-mux: Trying existing master
debug1: mux_client_request_session: master session id: 2
Shared connection to 127.0.0.1 closed.
FATAL: all hosts have already failed -- aborting
# Install the python modules into {{ edxapp_venv_dir }}
- name : install python base-requirements
# Need to use shell rather than pip so that we can maintain the context of our
# current working directory; some requirements are pathed relative to the
# edx-platform repo. Using the pip from inside the virtual environment
# implicitly installs everything into that virtual environment.
shell: >
{{ edxapp_venv_dir }}/bin/pip install -i {{ COMMON_PYPI_MIRROR_URL }} --exists-action w -r {{ base_requirements_file }}
chdir={{ edxapp_code_dir }}
environment: "{{ edxapp_environment }}"
sudo_user: "{{ edxapp_user }}"
tags:
- install
- install:app-requirements
Ansible beats our shell script here.
Idempotent:
- name: Clone git repo
git: repo=https://github.com/omarkhan/app.git dest=/home/user/app/
Not idempotent:
git clone https://github.com/omarkhan/app.git
But it's easy enough to make our shell script idempotent:
[ -e app ] || git clone https://github.com/omarkhan/app.git
Making shell scripts idempotent isn't that hard
mkdir -p