282 lines
13 KiB
YAML
282 lines
13 KiB
YAML
---
|
|
|
|
- hosts: webservers
|
|
vars:
|
|
nginx_public_deploy_key: |
|
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINbgxOufHY7SxQrJNTlHmye+xeNHBA1O5SGtGhGeOVZM github actions
|
|
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKA7DgTQ0G7+kdsX0lIUOAAOllwGSCu8s8TxPvr/61Y8q+pIO5mrZycI0xYcKP5NZaABqlFyXUUNfLj7RLqteBxqq2QZP4NOJ1MutYRIkzJ9YW0f565jHaOqSguz0MY+1sCHtuEPiUUZoNexkKN7SIx60SfoaMEvGjAj46txA7VFbJUuKcJtA1Yvmn0C0KoXUUQ/G+JqvjQ7QuKLQYdTZ8S9OEvNaqNfwNSwvy1/LCnuajFw0O+H5bz7AcS5Iuj+9k8wgHPK1a1rQEdteOcn2XBCvta/VOVlFLv6/9K3iU3EJ1pyaZ88UkuJef8aWnH/AJGaF2gLqUbBuL+UeXyD41 julien+yubikey4@palard.fr
|
|
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8vv8vwmbyhFEa0chj8LklnnY6DRLKj2OM0NgaMTd9SsrtBeLMqTt34pU+kKl6/9EIe9P8Z1/fWFyOiTsE7Khf3rkNsoILPmEV14i18Bvtp4nMtljqZaKVkAcRjPvo7flRWNxxL2Zbo+BEr3wVCl3Sc6YV8oQzCwVPKf34AB39b+PW4f3580Aqcd4Ci6zca0Ol95tLDv1slX1A7QcpoZAne8kj5h6bb4cC7FLBC9+xOSKmzoLOlP7LsyxaUUGRyi/FeMoma1VES65aIJ5U23GtZrzZI3tKz+vpQvOVaozNTDkNLiiJkjd3Ew1I10wArpZixjwSndP8CvGFyJc1XUXZ julien+yubikey5@palard.fr
|
|
|
|
tasks:
|
|
- name: Basic setup
|
|
include_role: name=common
|
|
|
|
- name: Configure french locale
|
|
locale_gen: name="{{ item }}" state=present
|
|
with_items:
|
|
- en_US.UTF-8
|
|
- fr_FR.UTF-8
|
|
|
|
- name: Install requirements
|
|
apt:
|
|
state: present
|
|
name: [nginx, sudo]
|
|
|
|
- name: Setup afpy.org
|
|
include_role: name=nginx
|
|
vars:
|
|
nginx_owner: afpy-org
|
|
nginx_domain: afpy.org
|
|
nginx_certificates: [afpy.org, www.afpy.org]
|
|
nginx_conf: |
|
|
server
|
|
{
|
|
listen [::]:80; listen 80;
|
|
server_name www.afpy.org afpy.org;
|
|
return 301 https://www.afpy.org$request_uri;
|
|
}
|
|
|
|
server
|
|
{
|
|
listen [::]:443 ssl http2; listen 443 ssl http2;
|
|
server_name afpy.org;
|
|
include snippets/letsencrypt-afpy.org.conf;
|
|
return 301 https://www.afpy.org$request_uri;
|
|
}
|
|
|
|
server
|
|
{
|
|
listen [::]:443 ssl http2; listen 443 ssl http2;
|
|
server_name www.afpy.org;
|
|
root /var/www/afpy.org/;
|
|
include snippets/letsencrypt-afpy.org.conf;
|
|
index index.html;
|
|
# font-src 'self' for afpy.org/admin/ which loads fonts like:
|
|
# https://www.afpy.org/admin/static/bootstrap/bootstrap4/fonts/fontawesome-webfont.eot?#iefix&v=4.7.0
|
|
add_header Content-Security-Policy "default-src 'none'; font-src 'self'; img-src 'self'; style-src 'self'; script-src 'self'; frame-ancestors 'self'; frame-src https://www.helloasso.com https://web.libera.chat;";
|
|
add_header X-Content-Type-Options "nosniff";
|
|
|
|
location /discord
|
|
{
|
|
return 301 https://discord.gg/qaxq8tVcjx;
|
|
}
|
|
|
|
location /
|
|
{
|
|
include proxy_params;
|
|
proxy_pass http://unix:/run/afpy-org/website.sock;
|
|
}
|
|
|
|
location /static/
|
|
{
|
|
alias /home/afpy-org/src/afpy/static/;
|
|
}
|
|
|
|
location /planet/
|
|
{
|
|
return 301 https://planet.afpy.org/atom.xml;
|
|
}
|
|
|
|
location /feed/actualites/rss.xml
|
|
{
|
|
return 301 https://discuss.afpy.org/c/association.rss;
|
|
}
|
|
|
|
location /feed/emplois/rss.xml
|
|
{
|
|
return 301 https://discuss.afpy.org/c/emplois.rss;
|
|
}
|
|
|
|
location ~ ^/doc/python/(.*)$ {return 301 https://docs.python.org/fr/$1;}
|
|
location = /logo.png { return 301 https://www.afpy.org/static/images/logo.svg; }
|
|
location = /posts/emplois { return 301 https://www.afpy.org/emplois; }
|
|
location = /post/edit/emplois { return 301 https://www.afpy.org/emplois/new; }
|
|
location = /discussion { return 301 https://discuss.afpy.org/; }
|
|
location = /posts/actualites { return 301 https://www.afpy.org/actualites; }
|
|
location = /membres/adhesion { return 301 https://www.afpy.org/adherer; }
|
|
location = /jobs { return 301 https://www.afpy.org/emplois; }
|
|
location = /offres-demploi/RSS { return 301 https://www.afpy.org/feed/emplois/rss.xml; }
|
|
location = "/news/aggregator" { return 301 https://www.afpy.org/posts/actualites/1345367761; }
|
|
location = "/news/pyconfr-2012" { return 301 https://www.afpy.org/posts/actualites/1345377295; }
|
|
location = "/news/le-nouveau-site-de-lafpy" { return 301 https://www.afpy.org/posts/actualites/1364754937; }
|
|
location = "/news/un-hackathon-a-paris" { return 301 https://www.afpy.org/posts/actualites/1373474773; }
|
|
location = "/news/julython-contribuez-a-des-projets-opensource" { return 301 https://www.afpy.org/posts/actualites/1373475142; }
|
|
location = "/news/lappel-a-contribution-pour-pyconfr13-est-ouvert" { return 301 https://www.afpy.org/posts/actualites/1374511126; }
|
|
location = "/news/naissance-dune-communaute-saltstack-francophone" { return 301 https://www.afpy.org/posts/actualites/1392304489; }
|
|
location = "/news/pycon-fr-2014" { return 301 https://www.afpy.org/posts/actualites/1392311614; }
|
|
location = "/news/pyconfr15-ou-nous-emmeneras-tu-cette-annee" { return 301 https://www.afpy.org/posts/actualites/1423208987; }
|
|
location = "/news/pycon-fr-2015-we-want-you" { return 301 https://www.afpy.org/posts/actualites/1433966273; }
|
|
location = "/news/pycon-fr-2015-lappel-a-conferencier-est-prolonge" { return 301 https://www.afpy.org/posts/actualites/1438067732; }
|
|
location = "/news/pv-de-lassemblee-generale-ordinaire-2017" { return 301 https://www.afpy.org/posts/actualites/1506345679; }
|
|
location = "/news/code-en-seine" { return 301 https://www.afpy.org/posts/actualites/1507801636; }
|
|
location = "/news/rencontre-python-a-lyon" { return 301 https://www.afpy.org/posts/actualites/1508335902; }
|
|
location = "/news/cours-en-ligne-python-3-des-fondamentaux-aux-concepts-avances-du-langage" { return 301 https://www.afpy.org/posts/actualites/1509982321; }
|
|
location = "/news/atelier-de-contribution-a-ansible-a-paris" { return 301 https://www.afpy.org/posts/actualites/1509982513; }
|
|
location = "/news/rencontre-python-a-lyon-une-carte-pour-les-amener-tous-et-dans-la-connaissance-les-lier" { return 301 https://www.afpy.org/posts/actualites/1510650668; }
|
|
location = "/news/hackaton-la-boite-incubateur-imt-atlantique-rennes" { return 301 https://www.afpy.org/posts/actualites/1511358816; }
|
|
location = "/news/ou-sont-mes-variables" { return 301 https://www.afpy.org/posts/actualites/1512378516; }
|
|
location = "/news/a-vos-framewoks" { return 301 https://www.afpy.org/posts/actualites/1512996562; }
|
|
location = "/news/atelier-contribuez-a-la-traduction-de-la-doc-de-python-en-francais" { return 301 https://www.afpy.org/posts/actualites/1515405342; }
|
|
location = "/news/soiree-python-a-marseille-le-9-2-2018" { return 301 https://www.afpy.org/posts/actualites/1518042512; }
|
|
location = "/news/meetup-python-amiens-1" { return 301 https://www.afpy.org/posts/actualites/1523519011; }
|
|
}
|
|
|
|
- name: afpy user can reload own website
|
|
lineinfile:
|
|
path: /etc/sudoers
|
|
state: present
|
|
regexp: '^afpy-org '
|
|
line: "afpy-org ALL = NOPASSWD: /bin/systemctl restart afpy-org.service"
|
|
validate: /usr/sbin/visudo -cf %s
|
|
|
|
- name: Initial clone
|
|
become: true
|
|
become_user: afpy-org
|
|
git:
|
|
repo: https://github.com/AFPy/site/
|
|
dest: /home/afpy-org/src/
|
|
update: yes
|
|
|
|
- name: Setup or upgrade venv
|
|
become: true
|
|
become_user: afpy-org
|
|
command: python3 -m venv --upgrade-deps /home/afpy-org/venv
|
|
changed_when: False
|
|
|
|
- name: pip install AFPy website
|
|
become: true
|
|
become_user: afpy-org
|
|
pip:
|
|
requirements: /home/afpy-org/src/requirements.txt
|
|
virtualenv_command: /usr/bin/python3 -m venv
|
|
virtualenv: "/home/afpy-org/venv/"
|
|
|
|
- name: pip install gunicorn
|
|
become: true
|
|
become_user: afpy-org
|
|
pip:
|
|
name: gunicorn
|
|
virtualenv_command: /usr/bin/python3 -m venv
|
|
virtualenv: "/home/afpy-org/venv/"
|
|
|
|
- name: systemd afpy.org service
|
|
copy:
|
|
dest: /etc/systemd/system/afpy-org.service
|
|
content: |
|
|
[Unit]
|
|
Description=AFPy website
|
|
After=network.target
|
|
|
|
[Service]
|
|
PIDFile=/run/afpy-org/website.pid
|
|
User=afpy-org
|
|
Group=afpy-org
|
|
RuntimeDirectory=afpy-org
|
|
WorkingDirectory=/home/afpy-org/src/
|
|
Environment="SENTRY_DSN={{ afpy_org_sentry_dsn }}" "FLASK_PORT=false" "FLASK_DEBUG=false" "FLASK_HOST=www.afpy.org" "FLASK_SECRET_KEY={{ vault_new_afpy_org_flask_secret_key }}" "DB_NAME=/home/afpy-org/afpy.db" "IMAGES_PATH=/home/afpy-org/images/"
|
|
ExecStart=/home/afpy-org/venv/bin/gunicorn -w 2 \
|
|
--pid /run/afpy-org/website.pid \
|
|
--bind unix:/run/afpy-org/website.sock afpy:application
|
|
ExecReload=/bin/kill -s HUP $MAINPID
|
|
ExecStop=/bin/kill -s TERM $MAINPID
|
|
PrivateTmp=true
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
|
|
- service: name=afpy-org state=started enabled=yes
|
|
|
|
- name: Redirect afpyro.afpy.org
|
|
include_role: name=nginx
|
|
vars:
|
|
nginx_domain: afpyro.afpy.org
|
|
nginx_certificates: [afpyro.afpy.org]
|
|
nginx_conf: |
|
|
server
|
|
{
|
|
listen [::]:80; listen 80;
|
|
server_name afpyro.afpy.org;
|
|
return 301 https://discuss.afpy.org/upcoming-events;
|
|
}
|
|
|
|
server
|
|
{
|
|
listen [::]:443 ssl http2; listen 443 ssl http2;
|
|
server_name afpyro.afpy.org;
|
|
include snippets/letsencrypt-afpyro.afpy.org.conf;
|
|
return 301 https://discuss.afpy.org/upcoming-events;
|
|
}
|
|
|
|
- name: Setup salt-fr.afpy.org
|
|
include_role: name=nginx
|
|
vars:
|
|
nginx_owner: salt-fr-afpy-org
|
|
nginx_path: /var/www/salt-fr.afpy.org
|
|
nginx_domain: salt-fr.afpy.org
|
|
nginx_certificates: [salt-fr.afpy.org]
|
|
nginx_public_deploy_key: |
|
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHVrME7+AYhM4n6opE5gVJbWsZHLETucV2wV+kDvnLk3
|
|
{{ authorized_keys['mdk'] | join(LF) }}
|
|
nginx_extra: |
|
|
add_header Content-Security-Policy "default-src 'none'; font-src https://cdnjs.cloudflare.com; img-src 'self' https://www.gravatar.com; style-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; script-src 'self' https://cdnjs.cloudflare.com; frame-ancestors 'self';";
|
|
add_header X-Content-Type-Options "nosniff";
|
|
|
|
- name: Setup nantes.afpy.org
|
|
include_role: name=nginx
|
|
vars:
|
|
nginx_owner: nantes-afpy-org
|
|
nginx_path: /var/www/nantes.afpy.org
|
|
nginx_domain: nantes.afpy.org
|
|
nginx_certificates: [nantes.afpy.org]
|
|
nginx_public_deploy_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGsky9ccA9SkMbFpaL9yEwLUW6y320kmwoCdGVCsWd3L"
|
|
|
|
- name: Setup lists.afpy.org redirection
|
|
include_role: name=nginx
|
|
vars:
|
|
nginx_domain: lists.afpy.org
|
|
nginx_certificates: [lists.afpy.org]
|
|
nginx_conf: |
|
|
server
|
|
{
|
|
listen [::]:80; listen 80;
|
|
server_name lists.afpy.org;
|
|
return 301 https://discuss.afpy.org/;
|
|
}
|
|
|
|
server
|
|
{
|
|
listen [::]:443 ssl http2; listen 443 ssl http2;
|
|
server_name lists.afpy.org;
|
|
include snippets/letsencrypt-lists.afpy.org.conf;
|
|
return 301 https://discuss.afpy.org/;
|
|
}
|
|
|
|
# To learn more about this service see https://dl.afpy.org/photos/README.txt
|
|
- name: Setup photos.afpy.org
|
|
include_role: name=nginx
|
|
vars:
|
|
nginx_domain: photos.afpy.org
|
|
nginx_certificates: [photos.afpy.org]
|
|
nginx_conf: |
|
|
server
|
|
{
|
|
listen [::]:80; listen 80;
|
|
server_name photos.afpy.org;
|
|
return 301 https://photos.afpy.org$request_uri;
|
|
}
|
|
|
|
server
|
|
{
|
|
listen [::]:443 ssl http2; listen 443 ssl http2;
|
|
server_name photos.afpy.org;
|
|
add_header Content-Security-Policy "default-src 'none'; img-src 'self'; style-src 'self'; script-src 'self'; frame-ancestors 'self';";
|
|
add_header X-Content-Type-Options "nosniff";
|
|
include snippets/letsencrypt-photos.afpy.org.conf;
|
|
root /var/www/photos.afpy.org/;
|
|
}
|
|
|
|
|
|
handlers:
|
|
- name: reload nginx
|
|
service: name=nginx state=reloaded
|