feat(ansible): ansible configuration to deploy {123done,321done}-stage.dev.lcip.org

This commit is contained in:
John Morrison 2015-11-16 22:51:09 -08:00
Родитель 81020e00e5
Коммит 423699f8ea
29 изменённых файлов: 964 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,6 @@
build:
@echo ${stack} ${key}
PYTHONUNBUFFERED=1 ansible-playbook playbooks/app.yml \
-e "stack_name=${stack}" -e "keyname=${key}" \
-e "trusted_client_id=${trusted_client_id}" -e "trusted_client_secret=${trusted_client_secret}" \
-e "untrusted_client_id=${untrusted_client_id}" -e "untrusted_client_secret=${untrusted_client_secret}"

Просмотреть файл

@ -0,0 +1,9 @@
The command `make stack=one23done-stage key=yourkeyname trusted_client_id="dead..." client_secret="beef..." untrusted_client_id="feed..." untrusted_client_secret="deaf..."` will create an EC2+ELB instance [1] with the following attributes:
* builds and runs 123done (https://github.com/mozilla/123done) webserver as both trusted (123done) and untrusted (321done)
* an AWS ELB serving both port 80, and port 443 traffic with a SSL certificate for *.dev.lcip.org
* registers `one23done-stage.dev.lcip.org` in DNS as a A record, and an MX record to receive email
* node processes managed by supervisorctl
* ssh access to `ssh ec2-user@meta-one23done-stage.dev.lcip.org`
[1] assumes you have AWS access keys set up in mozilla's cloudservices-aws-dev IAM, but this ansible code should be not hard to re-use in some other IAM

Просмотреть файл

@ -0,0 +1,5 @@
[defaults]
hostfile = hosts
[ssh_connection]
control_path = %(directory)s/%%h-%%r

Просмотреть файл

@ -0,0 +1,8 @@
---
owner: fxa
keyname: jrgm
region: us-west-2
one23done_git_repo: https://github.com/mozilla/123done.git
one23done_git_version: oauth
hosted_zone: lcip.org
ssl_certificate_name: exp20170412_wildcard_dev_lcip.org

7
packages/123done/ansible/env/one23done-stage.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,7 @@
auth_uri: "https://oauth.stage.mozaws.net/v1/authorization"
content_uri: "https://accounts.stage.mozaws.net"
oauth_uri: "https://oauth.stage.mozaws.net/v1"
profile_uri: "https://profile.stage.mozaws.net/v1"
preverify_email_audience: "api-accounts.stage.mozaws.net"
fqdn_trusted: "123done-stage.dev.lcip.org"
fqdn_untrusted: "321done-stage.dev.lcip.org"

Просмотреть файл

@ -0,0 +1 @@
localhost

Просмотреть файл

@ -0,0 +1,56 @@
---
- hosts: localhost
connection: local
gather_facts: false
vars_files:
- "../defaults.yml"
- "../env/{{ stack_name }}.yml"
tasks:
- name: validate vars
assert:
that:
- stack_name != ''
- keyname != ''
- region != ''
- owner != ''
- name: Create a stack for running 123done and 321done oauth branch
action: cloudformation
state=present
region="{{ region }}"
stack_name="{{ stack_name }}"
template="../templates/app.json"
args:
template_parameters:
KeyName: "{{ keyname }}"
StackName: "{{ stack_name }}"
HostedZone: "{{ hosted_zone }}"
FQDNTrusted: "{{ fqdn_trusted }}"
FQDNUntrusted: "{{ fqdn_untrusted }}"
SSLCertificateName: "{{ ssl_certificate_name }}"
register: stack
- debug: var=stack
- name: add new host
add_host: hostname={{ stack['stack_outputs']['EC2HostName'] }} groupname=whatevs
- name: Configure instance
hosts: whatevs
remote_user: ec2-user
gather_facts: true
vars_files:
- "../defaults.yml"
- "../env/{{ stack_name }}.yml"
vars:
public_hostname: "{{ hostvars['localhost']['stack']['stack_outputs']['PublicDNS'] }}"
ec2_hostname: "{{ hostvars['localhost']['stack']['stack_outputs']['EC2HostName'] }}"
roles:
- common
- team
- nginx
- redis
- nodejs
- 123done
- 321done

Просмотреть файл

@ -0,0 +1,16 @@
[program:123done-web]
command=node server.js
directory=/home/app/123done
autostart=true
autorestart=unexpected
startsecs=1
startretries=3
stopwaitsecs=3
stdout_logfile=/var/log/123done-web.log
stdout_logfile_maxbytes=100MB
stdout_logfile_backups=10
stderr_logfile=/var/log/123done-web-err.log
stderr_logfile_maxbytes=100MB
stderr_logfile_backups=10
user=app
environment=PORT=10000

Просмотреть файл

@ -0,0 +1,16 @@
---
- name: install 123done dependencies
sudo: true
sudo_user: app
npm: path=/home/app/123done
notify: restart 123done-web
- name: generate 123done pub/priv keypair
sudo: true
command: node scripts/gen_keys.js chdir=/home/app/123done creates=/home/app/123done/secret-key.json
notify: restart 123done-web
- name: restart 123done-web
sudo: true
supervisorctl: name=123done-web state=restarted

Просмотреть файл

@ -0,0 +1,29 @@
---
- name: install libgmp
sudo: true
yum: name=gmp state=present
- name: install 123done
sudo: true
sudo_user: app
git: repo={{ one23done_git_repo }}
dest=/home/app/123done
version={{ one23done_git_version }}
force=true
notify:
- install 123done dependencies
- generate 123done pub/priv keypair
- restart 123done-web
- name: configure 123done
sudo: true
template: src=config.json.j2 dest=/home/app/123done/config.json owner=app group=app mode=0644
notify: restart 123done-web
- name: supervise 123done-web server
sudo: true
copy: src=123done-web.conf dest=/etc/supervisor.d/123done-web.conf
notify: update supervisor
- meta: flush_handlers

Просмотреть файл

@ -0,0 +1,14 @@
{
"client_id": "{{ trusted_client_id }}",
"client_secret": "{{ trusted_client_secret }}",
"auth_uri": "{{ auth_uri }}",
"content_uri": "{{ content_uri }}",
"oauth_uri": "{{ oauth_uri }}",
"profile_uri": "{{ profile_uri }}",
"redirect_uri": "https://{{ fqdn_trusted }}/api/oauth",
"preverify_email_audience": "{{ preverify_email_audience }}",
"preverify_email_jku": "https://{{ fqdn_trusted }}/.well-known/public-keys",
"scopes": "profile",
"publicKeyFile": "./public-key.json",
"secretKeyFile": "./secret-key.json"
}

Просмотреть файл

@ -0,0 +1,16 @@
[program:321done-web]
command=node server.js
directory=/home/app/321done
autostart=true
autorestart=unexpected
startsecs=1
startretries=3
stopwaitsecs=3
stdout_logfile=/var/log/321done-web.log
stdout_logfile_maxbytes=100MB
stdout_logfile_backups=10
stderr_logfile=/var/log/321done-web-err.log
stderr_logfile_maxbytes=100MB
stderr_logfile_backups=10
user=app
environment=PORT=11000

Просмотреть файл

@ -0,0 +1,16 @@
---
- name: install 321done dependencies
sudo: true
sudo_user: app
npm: path=/home/app/321done
notify: restart 321done-web
- name: generate 321done pub/priv keypair
sudo: true
command: node scripts/gen_keys.js chdir=/home/app/321done creates=/home/app/321done/secret-key.json
notify: restart 321done-web
- name: restart 321done-web
sudo: true
supervisorctl: name=321done-web state=restarted

Просмотреть файл

@ -0,0 +1,29 @@
---
- name: install libgmp
sudo: true
yum: name=gmp state=present
- name: install 321done
sudo: true
sudo_user: app
git: repo={{ one23done_git_repo }}
dest=/home/app/321done
version={{ one23done_git_version }}
force=true
notify:
- install 321done dependencies
- generate 321done pub/priv keypair
- restart 321done-web
- name: configure 321done
sudo: true
template: src=config.json.j2 dest=/home/app/321done/config.json owner=app group=app mode=0644
notify: restart 321done-web
- name: supervise 321done-web server
sudo: true
copy: src=321done-web.conf dest=/etc/supervisor.d/321done-web.conf
notify: update supervisor
- meta: flush_handlers

Просмотреть файл

@ -0,0 +1,14 @@
{
"client_id": "{{ untrusted_client_id }}",
"client_secret": "{{ untrusted_client_secret }}",
"auth_uri": "{{ auth_uri }}",
"content_uri": "{{ content_uri }}",
"oauth_uri": "{{ oauth_uri }}",
"profile_uri": "{{ profile_uri }}",
"redirect_uri": "https://{{ fqdn_untrusted }}/api/oauth",
"preverify_email_audience": "{{ preverify_email_audience }}",
"preverify_email_jku": "https://{{ fqdn_untrusted }}/.well-known/public-keys",
"scopes": "profile:email profile:uid profile:display_name",
"publicKeyFile": "./public-key.json",
"secretKeyFile": "./secret-key.json"
}

Просмотреть файл

@ -0,0 +1,8 @@
description "supervisor"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
exec /usr/bin/supervisord --configuration /etc/supervisord.conf

Просмотреть файл

@ -0,0 +1,8 @@
[Unit]
Description=supervisor
[Service]
ExecStart=/usr/bin/supervisord --configuration /etc/supervisord.conf
[Install]
WantedBy=multi-user.target

Просмотреть файл

@ -0,0 +1,139 @@
; supervisor config file.
;
; For more information on the config file, please see:
; http://supervisord.org/configuration.html
;
; Note: shell expansion ("~" or "$HOME") is not supported. Environment
; variables can be expanded using this syntax: "%(ENV_HOME)s".
[unix_http_server]
file=/tmp/supervisor.sock ; (the path to the socket file)
chmod=0770 ; socket file mode (default 0700)
chown=root:supervsr ; socket file uid:gid owner
;username=user ; (default is no username (open server))
;password=123 ; (default is no password (open server))
;[inet_http_server] ; inet (TCP) server disabled by default
;port=127.0.0.1:9001 ; (ip_address:port specifier, *:port for all iface)
;username=user ; (default is no username (open server))
;password=123 ; (default is no password (open server))
[supervisord]
logfile=/var/log/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=2 ; (num of main logfile rotation backups;default 10)
loglevel=info ; (log level;default info; others: debug,warn,trace)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=true ; (start in foreground if true;default false)
minfds=1024 ; (min. avail startup file descriptors;default 1024)
minprocs=200 ; (min. avail process descriptors;default 200)
;umask=022 ; (process file creation umask;default 022)
;user=chrism ; (default is current user, required if root)
;identifier=supervisor ; (supervisord identifier, default is 'supervisor')
;directory=/tmp ; (default is not to cd during start)
;nocleanup=true ; (don't clean up tempfiles at start;default false)
;childlogdir=/tmp ; ('AUTO' child log dir, default $TEMP)
;environment=KEY="value" ; (key value pairs to add to environment)
;strip_ansi=false ; (strip ansi escape codes in logs; def. false)
; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
;username=chris ; should be same as http_username if set
;password=123 ; should be same as http_password if set
;prompt=mysupervisor ; cmd line prompt (default "supervisor")
;history_file=~/.sc_history ; use readline history if available
; The below sample program section shows all possible program subsection values,
; create one or more 'real' program: sections to be able to control them under
; supervisor.
;[program:theprogramname]
;command=/bin/cat ; the program (relative uses PATH, can take args)
;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
;numprocs=1 ; number of processes copies to start (def 1)
;directory=/tmp ; directory to cwd to before exec (def no cwd)
;umask=022 ; umask for process (default None)
;priority=999 ; the relative start priority (default 999)
;autostart=true ; start at supervisord start (default: true)
;autorestart=unexpected ; whether/when to restart (default: unexpected)
;startsecs=1 ; number of secs prog must stay running (def. 1)
;startretries=3 ; max # of serial start failures (default 3)
;exitcodes=0,2 ; 'expected' exit codes for process (default 0,2)
;stopsignal=QUIT ; signal used to kill process (default TERM)
;stopwaitsecs=10 ; max num secs to wait b4 SIGKILL (default 10)
;stopasgroup=false ; send stop signal to the UNIX process group (default false)
;killasgroup=false ; SIGKILL the UNIX process group (def false)
;user=chrism ; setuid to this UNIX account to run the program
;redirect_stderr=true ; redirect proc stderr to stdout (default false)
;stdout_logfile=/a/path ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=2 ; # of stdout logfile backups (default 10)
;stdout_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0)
;stdout_events_enabled=false ; emit events on stdout writes (default false)
;stderr_logfile=/a/path ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups=2 ; # of stderr logfile backups (default 10)
;stderr_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0)
;stderr_events_enabled=false ; emit events on stderr writes (default false)
;environment=A="1",B="2" ; process environment additions (def no adds)
;serverurl=AUTO ; override serverurl computation (childutils)
; The below sample eventlistener section shows all possible
; eventlistener subsection values, create one or more 'real'
; eventlistener: sections to be able to handle event notifications
; sent by supervisor.
;[eventlistener:theeventlistenername]
;command=/bin/eventlistener ; the program (relative uses PATH, can take args)
;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
;numprocs=1 ; number of processes copies to start (def 1)
;events=EVENT ; event notif. types to subscribe to (req'd)
;buffer_size=10 ; event buffer queue size (default 10)
;directory=/tmp ; directory to cwd to before exec (def no cwd)
;umask=022 ; umask for process (default None)
;priority=-1 ; the relative start priority (default -1)
;autostart=true ; start at supervisord start (default: true)
;autorestart=unexpected ; whether/when to restart (default: unexpected)
;startsecs=1 ; number of secs prog must stay running (def. 1)
;startretries=3 ; max # of serial start failures (default 3)
;exitcodes=0,2 ; 'expected' exit codes for process (default 0,2)
;stopsignal=QUIT ; signal used to kill process (default TERM)
;stopwaitsecs=10 ; max num secs to wait b4 SIGKILL (default 10)
;stopasgroup=false ; send stop signal to the UNIX process group (default false)
;killasgroup=false ; SIGKILL the UNIX process group (def false)
;user=chrism ; setuid to this UNIX account to run the program
;redirect_stderr=true ; redirect proc stderr to stdout (default false)
;stdout_logfile=/a/path ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=2 ; # of stdout logfile backups (default 10)
;stdout_events_enabled=false ; emit events on stdout writes (default false)
;stderr_logfile=/a/path ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups ; # of stderr logfile backups (default 10)
;stderr_events_enabled=false ; emit events on stderr writes (default false)
;environment=A="1",B="2" ; process environment additions
;serverurl=AUTO ; override serverurl computation (childutils)
; The below sample group section shows all possible group values,
; create one or more 'real' group: sections to create "heterogeneous"
; process groups.
;[group:thegroupname]
;programs=progname1,progname2 ; each refers to 'x' in [program:x] definitions
;priority=999 ; the relative start priority (default 999)
; The [include] section can just contain the "files" setting. This
; setting can list multiple files (separated by whitespace or
; newlines). It can also contain wildcards. The filenames are
; interpreted as relative to this file. Included files *cannot*
; include files themselves.
[include]
files = supervisor.d/*.conf

Просмотреть файл

@ -0,0 +1,9 @@
---
- name: restart supervisor
sudo: true
service: name=supervisor state=restarted
- name: update supervisor
sudo: true
command: supervisorctl update

Просмотреть файл

@ -0,0 +1,69 @@
---
- name: update installed packages
sudo: true
yum: name=* state=latest
- name: install base packages
sudo: true
yum: name={{ item }} state=present
with_items:
- epel-release
- gcc-c++
- git
- ntp
- python-pip
- name: create supervsr group for using supervisorctl
sudo: true
group: name=supervsr state=present
- name: create app user
sudo: true
user: name=app state=present append=yes groups=supervsr
- name: make /home/app go-readable
sudo: true
file: path=/home/app mode=go+rx state=directory
- name: add ec2-user to group supervsr
sudo: true
user: name=ec2-user append=yes groups=supervsr
- name: install supervisord
sudo: true
pip: name=supervisor version=3.1.3 state=present extra_args='--install-option="--install-scripts=/usr/bin"'
- file: path=/etc/supervisor.d state=directory
sudo: true
- file: path=/data state=directory owner=app group=app mode=0777
sudo: true
- name: upstart or systemd?
sudo: true
command: which initctl
failed_when: false
changed_when: false
register: is_upstart
- name: upstart supervisord
sudo: true
copy: src=supervisor.conf dest=/etc/init/supervisor.conf owner=root group=root
when: is_upstart.rc == 0
- name: systemd supervisord
sudo: true
copy: src=supervisor.systemd dest=/etc/systemd/system/supervisor.service owner=root group=root
when: is_upstart.rc != 0
- name: configure supervisord
sudo: true
copy: src=supervisord.conf dest=/etc/supervisord.conf owner=root group=root
notify: restart supervisor
- name: start supervisord
sudo: true
service: name=supervisor state=started
- meta: flush_handlers

Просмотреть файл

@ -0,0 +1,88 @@
types {
text/html html htm shtml;
text/css css;
text/xml xml;
image/gif gif;
image/jpeg jpeg jpg;
application/javascript js;
application/atom+xml atom;
application/rss+xml rss;
text/mathml mml;
text/plain txt;
text/vnd.sun.j2me.app-descriptor jad;
text/vnd.wap.wml wml;
text/x-component htc;
image/png png;
image/tiff tif tiff;
image/vnd.wap.wbmp wbmp;
image/x-icon ico;
image/x-jng jng;
image/x-ms-bmp bmp;
image/svg+xml svg svgz;
image/webp webp;
application/font-woff woff;
application/java-archive jar war ear;
application/json json;
application/mac-binhex40 hqx;
application/msword doc;
application/pdf pdf;
application/postscript ps eps ai;
application/rtf rtf;
application/vnd.apple.mpegurl m3u8;
application/vnd.ms-excel xls;
application/vnd.ms-fontobject eot;
application/vnd.ms-powerpoint ppt;
application/vnd.wap.wmlc wmlc;
application/vnd.google-earth.kml+xml kml;
application/vnd.google-earth.kmz kmz;
application/x-7z-compressed 7z;
application/x-cocoa cco;
application/x-java-archive-diff jardiff;
application/x-java-jnlp-file jnlp;
application/x-makeself run;
application/x-perl pl pm;
application/x-pilot prc pdb;
application/x-rar-compressed rar;
application/x-redhat-package-manager rpm;
application/x-sea sea;
application/x-shockwave-flash swf;
application/x-stuffit sit;
application/x-tcl tcl tk;
application/x-x509-ca-cert der pem crt;
application/x-xpinstall xpi;
application/xhtml+xml xhtml;
application/xspf+xml xspf;
application/zip zip;
application/octet-stream bin exe dll;
application/octet-stream deb;
application/octet-stream dmg;
application/octet-stream iso img;
application/octet-stream msi msp msm;
application/vnd.openxmlformats-officedocument.wordprocessingml.document docx;
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx;
application/vnd.openxmlformats-officedocument.presentationml.presentation pptx;
audio/midi mid midi kar;
audio/mpeg mp3;
audio/ogg ogg;
audio/x-m4a m4a;
audio/x-realaudio ra;
video/3gpp 3gpp 3gp;
video/mp2t ts;
video/mp4 mp4;
video/mpeg mpeg mpg;
video/quicktime mov;
video/webm webm;
video/x-flv flv;
video/x-m4v m4v;
video/x-mng mng;
video/x-ms-asf asx asf;
video/x-ms-wmv wmv;
video/x-msvideo avi;
}

Просмотреть файл

@ -0,0 +1,9 @@
---
- name: restart nginx
sudo: true
service: name=nginx state=restarted
- name: reload nginx config
sudo: true
command: nginx -s reload

Просмотреть файл

@ -0,0 +1,43 @@
---
- name: install nginx
sudo: true
yum: name=nginx state=present
- name: ensure /etc/nginx directory
sudo: true
file: path=/etc/nginx state=directory mode=0755
- name: clean out extra nginx configuration
sudo: true
file: path=/etc/nginx/{{ item }} state=absent
with_items:
- conf.d
- default.d
- fastcgi.conf
- fastcgi.conf.default
- fastcgi_params
- fastcgi_params.default
- koi-utf
- koi-win
- mime.types.default
- nginx.conf.default
- scgi_params
- scgi_params.default
- uwsgi_params
- uwsgi_params.default
- win-utf
- name: template nginx.conf
sudo: true
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: reload nginx config
- name: copy mime.types
sudo: true
copy: src=mime.types dest=/etc/nginx/mime.types
notify: reload nginx config
- name: start nginx
sudo: true
service: name=nginx state=started enabled=true

Просмотреть файл

@ -0,0 +1,71 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
tcp_nopush on;
tcp_nodelay on;
types_hash_max_size 2048;
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80 default;
return 301 https://$host$request_uri;
}
upstream 123done_upstream {
server 127.0.0.1:10000;
keepalive 64;
}
server {
listen 9000;
server_name {{ fqdn_trusted }};
location / {
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Connection "";
proxy_http_version 1.1;
proxy_pass http://123done_upstream;
}
}
upstream 321done_upstream {
server 127.0.0.1:11000;
keepalive 64;
}
server {
listen 9000;
server_name {{ fqdn_untrusted }};
location / {
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Connection "";
proxy_http_version 1.1;
proxy_pass http://321done_upstream;
}
}
}

Просмотреть файл

@ -0,0 +1,19 @@
---
- name: install nave
sudo: true
get_url: url=https://raw.githubusercontent.com/dannycoates/nave/master/nave.sh
dest=/usr/bin/nave
mode=755
- name: install node
sudo: true
command: /usr/bin/nave usemain 0.10
# TODO detect actual changes
changed_when: false
- name: upgrade npm to npm@2.14.10
sudo: true
npm: name=npm global=true state=present version=2.14.10
- meta: flush_handlers

Просмотреть файл

@ -0,0 +1,14 @@
---
- name: install redis and hiredis
sudo: true
yum: name={{ item }} state=present enablerepo=epel
with_items:
- redis
- hiredis
- name: start redis
sudo: true
service: name=redis enabled=yes state=started
- meta: flush_handlers

Просмотреть файл

@ -0,0 +1,4 @@
---
- name: update authorized_keys
shell: cat /home/ec2-user/identity-pubkeys/*.pub >> ~/.ssh/authorized_keys

Просмотреть файл

@ -0,0 +1,19 @@
---
- name: install human tools
sudo: true
yum: name={{ item }} state=present
with_items:
- emacs-nox
- htop
- lsof
- mlocate
- strace
- tmux
- name: get team public keys
git: repo=https://github.com/mozilla/identity-pubkeys.git
dest=/home/ec2-user/identity-pubkeys
version=faf11d61fdc166004c134b75587d059734f5bdb1
force=true
notify: update authorized_keys

Просмотреть файл

@ -0,0 +1,222 @@
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "123done stack",
"Parameters": {
"KeyName": {
"Description": "Name of an existing EC2 KeyPair for SSH access.",
"Type": "AWS::EC2::KeyPair::KeyName",
"ConstraintDescription": "must be the name of an existing EC2 KeyPair."
},
"StackName": {
"Description": "Name for this Cloudformation stack.",
"Type": "String"
},
"InstanceType": {
"Description": "EC2 instance type",
"Type": "String",
"Default": "t2.small",
"AllowedValues": [
"t2.small",
"t2.medium"
],
"ConstraintDescription": "must be a valid EC2 instance type."
},
"HostedZone": {
"Description": "The DNS name of an existing Amazon Route 53 hosted zone.",
"Type": "String",
"AllowedPattern": "(?!-)[a-zA-Z0-9-.]{1,63}(?<!-)",
"ConstraintDescription": "must be a valid DNS zone name."
},
"SSLCertificateName": {
"Description": "Name of SSLCertificate to use with HostedZone.",
"Type": "String",
"ConstraintDescription": "must be a valid certificate stored in EC2."
},
"FQDNTrusted": {
"Description": "Fully qualified domain name of this trusted instance (e.g., 123done...).",
"Type": "String"
},
"FQDNUntrusted": {
"Description": "Fully qualified domain name of this untrusted instance (e.g., 321done...).",
"Type": "String"
}
},
"Mappings": {
"RegionMap" : {
"us-east-1" : { "AMI" : "ami-60b6c60a" },
"us-west-2" : { "AMI" : "ami-f0091d91" },
"us-west-1" : { "AMI" : "ami-d5ea86b5" },
"eu-west-1" : { "AMI" : "ami-bff32ccc" },
"eu-central-1" : { "AMI" : "ami-bc5b48d0" },
"ap-southeast-1" : { "AMI" : "ami-c9b572aa" },
"ap-northeast-1" : { "AMI" : "ami-383c1956" },
"ap-southeast-2" : { "AMI" : "ami-48d38c2b" },
"sa-east-1" : { "AMI" : "ami-6817af04" }
}
},
"Resources": {
"EC2Instance": {
"Type": "AWS::EC2::Instance",
"Properties": {
"InstanceType": { "Ref": "InstanceType" },
"SecurityGroups": [ { "Ref": "EC2InstanceSecurityGroup" } ],
"KeyName": { "Ref": "KeyName" },
"Tags": [
{
"Key" : "Name",
"Value" : { "Ref": "StackName" }
}
],
"ImageId": { "Fn::FindInMap": [ "RegionMap", { "Ref": "AWS::Region" }, "AMI" ] }
}
},
"EC2InstanceSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Enable access to port 22, and 443 from ELB",
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": "22",
"ToPort": "22",
"CidrIp": "0.0.0.0/0"
}
]
}
},
"EC2SecurityGroupIngress9000" : {
"Type" : "AWS::EC2::SecurityGroupIngress",
"Properties" : {
"GroupName" : { "Ref" : "EC2InstanceSecurityGroup" },
"IpProtocol" : "tcp",
"FromPort": 9000,
"ToPort": 9000,
"SourceSecurityGroupName" : { "Ref" : "ELBSecurityGroup" }
}
},
"EC2SecurityGroupIngress80" : {
"Type" : "AWS::EC2::SecurityGroupIngress",
"Properties" : {
"GroupName" : { "Ref" : "EC2InstanceSecurityGroup" },
"IpProtocol" : "tcp",
"FromPort": 80,
"ToPort": 80,
"SourceSecurityGroupName" : { "Ref" : "ELBSecurityGroup" }
}
},
"ELBSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Fxa 123done ELB",
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": "443",
"ToPort": "443",
"CidrIp": "0.0.0.0/0"
},
{
"IpProtocol": "tcp",
"FromPort": "80",
"ToPort": "80",
"CidrIp": "0.0.0.0/0"
}
]
}
},
"ELB":{
"Type": "AWS::ElasticLoadBalancing::LoadBalancer",
"Properties":{
"AvailabilityZones": { "Fn::GetAZs": "" },
"ConnectionDrainingPolicy":{ "Enabled": true, "Timeout": 15 },
"Listeners":[
{
"InstancePort": "9000",
"LoadBalancerPort": "443",
"PolicyNames": [ "ELBSecurityPolicy-2015-05" ],
"Protocol": "HTTPS",
"SSLCertificateId":{
"Fn::Join":[ "", [
"arn:aws:iam::",
{ "Ref": "AWS::AccountId" },
":server-certificate/",
{ "Ref": "SSLCertificateName" }
] ]
}
},
{
"InstancePort": "80",
"LoadBalancerPort": "80",
"Protocol": "HTTP"
}
],
"HealthCheck": {
"Target": "HTTP:9000/",
"HealthyThreshold": "3",
"UnhealthyThreshold": "10",
"Interval": "15",
"Timeout": "5"
},
"Instances": [ { "Ref": "EC2Instance" } ],
"SecurityGroups": [ { "Fn::GetAtt": [ "ELBSecurityGroup", "GroupId" ] } ]
}
},
"ELBDNSRecord": {
"Type": "AWS::Route53::RecordSet",
"DependsOn": "ELB",
"Properties": {
"HostedZoneName": { "Fn::Join": [ "", [ { "Ref": "HostedZone" }, "." ] ] },
"Comment": "DNS name of the trusted HTTPS ELB for the EC2 instance.",
"Name": { "Ref": "FQDNTrusted" },
"Type": "CNAME",
"TTL": "60",
"ResourceRecords": [ { "Fn::GetAtt": [ "ELB", "DNSName" ] } ]
}
},
"ELBDNSRecordUntrusted": {
"Type": "AWS::Route53::RecordSet",
"DependsOn": "ELB",
"Properties": {
"HostedZoneName": { "Fn::Join": [ "", [ { "Ref": "HostedZone" }, "." ] ] },
"Comment": "DNS name of the untrusted HTTPS ELB for the EC2 instance.",
"Name": { "Ref": "FQDNUntrusted" },
"Type": "CNAME",
"TTL": "60",
"ResourceRecords": [ { "Fn::GetAtt": [ "ELB", "DNSName" ] } ]
}
},
"EC2DNSRecord": {
"Type": "AWS::Route53::RecordSet",
"DependsOn": "ELB",
"Properties": {
"HostedZoneName": { "Fn::Join": [ "", [ { "Ref": "HostedZone" }, "." ] ] },
"Comment": "DNS name of the EC2 instance.",
"Name": { "Fn::Join": [ "", [ "meta-", { "Ref": "FQDNTrusted" } ] ] },
"Type": "CNAME",
"TTL": "60",
"ResourceRecords": [ { "Fn::GetAtt": [ "EC2Instance", "PublicDnsName" ] } ]
}
}
},
"Outputs": {
"PublicDNS": {
"Description": "Public ELB DNSName",
"Value": { "Ref": "ELBDNSRecord" }
},
"EC2SSHAccess": {
"Description": "SSH DNSName",
"Value": { "Ref": "EC2DNSRecord" }
},
"EC2HostName": {
"Description": "Hostname assigned by EC2",
"Value": { "Fn::GetAtt": [ "EC2Instance", "PublicDnsName" ] }
},
"InstanceId": {
"Description": "InstanceId",
"Value": { "Ref": "EC2Instance" }
}
}
}