Skip to content

Instantly share code, notes, and snippets.

@teyc
Last active October 12, 2019 00:41
Show Gist options
  • Select an option

  • Save teyc/236c44870453e1a2890aef8cb0264f80 to your computer and use it in GitHub Desktop.

Select an option

Save teyc/236c44870453e1a2890aef8cb0264f80 to your computer and use it in GitHub Desktop.
Ansible - Setting up new website
# OK profile for Ansible
eval $(ssh-agent)
ansible-playbook git-install.yml --extra-vars="hostname=webservers" -K
ansible-playbook nginx-install.yml --extra-vars="hostname=webservers" -K
# deployment
ansible-playbook lemp-install.yml --extra-vars="hostname=drsweeteng.com domain=drsweeteng.com ansible_user=root"
ansible-playbook main-install.yml --extra-vars="hostname=drsweeteng.com domain=drsweeteng.com ansible_user=root"
ansible-playbook add-domain-git.yml --extra-vars="hostname=drsweeteng.com domain=drsweeteng.com ansible_user=root"

Setting up new website with PHP, Ansible, Git deploy and A+ with ssllabs.com

At the end of this you should have

  1. mosh shell - drop-in replacement for ssh that is more responsive

  2. authorized_keys for root

    • includes a breakglass key
  3. LEMP server at

  4. git@domain.com:/srv/git/domain.com.git

With Ansible

  1. Ansible /etc/ansible/hosts

    [webservers]
    <Your.Ip.Addr.ess>
    
  2. Update DNS A or CNAME records

    domain.com
    dev.domain.com
    
  3. Run master playbook

    ansible-playbook main-install.yml --extra-vars="hostname=<Your.Ip.Addr.ess> domain=domain.com ansible_user=root"
    

Manually

  1. ssh

    1. authorized_keys (chui, breakglass)

    2. allow users

  2. nginx

    1. http:// redirect https://domain.com

    2. http://www redirect https://domain.com

    3. https://domain.com

    4. document_root /var/www/domain.com/public

  3. git

    1. git user

      https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server
      
      adduser git
      mkdir /home/git/.ssh
      # TODO authorized_keys
      
    2. git bare repo

    3. git hook

  4. mail redirect

  5. back up

Notes for future work

encrypting and decrypting passwords

echo "jHOjdlhh39" | openssl enc -base64 -aes-128-cbc -k asdf | openssl enc -d -base64 -aes-128-cbc -k asdf

