├── .gitignore ├── roles ├── mysql │ ├── defaults │ │ └── main.yml │ ├── templates │ │ ├── .my.cnf.j2 │ │ └── s3mysqlbackup.sh.j2 │ ├── handlers │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── README.md ├── nginx-passenger │ ├── vars │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── templates │ │ ├── passenger.list │ │ └── etc_nginx_sites-available.conf.j2 │ ├── defaults │ │ └── main.yml │ ├── README.md │ ├── meta │ │ └── main.yml │ └── tasks │ │ └── main.yml ├── ssl │ ├── meta │ │ └── main.yml │ ├── defaults │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ │ └── config.j2 ├── nodejs │ └── tasks │ │ └── main.yml ├── webserver │ ├── meta │ │ └── main.yml │ └── tasks │ │ └── main.yml ├── rvm_io.ruby │ ├── tests │ │ ├── ansible.cfg │ │ ├── dockerfiles │ │ │ ├── centos6 │ │ │ │ └── Dockerfile │ │ │ ├── centos7 │ │ │ │ └── Dockerfile │ │ │ ├── ubuntu16 │ │ │ │ └── Dockerfile │ │ │ ├── debian9 │ │ │ │ └── Dockerfile │ │ │ ├── debian8 │ │ │ │ ├── Dockerfile │ │ │ │ └── build │ │ │ └── ubuntu14 │ │ │ │ ├── Dockerfile │ │ │ │ └── build │ │ ├── inventory │ │ ├── root.yml │ │ ├── user.yml │ │ ├── docker-compose.yml │ │ └── assertions.yml │ ├── .gitignore │ ├── tasks │ │ ├── main.yml │ │ ├── rvm.yml │ │ └── rubies.yml │ ├── meta │ │ └── main.yml │ ├── vars │ │ └── main.yml │ ├── LICENSE │ ├── .travis.yml │ ├── defaults │ │ └── main.yml │ ├── CHANGELOG.md │ └── README.md ├── s3cmd │ ├── templates │ │ └── s3cfg.j2 │ └── tasks │ │ └── main.yml ├── deploy │ ├── templates │ │ └── database.yml.j2 │ └── tasks │ │ └── main.yml └── user │ └── tasks │ └── main.yml ├── .github └── FUNDING.yml ├── playbook.yml ├── group_vars └── all ├── installer.sh ├── config.yml.example └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | config.yml 2 | *.retry -------------------------------------------------------------------------------- /roles/mysql/defaults/main.yml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [bradymholt] 2 | -------------------------------------------------------------------------------- /roles/mysql/templates/.my.cnf.j2: -------------------------------------------------------------------------------- 1 | [client] 2 | user=root 3 | password= -------------------------------------------------------------------------------- /roles/nginx-passenger/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | webserver_user: www-data 3 | -------------------------------------------------------------------------------- /roles/ssl/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependencies: 3 | - role: nginx-passenger 4 | -------------------------------------------------------------------------------- /roles/nodejs/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: install 2 | apt: name=nodejs state=present -------------------------------------------------------------------------------- /roles/webserver/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependencies: 3 | - role: nginx-passenger 4 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/tests/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | inventory = inventory 3 | roles_path = ../../ 4 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | */**.DS_Store 3 | ._* 4 | .*.sw* 5 | *~ 6 | .idea/ 7 | *.retry 8 | -------------------------------------------------------------------------------- /roles/mysql/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart mysql 3 | service: name={{ mysql_service }} state=restarted 4 | -------------------------------------------------------------------------------- /roles/nginx-passenger/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Reload nginx 3 | service: name=nginx state=reloaded enabled=true -------------------------------------------------------------------------------- /roles/s3cmd/templates/s3cfg.j2: -------------------------------------------------------------------------------- 1 | [default] 2 | access_key = {{ s3_key }} 3 | secret_key = {{ s3_secret }} 4 | use_https = True -------------------------------------------------------------------------------- /roles/nginx-passenger/templates/passenger.list: -------------------------------------------------------------------------------- 1 | deb https://oss-binaries.phusionpassenger.com/apt/passenger {{ distro.stdout }} main 2 | -------------------------------------------------------------------------------- /roles/nginx-passenger/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | nginx_conf_dir: /etc/nginx 3 | nginx_conf_file: "{{ nginx_conf_dir }}/sites-available/{{ app_name }}.conf" 4 | -------------------------------------------------------------------------------- /roles/s3cmd/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: install 2 | apt: name=s3cmd state=present 3 | 4 | - name: configure 5 | template: 6 | src="s3cfg.j2" 7 | dest="~/.s3cfg" -------------------------------------------------------------------------------- /roles/ssl/defaults/main.yml: -------------------------------------------------------------------------------- 1 | dehydrated_install_dir: /etc/dehydrated 2 | dehydrated_script_name: dehydrated.sh 3 | challenge_root_dir: /var/www/dehydrated 4 | challenge_relative_dir: /.well-known/acme-challenge 5 | letsencrypt_use_live_ca: false 6 | -------------------------------------------------------------------------------- /roles/deploy/templates/database.yml.j2: -------------------------------------------------------------------------------- 1 | production: 2 | adapter: mysql2 3 | encoding: utf8 4 | host: localhost 5 | database: {{ mysql_db_name }} 6 | pool: 5 7 | username: {{ mysql_db_user }} 8 | password: {{ mysql_db_password }} 9 | timeout: 5000 -------------------------------------------------------------------------------- /roles/rvm_io.ruby/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Install RVM 4 | import_tasks: 'rvm.yml' 5 | become: true 6 | become_user: '{{ rvm1_user }}' 7 | 8 | - name: Install Ruby and Gems 9 | import_tasks: 'rubies.yml' 10 | become: true 11 | become_user: '{{ rvm1_user }}' 12 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/tests/dockerfiles/centos6/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:6 2 | 3 | RUN yum update -y && \ 4 | yum install -y \ 5 | initscripts \ 6 | sudo \ 7 | && yum clean all 8 | 9 | RUN useradd -ms /bin/bash user \ 10 | && echo 'user ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers 11 | 12 | CMD ["/sbin/init"] 13 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/tests/dockerfiles/centos7/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | 3 | RUN yum update -y && \ 4 | yum install -y \ 5 | sudo \ 6 | which \ 7 | && yum clean all 8 | 9 | RUN useradd -ms /bin/bash user \ 10 | && echo 'user ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers 11 | 12 | CMD ["/usr/sbin/init"] 13 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/tests/inventory: -------------------------------------------------------------------------------- 1 | [centos] 2 | tests_centos6_1 ansible_connection=docker 3 | tests_centos7_1 ansible_connection=docker 4 | [debian] 5 | tests_debian8_1 ansible_connection=docker 6 | tests_debian9_1 ansible_connection=docker 7 | [ubuntu] 8 | tests_ubuntu14_1 ansible_connection=docker 9 | tests_ubuntu16_1 ansible_connection=docker 10 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/tests/dockerfiles/ubuntu16/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:16.04 2 | 3 | RUN apt-get update && \ 4 | apt-get install -y \ 5 | curl \ 6 | python \ 7 | sudo \ 8 | && rm -rf /var/lib/apt/lists/* 9 | 10 | RUN useradd -ms /bin/bash user \ 11 | && echo 'user ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers 12 | 13 | CMD ["/sbin/init"] 14 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/tests/dockerfiles/debian9/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:9 2 | 3 | RUN apt-get update && \ 4 | apt-get install -y \ 5 | curl \ 6 | gpg \ 7 | python \ 8 | sudo \ 9 | systemd \ 10 | && rm -rf /var/lib/apt/lists/* 11 | 12 | RUN useradd -ms /bin/bash user \ 13 | && echo 'user ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers 14 | 15 | CMD ["/bin/systemd"] 16 | -------------------------------------------------------------------------------- /roles/webserver/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: create deploy directory 2 | file: path={{ deploy_directory }} state=directory owner={{ deploy_user }} group={{ webserver_user }} mode=0775 3 | 4 | - name: update apt cache 5 | apt: update_cache=yes 6 | 7 | - name: install base libraries 8 | apt: name={{ item }} state=present 9 | with_items: 10 | - libxslt-dev 11 | - libxml2-dev 12 | - libmysqlclient-dev 13 | - imagemagick -------------------------------------------------------------------------------- /roles/user/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: create deploy user 2 | user: name={{ deploy_user }} shell=/bin/bash append=true 3 | 4 | - name: add deploy user public key to authorized_keys 5 | authorized_key: user={{ deploy_user }} key=https://github.com/{{ gh_pubkey_user }}.keys 6 | 7 | - name: add deploy user to sudoers 8 | lineinfile: 9 | "dest=/etc/sudoers 10 | regexp='^{{ deploy_user }} ALL' 11 | line='{{ deploy_user }} ALL=(ALL) NOPASSWD: ALL' 12 | state=present" -------------------------------------------------------------------------------- /roles/rvm_io.ruby/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: Nick Janetakis 4 | description: The official rvm role to install and manage your ruby versions. 5 | company: '' 6 | license: license (MIT) 7 | min_ansible_version: 2.2 8 | 9 | platforms: 10 | - name: EL 11 | versions: 12 | - all 13 | - name: Ubuntu 14 | versions: 15 | - all 16 | 17 | galaxy_tags: 18 | - development 19 | - web 20 | 21 | dependencies: [] 22 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/tests/root.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | gather_facts: false 4 | vars: 5 | rvm1_user: root 6 | rvm1_install_flags: '--auto-dotfiles' 7 | rvm1_install_path: '/home/{{ rvm1_user }}/.rvm' 8 | rvm1_rubies: 9 | - 'ruby-2.2.5' 10 | - 'ruby-2.3.1' 11 | roles: 12 | - role: rvm1-ansible 13 | 14 | # Asserts tasks 15 | - hosts: all 16 | gather_facts: false 17 | tasks: 18 | - name: Assert tasks 19 | include: assertions.yml 20 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/tests/user.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | gather_facts: false 4 | remote_user: user 5 | vars: 6 | rvm1_user: user 7 | rvm1_install_path: '/home/{{ rvm1_user }}/.rvm' 8 | rvm1_rubies: 9 | - 'ruby-2.2.5' 10 | - 'ruby-2.3.1' 11 | roles: 12 | - role: rvm1-ansible 13 | 14 | # Asserts tasks 15 | - hosts: all 16 | gather_facts: false 17 | remote_user: user 18 | tasks: 19 | - name: Assert tasks 20 | include: assertions.yml 21 | -------------------------------------------------------------------------------- /playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: provision 3 | hosts: all 4 | remote_user: root 5 | roles: 6 | - user 7 | - rvm_io.ruby 8 | - s3cmd 9 | - nodejs 10 | - mysql 11 | - nginx-passenger 12 | - role: ssl 13 | when: use_ssl 14 | domainsets: 15 | - domains: 16 | - "{{ webserver_name }}" 17 | - webserver 18 | 19 | - name: deploy 20 | hosts: all 21 | remote_user: "{{ deploy_user }}" 22 | gather_facts: no 23 | roles: 24 | - { role: deploy, tags: ['deploy'] } -------------------------------------------------------------------------------- /roles/rvm_io.ruby/tests/dockerfiles/debian8/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:8 2 | 3 | RUN apt-get update \ 4 | && apt-get install -y \ 5 | curl \ 6 | build-essential \ 7 | libbz2-dev \ 8 | libffi-dev \ 9 | libncurses5-dev \ 10 | libreadline-dev \ 11 | libssl-dev \ 12 | sudo \ 13 | wget \ 14 | && rm -rf /var/lib/apt/lists/* 15 | 16 | WORKDIR /opt/ 17 | COPY build /opt/build 18 | RUN bash build 19 | 20 | RUN useradd -ms /bin/bash user \ 21 | && echo 'user ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers 22 | 23 | CMD ["/sbin/init"] 24 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | rvm1_temp_download_path: '/tmp' 4 | 5 | rvm1_default_ruby_version: '{{ rvm1_rubies | last if rvm1_rubies and rvm1_rubies is iterable else rvm1_rubies }}' 6 | 7 | rvm1_rvm: '{{ rvm1_install_path }}/bin/rvm' 8 | 9 | rvm1_symlink_binaries: 10 | - 'erb' 11 | - 'executable-hooks-uninstaller' 12 | - 'gem' 13 | - 'irb' 14 | - 'rake' 15 | - 'rdoc' 16 | - 'ri' 17 | - 'ruby' 18 | 19 | rvm1_symlink_bundler_binaries: 20 | - 'bundle' 21 | - 'bundler' 22 | 23 | rvm1_symlink_to: '/usr/local/bin' 24 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/tests/dockerfiles/ubuntu14/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:14.04 2 | 3 | RUN apt-get update && \ 4 | apt-get install -y \ 5 | curl \ 6 | build-essential \ 7 | libbz2-dev \ 8 | libffi-dev \ 9 | libncurses5-dev \ 10 | libreadline-dev \ 11 | libssl-dev \ 12 | sudo \ 13 | wget \ 14 | && rm -rf /var/lib/apt/lists/* 15 | 16 | WORKDIR /opt/ 17 | COPY build /opt/build 18 | RUN bash build 19 | 20 | RUN useradd -ms /bin/bash user \ 21 | && echo 'user ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers 22 | 23 | CMD ["/sbin/init"] 24 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/tests/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | centos6: 4 | build: ./dockerfiles/centos6 5 | cap_add: 6 | - ALL 7 | centos7: 8 | build: ./dockerfiles/centos7 9 | cap_add: 10 | - ALL 11 | debian8: 12 | build: ./dockerfiles/debian8 13 | cap_add: 14 | - ALL 15 | debian9: 16 | build: ./dockerfiles/debian9 17 | cap_add: 18 | - ALL 19 | ubuntu14: 20 | build: ./dockerfiles/ubuntu14 21 | cap_add: 22 | - ALL 23 | ubuntu16: 24 | build: ./dockerfiles/ubuntu16 25 | cap_add: 26 | - ALL 27 | -------------------------------------------------------------------------------- /group_vars/all: -------------------------------------------------------------------------------- 1 | --- 2 | ansible_python_interpreter: /usr/bin/python3 3 | 4 | deploy_directory: "/home/{{ deploy_user }}/apps/{{ app_name }}" 5 | 6 | mysql_db_name: "{{ app_name }}" 7 | mysql_db_user: "{{ app_name }}" 8 | 9 | rvm1_user: "{{ deploy_user }}" 10 | rvm1_rubies: ["{{ruby_version}}"] 11 | rvm1_install_path: "/home/{{ deploy_user }}/.rvm" 12 | 13 | phusion_ruby_path: "/home/{{ deploy_user }}/.rvm/wrappers/{{ruby_version}}/ruby" 14 | s3_db_backup_location: s3://{{ app_name }}/db_backups 15 | letsencrypt_use_live_ca: true # If true, will use the Live Let's Encrypt ACME servers; otherwise will use staging server 16 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/tests/dockerfiles/debian8/build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | PI=/opt 4 | EXPECTED_VERSION="2.7.10" 5 | 6 | get_source(){ 7 | wget https://www.python.org/ftp/python/2.7.10/Python-2.7.10.tar.xz 8 | tar xvf Python-2.7.10.tar.xz 9 | cd Python-2.7.10 10 | } 11 | 12 | install_configure(){ 13 | ./configure 14 | make 15 | make install 16 | } 17 | 18 | remove(){ 19 | rm $PI/Python-2.7.10.tar.xz 20 | rm -rf $PI/Python-2.7.10 21 | } 22 | 23 | update_alternatives(){ 24 | update-alternatives --install /usr/bin/python python /usr/local/bin/python 10 25 | } 26 | 27 | version(){ 28 | VERSION=$(python -c "print __import__('sys').version[0:6]") 29 | 30 | if [ "$VERSION" == "$EXPECTED_VERSION" ]; 31 | then echo "Python $VERSION installed OK"; 32 | else echo "FAIL"; 33 | fi 34 | } 35 | 36 | cd $PI 37 | get_source 38 | install_configure 39 | update_alternatives 40 | remove 41 | 42 | version 43 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/tests/dockerfiles/ubuntu14/build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | PI=/opt 4 | EXPECTED_VERSION="2.7.10" 5 | 6 | get_source(){ 7 | wget https://www.python.org/ftp/python/2.7.10/Python-2.7.10.tar.xz 8 | tar xvf Python-2.7.10.tar.xz 9 | cd Python-2.7.10 10 | } 11 | 12 | install_configure(){ 13 | ./configure 14 | make 15 | make install 16 | } 17 | 18 | remove(){ 19 | rm $PI/Python-2.7.10.tar.xz 20 | rm -rf $PI/Python-2.7.10 21 | } 22 | 23 | update_alternatives(){ 24 | update-alternatives --install /usr/bin/python python /usr/local/bin/python 10 25 | } 26 | 27 | version(){ 28 | VERSION=$(python -c "print __import__('sys').version[0:6]") 29 | 30 | if [ "$VERSION" == "$EXPECTED_VERSION" ]; 31 | then echo "Python $VERSION installed OK"; 32 | else echo "FAIL"; 33 | fi 34 | } 35 | 36 | cd $PI 37 | get_source 38 | install_configure 39 | update_alternatives 40 | remove 41 | 42 | version 43 | -------------------------------------------------------------------------------- /installer.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [[ ! -f config.ru ]] ; then 4 | echo 'It appears the current working directory is not a Rails application.' 5 | exit 1 6 | fi 7 | 8 | # Clone ansible-rails into a folder called ops/ 9 | git clone https://github.com/bradymholt/ansible-rails.git ops && \ 10 | 11 | # Remove the installer file because it is not needed 12 | rm ./ops/installer.sh 13 | 14 | # Remove ops/.git folder to make the clone part of the Rails app itself 15 | rm -rf ./ops/.git && \ 16 | 17 | # Initial the config file using the template 18 | mv ops/config.yml.example ops/config.yml 19 | 20 | # Add ops/config.yml to .gitignore 21 | echo "ops/config.yml" >> .gitignore 22 | 23 | # Add new tasks to Rakefile 24 | cat <> ./Rakefile 25 | 26 | task :provision do 27 | sh "ansible-playbook -i ./ops/config.yml ./ops/playbook.yml" 28 | end 29 | 30 | task :deploy do 31 | sh "ansible-playbook -i ./ops/config.yml ./ops/playbook.yml --tags 'deploy'" 32 | end 33 | EOT -------------------------------------------------------------------------------- /roles/deploy/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: precompile assets 2 | local_action: command bundle exec rake assets:precompile chdir=../ 3 | 4 | - name: copy files (src is Rails root folder) 5 | synchronize: src=../../../../ dest={{ deploy_directory }} delete=yes rsync_opts=--exclude=.git/,--exclude=log/,--exclude=tmp/cache 6 | 7 | - name: config database.yml 8 | template: src=database.yml.j2 dest={{ deploy_directory}}/config/database.yml 9 | 10 | - name: bundle install 11 | command: bash -lc bundle install chdir={{ deploy_directory }} 12 | 13 | - name: migrate database 14 | command: bash -lc bundle exec rake db:migrate RAILS_ENV="production" chdir={{ deploy_directory }} 15 | 16 | - name: tmp clear 17 | command: bash -lc bundle exec rake tmp:clear chdir={{ deploy_directory }} 18 | 19 | - name: log clear 20 | command: bash -lc bundle exec rake log:clear chdir={{ deploy_directory }} 21 | 22 | - name: restart app 23 | file: 24 | state: touch 25 | path: "{{ deploy_directory }}/tmp/restart.txt" -------------------------------------------------------------------------------- /config.yml.example: -------------------------------------------------------------------------------- 1 | all: 2 | vars: 3 | # The following vars apply globally; additional config is in group_vars/all. 4 | app_name: my-app # name of application 5 | deploy_user: bholt # name of the remote user account for provisioning and deployment 6 | gh_pubkey_user: bradymholt # the Public key for this GitHub user will be added to authorized_keys for deploy_user 7 | ruby_version: ruby-2.4.3 # version of Ruby 8 | production: 9 | hosts: 10 | 159.65.171.101 # The hostname or IP address of the remote server 11 | vars: 12 | webserver_name: demo.geekytidbits.com # Virtual server name for Nginx config 13 | use_ssl: true # If true, SSL cert will be obtained from Let's Encrypt and Nginx provisioned for SSL 14 | mysql_root_password: 12345 # root pasword for MySQL instance 15 | mysql_db_password: 67890 # the application database will be configured with this password 16 | s3_key: 123_key_here # S3 Access Key used for uploading database backups 17 | s3_secret: 123_secret_here # S3 Access Secret used for uploading database backups 18 | -------------------------------------------------------------------------------- /roles/nginx-passenger/templates/etc_nginx_sites-available.conf.j2: -------------------------------------------------------------------------------- 1 | server { 2 | gzip on; 3 | listen 80; 4 | 5 | gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/json; 6 | server_name {{ webserver_name }}; 7 | root {{ deploy_directory }}/public; 8 | 9 | #ssl_config_marker 10 | 11 | # Turn on Passenger 12 | passenger_enabled on; 13 | passenger_ruby {{ phusion_ruby_path }}; 14 | passenger_env_var SECRET_KEY_BASE {{ secret_key_base }}; 15 | 16 | client_max_body_size 100M; 17 | 18 | location /robots.txt {} 19 | 20 | location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { 21 | expires 1y; 22 | log_not_found off; 23 | } 24 | 25 | location ~ ^/(assets|images|javascripts|stylesheets|swfs|system)/ { 26 | gzip_static on; 27 | expires max; 28 | add_header Cache-Control public; 29 | add_header Last-Modified ""; 30 | add_header ETag ""; 31 | 32 | break; 33 | } 34 | } 35 | 36 | server { 37 | server_name {{ webserver_name }}; 38 | rewrite ^ http://www.{{ webserver_name }}$request_uri? permanent; 39 | } 40 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Nick Janetakis nick.janetakis@gmail.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | 'Software'), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /roles/nginx-passenger/README.md: -------------------------------------------------------------------------------- 1 | nginx-passenger 2 | ========= 3 | 4 | Ansible role for installing nginx with passenger on Debian/Ubuntu. It does the following: 5 | 6 | 1. Remove apache2, nginx and passenger 7 | 2. Install Passenger PGP key 8 | 3. Add HTTPS support for apt 9 | 4. Add passenger source to /etc/apt/sources.list.d/ depending on distro 10 | 5. apt-get update 11 | 6. Install nginx-extras and passenger 12 | 7. Set passenger_root and passenger_ruby 13 | 8. Restart nginx 14 | 15 | This role *ONLY* ensures that nginx and passenger are installed and configed correctly. You need to config nginx to deploy your app. 16 | 17 | Requirements 18 | ------------ 19 | 20 | 1. You *should* have ruby installed at `/usr/bin/ruby`. `passenger_ruby` will point to `/usr/bin/ruby` 21 | 2. You need `sudo: yes` to play the role. 22 | 23 | Role Variables 24 | -------------- 25 | 26 | NONE 27 | 28 | Dependencies 29 | ------------ 30 | 31 | NONE 32 | 33 | Example Playbook 34 | ---------------- 35 | 36 | ``` 37 | - hosts: servers 38 | sudo: yes 39 | roles: 40 | - role: ChengLong.nginx-passenger 41 | ``` 42 | 43 | License 44 | ------- 45 | 46 | WTFPL 47 | 48 | Author Information 49 | ------------------ 50 | 51 | [Cheng Long](https://twitter.com/ChengLong_) 52 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/tests/assertions.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Check that ruby exists 3 | shell: . $HOME/.bash_profile && ruby -v | cut -c1-4 4 | args: 5 | executable: /bin/bash 6 | register: check_ruby 7 | changed_when: false 8 | - assert: 9 | that: 10 | - check_ruby.stdout == 'ruby' 11 | - check_ruby.rc == 0 12 | msg: No ruby installed 13 | 14 | - name: Check default ruby 15 | shell: ~/.rvm/wrappers/default/ruby -v | cut -c1-10 16 | register: check_ruby_default 17 | changed_when: false 18 | - assert: 19 | that: 20 | - check_ruby_default.stdout == 'ruby 2.3.1' 21 | msg: No default ruby installed 22 | 23 | - name: Check multiple rubies 24 | command: ls ~/.rvm/rubies 25 | register: check_ruby_multiple 26 | changed_when: false 27 | - assert: 28 | that: 29 | - "'ruby-2.2.5' in check_ruby_multiple.stdout" 30 | - "'ruby-2.3.1' in check_ruby_multiple.stdout" 31 | msg: No multiple rubies installed 32 | 33 | - name: Check bundler symlinked on system path 34 | shell: ls ~/.rvm/wrappers/default/ |grep 'bundler' 35 | register: check_ruby_bundler 36 | changed_when: false 37 | - assert: 38 | that: 39 | - check_ruby_bundler.stdout == 'bundler' 40 | msg: No bundler symlinked on system path 41 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: generic 3 | 4 | sudo: required 5 | 6 | env: 7 | DOCKER_COMPOSE_VERSION: 1.16.1 8 | 9 | services: 10 | - docker 11 | 12 | cache: 13 | pip: true 14 | directories: 15 | - $HOME/docker 16 | 17 | before_install: 18 | - if [[ -d $HOME/docker ]]; then ls $HOME/docker/*.tar.gz | xargs -I {file} sh -c "zcat {file} | docker load"; fi 19 | - sudo rm /usr/local/bin/docker-compose 20 | - curl -L https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_VERSION/docker-compose-`uname -s`-`uname -m` > docker-compose 21 | - chmod +x docker-compose 22 | - sudo mv docker-compose /usr/local/bin 23 | 24 | install: 25 | - sudo pip install ansible==2.2.2 > /dev/null 2>&1 26 | 27 | script: 28 | - cd tests 29 | - docker-compose up -d > /dev/null 2>&1 30 | - ansible-playbook user.yml -l centos 31 | - ansible-playbook user.yml -l debian 32 | - ansible-playbook user.yml -l ubuntu 33 | 34 | before_cache: 35 | - > 36 | mkdir -p $HOME/docker && docker images -a --filter='dangling=false' --format '{{.Repository}}:{{.Tag}} {{.ID}}' 37 | | xargs -n 2 -t sh -c 'test -e $HOME/docker/$1.tar.gz || docker save $0 | gzip -2 > $HOME/docker/$1.tar.gz' 38 | 39 | notifications: 40 | webhooks: https://galaxy.ansible.com/api/v1/notifications/ 41 | -------------------------------------------------------------------------------- /roles/mysql/templates/s3mysqlbackup.sh.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Based on https://gist.github.com/2206527 4 | 5 | # Be pretty 6 | echo -e " " 7 | echo -e " . ____ . ______________________________" 8 | echo -e " |/ \| | |" 9 | echo -e "[| \e[1;31m♥ ♥\e[00m |] | S3 MySQL Backup Script v.0.1 |" 10 | echo -e " |___==___| / © oodavid 2012 |" 11 | echo -e " |______________________________|" 12 | echo -e " " 13 | 14 | # Basic variables 15 | mysqlpass="{{ mysql_root_password }}" 16 | bucket="{{ s3_db_backup_location }}" 17 | 18 | # Timestamp (sortable AND readable) 19 | stamp=`date +"%s - %A %d %B %Y @ %H%M"` 20 | 21 | # List all the databases 22 | databases=`mysql -u root -p$mysqlpass -e "SHOW DATABASES;" | tr -d "| " | grep -v "\(Database\|information_schema\|performance_schema\|mysql\|test\)"` 23 | 24 | # Feedback 25 | echo -e "Dumping to \e[1;32m$bucket/$stamp/\e[00m" 26 | 27 | # Loop the databases 28 | for db in $databases; do 29 | 30 | # Define our filenames 31 | filename="$stamp - $db.sql.gz" 32 | tmpfile="/tmp/$filename" 33 | object="$bucket/$stamp/$filename" 34 | 35 | # Feedback 36 | echo -e "\e[1;34m$db\e[00m" 37 | 38 | # Dump and zip 39 | echo -e " creating \e[0;35m$tmpfile\e[00m" 40 | mysqldump -u root -p$mysqlpass --force --opt --databases "$db" | gzip -c > "$tmpfile" 41 | 42 | # Upload 43 | echo -e " uploading..." 44 | s3cmd put "$tmpfile" "$object" 45 | 46 | # Delete 47 | rm -f "$tmpfile" 48 | 49 | done; 50 | 51 | # Jobs a goodun 52 | echo -e "\e[1;32mJobs a goodun\e[00m" -------------------------------------------------------------------------------- /roles/mysql/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: install 2 | apt: name={{ item }} cache_valid_time=3600 state=present 3 | with_items: 4 | - libmysqlclient-dev 5 | - python-dev 6 | - mysql-server 7 | - python3-pip 8 | - python3-mysqldb 9 | 10 | - name: setup root config 11 | template: src=.my.cnf.j2 dest=~/.my.cnf owner=root mode=0644 12 | - name: Start the MySQL service 13 | service: 14 | name: mysql 15 | state: started 16 | enabled: true 17 | 18 | - name: update mysql root password for all root accounts 19 | mysql_user: 20 | name: root 21 | host: "{{ item }}" 22 | password: "{{ mysql_root_password }}" 23 | login_user: root 24 | login_password: "{{ mysql_root_password }}" 25 | check_implicit_admin: yes 26 | priv: "*.*:ALL,GRANT" 27 | with_items: 28 | - "{{ inventory_hostname }}" 29 | - 127.0.0.1 30 | - ::1 31 | - localhost 32 | 33 | - name: remove the test database 34 | mysql_db: name=test state=absent login_user=root login_password={{ mysql_root_password }} 35 | 36 | - name: create the app database 37 | mysql_db: name={{ mysql_db_name }} state=present login_user=root login_password={{ mysql_root_password }} 38 | 39 | - name: create the database users 40 | mysql_user: name={{ mysql_db_user }} password={{ mysql_db_password }} host=localhost priv="*.*:ALL" state=present login_user=root login_password={{ mysql_root_password }} 41 | 42 | - name: copy backup script 43 | template: src="s3mysqlbackup.sh.j2" dest="~/s3mysqlbackup.sh" mode="u+x" 44 | 45 | - name: setup backup cron 46 | cron: name="Daily MySQL Backup" minute="0" hour="1" 47 | job="bash /root/s3mysqlbackup.sh >/dev/null 2>&1" 48 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # Install 1 or more versions of ruby 4 | # The last ruby listed will be set as the default ruby 5 | rvm1_rubies: 6 | - 'ruby-2.3.1' 7 | 8 | # Install bundler 9 | rvm1_bundler_install: True 10 | 11 | # Delete a specific version of ruby (ie. ruby-2.1.0) 12 | rvm1_delete_ruby: 13 | 14 | # Install path for rvm (defaults to user based install) 15 | rvm1_install_path: '~/.rvm' 16 | 17 | # Add or remove any install flags 18 | # NOTE: If you are doing a ROOT BASED INSTALL then 19 | # make sure you REMOVE the --user-install flag below 20 | rvm1_install_flags: '--auto-dotfiles --user-install' 21 | 22 | # Add additional ruby install flags 23 | rvm1_ruby_install_flags: 24 | 25 | # Set the owner for the rvm directory 26 | rvm1_user: 'ubuntu' 27 | 28 | # URL for the latest installer script 29 | rvm1_rvm_latest_installer: 'https://raw.githubusercontent.com/rvm/rvm/master/binscripts/rvm-installer' 30 | 31 | # rvm version to use 32 | rvm1_rvm_version: 'stable' 33 | 34 | # Check and update rvm, disabling this will force rvm to never update 35 | rvm1_rvm_check_for_updates: True 36 | 37 | # GPG key verification, use an empty string if you want to skip this 38 | # Note: Unless you know what you're doing, just keep it as is 39 | # Identity proof: https://keybase.io/mpapis 40 | # PGP message: https://rvm.io/mpapis.asc 41 | rvm1_gpg_keys: '409B6B1796C275462A1703113804BB82D39DC0E3' 42 | 43 | # The GPG key server 44 | rvm1_gpg_key_server: 'hkp://keys.gnupg.net' 45 | 46 | # autolib mode, see https://rvm.io/rvm/autolibs 47 | rvm1_autolib_mode: 3 48 | 49 | # Name of UID 0 user 50 | root_user: 'root' 51 | 52 | # Name of GID 0 group -- BSD systems typically use wheel instead of root 53 | root_group: '{{ root_user }}' 54 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/tasks/rvm.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Detect rvm binary 4 | stat: path='{{ rvm1_rvm }}' 5 | register: rvm_binary 6 | 7 | - name: Detect rvm installer 8 | stat: path='{{ rvm1_temp_download_path }}/rvm-installer.sh' 9 | register: rvm_installer 10 | 11 | - name: Detect current rvm version 12 | command: '{{ rvm1_rvm}} version' 13 | changed_when: False 14 | register: rvm_current_version 15 | when: rvm_binary.stat.exists 16 | 17 | - name: Install rvm installer 18 | get_url: 19 | url: '{{ rvm1_rvm_latest_installer }}' 20 | dest: '{{ rvm1_temp_download_path }}/rvm-installer.sh' 21 | mode: 0755 22 | when: not rvm_installer.stat.exists 23 | 24 | - name: Import GPG keys 25 | command: 'gpg --keyserver {{ rvm1_gpg_key_server }} --recv-keys {{ rvm1_gpg_keys }}' 26 | changed_when: False 27 | check_mode: False 28 | when: not ansible_check_mode and rvm1_gpg_keys != '' 29 | register: gpg_result 30 | until: gpg_result.rc == 0 31 | retries: 5 32 | delay: 5 33 | ignore_errors: True 34 | 35 | - name: Import GPG keys the other way 36 | shell: curl -sSL https://rvm.io/mpapis.asc | gpg --import - 37 | when: not ansible_check_mode and rvm1_gpg_keys != '' and gpg_result.rc != 0 38 | 39 | - name: Install rvm 40 | command: > 41 | {{ rvm1_temp_download_path }}/rvm-installer.sh {{ rvm1_rvm_version }} 42 | --path {{ rvm1_install_path }} {{ rvm1_install_flags }} 43 | when: not rvm_binary.stat.exists 44 | 45 | - name: Update rvm 46 | shell: '{{ rvm1_rvm }} get {{ rvm1_rvm_version }} && {{ rvm1_rvm }} reload' 47 | changed_when: False 48 | when: rvm_binary.stat.exists and rvm1_rvm_check_for_updates 49 | 50 | - name: Configure rvm 51 | command: '{{ rvm1_rvm }} autolibs {{ rvm1_autolib_mode }}' 52 | when: not rvm_binary.stat.exists 53 | -------------------------------------------------------------------------------- /roles/nginx-passenger/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: Cheng Long 4 | description: Install nginx with passenger on Debian/Ubuntu 5 | # Some suggested licenses: 6 | # - BSD (default) 7 | # - MIT 8 | # - GPLv2 9 | # - GPLv3 10 | # - Apache 11 | # - CC-BY 12 | license: WTFPL 13 | min_ansible_version: 1.7 14 | # 15 | # Below are all platforms currently available. Just uncomment 16 | # the ones that apply to your role. If you don't see your 17 | # platform on this list, let us know and we'll get it added! 18 | # 19 | platforms: 20 | - name: Ubuntu 21 | versions: 22 | - all 23 | - lucid 24 | - maverick 25 | - natty 26 | - oneiric 27 | - precise 28 | - quantal 29 | - raring 30 | - saucy 31 | - trusty 32 | #- name: SLES 33 | # versions: 34 | # - all 35 | # - 10SP3 36 | # - 10SP4 37 | # - 11 38 | # - 11SP1 39 | # - 11SP2 40 | # - 11SP3 41 | #- name: GenericLinux 42 | # versions: 43 | # - all 44 | # - any 45 | - name: Debian 46 | versions: 47 | - all 48 | - etch 49 | - lenny 50 | - squeeze 51 | - wheezy 52 | # 53 | # Below are all categories currently available. Just as with 54 | # the platforms above, uncomment those that apply to your role. 55 | # 56 | categories: 57 | #- cloud 58 | #- cloud:ec2 59 | #- cloud:gce 60 | #- cloud:rax 61 | #- clustering 62 | #- database 63 | #- database:nosql 64 | #- database:sql 65 | - development 66 | #- monitoring 67 | #- networking 68 | #- packaging 69 | - system 70 | #- web 71 | dependencies: [] 72 | # List your role dependencies here, one per line. Only 73 | # dependencies available via galaxy should be listed here. 74 | # Be sure to remove the '[]' above if you add dependencies 75 | # to this list. 76 | 77 | -------------------------------------------------------------------------------- /roles/nginx-passenger/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: remove apache2, nginx and passenger 3 | apt: name={{ item }} state=absent 4 | with_items: 5 | - apache2 6 | - nginx 7 | - passenger 8 | 9 | - name: Phusion Passenger - add APT key 10 | apt_key: keyserver=keyserver.ubuntu.com id=561F9B9CAC40B2F7 state=present 11 | 12 | - name: Phusion Passenger - add APT repository 13 | apt_repository: 14 | repo: deb https://oss-binaries.phusionpassenger.com/apt/passenger {{ ansible_distribution_release }} main 15 | state: present 16 | 17 | - name: Find ubuntu/debian distro short name 18 | shell: > 19 | lsb_release -c | cut -d: -f2 | sed 's/\s//g' 20 | register: distro 21 | 22 | - name: Phusion Passenger - add source 23 | template: src=passenger.list dest=/etc/apt/sources.list.d/passenger.list owner=root group=root mode=0600 24 | 25 | - name: Phusion Passenger - install packages 26 | apt: name={{ item }} state=present 27 | with_items: 28 | - nginx-extras 29 | - passenger 30 | 31 | - name: Phusion Passenger - ensure passenger.conf included in nginx.conf 32 | lineinfile: 33 | dest=/etc/nginx/nginx.conf 34 | state=present 35 | backup=yes 36 | regexp='passenger.conf' 37 | line='include /etc/nginx/passenger.conf;' 38 | 39 | - name: Phusion Passenger - ensure passenger_root is excluded 40 | lineinfile: 41 | dest=/etc/nginx/nginx.conf 42 | state=absent 43 | backup=yes 44 | regexp='passenger_root' 45 | 46 | - name: nginx - remove the default app 47 | file: 48 | state: absent 49 | path: /etc/nginx/sites-enabled/default 50 | 51 | - name: nginx - remove the app symlink if exists 52 | file: 53 | state: absent 54 | path: /etc/nginx/sites-enabled/{{ app_name }} 55 | 56 | - name: generate a UUID for SECRET_KEY_BASE env var 57 | command: "uuidgen" 58 | register: uuidgen_output 59 | 60 | - set_fact: 61 | secret_key_base: "{{ uuidgen_output.stdout }}" 62 | 63 | - name: nginx - setup config for app 64 | template: src=etc_nginx_sites-available.conf.j2 dest={{ nginx_conf_file }} group={{ webserver_user }} owner={{ webserver_user }} force=yes 65 | 66 | - name: nginx - enable the app 67 | file: 68 | state: link 69 | src: "{{ nginx_conf_file }}" 70 | dest: /etc/nginx/sites-enabled/{{ app_name }} 71 | notify: Reload nginx -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ansible-rails 2 | 3 | 4 | 5 |
6 | 7 |  **Would you take a quick second and ⭐️ my repo?** 8 | 9 |
10 | 11 | This project is an Ansible playbook for provisioning and deploying a Rails/MySQL app to an Ubuntu server. It is intended to be added to an existing Rails application folder. Tested with: Rails 5.1.5, Ruby 2.4.3, Ubuntu 16.04 (Xenial). 12 | 13 | ## Demo 14 | 15 | [![asciicast](https://asciinema.org/a/166682.png)](https://asciinema.org/a/166682) 16 | 17 | ## Setup 18 | 19 | 1. [Ansible](http://docs.ansible.com/ansible/latest/intro_installation.html) >= 2.4.1 must be installed 20 | 1. This playbook assumes you are targeting MySQL for your production database and have `gem 'mysql2'` included in your Gemfile. 21 | 1. From your Rails application folder run: 22 | 23 | ```shell 24 | \curl -sSL https://raw.githubusercontent.com/bradymholt/ansible-rails/master/installer.sh | bash 25 | ``` 26 | 27 | which will: 28 | 29 | 1. Add this project to a new folder in your app called "ops" 30 | 2. Initialize the config file 31 | 3. Add 2 new rake tasks to your Rakefile: `provision` and `deploy`. 32 | 33 | If you would prefer, you can run the commands in this file manually. 34 | 1. Edit the `ops/config.yml` file and add your project configuration 35 | 36 | ## Provisioning 37 | 38 | Provisioning is used to to setup the the server and initially deploy the application. 39 | 40 | To provision your server, run: `rake provision`. This will do the following: 41 | 42 | - Install the following: 43 | - RVM 44 | - Nginx 45 | - Phusion passenger 46 | - MySQL 47 | - Libraries: libxslt-dev, libxml2-dev, libmysqlclient-dev, imagemagick 48 | - Create a user with ssh access and sudo authorization 49 | - Setup a daily backup job to backup MySQL database to S3 50 | - Create an app directory with appropriate permissions where Nginx config is pointing to 51 | - Configure TLS (https) via Let's Encrypt 52 | - Define an environment variable named `SECRET_KEY_BASE` with a unique uuid value. 53 | - Deploy the application: 54 | - Precompile assets locally with `rake assets:precompile`. 55 | - Copy app files to to remote server in the deploy directory 56 | - Update `config/database.yml` on remote server with correct production db config 57 | - Run the following remotely: 58 | - `bundle install` 59 | - `rake db:migrate RAILS_ENV="production"` 60 | - `rake tmp:clear` 61 | - `rake log:clear` 62 | - `touch tmp/restart.txt` (restart the app) 63 | 64 | ## Deploying 65 | 66 | If you have already provisioned your server and want to redeploy changes to your Rails app, run `rake deploy`. This will only run the deploy tasks from the playbook and be much faster. 67 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/tasks/rubies.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Detect if rubies are installed 4 | command: '{{ rvm1_rvm }} {{ item }} do true' 5 | changed_when: False 6 | failed_when: False 7 | register: detect_rubies 8 | with_items: '{{ rvm1_rubies }}' 9 | when: rvm1_rubies 10 | 11 | - name: Install rubies 12 | command: '{{ rvm1_rvm }} install {{ item.item }} {{ rvm1_ruby_install_flags }}' 13 | when: rvm1_rubies and item.rc|default(0) != 0 14 | with_items: '{{ detect_rubies.results }}' 15 | 16 | - name: Detect default ruby version 17 | command: '{{ rvm1_rvm }} alias list default' 18 | changed_when: False 19 | register: detect_default_ruby_version 20 | 21 | - name: Select default ruby 22 | command: '{{ rvm1_rvm }} alias create default {{ rvm1_default_ruby_version }}' 23 | when: detect_default_ruby_version.stdout|default() == '' or 24 | rvm1_default_ruby_version not in detect_default_ruby_version.stdout 25 | 26 | - name: Detect installed ruby patch number 27 | shell: > 28 | {{ rvm1_rvm }} list strings | grep {{ item }} | tail -n 1 29 | with_items: '{{ rvm1_rubies }}' 30 | changed_when: False 31 | register: ruby_patch 32 | check_mode: no # Run in normal mode when in --check mode (http://docs.ansible.com/ansible/playbooks_checkmode.html) 33 | 34 | - name: Install bundler if not installed 35 | shell: > 36 | ls {{ rvm1_install_path }}/wrappers/{{ item.stdout }} 37 | | if ! grep "^bundler " ; then {{ rvm1_install_path }}/wrappers/{{ item.stdout }}/gem install bundler ; fi 38 | args: 39 | creates: '{{ rvm1_install_path }}/wrappers/{{ item.stdout }}/bundler' 40 | with_items: '{{ ruby_patch.results }}' 41 | when: rvm1_bundler_install 42 | register: bundler_install 43 | changed_when: '"Successfully installed bundler" in bundler_install.stdout' 44 | 45 | - name: Symlink ruby related binaries on the system path 46 | file: 47 | state: 'link' 48 | src: '{{ rvm1_install_path }}/wrappers/default/{{ item }}' 49 | dest: '{{ rvm1_symlink_to }}/{{ item }}' 50 | owner: '{{ root_user }}' 51 | group: '{{ root_group }}' 52 | when: not '--user-install' in rvm1_install_flags 53 | with_items: '{{ rvm1_symlink_binaries }}' 54 | 55 | - name: Symlink bundler binaries on the system path 56 | file: 57 | state: 'link' 58 | src: '{{ rvm1_install_path }}/wrappers/default/{{ item }}' 59 | dest: '{{ rvm1_symlink_to }}/{{ item }}' 60 | owner: '{{ root_user }}' 61 | group: '{{ root_group }}' 62 | when: not '--user-install' in rvm1_install_flags and rvm1_bundler_install 63 | with_items: '{{ rvm1_symlink_bundler_binaries }}' 64 | 65 | - name: Detect if ruby version can be deleted 66 | command: '{{ rvm1_rvm }} {{ rvm1_delete_ruby }} do true' 67 | changed_when: False 68 | failed_when: False 69 | register: detect_delete_ruby 70 | when: rvm1_delete_ruby 71 | 72 | - name: Delete ruby version 73 | command: '{{ rvm1_rvm }} remove {{ rvm1_delete_ruby }}' 74 | changed_when: False 75 | when: rvm1_delete_ruby and detect_delete_ruby.rc == 0 76 | -------------------------------------------------------------------------------- /roles/ssl/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # Source: https://gist.github.com/raphaelm/10226edb0e46f7ce844e 2 | --- 3 | - name: Ensure Challenge directory exists 4 | file: path="{{ challenge_root_dir }}{{challenge_relative_dir}}" state=directory mode=0755 owner=root group={{webserver_user}} recurse=yes 5 | 6 | - name: Ensure curl is installed 7 | apt: name=curl state=installed 8 | 9 | - name: Ensure SSL base directory exists 10 | file: path={{ dehydrated_install_dir }} state=directory mode=0750 owner=root group={{webserver_user}} 11 | 12 | - name: Ensure SSL domain list exists 13 | command: "touch {{ dehydrated_install_dir }}/domains.txt" 14 | args: 15 | creates: "{{ dehydrated_install_dir }}/domains.txt" 16 | 17 | - name: Ensure LE config exists 18 | template: src=config.j2 dest="{{ dehydrated_install_dir }}/config" mode=0750 owner=root 19 | 20 | - name: Download dehydrated shell script 21 | get_url: 22 | url: https://raw.githubusercontent.com/lukas2511/dehydrated/master/dehydrated 23 | dest: "{{ dehydrated_install_dir }}/{{dehydrated_script_name}}" 24 | mode: 0700 25 | 26 | - name: Add line to domains file 27 | lineinfile: 28 | dest: "{{ dehydrated_install_dir }}/domains.txt" 29 | line: "{{ item.domains | join(' ') }}" 30 | with_items: "{{ domainsets }}" 31 | 32 | - name: Configure Nginx to serve the Challenge directory 33 | blockinfile: 34 | dest: "{{ nginx_conf_file }}" 35 | insertafter: "#ssl_config_marker" 36 | marker: "# {mark} ANSIBLE MANAGED BLOCK (CHALLENGE DIR CONFIG)" 37 | block: | 38 | location ^~ {{ challenge_relative_dir }} { 39 | root {{ challenge_root_dir }}; 40 | } 41 | register: challenge_directory_config 42 | 43 | - name: Reload nginx # Force reload when challenge_directory_config.changed because we need it to run before running LE script 44 | service: name=nginx state=reloaded enabled=true 45 | when: challenge_directory_config.changed 46 | 47 | - name: Execute dehydrated shell script 48 | shell: "./{{dehydrated_script_name}} --register --accept-terms && ./{{dehydrated_script_name}} -c" 49 | args: 50 | chdir: "{{ dehydrated_install_dir }}" 51 | notify: Reload nginx 52 | 53 | - name: Configure SSL in Nginx 54 | blockinfile: 55 | dest: "{{ nginx_conf_file }}" 56 | insertafter: "#ssl_config_marker" 57 | marker: "# {mark} ANSIBLE MANAGED BLOCK (SSL CONFIG)" 58 | block: | 59 | listen 443 ssl; 60 | ssl_certificate {{dehydrated_install_dir}}/certs/{{ webserver_name }}/fullchain.pem; 61 | ssl_certificate_key {{dehydrated_install_dir}}/certs/{{ webserver_name }}/privkey.pem; 62 | notify: Reload nginx 63 | 64 | - name: Remove default listen port (will be replaced with another server block) 65 | lineinfile: 66 | dest: "{{ nginx_conf_file }}" 67 | state: absent 68 | regexp: '#default_listen_marker' 69 | 70 | - name: Configure forced SSL redirect in Nginx 71 | blockinfile: 72 | dest: "{{ nginx_conf_file }}" 73 | insertafter: "#ssl_forced_config_marker" 74 | marker: "# {mark} ANSIBLE MANAGED BLOCK (FORCE SSL CONFIG)" 75 | block: | 76 | server { 77 | listen 80; 78 | server_name {{ webserver_name }}; 79 | rewrite ^ https://$server_name$request_uri? permanent; 80 | } 81 | notify: Reload nginx 82 | 83 | - name: Add LE cronjob 84 | cron: name=lets-encrypt hour=4 minute=23 day=*/3 job="{{ dehydrated_install_dir }}/{{ dehydrated_script_name }} -c && service nginx reload" 85 | -------------------------------------------------------------------------------- /roles/ssl/templates/config.j2: -------------------------------------------------------------------------------- 1 | ######################################################## 2 | # This is the main config file for dehydrated # 3 | # # 4 | # This file is looked for in the following locations: # 5 | # $SCRIPTDIR/config (next to this script) # 6 | # /usr/local/etc/dehydrated/config # 7 | # /etc/dehydrated/config # 8 | # ${PWD}/config (in current working-directory) # 9 | # # 10 | # Default values of this config are in comments # 11 | ######################################################## 12 | 13 | # Resolve names to addresses of IP version only. (curl) 14 | # supported values: 4, 6 15 | # default: 16 | #IP_VERSION= 17 | 18 | # Path to certificate authority (default: https://acme-v01.api.letsencrypt.org/directory) 19 | CA="{{ "https://acme-v01.api.letsencrypt.org/directory" if (letsencrypt_use_live_ca | bool) == true else "https://acme-staging.api.letsencrypt.org/directory" }}" 20 | 21 | # Path to license agreement (default: https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf) 22 | #LICENSE="https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf" 23 | 24 | # Which challenge should be used? Currently http-01 and dns-01 are supported 25 | CHALLENGETYPE="http-01" 26 | 27 | # Path to a directory containing additional config files, allowing to override 28 | # the defaults found in the main configuration file. Additional config files 29 | # in this directory needs to be named with a '.sh' ending. 30 | # default: 31 | #CONFIG_D= 32 | 33 | # Base directory for account key, generated certificates and list of domains (default: $SCRIPTDIR -- uses config directory if undefined) 34 | #BASEDIR=$SCRIPTDIR 35 | 36 | # File containing the list of domains to request certificates for (default: $BASEDIR/domains.txt) 37 | #DOMAINS_TXT="${BASEDIR}/domains.txt" 38 | 39 | # Output directory for generated certificates 40 | #CERTDIR="${BASEDIR}/certs" 41 | 42 | # Directory for account keys and registration information 43 | #ACCOUNTDIR="${BASEDIR}/accounts" 44 | 45 | # Output directory for challenge-tokens to be served by webserver or deployed in HOOK (default: /var/www/dehydrated) 46 | WELLKNOWN="/var/www/dehydrated/.well-known/acme-challenge" 47 | 48 | # Default keysize for private keys (default: 4096) 49 | #KEYSIZE="4096" 50 | 51 | # Path to openssl config file (default: - tries to figure out system default) 52 | #OPENSSL_CNF= 53 | 54 | # Program or function called in certain situations 55 | # 56 | # After generating the challenge-response, or after failed challenge (in this case altname is empty) 57 | # Given arguments: clean_challenge|deploy_challenge altname token-filename token-content 58 | # 59 | # After successfully signing certificate 60 | # Given arguments: deploy_cert domain path/to/privkey.pem path/to/cert.pem path/to/fullchain.pem 61 | # 62 | # BASEDIR and WELLKNOWN variables are exported and can be used in an external program 63 | # default: 64 | #HOOK= 65 | 66 | # Chain clean_challenge|deploy_challenge arguments together into one hook call per certificate (default: no) 67 | #HOOK_CHAIN="no" 68 | 69 | # Minimum days before expiration to automatically renew certificate (default: 30) 70 | #RENEW_DAYS="30" 71 | 72 | # Regenerate private keys instead of just signing new certificates on renewal (default: yes) 73 | #PRIVATE_KEY_RENEW="yes" 74 | 75 | # Which public key algorithm should be used? Supported: rsa, prime256v1 and secp384r1 76 | #KEY_ALGO=rsa 77 | 78 | # E-mail to use during the registration (default: ) 79 | #CONTACT_EMAIL= 80 | 81 | # Lockfile location, to prevent concurrent access (default: $BASEDIR/lock) 82 | #LOCKFILE="${BASEDIR}/lock" 83 | 84 | # Option to add CSR-flag indicating OCSP stapling to be mandatory (default: no) 85 | #OCSP_MUST_STAPLE="no" 86 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | ## MASTER 3 | 4 | ### v2.0.1 5 | * Fix issue `src file does not exist` cause by testrb 6 | 7 | ### v2.0.0 8 | * Bump ansible version to 2.2 9 | * Update readme 10 | 11 | ### v1.3.9 12 | * Fix bugs 13 | * Use a non-root user by default for the installation. 14 | 15 | ### v1.3.8 16 | * Bump ruby version to 2.2.2 17 | * Fix Bundler symlinking on system path 18 | * This fixes the location of the bundler pointing to the global ruby version 19 | * Ensure a default value is supplied when detecting ruby, fixes #78 20 | * Update rvm installer path 21 | * Update become method 22 | * Ensure installed rubies and gems are owned correctly by rvm1_user 23 | 24 | ### v1.3.7 25 | * Fix #40 by using a proper gem path 26 | 27 | ### v1.3.6 28 | * Recent changes to rvm made bundler not get installed by default 29 | * This patch installs bundler by default 30 | 31 | ### v1.3.5 32 | * Ensure rvm1_user owns all rvm related files 33 | * Allow passing in custom configuration options when installing ruby 34 | 35 | ### v1.3.4 36 | * Change the default system wide install dir back to /usr/local/rvm 37 | * Add the rvm1_user: 'root' default variable to let you set the rvm directory owner 38 | * Update the README on why setting sudo: True is necessary 39 | 40 | ### v1.3.3 41 | * Fix an incorrect condition which caused Ansible to error out 42 | 43 | ### v1.3.2 44 | * Import the GPG signature every time rvm runs get [version]. 45 | 46 | ### v1.3.1 47 | * Add gpg signature verification 48 | 49 | ### v1.3.0 50 | * Remove the python-httplib2 dependency so it should work on CentOS 7 51 | * Change how versions are set, check the readme 52 | * Always run rvm update unless you disable it by overwriting rvm1_rvm_check_for_updates 53 | 54 | ### v1.2.0 55 | * Add CentOS/RHEL support 56 | 57 | ### v1.1.1 58 | * Fix #7 and #8 by no longer chowning the user:group 59 | * Symlink the ruby related bins to /usr/local/bin when doing a system wide install 60 | * Remove the temp install dir, always use /tmp 61 | * Expose the rvm install flags in a new default variable rvm1_install_flags 62 | * Change the default system wide install dir to /usr/local/lib/rvm 63 | * Update the readme to be much more clear and provide 3 examples of how to install rvm 64 | * Update the travis test to test against ansible 1.7.1 instead of 1.6.2 65 | * Reformat all of the tasks to make them more readable and maintainable 66 | 67 | ### v1.0.2 68 | * Force sudo as root when having to apt install python-httplib2, fixes #5. 69 | 70 | ### v1.0.1 71 | * Install httplib2 if necessary (the ansible uri module depends on this) 72 | 73 | 74 | ### v1.0.0 75 | * Add ability to define 1 or more ruby versions 76 | * Add ability to delete ruby versions 77 | * Expose a few useful variables and paths 78 | * Switch over from nickjj.ruby to rvm1-ansible 79 | 80 | ### v0.1.9 81 | * Really fix the detect tasks so they are idempotent 82 | 83 | ### v0.1.8 84 | * Fix the detect tasks so they are idempotent 85 | 86 | ### v0.1.7 87 | * Simplify the default ruby selection tasks into a single task 88 | 89 | ### v0.1.6 90 | * Fix the default ruby selection task so it works for both local and system installs 91 | 92 | ### v0.1.5 93 | * Fix a bug where /etc/profile.d/rvm.sh would be sourced even if it did not exist 94 | * Add the --default flag to the rvm use command 95 | 96 | ### v0.1.4 97 | * Bump the default version of ruby to 2.1.2 98 | 99 | ### v0.1.3 100 | * Fix a bug with how the upgrade task was checking for rvm's existence 101 | * Change how the role checks to determine if rvm is installed 102 | 103 | ### v0.1.2 104 | * Allow you to specify a local path or url for the rvm installer script 105 | * Allow you to specify a url or variable value for the latest rvm stable version number 106 | 107 | ### v0.1.1 108 | * Auto upgrade rvm in an idempotent way but also allow you to turn this off 109 | * Keep the rvm installer file on the server instead of deleting it in case http://get.rvm.io is down 110 | * Toggle a variable to force update the installer 111 | 112 | ### v0.1.0 113 | * View the readme to get a better understanding of what ansible-ruby does. 114 | -------------------------------------------------------------------------------- /roles/mysql/README.md: -------------------------------------------------------------------------------- 1 | MySQL Server 2 | ============ 3 | 4 | This roles helps to install MySQL Server across RHEL and Ubuntu variants. 5 | Apart from installing the MySQL Server, it applies basic hardening, like 6 | securing the root account with password, and removing test databases. The role 7 | can also be used to add databases to the MySQL server and create users in the 8 | database. It also supports configuring the databases for replication--both 9 | master and slave can be configured via this role. 10 | 11 | Requirements 12 | ------------ 13 | 14 | This role requires Ansible 1.4 or higher, and platform requirements are listed 15 | in the metadata file. 16 | 17 | Role Variables 18 | -------------- 19 | 20 | The variables that can be passed to this role and a brief description about 21 | them are as follows: 22 | 23 | mysql_port: 3306 # The port for mysql server to listen 24 | mysql_bind_address: "0.0.0.0" # The bind address for mysql server 25 | mysql_root_db_pass: foobar # The root DB password 26 | 27 | # A list that has all the databases to be 28 | # created and their replication status: 29 | mysql_db: 30 | - name: foo 31 | replicate: yes 32 | - name: bar 33 | replicate: no 34 | 35 | # A list of the mysql users to be created 36 | # and their password and privileges: 37 | mysql_users: 38 | - name: benz 39 | pass: foobar 40 | priv: "*.*:ALL" 41 | 42 | # If the database is replicated the users 43 | # to be used for replication: 44 | mysql_repl_user: 45 | - name: repl 46 | pass: foobar 47 | 48 | # The role of this server in replication: 49 | mysql_repl_role: master 50 | 51 | # A unique id for the mysql server (used in replication): 52 | mysql_db_id: 7 53 | 54 | Examples 55 | -------- 56 | 57 | 1) Install MySQL Server and set the root password, but don't create any 58 | database or users. 59 | 60 | - hosts: all 61 | roles: 62 | - {role: mysql, mysql_root_db_pass: foobar, mysql_db: none, mysql_users: none } 63 | 64 | 2) Install MySQL Server and create 2 databases and 2 users. 65 | 66 | - hosts: all 67 | roles: 68 | - {role: mysql, mysql_db: [{name: benz}, 69 | {name: benz2}], 70 | mysql_users: [{name: ben3, pass: foobar, priv: "*.*:ALL"}, 71 | {name: ben2, pass: foo}] } 72 | 73 | Note: If users are specified and password/privileges are not specified, then 74 | default values are set. 75 | 76 | 3) Install MySQL Server and create 2 databases and 2 users and configure the 77 | database as replication master with one database configured for replication. 78 | 79 | - hosts: all 80 | roles: 81 | - {role: mysql, mysql_db: [{name: benz, replicate: yes }, 82 | { name: benz2, replicate: no}], 83 | mysql_users: [{name: ben3, pass: foobar, priv: "*.*:ALL"}, 84 | {name: ben2, pass: foo}], 85 | mysql_repl_user: [{name: repl, pass: foobar}] } 86 | 87 | 4) A fully installed/configured MySQL Server with master and slave 88 | replication. 89 | 90 | - hosts: master 91 | roles: 92 | - {role: mysql, mysql_db: [{name: benz}, {name: benz2}], 93 | mysql_users: [{name: ben3, pass: foobar, priv: "*.*:ALL"}, 94 | {name: ben2, pass: foo}], 95 | mysql_db_id: 8 } 96 | 97 | - hosts: slave 98 | roles: 99 | - {role: mysql, mysql_db: none, mysql_users: none, 100 | mysql_repl_role: slave, mysql_repl_master: vm2, 101 | mysql_db_id: 9, mysql_repl_user: [{name: repl, pass: foobar}] } 102 | 103 | Note: When configuring the full replication please make sure the master is 104 | configured via this role and the master is available in inventory and facts 105 | have been gathered for master. The replication tasks assume the database is 106 | new and has no data. 107 | 108 | 109 | Dependencies 110 | ------------ 111 | 112 | None 113 | 114 | License 115 | ------- 116 | 117 | BSD 118 | 119 | Author Information 120 | ------------------ 121 | 122 | Benno Joy 123 | 124 | 125 | -------------------------------------------------------------------------------- /roles/rvm_io.ruby/README.md: -------------------------------------------------------------------------------- 1 | ## What is rvm1-ansible? [![Build Status](https://travis-ci.org/rvm/rvm1-ansible.svg?branch=master)](https://travis-ci.org/rvm/rvm1-ansible) [![Ansible Role](https://img.shields.io/badge/role-rvm_io-red.svg)](https://galaxy.ansible.com/rvm_io/ruby/) 2 | 3 | It is an [Ansible](http://www.ansible.com/home) role to install and manage ruby versions using rvm. 4 | 5 | ### Why should you use rvm? 6 | 7 | In production it's useful because compiling a new version of ruby can easily 8 | take upwards of 10 minutes. That's 10 minutes of your CPU being pegged at 100%. 9 | 10 | rvm has pre-compiled binaries for a lot of operating systems. That means you can 11 | install ruby in about 1 minute, even on a slow micro instance. 12 | 13 | This role even adds the ruby binaries to your system path when doing a system 14 | wide install. This allows you to access them as if they were installed without 15 | using a version manager while still benefiting from what rvm has to offer. 16 | 17 | ## Installation 18 | 19 | `$ ansible-galaxy install rvm_io.ruby` 20 | 21 | ## Role variables 22 | 23 | Below is a list of default values that you can configure: 24 | 25 | ```yaml 26 | --- 27 | 28 | # Install 1 or more versions of ruby 29 | # The last ruby listed will be set as the default ruby 30 | rvm1_rubies: 31 | - 'ruby-2.3.1' 32 | 33 | # Install the bundler gem 34 | rvm1_bundler_install: True 35 | 36 | # Delete a specific version of ruby (ie. ruby-2.1.0) 37 | rvm1_delete_ruby: 38 | 39 | # Install path for rvm (defaults to single user) 40 | # NOTE: If you are doing a ROOT BASED INSTALL then make sure you 41 | # set the install path to something like '/usr/local/rvm' 42 | rvm1_install_path: '~/.rvm' 43 | 44 | # Add or remove any install flags 45 | # NOTE: If you are doing a ROOT BASED INSTALL then 46 | # make sure you REMOVE the --user-install flag below 47 | rvm1_install_flags: '--auto-dotfiles --user-install' 48 | 49 | # Add additional ruby install flags 50 | rvm1_ruby_install_flags: 51 | 52 | # Set the owner for the rvm directory 53 | # NOTE: If you are doing a ROOT BASED INSTALL then 54 | # make sure you set rvm1_user to 'root' 55 | rvm1_user: 'ubuntu' 56 | 57 | # URL for the latest installer script 58 | rvm1_rvm_latest_installer: 'https://raw.githubusercontent.com/rvm/rvm/master/binscripts/rvm-installer' 59 | 60 | # rvm version to use 61 | rvm1_rvm_version: 'stable' 62 | 63 | # Check and update rvm, disabling this will force rvm to never update 64 | rvm1_rvm_check_for_updates: True 65 | 66 | # GPG key verification, use an empty string if you want to skip this 67 | # Note: Unless you know what you're doing, just keep it as is 68 | # Identity proof: https://keybase.io/mpapis 69 | # PGP message: https://rvm.io/mpapis.asc 70 | rvm1_gpg_keys: '409B6B1796C275462A1703113804BB82D39DC0E3' 71 | 72 | # The GPG key server 73 | rvm1_gpg_key_server: 'hkp://keys.gnupg.net' 74 | 75 | # autolib mode, see https://rvm.io/rvm/autolibs 76 | rvm1_autolib_mode: 3 77 | ``` 78 | 79 | ## Example playbooks 80 | 81 | ```yaml 82 | --- 83 | 84 | - name: Configure servers with ruby support for single user 85 | hosts: all 86 | 87 | roles: 88 | - { role: rvm_io.ruby, 89 | tags: ruby, 90 | rvm1_rubies: ['ruby-2.3.1'], 91 | rvm1_user: 'ubuntu' 92 | } 93 | ``` 94 | 95 | If you need to pass a list of ruby versions, pass it in an array like so. 96 | 97 | ```yaml 98 | --- 99 | - name: Configure servers with ruby support system wide 100 | hosts: all 101 | roles: 102 | - { role: rvm_io.ruby, 103 | tags: ruby, 104 | become: yes, 105 | 106 | rvm1_rubies: ['ruby-2.2.5','ruby-2.3.1'], 107 | rvm1_install_flags: '--auto-dotfiles', # Remove --user-install from defaults 108 | rvm1_install_path: /usr/local/rvm, # Set to system location 109 | rvm1_user: root # Need root account to access system location 110 | } 111 | ``` 112 | _rvm_rubies must be specified via `ruby-x.x.x` so that if you want_ 113 | _ruby 2.2.5, you will need to pass in an array **rvm_rubies: ['ruby-2.2.5']**_ 114 | 115 | 116 | #### System wide installation 117 | 118 | The above example would setup ruby system wide. It's very important that you run the 119 | play as root because it will need to write to a system location specified by rvm1_install_path 120 | 121 | #### To the same user as `ansible_user` 122 | 123 | In this case, just overwrite `rvm_install_path` and by default is set the `--user-install` flag: 124 | 125 | ```yaml 126 | rvm1_install_flags: '--auto-dotfiles --user-install' 127 | rvm1_install_path: '/home/{{ ansible_user }}/.rvm' 128 | ``` 129 | 130 | #### To a user that is not `ansible_user` 131 | 132 | You **will need root access here** because you will be writing outside the ansible 133 | user's home directory. Other than that it's the same as above, except you will 134 | supply a different user account: 135 | 136 | ```yaml 137 | rvm1_install_flags: '--auto-dotfiles --user-install' 138 | rvm1_install_path: '/home/someuser/.rvm' 139 | ``` 140 | 141 | #### A quick note about `rvm1_user` 142 | 143 | In some cases you may want the rvm folder and its files to be owned by a specific 144 | user instead of root. Simply set `rvm1_user: 'foo'` and when ruby gets installed 145 | it will ensure that `foo` owns the rvm directory. 146 | 147 | ## Upgrading and removing old versions of ruby 148 | 149 | A common work flow for upgrading your ruby version would be: 150 | 151 | 1. Install the new version 152 | 2. Run your application role so that bundle install re-installs your gems 153 | 3. Delete the previous version of ruby 154 | 155 | ### Leverage ansible's `--extra-vars` 156 | 157 | Just add `--extra-vars 'rvm1_delete_ruby=ruby-2.1.0'` to the end of your play book command and that version will be removed. 158 | 159 | ## Requirements 160 | 161 | - Tested on ubuntu 12.04 LTS but it should work on other versions that are similar. 162 | - Tested on RHEL6.5 and CentOS [6.5, 6.6, 6.7] 163 | 164 | ## Ansible galaxy 165 | 166 | You can find it on the official [ansible galaxy](https://galaxy.ansible.com/rvm_io/ruby/) if you want to rate it. 167 | 168 | ## License 169 | 170 | MIT 171 | --------------------------------------------------------------------------------