- hosts: "{{ hostname }}"
gather_facts: False
become: true
become_user: root
become_method: sudo
vars:
- packages: ["git"]
git_base_dir: "/srv/git"
project_dir: "{{ domain }}.git"
web_dir: "/var/www/{{ domain }}/public"
tasks:
- name: Installing {{ packages }} on {{ hostname }}
apt:
name: "{{ packages }}"
state: present
#with_items: "{{ packages }}"
- name: Create or change git's password
user:
name: "git"
shell: "/usr/bin/git-shell"
groups: "www-data"
create_home: yes
update_password: on_create
- name: Set authorized_keys for git user
authorized_key:
user: git
state: present
key: '{{ item }}'
with_file:
- '/mnt/c/users/teyc/.ssh/george.pub'
- '/mnt/c/users/teyc/.ssh/id_ed25519.pub'
- '/mnt/c/users/teyc/.ssh/letsdobusiness_breakglass.pub'
- name: Create a base git directory
file:
path: "{{ git_base_dir }}"
state: directory
- name: Create a bare repository at {{ project_dir }}
command: git init --bare {{ project_dir }}
args:
creates: "{{ project_dir }}"
chdir: "{{ git_base_dir }}"
- name: Set the permissions on {{ git_base_dir }}/{{ project_dir }}
file:
path: "{{ git_base_dir }}/{{ project_dir }}"
state: directory
mode: 0755
owner: git
group: git
recurse: True
- name: Create post-receive hook on {{ git_base_dir }}/{{ project_dir }}
template:
src: "post-receive.j2"
dest: "{{ git_base_dir }}/{{ project_dir }}/hooks/post-receive"
owner: git
group: git
mode: 0744
- name: Set post-receive hook on {{ git_base_dir }}/{{ project_dir }}
blockinfile:
path: "{{ git_base_dir }}/{{ project_dir }}/hooks/post-receive"
create: yes
block: |
if [[ "master" == "$branch" ]] || [[ "dev" == "$branch" ]]
then
domain_webdir="/var/www/{{ domain }}"
GIT_WORK_TREE=$domain_webdir git checkout -f "$branch"
# if public isn't a symlink remove it
if [ ! -L $domain_webdir/public ]
then rm -rf $domain_webdir/public
fi
ln -s $domain_webdir/app $domain_webdir/public
cp $domain_webdir/app/lib/global_variables.php.sample $domain_webdir/app/lib/global_variables.php
fi
# vim: set sw=2 : ts=2 :
- hosts: "{{ hostname }}"
become_user: root
become_method: sudo
vars:
domain: drsweeteng.com
domains: ["{{ domain }}", "dev.{{ domain }}"]
packages: ["python-certbot-nginx", "nginx", "php-fpm"]
tasks:
- name: Installing nginx on {{ packages }}
apt:
name: "{{ packages }}"
state: present
- name: Use www-data user for nginx
lineinfile:
dest: /etc/nginx/nginx.conf
regexp: "^user\\s+.+;$"
line: "user www-data;"
- name: Enable Perfect Forward Secrecy for nginx
openssl_dhparam:
path: /etc/ssl/certs/dhparam.pem
- name: Create php-fpm groups for {{ domains }}
loop: "{{ domains }}"
loop_control:
loop_var: "domain"
group:
name: "{{ domain }}"
system: yes
- name: Add www-data to php-fpm groups {{ domains }}
user:
name: www-data
group: www-data
append: yes
groups: "{{ domains }}"
- name: Create php-fpm users for {{ domains }}
loop: "{{ domains }}"
loop_control:
loop_var: "domain"
user:
name: "{{ domain }}"
group: "{{ domain }}"
system: yes
create_home: no
- name: Ensure www directory exists at /var/www/{{ domain }}
file:
path: "{{ item.directory }}"
state: directory
owner: "{{ item.owner }}"
group: "{{ item.owner }}"
mode: u=rwx,g=rwx,o=rx
loop:
- directory: "/var/www/{{ domain }}"
owner: "{{ domain }}"
- directory: "/var/www/dev.{{ domain }}"
owner: "dev.{{ domain }}"
- name: Create php configuration file for {{ domains }}
loop: "{{ domains }}"
loop_control:
loop_var: "domain"
template:
src: "php-fpm.conf.j2"
dest: "/etc/php/7.2/fpm/pool.d/{{ domain }}.conf"
handlers:
- name: Reload nginx
service:
name: nginx
state: reloaded
- name: Reload php-fpm
service:
name: php-fpm
state: reloaded
#- hosts: "{{ hostname }}"
# gather_facts: false
# become_user: root
# become_method: sudo
# copy:
# src: nginx.http.redirect.conf.j2
# dest: /etc/nginx/sites-enabled/nginx.http.redirect.conf
- hosts: "{{ hostname }}"
gather_facts: false
become_user: root
become_method: sudo
roles:
- geerlingguy.certbot
- geerlingguy.nginx
vars:
certbot_admin_email: teyc@cognoware.com
certbot_create_if_missing: true
certbot_create_standalone_stop_services:
- nginx
certbot_certs:
- domains:
- "{{ domain }}"
- "dev.{{ domain }}"
extra_parameters: |
# index.php
index index.html index.php;
# index.php fallback
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# handle .php
location ~ \.php$ {
#include nginxconfig.io/php_fastcgi.conf;
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php-fpm-{{ domain }}.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
ssl_certificate /etc/letsencrypt/live/{{ domain }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ domain }}/privkey.pem;
# https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
# Perfect forward secrecy - ensures attacker cannot decrypt
# past communications
# openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ecdh_curve secp384r1;
# HSTS
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; ";
nginx_vhosts:
- listen: "80 default_server"
server_name: "_"
filename: "http.redirect.conf"
extra_parameters: "return 301 https://$host$request_uri;"
- listen: "443 ssl http2"
server_name: "{{ domain }}"
server_name_redirect: "www.{{ domain }}"
root: "/var/www/{{ domain }}/public"
index: "index.php"
state: "present"
filename: "{{ domain }}.conf"
extra_parameters: "{{ extra_parameters }}"
- listen: "443 ssl http2"
server_name: "dev.{{ domain }}"
#server_name_redirect: "www.{{ domain }}"
root: "/var/www/dev.{{ domain }}/public"
index: "index.php"
state: "present"
#template: "nginx.conf.https.j2"
filename: "dev.{{ domain }}.conf"
extra_parameters: "{{ extra_parameters }}"
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA7LHEc+eBB88tuoXTUfEvjqVM8IWLAxD9cSN0ZmWXYiukRkTPij9VZm3XIIfpZ+W34GAY4jrqerEEV81iXom+k0PFXVWN9cnrVEVO9EIf35DXrd7i4h4MF6iKSLFRF6ejOlhoNgvkOWBr3ePbrgpb6GcYLvEKiUzMl2PkQEdvC8v9S2kYNyzw+ZwNgpzS1ald4M1i5fjnbu9b4OCY0ViZdh7s+kUY4WxQJS2ZdKreM7Jt/Lx0Szk1ekMACZRwegfBORFVg+5JQRw5tPAIfMaNYFsd+UlkCeYp290VfPx+V+YyZ0rcNRMmhsLtF6hJdQD2AImkrKuGAH84mDp/xnc+lQ== teyc@cognoware.com
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCt3lOHVf3ErRgvFIVAKv6iMH2fw7E8yT0iWAU+MhejElgRj+yFhnnIzKX25S5CtD4bP3LATrMr2DMMSGXJP9I6chVicXtWFPRUiGjnxznvW2I8f4zcnqw2uPzOXGZY4veJ5yiTI7nZSwTUyj1dB40fsyYerCCMm8z0nzXUmGuOm/mO13Q/kMM6rDuTxQ/AaVHpjg+a1HsP2fx35EpeNHfjR5tW5gSvTSpceYi2ZzzNwo/hkO1DwpHl0Art/Mp7CXAq0aOc+ZcfPXPXOwmZMyAxxqVBrSSYGgKyCaaZKpyOJ0sx8scwYbB1zquBGLBplsrpg1SRP+V9sivbcOMPlrGf root@letsdobusiness.com.au
- hosts: "{{ hostname }}"
become_user: root
become_method: sudo
vars:
packages: ["nginx", "mysql-server", "mysql-client-core-5.7", "php-fpm"]
tasks:
- name: Installing nginx on {{ packages }}
apt:
name: "{{ packages }}"
state: present
- name: Use www-data user for nginx
lineinfile:
dest: /etc/nginx/nginx.conf
regexp: "^user\\s+.+;$"
line: "user www-data;"
---
- hosts: "{{ hostname }}"
user: root
- name: Execute lemp-install.yml
import_playbook: lemp-install.yml
- name: Execute user-install.yml
import_playbook: user-install.yml
- name: Execute mosh-install.yml
import_playbook: mosh-install.yml
- name: Execute add-domain-git.yml
import_playbook: add-domain-git.yml
- name: Execute add-domain-lemp.yml
import_playbook: add-domain-lemp.yml
- hosts: "{{ hostname }}"
become: true
become_user: root
become_method: sudo
tasks:
- name: Install mosh
apt:
name: mosh
state: present
[{{ domain }}]
user = {{ domain }}
group = {{ domain }}
listen = /var/run/php-fpm-{{ domain }}.sock
listen.owner = www-data
listen.group = www-data
php_admin_value[disable_functions] = exec,passthru,shell_exec,system
php_admin_flag[allow_url_fopen] = off
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
chdir = /
#!/bin/bash
while read oldrev newrev refname
do
branch=$(git rev-parse --symbolic --abbrev-ref $refname)
# BEGIN ANSIBLE MANAGED BLOCK
# END ANSIBLE MANAGED BLOCK
done
- hosts: "{{ hostname }}"
become_user: root
become_method: sudo
tasks:
- name: Add teyc user
user:
name: teyc
shell: /usr/bin/bash
groups: sudo
create_home: yes
ssh_key_file: '/mnt/c/users/teyc/.ssh/id_ed25519.pub'
password: $1$23HA3uu2$C2Q/klzMtsIdSZhLtpFTD1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment