Repository: ansible/ansible-examples Branch: master Commit: b50586543c6c Files: 306 Total size: 349.1 KB Directory structure: gitextract_jrxe4k79/ ├── .github/ │ └── workflows/ │ └── main.yml ├── .gitignore ├── README.md ├── jboss-standalone/ │ ├── LICENSE.md │ ├── README.md │ ├── demo-aws-launch.yml │ ├── deploy-application.yml │ ├── group_vars/ │ │ └── all │ ├── hosts │ ├── roles/ │ │ ├── java-app/ │ │ │ ├── files/ │ │ │ │ ├── jboss-helloworld.war │ │ │ │ └── ticket-monster.war │ │ │ └── tasks/ │ │ │ └── main.yml │ │ └── jboss-standalone/ │ │ ├── files/ │ │ │ └── jboss-as-standalone.sh │ │ ├── handlers/ │ │ │ └── main.yml │ │ ├── tasks/ │ │ │ └── main.yml │ │ └── templates/ │ │ ├── iptables-save │ │ └── standalone.xml │ └── site.yml ├── lamp_haproxy/ │ ├── LICENSE.md │ ├── README.md │ ├── aws/ │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── demo-aws-launch.yml │ │ ├── group_vars/ │ │ │ ├── all │ │ │ ├── tag_ansible_group_dbservers │ │ │ ├── tag_ansible_group_lbservers │ │ │ └── tag_ansible_group_webservers │ │ ├── roles/ │ │ │ ├── base-apache/ │ │ │ │ └── tasks/ │ │ │ │ └── main.yml │ │ │ ├── common/ │ │ │ │ ├── files/ │ │ │ │ │ ├── RPM-GPG-KEY-EPEL-6 │ │ │ │ │ └── epel.repo │ │ │ │ ├── handlers/ │ │ │ │ │ └── main.yml │ │ │ │ ├── tasks/ │ │ │ │ │ └── main.yml │ │ │ │ └── templates/ │ │ │ │ ├── iptables.j2 │ │ │ │ └── ntp.conf.j2 │ │ │ ├── db/ │ │ │ │ ├── handlers/ │ │ │ │ │ └── main.yml │ │ │ │ ├── tasks/ │ │ │ │ │ └── main.yml │ │ │ │ └── templates/ │ │ │ │ └── my.cnf.j2 │ │ │ ├── haproxy/ │ │ │ │ ├── handlers/ │ │ │ │ │ └── main.yml │ │ │ │ ├── tasks/ │ │ │ │ │ └── main.yml │ │ │ │ └── templates/ │ │ │ │ └── haproxy.cfg.j2 │ │ │ ├── nagios/ │ │ │ │ ├── files/ │ │ │ │ │ ├── ansible-managed-services.cfg │ │ │ │ │ ├── localhost.cfg │ │ │ │ │ └── nagios.cfg │ │ │ │ ├── handlers/ │ │ │ │ │ └── main.yml │ │ │ │ ├── tasks/ │ │ │ │ │ └── main.yml │ │ │ │ └── templates/ │ │ │ │ ├── dbservers.cfg.j2 │ │ │ │ ├── lbservers.cfg.j2 │ │ │ │ └── webservers.cfg.j2 │ │ │ └── web/ │ │ │ └── tasks/ │ │ │ └── main.yml │ │ ├── rolling_update.yml │ │ └── site.yml │ ├── group_vars/ │ │ ├── all │ │ ├── dbservers │ │ ├── lbservers │ │ └── webservers │ ├── hosts │ ├── provision.yml │ ├── roles/ │ │ ├── base-apache/ │ │ │ └── tasks/ │ │ │ └── main.yml │ │ ├── common/ │ │ │ ├── files/ │ │ │ │ ├── RPM-GPG-KEY-EPEL-6 │ │ │ │ └── epel.repo │ │ │ ├── handlers/ │ │ │ │ └── main.yml │ │ │ ├── tasks/ │ │ │ │ └── main.yml │ │ │ └── templates/ │ │ │ ├── iptables.j2 │ │ │ └── ntp.conf.j2 │ │ ├── db/ │ │ │ ├── handlers/ │ │ │ │ └── main.yml │ │ │ ├── tasks/ │ │ │ │ └── main.yml │ │ │ └── templates/ │ │ │ └── my.cnf.j2 │ │ ├── haproxy/ │ │ │ ├── handlers/ │ │ │ │ └── main.yml │ │ │ ├── tasks/ │ │ │ │ └── main.yml │ │ │ └── templates/ │ │ │ └── haproxy.cfg.j2 │ │ ├── nagios/ │ │ │ ├── files/ │ │ │ │ ├── ansible-managed-services.cfg │ │ │ │ ├── localhost.cfg │ │ │ │ └── nagios.cfg │ │ │ ├── handlers/ │ │ │ │ └── main.yml │ │ │ ├── tasks/ │ │ │ │ └── main.yml │ │ │ └── templates/ │ │ │ ├── dbservers.cfg.j2 │ │ │ ├── lbservers.cfg.j2 │ │ │ └── webservers.cfg.j2 │ │ └── web/ │ │ └── tasks/ │ │ └── main.yml │ ├── rolling_update.yml │ └── site.yml ├── lamp_simple/ │ ├── LICENSE.md │ ├── README.md │ ├── group_vars/ │ │ ├── all │ │ └── dbservers │ ├── hosts │ ├── roles/ │ │ ├── common/ │ │ │ ├── handlers/ │ │ │ │ └── main.yml │ │ │ ├── tasks/ │ │ │ │ └── main.yml │ │ │ └── templates/ │ │ │ └── ntp.conf.j2 │ │ ├── db/ │ │ │ ├── handlers/ │ │ │ │ └── main.yml │ │ │ ├── tasks/ │ │ │ │ └── main.yml │ │ │ └── templates/ │ │ │ └── my.cnf.j2 │ │ └── web/ │ │ ├── handlers/ │ │ │ └── main.yml │ │ ├── tasks/ │ │ │ ├── copy_code.yml │ │ │ ├── install_httpd.yml │ │ │ └── main.yml │ │ └── templates/ │ │ └── index.php.j2 │ └── site.yml ├── lamp_simple_rhel7/ │ ├── LICENSE.md │ ├── README.md │ ├── group_vars/ │ │ ├── all │ │ └── dbservers │ ├── hosts │ ├── roles/ │ │ ├── common/ │ │ │ ├── handlers/ │ │ │ │ └── main.yml │ │ │ ├── tasks/ │ │ │ │ └── main.yml │ │ │ └── templates/ │ │ │ └── ntp.conf.j2 │ │ ├── db/ │ │ │ ├── handlers/ │ │ │ │ └── main.yml │ │ │ ├── tasks/ │ │ │ │ └── main.yml │ │ │ └── templates/ │ │ │ └── my.cnf.j2 │ │ └── web/ │ │ ├── tasks/ │ │ │ ├── copy_code.yml │ │ │ ├── install_httpd.yml │ │ │ └── main.yml │ │ └── templates/ │ │ └── index.php.j2 │ └── site.yml ├── language_features/ │ ├── ansible_pull.yml │ ├── batch_size_control.yml │ ├── cloudformation.yaml │ ├── complex_args.yml │ ├── conditionals_part1.yml │ ├── conditionals_part2.yml │ ├── custom_filters.yml │ ├── delegation.yml │ ├── environment.yml │ ├── eucalyptus-ec2.yml │ ├── file_secontext.yml │ ├── files/ │ │ └── cloudformation-example.json │ ├── filter_plugins/ │ │ └── custom_plugins.py │ ├── get_url.yml │ ├── group_by.yml │ ├── group_commands.yml │ ├── handlers/ │ │ └── handlers.yml │ ├── intermediate_example.yml │ ├── intro_example.yml │ ├── loop_nested.yml │ ├── loop_plugins.yml │ ├── loop_with_items.yml │ ├── mysql.yml │ ├── nested_playbooks.yml │ ├── netscaler.yml │ ├── postgresql.yml │ ├── prompts.yml │ ├── rabbitmq.yml │ ├── register_logic.yml │ ├── roles/ │ │ └── foo/ │ │ ├── files/ │ │ │ └── foo.txt │ │ ├── handlers/ │ │ │ └── main.yml │ │ ├── tasks/ │ │ │ └── main.yml │ │ ├── templates/ │ │ │ └── foo.j2 │ │ └── vars/ │ │ └── main.yml │ ├── roletest.yml │ ├── roletest2.yml │ ├── selective_file_sources.yml │ ├── tags.yml │ ├── tasks/ │ │ └── base.yml │ ├── templates/ │ │ ├── custom-filters.j2 │ │ ├── etc_cron.d_ansible-pull.j2 │ │ ├── etc_logrotate.d_ansible-pull.j2 │ │ ├── foo.j2 │ │ └── hostvars.j2 │ ├── upgraded_vars.yml │ ├── user_commands.yml │ ├── vars/ │ │ ├── CentOS.yml │ │ ├── defaults.yml │ │ └── external_vars.yml │ └── zfs.yml ├── mongodb/ │ ├── LICENSE.md │ ├── README.md │ ├── group_vars/ │ │ └── all │ ├── hosts │ ├── playbooks/ │ │ └── testsharding.yml │ ├── roles/ │ │ ├── common/ │ │ │ ├── files/ │ │ │ │ ├── 10gen.repo.j2 │ │ │ │ ├── RPM-GPG-KEY-EPEL-6 │ │ │ │ └── epel.repo.j2 │ │ │ ├── handlers/ │ │ │ │ └── main.yml │ │ │ ├── tasks/ │ │ │ │ └── main.yml │ │ │ └── templates/ │ │ │ ├── hosts.j2 │ │ │ └── iptables.j2 │ │ ├── mongoc/ │ │ │ ├── files/ │ │ │ │ └── secret │ │ │ ├── tasks/ │ │ │ │ └── main.yml │ │ │ └── templates/ │ │ │ ├── adduser.j2 │ │ │ ├── mongoc.conf.j2 │ │ │ └── mongoc.j2 │ │ ├── mongod/ │ │ │ ├── files/ │ │ │ │ └── secret │ │ │ ├── tasks/ │ │ │ │ ├── main.yml │ │ │ │ └── shards.yml │ │ │ └── templates/ │ │ │ ├── mongod.conf.j2 │ │ │ ├── mongod.j2 │ │ │ ├── repset_init.j2 │ │ │ └── shard_init.j2 │ │ └── mongos/ │ │ ├── files/ │ │ │ └── secret │ │ ├── tasks/ │ │ │ └── main.yml │ │ └── templates/ │ │ ├── enablesharding.j2 │ │ ├── mongos.conf.j2 │ │ ├── mongos.j2 │ │ └── testsharding.j2 │ └── site.yml ├── phillips_hue/ │ ├── README.md │ ├── ansible.cfg │ ├── ansible_colors.yml │ ├── effect.yml │ ├── hosts │ ├── on_off.yml │ ├── register.yml │ └── username_info.yml ├── rust-module-hello-world/ │ ├── Makefile │ ├── library/ │ │ └── .gitignore │ ├── module-src/ │ │ ├── Cargo.toml │ │ ├── src/ │ │ │ └── main.rs │ │ └── target/ │ │ └── .gitignore │ └── rust.yml ├── tomcat-memcached-failover/ │ ├── LICENSE.md │ ├── README.md │ ├── group_vars/ │ │ └── all │ ├── hosts │ ├── roles/ │ │ ├── common/ │ │ │ ├── handlers/ │ │ │ │ └── main.yml │ │ │ ├── tasks/ │ │ │ │ └── main.yml │ │ │ └── templates/ │ │ │ └── iptables.j2 │ │ ├── lb-nginx/ │ │ │ ├── handlers/ │ │ │ │ └── main.yml │ │ │ ├── tasks/ │ │ │ │ └── main.yml │ │ │ └── templates/ │ │ │ ├── default.conf.j2 │ │ │ └── nginx.conf.j2 │ │ ├── memcached/ │ │ │ ├── handlers/ │ │ │ │ └── main.yml │ │ │ ├── tasks/ │ │ │ │ └── main.yml │ │ │ └── templates/ │ │ │ ├── init.sh.j2 │ │ │ └── memcached.conf.j2 │ │ └── tomcat/ │ │ ├── files/ │ │ │ └── msm-sample-webapp-1.0-SNAPSHOT.war │ │ ├── handlers/ │ │ │ └── main.yml │ │ ├── tasks/ │ │ │ └── main.yml │ │ └── templates/ │ │ ├── context.xml.j2 │ │ ├── default.j2 │ │ └── server.xml.j2 │ └── site.yml ├── tomcat-standalone/ │ ├── LICENSE.md │ ├── README.md │ ├── group_vars/ │ │ └── tomcat-servers │ ├── hosts │ ├── roles/ │ │ ├── selinux/ │ │ │ └── tasks/ │ │ │ └── main.yml │ │ └── tomcat/ │ │ ├── files/ │ │ │ └── tomcat-initscript.sh │ │ ├── handlers/ │ │ │ └── main.yml │ │ ├── tasks/ │ │ │ └── main.yml │ │ └── templates/ │ │ ├── iptables-save │ │ ├── server.xml │ │ └── tomcat-users.xml │ └── site.yml ├── windows/ │ ├── create-user.yml │ ├── deploy-site.yml │ ├── enable-iis.yml │ ├── files/ │ │ └── helloworld.ps1 │ ├── install-msi.yml │ ├── ping.yml │ ├── run-powershell.yml │ ├── test.yml │ └── wamp_haproxy/ │ ├── demo-aws-wamp-launch.yml │ ├── group_vars/ │ │ ├── all │ │ ├── windows_dbservers │ │ └── windows_webservers │ ├── roles/ │ │ ├── elb/ │ │ │ └── tasks/ │ │ │ └── main.yml │ │ ├── iis/ │ │ │ └── tasks/ │ │ │ └── main.yml │ │ ├── mssql/ │ │ │ ├── files/ │ │ │ │ └── create-db.ps1 │ │ │ └── tasks/ │ │ │ └── main.yml │ │ └── web/ │ │ └── tasks/ │ │ └── main.yml │ ├── rolling_update.yml │ └── site.yml ├── wordpress-nginx/ │ ├── LICENSE.md │ ├── README.md │ ├── group_vars/ │ │ └── all │ ├── hosts.example │ ├── roles/ │ │ ├── common/ │ │ │ ├── files/ │ │ │ │ ├── RPM-GPG-KEY-EPEL-6 │ │ │ │ ├── epel.repo │ │ │ │ └── iptables-save │ │ │ ├── handlers/ │ │ │ │ └── main.yml │ │ │ └── tasks/ │ │ │ └── main.yml │ │ ├── mysql/ │ │ │ ├── handlers/ │ │ │ │ └── main.yml │ │ │ ├── tasks/ │ │ │ │ └── main.yml │ │ │ └── templates/ │ │ │ └── my.cnf.j2 │ │ ├── nginx/ │ │ │ ├── handlers/ │ │ │ │ └── main.yml │ │ │ ├── tasks/ │ │ │ │ └── main.yml │ │ │ └── templates/ │ │ │ └── default.conf │ │ ├── php-fpm/ │ │ │ ├── handlers/ │ │ │ │ └── main.yml │ │ │ ├── tasks/ │ │ │ │ └── main.yml │ │ │ └── templates/ │ │ │ └── wordpress.conf │ │ └── wordpress/ │ │ ├── tasks/ │ │ │ └── main.yml │ │ └── templates/ │ │ └── wp-config.php │ └── site.yml └── wordpress-nginx_rhel7/ ├── LICENSE.md ├── README.md ├── group_vars/ │ └── all ├── hosts.example ├── roles/ │ ├── common/ │ │ ├── files/ │ │ │ ├── RPM-GPG-KEY-EPEL-7 │ │ │ ├── RPM-GPG-KEY-NGINX │ │ │ ├── RPM-GPG-KEY-remi │ │ │ ├── epel.repo │ │ │ ├── nginx.repo │ │ │ └── remi.repo │ │ └── tasks/ │ │ └── main.yml │ ├── mariadb/ │ │ ├── handlers/ │ │ │ └── main.yml │ │ ├── tasks/ │ │ │ └── main.yml │ │ └── templates/ │ │ └── my.cnf.j2 │ ├── nginx/ │ │ ├── handlers/ │ │ │ └── main.yml │ │ ├── tasks/ │ │ │ └── main.yml │ │ └── templates/ │ │ └── default.conf │ ├── php-fpm/ │ │ ├── handlers/ │ │ │ └── main.yml │ │ ├── tasks/ │ │ │ └── main.yml │ │ └── templates/ │ │ └── wordpress.conf │ └── wordpress/ │ ├── tasks/ │ │ └── main.yml │ └── templates/ │ └── wp-config.php └── site.yml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/workflows/main.yml ================================================ name: Ansible Lint on: [push, pull_request] jobs: build: runs-on: ubuntu-latest steps: # Important: This sets up your GITHUB_WORKSPACE environment variable - uses: actions/checkout@v2 - name: Lint Ansible Playbook # replace "master" with any valid ref uses: ansible/ansible-lint-action@master with: # [required] # Paths to ansible files (i.e., playbooks, tasks, handlers etc..) # or valid Ansible directories according to the Ansible role # directory structure. # If you want to lint multiple ansible files, use the following syntax # targets: | # playbook_1.yml # playbook_2.yml targets: wordpress-nginx/site.yml ================================================ FILE: .gitignore ================================================ wordpress-nginx/hosts .DS_Store ================================================ FILE: README.md ================================================ Ansible Examples ---------------- This repository contains examples and best practices for building Ansible Playbooks. ================================================ FILE: jboss-standalone/LICENSE.md ================================================ Copyright (C) 2013 AnsibleWorks, Inc. This work is licensed under the Creative Commons Attribution 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/deed.en_US. ================================================ FILE: jboss-standalone/README.md ================================================ ## Standalone JBoss Deployment - Requires Ansible 1.2 or newer - Expects CentOS/RHEL 6 or 7 hosts These playbooks deploy a very basic implementation of JBoss Application Server, version 7. To use them, first edit the `hosts` inventory file to contain the hostnames of the machines on which you want JBoss deployed, and edit the group_vars/all file to set any JBoss configuration parameters you need. Then run the playbook, like this: ansible-playbook -i hosts site.yml When the playbook run completes, you should be able to see the JBoss Application Server running on the ports you chose, on the target machines. This is a very simple playbook and could serve as a starting point for more complex JBoss-based projects. ## Application deployment The playbook deploy-application.yml may be used to deploy the HelloWorld and Ticket Monster demo applications to JBoss hosts that have been deployed using site.yml, as above. Run the playbook using: ansible-playbook -i hosts deploy-application.yml The HelloWorld application will be available at `http://:/helloworld` The Ticket Monster application will be available at `http://:/ticket-monster` ## Provisioning for Amazon Web Services A simple playbook is provided, as an example, to provision hosts in preparation for running this JBoss deployment example. ansible-playbook -i hosts demo-aws-launch.yml ### Ideas for Improvement Here are some ideas for ways that these playbooks could be extended: - Write a playbook or an Ansible module to configure JBoss users. - Extend this configuration to multiple application servers fronted by a load balancer or other web server frontend. We would love to see contributions and improvements, so please fork this repository on GitHub and send us your changes via pull requests. ================================================ FILE: jboss-standalone/demo-aws-launch.yml ================================================ --- - name: Provision instances hosts: localhost connection: local gather_facts: False # load AWS variables from this group vars file vars_files: - group_vars/all tasks: - name: Launch instances ec2: access_key: "{{ ec2_access_key }}" secret_key: "{{ ec2_secret_key }}" keypair: "{{ ec2_keypair }}" group: "{{ ec2_security_group }}" type: "{{ ec2_instance_type }}" image: "{{ ec2_image }}" region: "{{ ec2_region }}" instance_tags: "{'ansible_group':'jboss', 'type':'{{ ec2_instance_type }}', 'group':'{{ ec2_security_group }}', 'Name':'demo_''{{ tower_user_name }}'}" count: "{{ ec2_instance_count }}" wait: true register: ec2 - name: Wait for SSH to come up wait_for: host: "{{ item.public_dns_name }}" port: 22 delay: 60 timeout: 320 state: started with_items: "{{ ec2.instances }}" ================================================ FILE: jboss-standalone/deploy-application.yml ================================================ --- # This playbook deploys two simple applications to JBoss server. - hosts: all roles: # Optionally, (re)deploy JBoss here. # - jboss-standalone - java-app ================================================ FILE: jboss-standalone/group_vars/all ================================================ # Here are variables related to the standalone JBoss installation http_port: 8080 https_port: 8443 # AWS specific variables ec2_access_key: ec2_secret_key: ec2_region: us-east-1 ec2_zone: ec2_image: ami-6c1e8f04 ec2_instance_type: m1.small ec2_keypair: djohnson ec2_security_group: default ec2_instance_count: 3 ec2_tag: demo ec2_tag_name_prefix: dj ec2_hosts: all wait_for_port: 22 # This user name will be set by Tower, when run through Tower tower_user_name: admin ================================================ FILE: jboss-standalone/hosts ================================================ appserver1 ================================================ FILE: jboss-standalone/roles/java-app/tasks/main.yml ================================================ --- - name: Copy application WAR file to host copy: src: jboss-helloworld.war dest: /tmp - name: Deploy HelloWorld to JBoss jboss: deploy_path: /usr/share/jboss-as/standalone/deployments/ src: /tmp/jboss-helloworld.war deployment: helloworld.war state: present - name: Copy application WAR file to host copy: src: ticket-monster.war dest: /tmp - name: Deploy Ticket Monster to JBoss jboss: deploy_path: /usr/share/jboss-as/standalone/deployments/ src: /tmp/ticket-monster.war deployment: ticket-monster.war state: present ================================================ FILE: jboss-standalone/roles/jboss-standalone/files/jboss-as-standalone.sh ================================================ #!/bin/sh # # JBoss standalone control script # # chkconfig: - 80 20 # description: JBoss AS Standalone # processname: standalone # pidfile: /var/run/jboss-as/jboss-as-standalone.pid # config: /etc/jboss-as/jboss-as.conf # Source function library. . /etc/init.d/functions # Load Java configuration. [ -r /etc/java/java.conf ] && . /etc/java/java.conf export JAVA_HOME ## # Set the JBoss user JBOSS_USER=jboss export JBOSS_USER # Load JBoss AS init.d configuration. if [ -z "$JBOSS_CONF" ]; then JBOSS_CONF="/etc/jboss-as/jboss-as.conf" fi [ -r "$JBOSS_CONF" ] && . "${JBOSS_CONF}" # Set defaults. if [ -z "$JBOSS_HOME" ]; then JBOSS_HOME=/usr/share/jboss-as fi export JBOSS_HOME if [ -z "$JBOSS_PIDFILE" ]; then JBOSS_PIDFILE=/var/run/jboss-as/jboss-as-standalone.pid fi export JBOSS_PIDFILE if [ -z "$JBOSS_CONSOLE_LOG" ]; then JBOSS_CONSOLE_LOG=/var/log/jboss-as/console.log fi if [ -z "$STARTUP_WAIT" ]; then STARTUP_WAIT=30 fi if [ -z "$SHUTDOWN_WAIT" ]; then SHUTDOWN_WAIT=30 fi if [ -z "$JBOSS_CONFIG" ]; then JBOSS_CONFIG=standalone.xml fi JBOSS_SCRIPT=$JBOSS_HOME/bin/standalone.sh prog='jboss-as' CMD_PREFIX='' if [ ! -z "$JBOSS_USER" ]; then if [ -x /etc/rc.d/init.d/functions ]; then CMD_PREFIX="daemon --user $JBOSS_USER" else CMD_PREFIX="su - $JBOSS_USER -c" fi fi start() { echo -n "Starting $prog: " if [ -f $JBOSS_PIDFILE ]; then read ppid < $JBOSS_PIDFILE if [ `ps --pid $ppid 2> /dev/null | grep -c $ppid 2> /dev/null` -eq '1' ]; then echo -n "$prog is already running" failure echo return 1 else rm -f $JBOSS_PIDFILE fi fi mkdir -p $(dirname $JBOSS_CONSOLE_LOG) cat /dev/null > $JBOSS_CONSOLE_LOG mkdir -p $(dirname $JBOSS_PIDFILE) chown $JBOSS_USER $(dirname $JBOSS_PIDFILE) || true #$CMD_PREFIX JBOSS_PIDFILE=$JBOSS_PIDFILE $JBOSS_SCRIPT 2>&1 > $JBOSS_CONSOLE_LOG & #$CMD_PREFIX JBOSS_PIDFILE=$JBOSS_PIDFILE $JBOSS_SCRIPT & if [ ! -z "$JBOSS_USER" ]; then if [ -x /etc/rc.d/init.d/functions ]; then daemon --user $JBOSS_USER LAUNCH_JBOSS_IN_BACKGROUND=1 JBOSS_PIDFILE=$JBOSS_PIDFILE $JBOSS_SCRIPT -c $JBOSS_CONFIG 2>&1 > $JBOSS_CONSOLE_LOG & else su - $JBOSS_USER -c "LAUNCH_JBOSS_IN_BACKGROUND=1 JBOSS_PIDFILE=$JBOSS_PIDFILE $JBOSS_SCRIPT -c $JBOSS_CONFIG" 2>&1 > $JBOSS_CONSOLE_LOG & fi fi count=0 launched=false until [ $count -gt $STARTUP_WAIT ] do grep 'JBoss AS.*started in' $JBOSS_CONSOLE_LOG > /dev/null if [ $? -eq 0 ] ; then launched=true break fi sleep 1 let count=$count+1; done success echo return 0 } stop() { echo -n $"Stopping $prog: " count=0; if [ -f $JBOSS_PIDFILE ]; then read kpid < $JBOSS_PIDFILE let kwait=$SHUTDOWN_WAIT # Try issuing SIGTERM kill -15 $kpid until [ `ps --pid $kpid 2> /dev/null | grep -c $kpid 2> /dev/null` -eq '0' ] || [ $count -gt $kwait ] do sleep 1 let count=$count+1; done if [ $count -gt $kwait ]; then kill -9 $kpid fi fi rm -f $JBOSS_PIDFILE success echo } status() { if [ -f $JBOSS_PIDFILE ]; then read ppid < $JBOSS_PIDFILE if [ `ps --pid $ppid 2> /dev/null | grep -c $ppid 2> /dev/null` -eq '1' ]; then echo "$prog is running (pid $ppid)" return 0 else echo "$prog dead but pid file exists" return 1 fi fi echo "$prog is not running" return 3 } case "$1" in start) start ;; stop) stop ;; restart) $0 stop $0 start ;; status) status ;; *) ## If no parameters are given, print which are avaiable. echo "Usage: $0 {start|stop|status|restart|reload}" exit 1 ;; esac ================================================ FILE: jboss-standalone/roles/jboss-standalone/handlers/main.yml ================================================ --- - name: restart jboss service: name: jboss state: restarted - name: restart iptables service: name: iptables state: restarted ================================================ FILE: jboss-standalone/roles/jboss-standalone/tasks/main.yml ================================================ --- - name: Install Java 1.7 and some basic dependencies yum: name: "{{ item }}" state: present with_items: - unzip - java-1.7.0-openjdk - libselinux-python - libsemanage-python - name: Download JBoss from jboss.org get_url: url: http://download.jboss.org/jbossas/7.1/jboss-as-7.1.1.Final/jboss-as-7.1.1.Final.zip dest: /opt/jboss-as-7.1.1.Final.zip - name: Extract archive unarchive: dest: /usr/share src: /opt/jboss-as-7.1.1.Final.zip creates: /usr/share/jboss-as copy: no # Rename the dir to avoid encoding the version in the init script - name: Rename install directory command: /bin/mv jboss-as-7.1.1.Final jboss-as args: chdir: /usr/share creates: /usr/share/jboss-as - name: Copying standalone.xml configuration file template: src: standalone.xml dest: /usr/share/jboss-as/standalone/configuration/ notify: restart jboss - name: Add group "jboss" group: name: jboss - name: Add user "jboss" user: name: jboss group: jboss home: /usr/share/jboss-as - name: Change ownership of JBoss installation file: path: /usr/share/jboss-as/ owner: jboss group: jboss state: directory recurse: yes - name: Copy the init script copy: src: jboss-as-standalone.sh dest: /etc/init.d/jboss mode: 0755 - name: Workaround for systemd bug shell: service jboss start && chkconfig jboss on ignore_errors: yes - name: Enable JBoss to be started at boot service: name: jboss enabled: yes state: started - name: deploy iptables rules template: src: iptables-save dest: /etc/sysconfig/iptables when: ansible_distribution_major_version != "7" notify: restart iptables - name: Ensure that firewalld is installed yum: name: firewalld state: present when: ansible_distribution_major_version == "7" - name: Ensure that firewalld is started service: name: firewalld state: started when: ansible_distribution_major_version == "7" - name: deploy firewalld rules firewalld: immediate: yes port: "{{ item }}" state: enabled permanent: yes when: ansible_distribution_major_version == "7" with_items: - "{{ http_port }}/tcp" - "{{ https_port }}/tcp" ================================================ FILE: jboss-standalone/roles/jboss-standalone/templates/iptables-save ================================================ # {{ ansible_managed }} *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [4:512] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport {{ http_port }} -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport {{ https_port }} -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT ================================================ FILE: jboss-standalone/roles/jboss-standalone/templates/standalone.xml ================================================ jdbc:h2:mem:test;DB_CLOSE_DELAY=-1 h2 sa sa org.h2.jdbcx.JdbcDataSource 1 true ${jboss.bind.address:127.0.0.1} ================================================ FILE: jboss-standalone/site.yml ================================================ --- # This playbook deploys a simple standalone JBoss server. - hosts: all roles: - jboss-standalone ================================================ FILE: lamp_haproxy/LICENSE.md ================================================ Copyright (C) 2013 AnsibleWorks, Inc. This work is licensed under the Creative Commons Attribution 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/deed.en_US. ================================================ FILE: lamp_haproxy/README.md ================================================ LAMP Stack + HAProxy: Example Playbooks ----------------------------------------------------------------------------- - Requires Ansible 1.2 - Expects CentOS/RHEL 6 hosts This example is an extension of the simple LAMP deployment. Here we'll install and configure a web server with an HAProxy load balancer in front, and deploy an application to the web servers. This set of playbooks also have the capability to dynamically add and remove web server nodes from the deployment. It also includes examples to do a rolling update of a stack without affecting the service. (To use this demonstration with Amazon Web Services, please use the `aws` sub-directory.) You can also optionally configure a Nagios monitoring node. ### Initial Site Setup First we configure the entire stack by listing our hosts in the 'hosts' inventory file, grouped by their purpose: [webservers] webserver1 webserver2 [dbservers] dbserver [lbservers] lbserver [monitoring] nagios After which we execute the following command to deploy the site: ansible-playbook -i hosts site.yml The deployment can be verified by accessing the IP address of your load balancer host in a web browser: http://:8888. Reloading the page should have you hit different webservers. The Nagios web interface can be reached at http:///nagios/ The default username and password are `nagiosadmin` / `nagiosadmin`. ### Removing and Adding a Node Removal and addition of nodes to the cluster is as simple as editing the hosts inventory and re-running: ansible-playbook -i hosts site.yml ### Rolling Update Rolling updates are the preferred way to update the web server software or deployed application, since the load balancer can be dynamically configured to take the hosts to be updated out of the pool. This will keep the service running on other servers so that the users are not interrupted. In this example the hosts are updated in serial fashion, which means that only one server will be updated at one time. If you have a lot of web server hosts, this behaviour can be changed by setting the `serial` keyword in `webservers.yml` file. Once the code has been updated in the source repository for your application which can be defined in the group_vars/all file, execute the following command: ansible-playbook -i hosts rolling_update.yml You can optionally pass: `-e webapp_version=xxx` to the `rolling_update` playbook to specify a specific version of the example webapp to deploy. ================================================ FILE: lamp_haproxy/aws/LICENSE.md ================================================ Copyright (C) 2013 AnsibleWorks, Inc. This work is licensed under the Creative Commons Attribution 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/deed.en_US. ================================================ FILE: lamp_haproxy/aws/README.md ================================================ LAMP Stack + HAProxy: Example Playbooks for Amazon Web Services ----------------------------------------------------------------------------- - Requires Ansible 1.2 - Expects CentOS/RHEL 6 hosts This example is an extension of the simple LAMP deployment. Here we'll install and configure a web server with an HAProxy load balancer in front, and deploy an application to the web servers. This set of playbooks also have the capability to dynamically add and remove web server nodes from the deployment. It also includes examples to do a rolling update of a stack without affecting the service. You can also optionally configure a Nagios monitoring node. ### Initial Site Setup First, we provision the hosts necessary for this demonstration using the included playbook, "demo-aws-launch.yml". This will provision the following instances, with the group structure specified below. The hosts are tagged via AWS EC2 tagging and the Ansible inventory sync script (or Tower) will create the appropriate groups from these tags. [tag_ansible_group_webservers] webserver1 webserver2 [tag_ansible_group_dbservers] dbserver [tag_ansible_group_lbservers] lbserver [tag_ansible_group_monitoring] nagios After which we execute the following command to deploy the site: ansible-playbook -i ec2.py site.yml The deployment can be verified by accessing the IP address of your load balancer host in a web browser: http://:8888. Reloading the page should have you hit different webservers. The Nagios web interface can be reached at http:///nagios/ The default username and password are "nagiosadmin" / "nagiosadmin". ### Removing and Adding a Node Removal and addition of nodes to the cluster is as simple as creating new instances, syncing the Ansible inventory and re-running: ansible-playbook -i ec2.py site.yml ### Rolling Update Rolling updates are the preferred way to update the web server software or deployed application, since the load balancer can be dynamically configured to take the hosts to be updated out of the pool. This will keep the service running on other servers so that the users are not interrupted. In this example the hosts are updated in serial fashion, which means that only one server will be updated at one time. If you have a lot of web server hosts, this behaviour can be changed by setting the 'serial' keyword in webservers.yml file. Once the code has been updated in the source repository for your application which can be defined in the group_vars/all file, execute the following command: ansible-playbook -i ec2.py rolling_update.yml You can optionally pass: -e webapp_version=xxx to the rolling_update playbook to specify a specific version of the example webapp to deploy. ================================================ FILE: lamp_haproxy/aws/demo-aws-launch.yml ================================================ --- # Provision instances in AWS specific to the LAMP HA Proxy demo - name: Provision instances in AWS hosts: localhost connection: local gather_facts: False # load AWS variables from this group vars file vars_files: - group_vars/all tasks: - name: Launch webserver instances ec2: access_key: "{{ ec2_access_key }}" secret_key: "{{ ec2_secret_key }}" keypair: "{{ ec2_keypair }}" group: "{{ ec2_security_group }}" type: "{{ ec2_instance_type }}" image: "{{ ec2_image }}" region: "{{ ec2_region }}" instance_tags: "{'ansible_group':'webservers', 'type':'{{ ec2_instance_type }}', 'group':'{{ ec2_security_group }}', 'Name':'demo_''{{ tower_user_name }}'}" count: "{{ ec2_instance_count }}" wait: true register: ec2 - name: Launch database instance ec2: access_key: "{{ ec2_access_key }}" secret_key: "{{ ec2_secret_key }}" keypair: "{{ ec2_keypair }}" group: "{{ ec2_security_group }}" type: "{{ ec2_instance_type }}" image: "{{ ec2_image }}" region: "{{ ec2_region }}" instance_tags: "{'ansible_group':'dbservers', 'type':'{{ ec2_instance_type }}', 'group':'{{ ec2_security_group }}', 'Name':'demo_''{{ tower_user_name }}'}" count: "1" wait: true register: ec2 - name: Launch load balancing instance ec2: access_key: "{{ ec2_access_key }}" secret_key: "{{ ec2_secret_key }}" keypair: "{{ ec2_keypair }}" group: "{{ ec2_security_group }}" type: "{{ ec2_instance_type }}" image: "{{ ec2_image }}" region: "{{ ec2_region }}" instance_tags: "{'ansible_group':'lbservers', 'type':'{{ ec2_instance_type }}', 'group':'{{ ec2_security_group }}', 'Name':'demo_''{{ tower_user_name }}'}" count: "1" wait: true register: ec2 - name: Launch monitoring instance ec2: access_key: "{{ ec2_access_key }}" secret_key: "{{ ec2_secret_key }}" keypair: "{{ ec2_keypair }}" group: "{{ ec2_security_group }}" type: "{{ ec2_instance_type }}" image: "{{ ec2_image }}" region: "{{ ec2_region }}" instance_tags: "{'ansible_group':'monitoring', 'type':'{{ ec2_instance_type }}', 'group':'{{ ec2_security_group }}', 'Name':'demo_''{{ tower_user_name }}'}" count: "1" wait: true register: ec2 - name: Wait for SSH to come up wait_for: host: "{{ item.public_dns_name }}" port: 22 delay: 60 timeout: 320 state: started with_items: "{{ ec2.instances }}" ================================================ FILE: lamp_haproxy/aws/group_vars/all ================================================ --- # Variables here are applicable to all host groups httpd_port: 80 ntpserver: 192.168.1.2 # AWS specific variables ec2_access_key: ec2_secret_key: ec2_region: us-east-1 ec2_zone: ec2_image: ami-bc8131d4 ec2_instance_type: m1.small ec2_keypair: djohnson ec2_security_group: default ec2_instance_count: 3 ec2_tag: demo ec2_tag_name_prefix: dj ec2_hosts: all wait_for_port: 22 # This user name will be set by Tower, when run through Tower tower_user_name: admin ================================================ FILE: lamp_haproxy/aws/group_vars/tag_ansible_group_dbservers ================================================ --- # The variables file used by the playbooks in the dbservers group. # These don't have to be explicitly imported by vars_files: they are autopopulated. mysqlservice: mysqld mysql_port: 3306 dbuser: root dbname: foodb upassword: abc ================================================ FILE: lamp_haproxy/aws/group_vars/tag_ansible_group_lbservers ================================================ --- # Variables for the HAproxy configuration # HAProxy supports "http" and "tcp". For SSL, SMTP, etc, use "tcp". mode: http # Port on which HAProxy should listen listenport: 8888 # A name for the proxy daemon, this wil be the suffix in the logs. daemonname: myapplb # Balancing Algorithm. Available options: # roundrobin, source, leastconn, source, uri # (if persistance is required use, "source") balance: roundrobin # Ethernet interface on which the load balancer should listen # Defaults to the first interface. Change this to: # # iface: eth1 # # ...to override. # iface: '{{ ansible_default_ipv4.interface }}' ================================================ FILE: lamp_haproxy/aws/group_vars/tag_ansible_group_webservers ================================================ --- # Variables for the web server configuration # Ethernet interface on which the web server should listen. # Defaults to the first interface. Change this to: # # iface: eth1 # # ...to override. # iface: '{{ ansible_default_ipv4.interface }}' # this is the repository that holds our sample webapp repository: https://github.com/bennojoy/mywebapp.git # this is the sha1sum of V5 of the test webapp. webapp_version: 351e47276cc66b018f4890a04709d4cc3d3edb0d ================================================ FILE: lamp_haproxy/aws/roles/base-apache/tasks/main.yml ================================================ --- # This role installs httpd - name: Install http yum: name: "{{ item }}" state: present with_items: - httpd - php - php-mysql - git - name: Configure SELinux to allow httpd to connect to remote database seboolean: name: httpd_can_network_connect_db state: true persistent: yes when: sestatus.rc != 0 - name: http service state service: name: httpd state: started enabled: yes ================================================ FILE: lamp_haproxy/aws/roles/common/files/RPM-GPG-KEY-EPEL-6 ================================================ -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.5 (GNU/Linux) mQINBEvSKUIBEADLGnUj24ZVKW7liFN/JA5CgtzlNnKs7sBg7fVbNWryiE3URbn1 JXvrdwHtkKyY96/ifZ1Ld3lE2gOF61bGZ2CWwJNee76Sp9Z+isP8RQXbG5jwj/4B M9HK7phktqFVJ8VbY2jfTjcfxRvGM8YBwXF8hx0CDZURAjvf1xRSQJ7iAo58qcHn XtxOAvQmAbR9z6Q/h/D+Y/PhoIJp1OV4VNHCbCs9M7HUVBpgC53PDcTUQuwcgeY6 pQgo9eT1eLNSZVrJ5Bctivl1UcD6P6CIGkkeT2gNhqindRPngUXGXW7Qzoefe+fV QqJSm7Tq2q9oqVZ46J964waCRItRySpuW5dxZO34WM6wsw2BP2MlACbH4l3luqtp Xo3Bvfnk+HAFH3HcMuwdaulxv7zYKXCfNoSfgrpEfo2Ex4Im/I3WdtwME/Gbnwdq 3VJzgAxLVFhczDHwNkjmIdPAlNJ9/ixRjip4dgZtW8VcBCrNoL+LhDrIfjvnLdRu vBHy9P3sCF7FZycaHlMWP6RiLtHnEMGcbZ8QpQHi2dReU1wyr9QgguGU+jqSXYar 1yEcsdRGasppNIZ8+Qawbm/a4doT10TEtPArhSoHlwbvqTDYjtfV92lC/2iwgO6g YgG9XrO4V8dV39Ffm7oLFfvTbg5mv4Q/E6AWo/gkjmtxkculbyAvjFtYAQARAQAB tCFFUEVMICg2KSA8ZXBlbEBmZWRvcmFwcm9qZWN0Lm9yZz6JAjYEEwECACAFAkvS KUICGw8GCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRA7Sd8qBgi4lR/GD/wLGPv9 qO39eyb9NlrwfKdUEo1tHxKdrhNz+XYrO4yVDTBZRPSuvL2yaoeSIhQOKhNPfEgT 9mdsbsgcfmoHxmGVcn+lbheWsSvcgrXuz0gLt8TGGKGGROAoLXpuUsb1HNtKEOwP Q4z1uQ2nOz5hLRyDOV0I2LwYV8BjGIjBKUMFEUxFTsL7XOZkrAg/WbTH2PW3hrfS WtcRA7EYonI3B80d39ffws7SmyKbS5PmZjqOPuTvV2F0tMhKIhncBwoojWZPExft HpKhzKVh8fdDO/3P1y1Fk3Cin8UbCO9MWMFNR27fVzCANlEPljsHA+3Ez4F7uboF p0OOEov4Yyi4BEbgqZnthTG4ub9nyiupIZ3ckPHr3nVcDUGcL6lQD/nkmNVIeLYP x1uHPOSlWfuojAYgzRH6LL7Idg4FHHBA0to7FW8dQXFIOyNiJFAOT2j8P5+tVdq8 wB0PDSH8yRpn4HdJ9RYquau4OkjluxOWf0uRaS//SUcCZh+1/KBEOmcvBHYRZA5J l/nakCgxGb2paQOzqqpOcHKvlyLuzO5uybMXaipLExTGJXBlXrbbASfXa/yGYSAG iVrGz9CE6676dMlm8F+s3XXE13QZrXmjloc6jwOljnfAkjTGXjiB7OULESed96MR XtfLk0W5Ab9pd7tKDR6QHI7rgHXfCopRnZ2VVQ== =V/6I -----END PGP PUBLIC KEY BLOCK----- ================================================ FILE: lamp_haproxy/aws/roles/common/files/epel.repo ================================================ [epel] name=Extra Packages for Enterprise Linux 6 - $basearch #baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch failovermethod=priority enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 [epel-debuginfo] name=Extra Packages for Enterprise Linux 6 - $basearch - Debug #baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch/debug mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-6&arch=$basearch failovermethod=priority enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 gpgcheck=1 [epel-source] name=Extra Packages for Enterprise Linux 6 - $basearch - Source #baseurl=http://download.fedoraproject.org/pub/epel/6/SRPMS mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-6&arch=$basearch failovermethod=priority enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 gpgcheck=1 ================================================ FILE: lamp_haproxy/aws/roles/common/handlers/main.yml ================================================ --- # Handlers for common notifications - name: restart ntp service: name=ntpd state=restarted - name: restart iptables service: name=iptables state=restarted ================================================ FILE: lamp_haproxy/aws/roles/common/tasks/main.yml ================================================ --- # This role contains common plays that will run on all nodes. - name: Install python bindings for SE Linux yum: name: "{{ item }}" state: present with_items: - libselinux-python - libsemanage-python - name: Create the repository for EPEL copy: src: epel.repo dest: /etc/yum.repos.d/epel.repo - name: Create the GPG key for EPEL copy: src: RPM-GPG-KEY-EPEL-6 dest: /etc/pki/rpm-gpg - name: install some useful nagios plugins yum: name: "{{ item }}" state: present with_items: - nagios-nrpe - nagios-plugins-swap - nagios-plugins-users - nagios-plugins-procs - nagios-plugins-load - nagios-plugins-disk - name: Install ntp yum: name: ntp state: present tags: ntp - name: Configure ntp file template: src: ntp.conf.j2 dest: /etc/ntp.conf tags: ntp notify: restart ntp - name: Start the ntp service service: name: ntpd state: started enabled: yes tags: ntp # work around RHEL 7, for now - name: insert iptables template template: src: iptables.j2 dest: /etc/sysconfig/iptables when: ansible_distribution_major_version != '7' notify: restart iptables - name: test to see if selinux is running command: getenforce register: sestatus changed_when: false ================================================ FILE: lamp_haproxy/aws/roles/common/templates/iptables.j2 ================================================ # {{ ansible_managed }} # Manual customization of this file is not recommended. *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] {% if (inventory_hostname in groups.tag_ansible_group_webservers) or (inventory_hostname in groups.tag_ansible_group_monitoring) %} -A INPUT -p tcp --dport 80 -j ACCEPT {% endif %} {% if (inventory_hostname in groups.tag_ansible_group_dbservers) %} -A INPUT -p tcp --dport 3306 -j ACCEPT {% endif %} {% if (inventory_hostname in groups.tag_ansible_group_lbservers) %} -A INPUT -p tcp --dport {{ listenport }} -j ACCEPT {% endif %} {% for host in groups.tag_ansible_group_monitoring %} -A INPUT -p tcp -s {{ hostvars[host].ansible_default_ipv4.address }} --dport 5666 -j ACCEPT {% endfor %} -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT ================================================ FILE: lamp_haproxy/aws/roles/common/templates/ntp.conf.j2 ================================================ driftfile /var/lib/ntp/drift restrict 127.0.0.1 restrict -6 ::1 server {{ ntpserver }} includefile /etc/ntp/crypto/pw keys /etc/ntp/keys ================================================ FILE: lamp_haproxy/aws/roles/db/handlers/main.yml ================================================ --- # Handler to handle DB tier notifications - name: restart mysql service: name=mysqld state=restarted ================================================ FILE: lamp_haproxy/aws/roles/db/tasks/main.yml ================================================ --- # This role will install MySQL and create db user and give permissions. - name: Install Mysql package yum: name: "{{ item }}" state: present with_items: - mysql-server - MySQL-python - name: Configure SELinux to start mysql on any port seboolean: name: mysql_connect_any state: true persistent: yes when: sestatus.rc != 0 - name: Create Mysql configuration file template: src: my.cnf.j2 dest: /etc/my.cnf notify: - restart mysql - name: Start Mysql Service service: name: mysqld state: started enabled: yes - name: Create Application Database mysql_db: name: "{{ dbname }}" state: present - name: Create Application DB User mysql_user: name: "{{ dbuser }}" password: "{{ upassword }}" priv: "*.*:ALL" host: '%' state: present ================================================ FILE: lamp_haproxy/aws/roles/db/templates/my.cnf.j2 ================================================ [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 port={{ mysql_port }} [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid ================================================ FILE: lamp_haproxy/aws/roles/haproxy/handlers/main.yml ================================================ --- # Handlers for HAproxy - name: restart haproxy service: name=haproxy state=restarted - name: reload haproxy service: name=haproxy state=reloaded ================================================ FILE: lamp_haproxy/aws/roles/haproxy/tasks/main.yml ================================================ --- # This role installs HAProxy and configures it. - name: Download and install haproxy yum: name: haproxy state: present - name: Configure the haproxy cnf file with hosts template: src: haproxy.cfg.j2 dest: /etc/haproxy/haproxy.cfg notify: restart haproxy - name: Start the haproxy service service: name: haproxy state: started enabled: yes ================================================ FILE: lamp_haproxy/aws/roles/haproxy/templates/haproxy.cfg.j2 ================================================ global log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user root group root daemon # turn on stats unix socket stats socket /var/lib/haproxy/stats level admin defaults mode {{ mode }} log global option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.0/8 option redispatch retries 3 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 backend app {% for host in groups.tag_ansible_group_lbservers %} listen {{ daemonname }} 0.0.0.0:{{ listenport }} {% endfor %} balance {{ balance }} {% for host in groups.tag_ansible_group_webservers %} server {{ host }} {{ hostvars[host]['ansible_' + iface].ipv4.address }}:{{ httpd_port }} {% endfor %} ================================================ FILE: lamp_haproxy/aws/roles/nagios/files/ansible-managed-services.cfg ================================================ # {{ ansible_managed }} # service checks to be applied to all hosts define service { use local-service host_name localhost service_description Root Partition check_command check_local_disk!20%!10%!/ } define service { use local-service host_name * service_description Current Users check_command check_local_users!20!50 } define service { use local-service host_name * service_description Total Processes check_command check_local_procs!250!400!RSZDT } define service { use local-service host_name * service_description Current Load check_command check_local_load!5.0,4.0,3.0!10.0,6.0,4.0 } define service { use local-service host_name * service_description Swap Usage check_command check_local_swap!20!10 } ================================================ FILE: lamp_haproxy/aws/roles/nagios/files/localhost.cfg ================================================ ############################################################################### # LOCALHOST.CFG - SAMPLE OBJECT CONFIG FILE FOR MONITORING THIS MACHINE # # Last Modified: 05-31-2007 # # NOTE: This config file is intended to serve as an *extremely* simple # example of how you can create configuration entries to monitor # the local (Linux) machine. # ############################################################################### ############################################################################### ############################################################################### # # HOST DEFINITION # ############################################################################### ############################################################################### # Define a host for the local machine define host{ use linux-server ; Name of host template to use ; This host definition will inherit all variables that are defined ; in (or inherited by) the linux-server host template definition. host_name localhost alias localhost address 127.0.0.1 } ############################################################################### ############################################################################### # # HOST GROUP DEFINITION # ############################################################################### ############################################################################### # Define an optional hostgroup for Linux machines define hostgroup{ hostgroup_name linux-servers ; The name of the hostgroup alias Linux Servers ; Long name of the group members localhost ; Comma separated list of hosts that belong to this group } ############################################################################### ############################################################################### # # SERVICE DEFINITIONS # ############################################################################### ############################################################################### # Define a service to "ping" the local machine define service{ use local-service ; Name of service template to use host_name localhost service_description PING check_command check_ping!100.0,20%!500.0,60% } # Define a service to check the disk space of the root partition # on the local machine. Warning if < 20% free, critical if # < 10% free space on partition. define service{ use local-service ; Name of service template to use host_name localhost service_description Root Partition check_command check_local_disk!20%!10%!/ } # Define a service to check the number of currently logged in # users on the local machine. Warning if > 20 users, critical # if > 50 users. define service{ use local-service ; Name of service template to use host_name localhost service_description Current Users check_command check_local_users!20!50 } # Define a service to check the number of currently running procs # on the local machine. Warning if > 250 processes, critical if # > 400 users. define service{ use local-service ; Name of service template to use host_name localhost service_description Total Processes check_command check_local_procs!250!400!RSZDT } # Define a service to check the load on the local machine. define service{ use local-service ; Name of service template to use host_name localhost service_description Current Load check_command check_local_load!5.0,4.0,3.0!10.0,6.0,4.0 } # Define a service to check the swap usage the local machine. # Critical if less than 10% of swap is free, warning if less than 20% is free define service{ use local-service ; Name of service template to use host_name localhost service_description Swap Usage check_command check_local_swap!20!10 } # Define a service to check SSH on the local machine. # Disable notifications for this service by default, as not all users may have SSH enabled. define service{ use local-service ; Name of service template to use host_name localhost service_description SSH check_command check_ssh notifications_enabled 0 } ================================================ FILE: lamp_haproxy/aws/roles/nagios/files/nagios.cfg ================================================ ############################################################################## # # NAGIOS.CFG - Sample Main Config File for Nagios 3.4.4 # # Read the documentation for more information on this configuration # file. I've provided some comments here, but things may not be so # clear without further explanation. # # Last Modified: 12-14-2008 # ############################################################################## # LOG FILE # This is the main log file where service and host events are logged # for historical purposes. This should be the first option specified # in the config file!!! log_file=/var/log/nagios/nagios.log # OBJECT CONFIGURATION FILE(S) # These are the object configuration files in which you define hosts, # host groups, contacts, contact groups, services, etc. # You can split your object definitions across several config files # if you wish (as shown below), or keep them all in a single config file. # You can specify individual object config files as shown below: cfg_file=/etc/nagios/objects/commands.cfg cfg_file=/etc/nagios/objects/contacts.cfg cfg_file=/etc/nagios/objects/timeperiods.cfg cfg_file=/etc/nagios/objects/templates.cfg # Definitions for monitoring the local (Linux) host cfg_file=/etc/nagios/objects/localhost.cfg cfg_file=/etc/nagios/ansible-managed-services.cfg cfg_dir=/etc/nagios/ansible-managed # OBJECT CACHE FILE # This option determines where object definitions are cached when # Nagios starts/restarts. The CGIs read object definitions from # this cache file (rather than looking at the object config files # directly) in order to prevent inconsistencies that can occur # when the config files are modified after Nagios starts. object_cache_file=/var/log/nagios/objects.cache # PRE-CACHED OBJECT FILE # This options determines the location of the precached object file. # If you run Nagios with the -p command line option, it will preprocess # your object configuration file(s) and write the cached config to this # file. You can then start Nagios with the -u option to have it read # object definitions from this precached file, rather than the standard # object configuration files (see the cfg_file and cfg_dir options above). # Using a precached object file can speed up the time needed to (re)start # the Nagios process if you've got a large and/or complex configuration. # Read the documentation section on optimizing Nagios to find our more # about how this feature works. precached_object_file=/var/log/nagios/objects.precache # RESOURCE FILE # This is an optional resource file that contains $USERx$ macro # definitions. Multiple resource files can be specified by using # multiple resource_file definitions. The CGIs will not attempt to # read the contents of resource files, so information that is # considered to be sensitive (usernames, passwords, etc) can be # defined as macros in this file and restrictive permissions (600) # can be placed on this file. resource_file=/etc/nagios/private/resource.cfg # STATUS FILE # This is where the current status of all monitored services and # hosts is stored. Its contents are read and processed by the CGIs. # The contents of the status file are deleted every time Nagios # restarts. status_file=/var/log/nagios/status.dat # STATUS FILE UPDATE INTERVAL # This option determines the frequency (in seconds) that # Nagios will periodically dump program, host, and # service status data. status_update_interval=10 # NAGIOS USER # This determines the effective user that Nagios should run as. # You can either supply a username or a UID. nagios_user=nagios # NAGIOS GROUP # This determines the effective group that Nagios should run as. # You can either supply a group name or a GID. nagios_group=nagios # EXTERNAL COMMAND OPTION # This option allows you to specify whether or not Nagios should check # for external commands (in the command file defined below). By default # Nagios will *not* check for external commands, just to be on the # cautious side. If you want to be able to use the CGI command interface # you will have to enable this. # Values: 0 = disable commands, 1 = enable commands check_external_commands=1 # EXTERNAL COMMAND CHECK INTERVAL # This is the interval at which Nagios should check for external commands. # This value works of the interval_length you specify later. If you leave # that at its default value of 60 (seconds), a value of 1 here will cause # Nagios to check for external commands every minute. If you specify a # number followed by an "s" (i.e. 15s), this will be interpreted to mean # actual seconds rather than a multiple of the interval_length variable. # Note: In addition to reading the external command file at regularly # scheduled intervals, Nagios will also check for external commands after # event handlers are executed. # NOTE: Setting this value to -1 causes Nagios to check the external # command file as often as possible. #command_check_interval=15s command_check_interval=-1 # EXTERNAL COMMAND FILE # This is the file that Nagios checks for external command requests. # It is also where the command CGI will write commands that are submitted # by users, so it must be writeable by the user that the web server # is running as (usually 'nobody'). Permissions should be set at the # directory level instead of on the file, as the file is deleted every # time its contents are processed. command_file=/var/spool/nagios/cmd/nagios.cmd # EXTERNAL COMMAND BUFFER SLOTS # This settings is used to tweak the number of items or "slots" that # the Nagios daemon should allocate to the buffer that holds incoming # external commands before they are processed. As external commands # are processed by the daemon, they are removed from the buffer. external_command_buffer_slots=4096 # LOCK FILE # This is the lockfile that Nagios will use to store its PID number # in when it is running in daemon mode. lock_file=/var/run/nagios.pid # TEMP FILE # This is a temporary file that is used as scratch space when Nagios # updates the status log, cleans the comment file, etc. This file # is created, used, and deleted throughout the time that Nagios is # running. temp_file=/var/log/nagios/nagios.tmp # TEMP PATH # This is path where Nagios can create temp files for service and # host check results, etc. temp_path=/tmp # EVENT BROKER OPTIONS # Controls what (if any) data gets sent to the event broker. # Values: 0 = Broker nothing # -1 = Broker everything # = See documentation event_broker_options=-1 # EVENT BROKER MODULE(S) # This directive is used to specify an event broker module that should # by loaded by Nagios at startup. Use multiple directives if you want # to load more than one module. Arguments that should be passed to # the module at startup are seperated from the module path by a space. # #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # # Do NOT overwrite modules while they are being used by Nagios or Nagios # will crash in a fiery display of SEGFAULT glory. This is a bug/limitation # either in dlopen(), the kernel, and/or the filesystem. And maybe Nagios... # # The correct/safe way of updating a module is by using one of these methods: # 1. Shutdown Nagios, replace the module file, restart Nagios # 2. Delete the original module file, move the new module file into place, restart Nagios # # Example: # # broker_module= [moduleargs] #broker_module=/somewhere/module1.o #broker_module=/somewhere/module2.o arg1 arg2=3 debug=0 # LOG ROTATION METHOD # This is the log rotation method that Nagios should use to rotate # the main log file. Values are as follows.. # n = None - don't rotate the log # h = Hourly rotation (top of the hour) # d = Daily rotation (midnight every day) # w = Weekly rotation (midnight on Saturday evening) # m = Monthly rotation (midnight last day of month) log_rotation_method=d # LOG ARCHIVE PATH # This is the directory where archived (rotated) log files should be # placed (assuming you've chosen to do log rotation). log_archive_path=/var/log/nagios/archives # LOGGING OPTIONS # If you want messages logged to the syslog facility, as well as the # Nagios log file set this option to 1. If not, set it to 0. use_syslog=1 # NOTIFICATION LOGGING OPTION # If you don't want notifications to be logged, set this value to 0. # If notifications should be logged, set the value to 1. log_notifications=1 # SERVICE RETRY LOGGING OPTION # If you don't want service check retries to be logged, set this value # to 0. If retries should be logged, set the value to 1. log_service_retries=1 # HOST RETRY LOGGING OPTION # If you don't want host check retries to be logged, set this value to # 0. If retries should be logged, set the value to 1. log_host_retries=1 # EVENT HANDLER LOGGING OPTION # If you don't want host and service event handlers to be logged, set # this value to 0. If event handlers should be logged, set the value # to 1. log_event_handlers=1 # INITIAL STATES LOGGING OPTION # If you want Nagios to log all initial host and service states to # the main log file (the first time the service or host is checked) # you can enable this option by setting this value to 1. If you # are not using an external application that does long term state # statistics reporting, you do not need to enable this option. In # this case, set the value to 0. log_initial_states=0 # EXTERNAL COMMANDS LOGGING OPTION # If you don't want Nagios to log external commands, set this value # to 0. If external commands should be logged, set this value to 1. # Note: This option does not include logging of passive service # checks - see the option below for controlling whether or not # passive checks are logged. log_external_commands=1 # PASSIVE CHECKS LOGGING OPTION # If you don't want Nagios to log passive host and service checks, set # this value to 0. If passive checks should be logged, set # this value to 1. log_passive_checks=1 # GLOBAL HOST AND SERVICE EVENT HANDLERS # These options allow you to specify a host and service event handler # command that is to be run for every host or service state change. # The global event handler is executed immediately prior to the event # handler that you have optionally specified in each host or # service definition. The command argument is the short name of a # command definition that you define in your host configuration file. # Read the HTML docs for more information. #global_host_event_handler=somecommand #global_service_event_handler=somecommand # SERVICE INTER-CHECK DELAY METHOD # This is the method that Nagios should use when initially # "spreading out" service checks when it starts monitoring. The # default is to use smart delay calculation, which will try to # space all service checks out evenly to minimize CPU load. # Using the dumb setting will cause all checks to be scheduled # at the same time (with no delay between them)! This is not a # good thing for production, but is useful when testing the # parallelization functionality. # n = None - don't use any delay between checks # d = Use a "dumb" delay of 1 second between checks # s = Use "smart" inter-check delay calculation # x.xx = Use an inter-check delay of x.xx seconds service_inter_check_delay_method=s # MAXIMUM SERVICE CHECK SPREAD # This variable determines the timeframe (in minutes) from the # program start time that an initial check of all services should # be completed. Default is 30 minutes. max_service_check_spread=30 # SERVICE CHECK INTERLEAVE FACTOR # This variable determines how service checks are interleaved. # Interleaving the service checks allows for a more even # distribution of service checks and reduced load on remote # hosts. Setting this value to 1 is equivalent to how versions # of Nagios previous to 0.0.5 did service checks. Set this # value to s (smart) for automatic calculation of the interleave # factor unless you have a specific reason to change it. # s = Use "smart" interleave factor calculation # x = Use an interleave factor of x, where x is a # number greater than or equal to 1. service_interleave_factor=s # HOST INTER-CHECK DELAY METHOD # This is the method that Nagios should use when initially # "spreading out" host checks when it starts monitoring. The # default is to use smart delay calculation, which will try to # space all host checks out evenly to minimize CPU load. # Using the dumb setting will cause all checks to be scheduled # at the same time (with no delay between them)! # n = None - don't use any delay between checks # d = Use a "dumb" delay of 1 second between checks # s = Use "smart" inter-check delay calculation # x.xx = Use an inter-check delay of x.xx seconds host_inter_check_delay_method=s # MAXIMUM HOST CHECK SPREAD # This variable determines the timeframe (in minutes) from the # program start time that an initial check of all hosts should # be completed. Default is 30 minutes. max_host_check_spread=30 # MAXIMUM CONCURRENT SERVICE CHECKS # This option allows you to specify the maximum number of # service checks that can be run in parallel at any given time. # Specifying a value of 1 for this variable essentially prevents # any service checks from being parallelized. A value of 0 # will not restrict the number of concurrent checks that are # being executed. max_concurrent_checks=0 # HOST AND SERVICE CHECK REAPER FREQUENCY # This is the frequency (in seconds!) that Nagios will process # the results of host and service checks. check_result_reaper_frequency=10 # MAX CHECK RESULT REAPER TIME # This is the max amount of time (in seconds) that a single # check result reaper event will be allowed to run before # returning control back to Nagios so it can perform other # duties. max_check_result_reaper_time=30 # CHECK RESULT PATH # This is directory where Nagios stores the results of host and # service checks that have not yet been processed. # # Note: Make sure that only one instance of Nagios has access # to this directory! check_result_path=/var/log/nagios/spool/checkresults # MAX CHECK RESULT FILE AGE # This option determines the maximum age (in seconds) which check # result files are considered to be valid. Files older than this # threshold will be mercilessly deleted without further processing. max_check_result_file_age=3600 # CACHED HOST CHECK HORIZON # This option determines the maximum amount of time (in seconds) # that the state of a previous host check is considered current. # Cached host states (from host checks that were performed more # recently that the timeframe specified by this value) can immensely # improve performance in regards to the host check logic. # Too high of a value for this option may result in inaccurate host # states being used by Nagios, while a lower value may result in a # performance hit for host checks. Use a value of 0 to disable host # check caching. cached_host_check_horizon=15 # CACHED SERVICE CHECK HORIZON # This option determines the maximum amount of time (in seconds) # that the state of a previous service check is considered current. # Cached service states (from service checks that were performed more # recently that the timeframe specified by this value) can immensely # improve performance in regards to predictive dependency checks. # Use a value of 0 to disable service check caching. cached_service_check_horizon=15 # ENABLE PREDICTIVE HOST DEPENDENCY CHECKS # This option determines whether or not Nagios will attempt to execute # checks of hosts when it predicts that future dependency logic test # may be needed. These predictive checks can help ensure that your # host dependency logic works well. # Values: # 0 = Disable predictive checks # 1 = Enable predictive checks (default) enable_predictive_host_dependency_checks=1 # ENABLE PREDICTIVE SERVICE DEPENDENCY CHECKS # This option determines whether or not Nagios will attempt to execute # checks of service when it predicts that future dependency logic test # may be needed. These predictive checks can help ensure that your # service dependency logic works well. # Values: # 0 = Disable predictive checks # 1 = Enable predictive checks (default) enable_predictive_service_dependency_checks=1 # SOFT STATE DEPENDENCIES # This option determines whether or not Nagios will use soft state # information when checking host and service dependencies. Normally # Nagios will only use the latest hard host or service state when # checking dependencies. If you want it to use the latest state (regardless # of whether its a soft or hard state type), enable this option. # Values: # 0 = Don't use soft state dependencies (default) # 1 = Use soft state dependencies soft_state_dependencies=0 # TIME CHANGE ADJUSTMENT THRESHOLDS # These options determine when Nagios will react to detected changes # in system time (either forward or backwards). #time_change_threshold=900 # AUTO-RESCHEDULING OPTION # This option determines whether or not Nagios will attempt to # automatically reschedule active host and service checks to # "smooth" them out over time. This can help balance the load on # the monitoring server. # WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE # PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY auto_reschedule_checks=0 # AUTO-RESCHEDULING INTERVAL # This option determines how often (in seconds) Nagios will # attempt to automatically reschedule checks. This option only # has an effect if the auto_reschedule_checks option is enabled. # Default is 30 seconds. # WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE # PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY auto_rescheduling_interval=30 # AUTO-RESCHEDULING WINDOW # This option determines the "window" of time (in seconds) that # Nagios will look at when automatically rescheduling checks. # Only host and service checks that occur in the next X seconds # (determined by this variable) will be rescheduled. This option # only has an effect if the auto_reschedule_checks option is # enabled. Default is 180 seconds (3 minutes). # WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE # PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY auto_rescheduling_window=180 # SLEEP TIME # This is the number of seconds to sleep between checking for system # events and service checks that need to be run. sleep_time=0.25 # TIMEOUT VALUES # These options control how much time Nagios will allow various # types of commands to execute before killing them off. Options # are available for controlling maximum time allotted for # service checks, host checks, event handlers, notifications, the # ocsp command, and performance data commands. All values are in # seconds. service_check_timeout=60 host_check_timeout=30 event_handler_timeout=30 notification_timeout=30 ocsp_timeout=5 perfdata_timeout=5 # RETAIN STATE INFORMATION # This setting determines whether or not Nagios will save state # information for services and hosts before it shuts down. Upon # startup Nagios will reload all saved service and host state # information before starting to monitor. This is useful for # maintaining long-term data on state statistics, etc, but will # slow Nagios down a bit when it (re)starts. Since its only # a one-time penalty, I think its well worth the additional # startup delay. retain_state_information=1 # STATE RETENTION FILE # This is the file that Nagios should use to store host and # service state information before it shuts down. The state # information in this file is also read immediately prior to # starting to monitor the network when Nagios is restarted. # This file is used only if the retain_state_information # variable is set to 1. state_retention_file=/var/log/nagios/retention.dat # RETENTION DATA UPDATE INTERVAL # This setting determines how often (in minutes) that Nagios # will automatically save retention data during normal operation. # If you set this value to 0, Nagios will not save retention # data at regular interval, but it will still save retention # data before shutting down or restarting. If you have disabled # state retention, this option has no effect. retention_update_interval=60 # USE RETAINED PROGRAM STATE # This setting determines whether or not Nagios will set # program status variables based on the values saved in the # retention file. If you want to use retained program status # information, set this value to 1. If not, set this value # to 0. use_retained_program_state=1 # USE RETAINED SCHEDULING INFO # This setting determines whether or not Nagios will retain # the scheduling info (next check time) for hosts and services # based on the values saved in the retention file. If you # If you want to use retained scheduling info, set this # value to 1. If not, set this value to 0. use_retained_scheduling_info=1 # RETAINED ATTRIBUTE MASKS (ADVANCED FEATURE) # The following variables are used to specify specific host and # service attributes that should *not* be retained by Nagios during # program restarts. # # The values of the masks are bitwise ANDs of values specified # by the "MODATTR_" definitions found in include/common.h. # For example, if you do not want the current enabled/disabled state # of flap detection and event handlers for hosts to be retained, you # would use a value of 24 for the host attribute mask... # MODATTR_EVENT_HANDLER_ENABLED (8) + MODATTR_FLAP_DETECTION_ENABLED (16) = 24 # This mask determines what host attributes are not retained retained_host_attribute_mask=0 # This mask determines what service attributes are not retained retained_service_attribute_mask=0 # These two masks determine what process attributes are not retained. # There are two masks, because some process attributes have host and service # options. For example, you can disable active host checks, but leave active # service checks enabled. retained_process_host_attribute_mask=0 retained_process_service_attribute_mask=0 # These two masks determine what contact attributes are not retained. # There are two masks, because some contact attributes have host and # service options. For example, you can disable host notifications for # a contact, but leave service notifications enabled for them. retained_contact_host_attribute_mask=0 retained_contact_service_attribute_mask=0 # INTERVAL LENGTH # This is the seconds per unit interval as used in the # host/contact/service configuration files. Setting this to 60 means # that each interval is one minute long (60 seconds). Other settings # have not been tested much, so your mileage is likely to vary... interval_length=60 # CHECK FOR UPDATES # This option determines whether Nagios will automatically check to # see if new updates (releases) are available. It is recommend that you # enable this option to ensure that you stay on top of the latest critical # patches to Nagios. Nagios is critical to you - make sure you keep it in # good shape. Nagios will check once a day for new updates. Data collected # by Nagios Enterprises from the update check is processed in accordance # with our privacy policy - see http://api.nagios.org for details. check_for_updates=1 # BARE UPDATE CHECK # This option deterines what data Nagios will send to api.nagios.org when # it checks for updates. By default, Nagios will send information on the # current version of Nagios you have installed, as well as an indicator as # to whether this was a new installation or not. Nagios Enterprises uses # this data to determine the number of users running specific version of # Nagios. Enable this option if you do not want this information to be sent. bare_update_check=0 # AGGRESSIVE HOST CHECKING OPTION # If you don't want to turn on aggressive host checking features, set # this value to 0 (the default). Otherwise set this value to 1 to # enable the aggressive check option. Read the docs for more info # on what aggressive host check is or check out the source code in # base/checks.c use_aggressive_host_checking=0 # SERVICE CHECK EXECUTION OPTION # This determines whether or not Nagios will actively execute # service checks when it initially starts. If this option is # disabled, checks are not actively made, but Nagios can still # receive and process passive check results that come in. Unless # you're implementing redundant hosts or have a special need for # disabling the execution of service checks, leave this enabled! # Values: 1 = enable checks, 0 = disable checks execute_service_checks=1 # PASSIVE SERVICE CHECK ACCEPTANCE OPTION # This determines whether or not Nagios will accept passive # service checks results when it initially (re)starts. # Values: 1 = accept passive checks, 0 = reject passive checks accept_passive_service_checks=1 # HOST CHECK EXECUTION OPTION # This determines whether or not Nagios will actively execute # host checks when it initially starts. If this option is # disabled, checks are not actively made, but Nagios can still # receive and process passive check results that come in. Unless # you're implementing redundant hosts or have a special need for # disabling the execution of host checks, leave this enabled! # Values: 1 = enable checks, 0 = disable checks execute_host_checks=1 # PASSIVE HOST CHECK ACCEPTANCE OPTION # This determines whether or not Nagios will accept passive # host checks results when it initially (re)starts. # Values: 1 = accept passive checks, 0 = reject passive checks accept_passive_host_checks=1 # NOTIFICATIONS OPTION # This determines whether or not Nagios will sent out any host or # service notifications when it is initially (re)started. # Values: 1 = enable notifications, 0 = disable notifications enable_notifications=1 # EVENT HANDLER USE OPTION # This determines whether or not Nagios will run any host or # service event handlers when it is initially (re)started. Unless # you're implementing redundant hosts, leave this option enabled. # Values: 1 = enable event handlers, 0 = disable event handlers enable_event_handlers=1 # PROCESS PERFORMANCE DATA OPTION # This determines whether or not Nagios will process performance # data returned from service and host checks. If this option is # enabled, host performance data will be processed using the # host_perfdata_command (defined below) and service performance # data will be processed using the service_perfdata_command (also # defined below). Read the HTML docs for more information on # performance data. # Values: 1 = process performance data, 0 = do not process performance data process_performance_data=0 # HOST AND SERVICE PERFORMANCE DATA PROCESSING COMMANDS # These commands are run after every host and service check is # performed. These commands are executed only if the # enable_performance_data option (above) is set to 1. The command # argument is the short name of a command definition that you # define in your host configuration file. Read the HTML docs for # more information on performance data. #host_perfdata_command=process-host-perfdata #service_perfdata_command=process-service-perfdata # HOST AND SERVICE PERFORMANCE DATA FILES # These files are used to store host and service performance data. # Performance data is only written to these files if the # enable_performance_data option (above) is set to 1. #host_perfdata_file=/tmp/host-perfdata #service_perfdata_file=/tmp/service-perfdata # HOST AND SERVICE PERFORMANCE DATA FILE TEMPLATES # These options determine what data is written (and how) to the # performance data files. The templates may contain macros, special # characters (\t for tab, \r for carriage return, \n for newline) # and plain text. A newline is automatically added after each write # to the performance data file. Some examples of what you can do are # shown below. #host_perfdata_file_template=[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$ #service_perfdata_file_template=[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$ # HOST AND SERVICE PERFORMANCE DATA FILE MODES # This option determines whether or not the host and service # performance data files are opened in write ("w") or append ("a") # mode. If you want to use named pipes, you should use the special # pipe ("p") mode which avoid blocking at startup, otherwise you will # likely want the defult append ("a") mode. #host_perfdata_file_mode=a #service_perfdata_file_mode=a # HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING INTERVAL # These options determine how often (in seconds) the host and service # performance data files are processed using the commands defined # below. A value of 0 indicates the files should not be periodically # processed. #host_perfdata_file_processing_interval=0 #service_perfdata_file_processing_interval=0 # HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING COMMANDS # These commands are used to periodically process the host and # service performance data files. The interval at which the # processing occurs is determined by the options above. #host_perfdata_file_processing_command=process-host-perfdata-file #service_perfdata_file_processing_command=process-service-perfdata-file # HOST AND SERVICE PERFORMANCE DATA PROCESS EMPTY RESULTS # THese options determine wether the core will process empty perfdata # results or not. This is needed for distributed monitoring, and intentionally # turned on by default. # If you don't require empty perfdata - saving some cpu cycles # on unwanted macro calculation - you can turn that off. Be careful! # Values: 1 = enable, 0 = disable #host_perfdata_process_empty_results=1 #service_perfdata_process_empty_results=1 # OBSESS OVER SERVICE CHECKS OPTION # This determines whether or not Nagios will obsess over service # checks and run the ocsp_command defined below. Unless you're # planning on implementing distributed monitoring, do not enable # this option. Read the HTML docs for more information on # implementing distributed monitoring. # Values: 1 = obsess over services, 0 = do not obsess (default) obsess_over_services=0 # OBSESSIVE COMPULSIVE SERVICE PROCESSOR COMMAND # This is the command that is run for every service check that is # processed by Nagios. This command is executed only if the # obsess_over_services option (above) is set to 1. The command # argument is the short name of a command definition that you # define in your host configuration file. Read the HTML docs for # more information on implementing distributed monitoring. #ocsp_command=somecommand # OBSESS OVER HOST CHECKS OPTION # This determines whether or not Nagios will obsess over host # checks and run the ochp_command defined below. Unless you're # planning on implementing distributed monitoring, do not enable # this option. Read the HTML docs for more information on # implementing distributed monitoring. # Values: 1 = obsess over hosts, 0 = do not obsess (default) obsess_over_hosts=0 # OBSESSIVE COMPULSIVE HOST PROCESSOR COMMAND # This is the command that is run for every host check that is # processed by Nagios. This command is executed only if the # obsess_over_hosts option (above) is set to 1. The command # argument is the short name of a command definition that you # define in your host configuration file. Read the HTML docs for # more information on implementing distributed monitoring. #ochp_command=somecommand # TRANSLATE PASSIVE HOST CHECKS OPTION # This determines whether or not Nagios will translate # DOWN/UNREACHABLE passive host check results into their proper # state for this instance of Nagios. This option is useful # if you have distributed or failover monitoring setup. In # these cases your other Nagios servers probably have a different # "view" of the network, with regards to the parent/child relationship # of hosts. If a distributed monitoring server thinks a host # is DOWN, it may actually be UNREACHABLE from the point of # this Nagios instance. Enabling this option will tell Nagios # to translate any DOWN or UNREACHABLE host states it receives # passively into the correct state from the view of this server. # Values: 1 = perform translation, 0 = do not translate (default) translate_passive_host_checks=0 # PASSIVE HOST CHECKS ARE SOFT OPTION # This determines whether or not Nagios will treat passive host # checks as being HARD or SOFT. By default, a passive host check # result will put a host into a HARD state type. This can be changed # by enabling this option. # Values: 0 = passive checks are HARD, 1 = passive checks are SOFT passive_host_checks_are_soft=0 # ORPHANED HOST/SERVICE CHECK OPTIONS # These options determine whether or not Nagios will periodically # check for orphaned host service checks. Since service checks are # not rescheduled until the results of their previous execution # instance are processed, there exists a possibility that some # checks may never get rescheduled. A similar situation exists for # host checks, although the exact scheduling details differ a bit # from service checks. Orphaned checks seem to be a rare # problem and should not happen under normal circumstances. # If you have problems with service checks never getting # rescheduled, make sure you have orphaned service checks enabled. # Values: 1 = enable checks, 0 = disable checks check_for_orphaned_services=1 check_for_orphaned_hosts=1 # SERVICE FRESHNESS CHECK OPTION # This option determines whether or not Nagios will periodically # check the "freshness" of service results. Enabling this option # is useful for ensuring passive checks are received in a timely # manner. # Values: 1 = enabled freshness checking, 0 = disable freshness checking check_service_freshness=1 # SERVICE FRESHNESS CHECK INTERVAL # This setting determines how often (in seconds) Nagios will # check the "freshness" of service check results. If you have # disabled service freshness checking, this option has no effect. service_freshness_check_interval=60 # SERVICE CHECK TIMEOUT STATE # This setting determines the state Nagios will report when a # service check times out - that is does not respond within # service_check_timeout seconds. This can be useful if a # machine is running at too high a load and you do not want # to consider a failed service check to be critical (the default). # Valid settings are: # c - Critical (default) # u - Unknown # w - Warning # o - OK service_check_timeout_state=c # HOST FRESHNESS CHECK OPTION # This option determines whether or not Nagios will periodically # check the "freshness" of host results. Enabling this option # is useful for ensuring passive checks are received in a timely # manner. # Values: 1 = enabled freshness checking, 0 = disable freshness checking check_host_freshness=0 # HOST FRESHNESS CHECK INTERVAL # This setting determines how often (in seconds) Nagios will # check the "freshness" of host check results. If you have # disabled host freshness checking, this option has no effect. host_freshness_check_interval=60 # ADDITIONAL FRESHNESS THRESHOLD LATENCY # This setting determines the number of seconds that Nagios # will add to any host and service freshness thresholds that # it calculates (those not explicitly specified by the user). additional_freshness_latency=15 # FLAP DETECTION OPTION # This option determines whether or not Nagios will try # and detect hosts and services that are "flapping". # Flapping occurs when a host or service changes between # states too frequently. When Nagios detects that a # host or service is flapping, it will temporarily suppress # notifications for that host/service until it stops # flapping. Flap detection is very experimental, so read # the HTML documentation before enabling this feature! # Values: 1 = enable flap detection # 0 = disable flap detection (default) enable_flap_detection=1 # FLAP DETECTION THRESHOLDS FOR HOSTS AND SERVICES # Read the HTML documentation on flap detection for # an explanation of what this option does. This option # has no effect if flap detection is disabled. low_service_flap_threshold=5.0 high_service_flap_threshold=20.0 low_host_flap_threshold=5.0 high_host_flap_threshold=20.0 # DATE FORMAT OPTION # This option determines how short dates are displayed. Valid options # include: # us (MM-DD-YYYY HH:MM:SS) # euro (DD-MM-YYYY HH:MM:SS) # iso8601 (YYYY-MM-DD HH:MM:SS) # strict-iso8601 (YYYY-MM-DDTHH:MM:SS) # date_format=us # TIMEZONE OFFSET # This option is used to override the default timezone that this # instance of Nagios runs in. If not specified, Nagios will use # the system configured timezone. # # NOTE: In order to display the correct timezone in the CGIs, you # will also need to alter the Apache directives for the CGI path # to include your timezone. Example: # # # SetEnv TZ "Australia/Brisbane" # ... # #use_timezone=US/Mountain #use_timezone=Australia/Brisbane # P1.PL FILE LOCATION # This value determines where the p1.pl perl script (used by the # embedded Perl interpreter) is located. If you didn't compile # Nagios with embedded Perl support, this option has no effect. p1_file=/usr/sbin/p1.pl # EMBEDDED PERL INTERPRETER OPTION # This option determines whether or not the embedded Perl interpreter # will be enabled during runtime. This option has no effect if Nagios # has not been compiled with support for embedded Perl. # Values: 0 = disable interpreter, 1 = enable interpreter enable_embedded_perl=1 # EMBEDDED PERL USAGE OPTION # This option determines whether or not Nagios will process Perl plugins # and scripts with the embedded Perl interpreter if the plugins/scripts # do not explicitly indicate whether or not it is okay to do so. Read # the HTML documentation on the embedded Perl interpreter for more # information on how this option works. use_embedded_perl_implicitly=1 # ILLEGAL OBJECT NAME CHARACTERS # This option allows you to specify illegal characters that cannot # be used in host names, service descriptions, or names of other # object types. illegal_object_name_chars=`~!$%^&*|'"<>?,()= # ILLEGAL MACRO OUTPUT CHARACTERS # This option allows you to specify illegal characters that are # stripped from macros before being used in notifications, event # handlers, etc. This DOES NOT affect macros used in service or # host check commands. # The following macros are stripped of the characters you specify: # $HOSTOUTPUT$ # $HOSTPERFDATA$ # $HOSTACKAUTHOR$ # $HOSTACKCOMMENT$ # $SERVICEOUTPUT$ # $SERVICEPERFDATA$ # $SERVICEACKAUTHOR$ # $SERVICEACKCOMMENT$ illegal_macro_output_chars=`~$&|'"<> # REGULAR EXPRESSION MATCHING # This option controls whether or not regular expression matching # takes place in the object config files. Regular expression # matching is used to match host, hostgroup, service, and service # group names/descriptions in some fields of various object types. # Values: 1 = enable regexp matching, 0 = disable regexp matching use_regexp_matching=0 # "TRUE" REGULAR EXPRESSION MATCHING # This option controls whether or not "true" regular expression # matching takes place in the object config files. This option # only has an effect if regular expression matching is enabled # (see above). If this option is DISABLED, regular expression # matching only occurs if a string contains wildcard characters # (* and ?). If the option is ENABLED, regexp matching occurs # all the time (which can be annoying). # Values: 1 = enable true matching, 0 = disable true matching use_true_regexp_matching=0 # ADMINISTRATOR EMAIL/PAGER ADDRESSES # The email and pager address of a global administrator (likely you). # Nagios never uses these values itself, but you can access them by # using the $ADMINEMAIL$ and $ADMINPAGER$ macros in your notification # commands. admin_email=nagios@localhost admin_pager=pagenagios@localhost # DAEMON CORE DUMP OPTION # This option determines whether or not Nagios is allowed to create # a core dump when it runs as a daemon. Note that it is generally # considered bad form to allow this, but it may be useful for # debugging purposes. Enabling this option doesn't guarantee that # a core file will be produced, but that's just life... # Values: 1 - Allow core dumps # 0 - Do not allow core dumps (default) daemon_dumps_core=0 # LARGE INSTALLATION TWEAKS OPTION # This option determines whether or not Nagios will take some shortcuts # which can save on memory and CPU usage in large Nagios installations. # Read the documentation for more information on the benefits/tradeoffs # of enabling this option. # Values: 1 - Enabled tweaks # 0 - Disable tweaks (default) use_large_installation_tweaks=0 # ENABLE ENVIRONMENT MACROS # This option determines whether or not Nagios will make all standard # macros available as environment variables when host/service checks # and system commands (event handlers, notifications, etc.) are # executed. Enabling this option can cause performance issues in # large installations, as it will consume a bit more memory and (more # importantly) consume more CPU. # Values: 1 - Enable environment variable macros (default) # 0 - Disable environment variable macros enable_environment_macros=1 # CHILD PROCESS MEMORY OPTION # This option determines whether or not Nagios will free memory in # child processes (processed used to execute system commands and host/ # service checks). If you specify a value here, it will override # program defaults. # Value: 1 - Free memory in child processes # 0 - Do not free memory in child processes #free_child_process_memory=1 # CHILD PROCESS FORKING BEHAVIOR # This option determines how Nagios will fork child processes # (used to execute system commands and host/service checks). Normally # child processes are fork()ed twice, which provides a very high level # of isolation from problems. Fork()ing once is probably enough and will # save a great deal on CPU usage (in large installs), so you might # want to consider using this. If you specify a value here, it will # program defaults. # Value: 1 - Child processes fork() twice # 0 - Child processes fork() just once #child_processes_fork_twice=1 # DEBUG LEVEL # This option determines how much (if any) debugging information will # be written to the debug file. OR values together to log multiple # types of information. # Values: # -1 = Everything # 0 = Nothing # 1 = Functions # 2 = Configuration # 4 = Process information # 8 = Scheduled events # 16 = Host/service checks # 32 = Notifications # 64 = Event broker # 128 = External commands # 256 = Commands # 512 = Scheduled downtime # 1024 = Comments # 2048 = Macros debug_level=0 # DEBUG VERBOSITY # This option determines how verbose the debug log out will be. # Values: 0 = Brief output # 1 = More detailed # 2 = Very detailed debug_verbosity=1 # DEBUG FILE # This option determines where Nagios should write debugging information. debug_file=/var/log/nagios/nagios.debug # MAX DEBUG FILE SIZE # This option determines the maximum size (in bytes) of the debug file. If # the file grows larger than this size, it will be renamed with a .old # extension. If a file already exists with a .old extension it will # automatically be deleted. This helps ensure your disk space usage doesn't # get out of control when debugging Nagios. max_debug_file_size=1000000 ================================================ FILE: lamp_haproxy/aws/roles/nagios/handlers/main.yml ================================================ --- # handlers for nagios - name: restart httpd service: name=httpd state=restarted - name: restart nagios service: name=nagios state=restarted ================================================ FILE: lamp_haproxy/aws/roles/nagios/tasks/main.yml ================================================ --- # This will install nagios - name: install nagios yum: pkg: "{{ item }}" state: present with_items: - nagios - nagios-plugins - nagios-plugins-nrpe - nagios-plugins-ping - nagios-plugins-ssh - nagios-plugins-http - nagios-plugins-mysql - nagios-devel notify: restart httpd - name: create nagios config dir file: path: /etc/nagios/ansible-managed state: directory - name: configure nagios copy: src: nagios.cfg dest: /etc/nagios/nagios.cfg notify: restart nagios - name: configure localhost monitoring copy: src: localhost.cfg dest: /etc/nagios/objects/localhost.cfg notify: restart nagios - name: configure nagios services copy: src: ansible-managed-services.cfg dest: /etc/nagios/ - name: create the nagios object files template: src: "{{ item + '.j2' }}" dest: "/etc/nagios/ansible-managed/{{ item }}" with_items: - webservers.cfg - dbservers.cfg - lbservers.cfg notify: restart nagios - name: start nagios service: name=nagios state=started enabled=yes ================================================ FILE: lamp_haproxy/aws/roles/nagios/templates/dbservers.cfg.j2 ================================================ # {{ ansible_managed }} define hostgroup { hostgroup_name dbservers alias Database Servers } {% for host in groups.tag_ansible_group_dbservers %} define host { use linux-server host_name {{ host }} alias {{ host }} address {{ hostvars[host].ansible_default_ipv4.address }} hostgroups dbservers } {% endfor %} #define service { # use local-service # hostgroup_name dbservers # service_description MySQL Database Server # check_command check_mysql # notifications_enabled 0 #} ================================================ FILE: lamp_haproxy/aws/roles/nagios/templates/lbservers.cfg.j2 ================================================ # {{ ansible_managed }} define hostgroup { hostgroup_name loadbalancers alias Load Balancers } {% for host in groups.tag_ansible_group_lbservers %} define host { use linux-server host_name {{ host }} alias {{ host }} address {{ hostvars[host].ansible_default_ipv4.address }} hostgroups loadbalancers } define service { use local-service host_name {{ host }} service_description HAProxy Load Balancer check_command check_http!-p{{ hostvars[host].listenport }} } {% endfor %} ================================================ FILE: lamp_haproxy/aws/roles/nagios/templates/webservers.cfg.j2 ================================================ # {{ ansible_managed }} define hostgroup { hostgroup_name webservers alias Web Servers } {% for host in groups.tag_ansible_group_webservers %} define host { use linux-server host_name {{ host }} alias {{ host }} address {{ hostvars[host].ansible_default_ipv4.address }} hostgroups webservers } {% endfor %} # service checks to be applied to the web server define service { use local-service hostgroup_name webservers service_description webserver check_command check_http notifications_enabled 0 } ================================================ FILE: lamp_haproxy/aws/roles/web/tasks/main.yml ================================================ --- - name: Copy the code from repository git: repo: "{{ repository }}" version: "{{ webapp_version }}" dest: /var/www/html/ ================================================ FILE: lamp_haproxy/aws/rolling_update.yml ================================================ --- # This playbook does a rolling update for all webservers serially (one at a time). # Change the value of serial: to adjust the number of server to be updated. # # The three roles that apply to the webserver hosts will be applied: common, # base-apache, and web. So any changes to configuration, package updates, etc, # will be applied as part of the rolling update process. # # gather facts from monitoring nodes for iptables rules - hosts: tag_ansible_group_monitoring tasks: [] - hosts: tag_ansible_group_webservers serial: 1 # These are the tasks to run before applying updates: pre_tasks: - name: disable nagios alerts for this host webserver service nagios: 'action=disable_alerts host={{ inventory_hostname }} services=webserver' delegate_to: "{{ item }}" with_items: "{{ groups.tag_ansible_group_monitoring }}" - name: disable the server in haproxy haproxy: 'state=disabled backend=myapplb host={{ inventory_hostname }} socket=/var/lib/haproxy/stats' delegate_to: "{{ item }}" with_items: "{{ groups.tag_ansible_group_lbservers }}" roles: - web ## Optionally, re-run the common and base-apache roles #- common #- base-apache # These tasks run after the roles: post_tasks: - name: wait for webserver to come up wait_for: 'host={{ inventory_hostname }} port=80 state=started timeout=80' - name: enable the server in haproxy haproxy: 'state=enabled backend=myapplb host={{ inventory_hostname }} socket=/var/lib/haproxy/stats' delegate_to: "{{ item }}" with_items: "{{ groups.tag_ansible_group_lbservers }}" - name: re-enable nagios alerts nagios: 'action=enable_alerts host={{ inventory_hostname }} services=webserver' delegate_to: "{{ item }}" with_items: "{{ groups.tag_ansible_group_monitoring }}" ================================================ FILE: lamp_haproxy/aws/site.yml ================================================ --- ## This playbook deploys the whole application stack in this site. # Apply common configuration to all hosts - hosts: all roles: - common # Configure and deploy database servers. - hosts: tag_ansible_group_dbservers roles: - db tags: - db # Configure and deploy the web servers. Note that we include two roles here, # the 'base-apache' role which simply sets up Apache, and 'web' which includes # our example web application. - hosts: tag_ansible_group_webservers roles: - base-apache - web tags: - web # Configure and deploy the load balancer(s). - hosts: tag_ansible_group_lbservers roles: - haproxy tags: - lb # Configure and deploy the Nagios monitoring node(s). - hosts: tag_ansible_group_monitoring roles: - base-apache - nagios tags: - monitoring ================================================ FILE: lamp_haproxy/group_vars/all ================================================ --- # Variables here are applicable to all host groups httpd_port: 80 ntpserver: 192.168.1.2 ================================================ FILE: lamp_haproxy/group_vars/dbservers ================================================ --- # The variables file used by the playbooks in the dbservers group. # These don't have to be explicitly imported by vars_files: they are autopopulated. mysqlservice: mysqld mysql_port: 3306 dbuser: root dbname: foodb upassword: abc ================================================ FILE: lamp_haproxy/group_vars/lbservers ================================================ --- # Variables for the HAproxy configuration # HAProxy supports "http" and "tcp". For SSL, SMTP, etc, use "tcp". mode: http # Port on which HAProxy should listen listenport: 8888 # A name for the proxy daemon, this wil be the suffix in the logs. daemonname: myapplb # Balancing Algorithm. Available options: # roundrobin, source, leastconn, source, uri # (if persistance is required use, "source") balance: roundrobin # Ethernet interface on which the load balancer should listen # Defaults to the first interface. Change this to: # # iface: eth1 # # ...to override. # iface: '{{ ansible_default_ipv4.interface }}' ================================================ FILE: lamp_haproxy/group_vars/webservers ================================================ --- # Variables for the web server configuration # Ethernet interface on which the web server should listen. # Defaults to the first interface. Change this to: # # iface: eth1 # # ...to override. # iface: '{{ ansible_default_ipv4.interface }}' # this is the repository that holds our sample webapp repository: https://github.com/bennojoy/mywebapp.git # this is the sha1sum of V5 of the test webapp. webapp_version: 351e47276cc66b018f4890a04709d4cc3d3edb0d ================================================ FILE: lamp_haproxy/hosts ================================================ [webservers] web1 web2 [dbservers] db1 [lbservers] lb1 [monitoring] nagios ================================================ FILE: lamp_haproxy/provision.yml ================================================ --- #Provision some instances: - hosts: localhost connection: local gather_facts: False vars_files: - group_vars/all tasks: - name: Launch webserver instances ec2: > access_key="{{ ec2_access_key }}" secret_key="{{ ec2_secret_key }}" keypair="{{ ec2_keypair }}" group="{{ ec2_security_group }}" type="{{ ec2_instance_type }}" image="{{ ec2_image }}" region="{{ ec2_region }}" instance_tags="{'ansible_group':'{{ ec2_tag_webservers }}', 'type':'{{ ec2_instance_type }}', 'group':'{{ ec2_security_group }}', 'Name':'demo_''{{ tower_user_name }}'}" count="{{ ec2_instance_count }}" register: ec2 - name: Launch database instance ec2: > access_key="{{ ec2_access_key }}" secret_key="{{ ec2_secret_key }}" keypair="{{ ec2_keypair }}" group="{{ ec2_security_group }}" type="{{ ec2_instance_type }}" image="{{ ec2_image }}" region="{{ ec2_region }}" instance_tags="{'ansible_group':'{{ ec2_tag_dbservers }}', 'type':'{{ ec2_instance_type }}', 'group':'{{ ec2_security_group }}', 'Name':'demo_''{{ tower_user_name }}'}" count="1" register: ec2 - name: Launch load balancing instance ec2: > access_key="{{ ec2_access_key }}" secret_key="{{ ec2_secret_key }}" keypair="{{ ec2_keypair }}" group="{{ ec2_security_group }}" type="{{ ec2_instance_type }}" image="{{ ec2_image }}" region="{{ ec2_region }}" instance_tags="{'ansible_group':'{{ ec2_tag_lbservers }}', 'type':'{{ ec2_instance_type }}', 'group':'{{ ec2_security_group }}', 'Name':'demo_''{{ tower_user_name }}'}" count="1" register: ec2 - name: Launch monitoring instance ec2: > access_key="{{ ec2_access_key }}" secret_key="{{ ec2_secret_key }}" keypair="{{ ec2_keypair }}" group="{{ ec2_security_group }}" type="{{ ec2_instance_type }}" image="{{ ec2_image }}" region="{{ ec2_region }}" instance_tags="{'ansible_group':'{{ ec2_tag_monitoring }}', 'type':'{{ ec2_instance_type }}', 'group':'{{ ec2_security_group }}', 'Name':'demo_''{{ tower_user_name }}'}" count="1" register: ec2 - name: Wait for SSH to come up local_action: wait_for host={{ item.public_dns_name }} port=22 delay=60 timeout=320 state=started with_items: "{{ ec2.instances }}" ================================================ FILE: lamp_haproxy/roles/base-apache/tasks/main.yml ================================================ --- # This role installs httpd - name: Install http yum: name: "{{ item }}" state: present with_items: - httpd - php - php-mysql - git - name: Configure SELinux to allow httpd to connect to remote database seboolean: name: httpd_can_network_connect_db state: true persistent: yes when: sestatus.rc != 0 - name: http service state service: name: httpd state: started enabled: yes ================================================ FILE: lamp_haproxy/roles/common/files/RPM-GPG-KEY-EPEL-6 ================================================ -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.5 (GNU/Linux) mQINBEvSKUIBEADLGnUj24ZVKW7liFN/JA5CgtzlNnKs7sBg7fVbNWryiE3URbn1 JXvrdwHtkKyY96/ifZ1Ld3lE2gOF61bGZ2CWwJNee76Sp9Z+isP8RQXbG5jwj/4B M9HK7phktqFVJ8VbY2jfTjcfxRvGM8YBwXF8hx0CDZURAjvf1xRSQJ7iAo58qcHn XtxOAvQmAbR9z6Q/h/D+Y/PhoIJp1OV4VNHCbCs9M7HUVBpgC53PDcTUQuwcgeY6 pQgo9eT1eLNSZVrJ5Bctivl1UcD6P6CIGkkeT2gNhqindRPngUXGXW7Qzoefe+fV QqJSm7Tq2q9oqVZ46J964waCRItRySpuW5dxZO34WM6wsw2BP2MlACbH4l3luqtp Xo3Bvfnk+HAFH3HcMuwdaulxv7zYKXCfNoSfgrpEfo2Ex4Im/I3WdtwME/Gbnwdq 3VJzgAxLVFhczDHwNkjmIdPAlNJ9/ixRjip4dgZtW8VcBCrNoL+LhDrIfjvnLdRu vBHy9P3sCF7FZycaHlMWP6RiLtHnEMGcbZ8QpQHi2dReU1wyr9QgguGU+jqSXYar 1yEcsdRGasppNIZ8+Qawbm/a4doT10TEtPArhSoHlwbvqTDYjtfV92lC/2iwgO6g YgG9XrO4V8dV39Ffm7oLFfvTbg5mv4Q/E6AWo/gkjmtxkculbyAvjFtYAQARAQAB tCFFUEVMICg2KSA8ZXBlbEBmZWRvcmFwcm9qZWN0Lm9yZz6JAjYEEwECACAFAkvS KUICGw8GCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRA7Sd8qBgi4lR/GD/wLGPv9 qO39eyb9NlrwfKdUEo1tHxKdrhNz+XYrO4yVDTBZRPSuvL2yaoeSIhQOKhNPfEgT 9mdsbsgcfmoHxmGVcn+lbheWsSvcgrXuz0gLt8TGGKGGROAoLXpuUsb1HNtKEOwP Q4z1uQ2nOz5hLRyDOV0I2LwYV8BjGIjBKUMFEUxFTsL7XOZkrAg/WbTH2PW3hrfS WtcRA7EYonI3B80d39ffws7SmyKbS5PmZjqOPuTvV2F0tMhKIhncBwoojWZPExft HpKhzKVh8fdDO/3P1y1Fk3Cin8UbCO9MWMFNR27fVzCANlEPljsHA+3Ez4F7uboF p0OOEov4Yyi4BEbgqZnthTG4ub9nyiupIZ3ckPHr3nVcDUGcL6lQD/nkmNVIeLYP x1uHPOSlWfuojAYgzRH6LL7Idg4FHHBA0to7FW8dQXFIOyNiJFAOT2j8P5+tVdq8 wB0PDSH8yRpn4HdJ9RYquau4OkjluxOWf0uRaS//SUcCZh+1/KBEOmcvBHYRZA5J l/nakCgxGb2paQOzqqpOcHKvlyLuzO5uybMXaipLExTGJXBlXrbbASfXa/yGYSAG iVrGz9CE6676dMlm8F+s3XXE13QZrXmjloc6jwOljnfAkjTGXjiB7OULESed96MR XtfLk0W5Ab9pd7tKDR6QHI7rgHXfCopRnZ2VVQ== =V/6I -----END PGP PUBLIC KEY BLOCK----- ================================================ FILE: lamp_haproxy/roles/common/files/epel.repo ================================================ [epel] name=Extra Packages for Enterprise Linux 6 - $basearch #baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch failovermethod=priority enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 [epel-debuginfo] name=Extra Packages for Enterprise Linux 6 - $basearch - Debug #baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch/debug mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-6&arch=$basearch failovermethod=priority enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 gpgcheck=1 [epel-source] name=Extra Packages for Enterprise Linux 6 - $basearch - Source #baseurl=http://download.fedoraproject.org/pub/epel/6/SRPMS mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-6&arch=$basearch failovermethod=priority enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 gpgcheck=1 ================================================ FILE: lamp_haproxy/roles/common/handlers/main.yml ================================================ --- # Handlers for common notifications - name: restart ntp service: name=ntpd state=restarted - name: restart iptables service: name=iptables state=restarted ================================================ FILE: lamp_haproxy/roles/common/tasks/main.yml ================================================ --- # This role contains common plays that will run on all nodes. - name: Install python bindings for SE Linux yum: name={{ item }} state=present with_items: - libselinux-python - libsemanage-python - name: Create the repository for EPEL copy: src=epel.repo dest=/etc/yum.repos.d/epel.repo - name: Create the GPG key for EPEL copy: src=RPM-GPG-KEY-EPEL-6 dest=/etc/pki/rpm-gpg - name: install some useful nagios plugins yum: name={{ item }} state=present with_items: - nagios-nrpe - nagios-plugins-swap - nagios-plugins-users - nagios-plugins-procs - nagios-plugins-load - nagios-plugins-disk - name: Install ntp yum: name=ntp state=present tags: ntp - name: Configure ntp file template: src=ntp.conf.j2 dest=/etc/ntp.conf tags: ntp notify: restart ntp - name: Start the ntp service service: name=ntpd state=started enabled=yes tags: ntp # work around RHEL 7, for now - name: insert iptables template template: src=iptables.j2 dest=/etc/sysconfig/iptables when: ansible_distribution_major_version != '7' notify: restart iptables - name: test to see if selinux is running command: getenforce register: sestatus changed_when: false ================================================ FILE: lamp_haproxy/roles/common/templates/iptables.j2 ================================================ # {{ ansible_managed }} # Manual customization of this file is not recommended. *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] {% if (inventory_hostname in groups.webservers) or (inventory_hostname in groups.monitoring) %} -A INPUT -p tcp --dport 80 -j ACCEPT {% endif %} {% if (inventory_hostname in groups.dbservers) %} -A INPUT -p tcp --dport 3306 -j ACCEPT {% endif %} {% if (inventory_hostname in groups.lbservers) %} -A INPUT -p tcp --dport {{ listenport }} -j ACCEPT {% endif %} {% for host in groups.monitoring %} -A INPUT -p tcp -s {{ hostvars[host].ansible_default_ipv4.address }} --dport 5666 -j ACCEPT {% endfor %} -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT ================================================ FILE: lamp_haproxy/roles/common/templates/ntp.conf.j2 ================================================ driftfile /var/lib/ntp/drift restrict 127.0.0.1 restrict -6 ::1 server {{ ntpserver }} includefile /etc/ntp/crypto/pw keys /etc/ntp/keys ================================================ FILE: lamp_haproxy/roles/db/handlers/main.yml ================================================ --- # Handler to handle DB tier notifications - name: restart mysql service: name=mysqld state=restarted ================================================ FILE: lamp_haproxy/roles/db/tasks/main.yml ================================================ --- # This role will install MySQL and create db user and give permissions. - name: Install Mysql package yum: name={{ item }} state=present with_items: - mysql-server - MySQL-python - name: Configure SELinux to start mysql on any port seboolean: name=mysql_connect_any state=true persistent=yes when: sestatus.rc != 0 - name: Create Mysql configuration file template: src=my.cnf.j2 dest=/etc/my.cnf notify: - restart mysql - name: Start Mysql Service service: name=mysqld state=started enabled=yes - name: Create Application Database mysql_db: name={{ dbname }} state=present - name: Create Application DB User mysql_user: name={{ dbuser }} password={{ upassword }} priv=*.*:ALL host='%' state=present ================================================ FILE: lamp_haproxy/roles/db/templates/my.cnf.j2 ================================================ [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 port={{ mysql_port }} [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid ================================================ FILE: lamp_haproxy/roles/haproxy/handlers/main.yml ================================================ --- # Handlers for HAproxy - name: restart haproxy service: name=haproxy state=restarted - name: reload haproxy service: name=haproxy state=reloaded ================================================ FILE: lamp_haproxy/roles/haproxy/tasks/main.yml ================================================ --- # This role installs HAProxy and configures it. - name: Download and install haproxy yum: name=haproxy state=present - name: Configure the haproxy cnf file with hosts template: src=haproxy.cfg.j2 dest=/etc/haproxy/haproxy.cfg notify: restart haproxy - name: Start the haproxy service service: name=haproxy state=started enabled=yes ================================================ FILE: lamp_haproxy/roles/haproxy/templates/haproxy.cfg.j2 ================================================ global log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user root group root daemon # turn on stats unix socket stats socket /var/lib/haproxy/stats level admin defaults mode {{ mode }} log global option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.0/8 option redispatch retries 3 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 backend app {% for host in groups.lbservers %} listen {{ daemonname }} 0.0.0.0:{{ listenport }} {% endfor %} balance {{ balance }} {% for host in groups.webservers %} server {{ host }} {{ hostvars[host]['ansible_' + iface].ipv4.address }}:{{ httpd_port }} {% endfor %} ================================================ FILE: lamp_haproxy/roles/nagios/files/ansible-managed-services.cfg ================================================ # {{ ansible_managed }} # service checks to be applied to all hosts define service { use local-service host_name localhost service_description Root Partition check_command check_local_disk!20%!10%!/ } define service { use local-service host_name * service_description Current Users check_command check_local_users!20!50 } define service { use local-service host_name * service_description Total Processes check_command check_local_procs!250!400!RSZDT } define service { use local-service host_name * service_description Current Load check_command check_local_load!5.0,4.0,3.0!10.0,6.0,4.0 } define service { use local-service host_name * service_description Swap Usage check_command check_local_swap!20!10 } ================================================ FILE: lamp_haproxy/roles/nagios/files/localhost.cfg ================================================ ############################################################################### # LOCALHOST.CFG - SAMPLE OBJECT CONFIG FILE FOR MONITORING THIS MACHINE # # Last Modified: 05-31-2007 # # NOTE: This config file is intended to serve as an *extremely* simple # example of how you can create configuration entries to monitor # the local (Linux) machine. # ############################################################################### ############################################################################### ############################################################################### # # HOST DEFINITION # ############################################################################### ############################################################################### # Define a host for the local machine define host{ use linux-server ; Name of host template to use ; This host definition will inherit all variables that are defined ; in (or inherited by) the linux-server host template definition. host_name localhost alias localhost address 127.0.0.1 } ############################################################################### ############################################################################### # # HOST GROUP DEFINITION # ############################################################################### ############################################################################### # Define an optional hostgroup for Linux machines define hostgroup{ hostgroup_name linux-servers ; The name of the hostgroup alias Linux Servers ; Long name of the group members localhost ; Comma separated list of hosts that belong to this group } ############################################################################### ############################################################################### # # SERVICE DEFINITIONS # ############################################################################### ############################################################################### # Define a service to "ping" the local machine define service{ use local-service ; Name of service template to use host_name localhost service_description PING check_command check_ping!100.0,20%!500.0,60% } # Define a service to check the disk space of the root partition # on the local machine. Warning if < 20% free, critical if # < 10% free space on partition. define service{ use local-service ; Name of service template to use host_name localhost service_description Root Partition check_command check_local_disk!20%!10%!/ } # Define a service to check the number of currently logged in # users on the local machine. Warning if > 20 users, critical # if > 50 users. define service{ use local-service ; Name of service template to use host_name localhost service_description Current Users check_command check_local_users!20!50 } # Define a service to check the number of currently running procs # on the local machine. Warning if > 250 processes, critical if # > 400 users. define service{ use local-service ; Name of service template to use host_name localhost service_description Total Processes check_command check_local_procs!250!400!RSZDT } # Define a service to check the load on the local machine. define service{ use local-service ; Name of service template to use host_name localhost service_description Current Load check_command check_local_load!5.0,4.0,3.0!10.0,6.0,4.0 } # Define a service to check the swap usage the local machine. # Critical if less than 10% of swap is free, warning if less than 20% is free define service{ use local-service ; Name of service template to use host_name localhost service_description Swap Usage check_command check_local_swap!20!10 } # Define a service to check SSH on the local machine. # Disable notifications for this service by default, as not all users may have SSH enabled. define service{ use local-service ; Name of service template to use host_name localhost service_description SSH check_command check_ssh notifications_enabled 0 } ================================================ FILE: lamp_haproxy/roles/nagios/files/nagios.cfg ================================================ ############################################################################## # # NAGIOS.CFG - Sample Main Config File for Nagios 3.4.4 # # Read the documentation for more information on this configuration # file. I've provided some comments here, but things may not be so # clear without further explanation. # # Last Modified: 12-14-2008 # ############################################################################## # LOG FILE # This is the main log file where service and host events are logged # for historical purposes. This should be the first option specified # in the config file!!! log_file=/var/log/nagios/nagios.log # OBJECT CONFIGURATION FILE(S) # These are the object configuration files in which you define hosts, # host groups, contacts, contact groups, services, etc. # You can split your object definitions across several config files # if you wish (as shown below), or keep them all in a single config file. # You can specify individual object config files as shown below: cfg_file=/etc/nagios/objects/commands.cfg cfg_file=/etc/nagios/objects/contacts.cfg cfg_file=/etc/nagios/objects/timeperiods.cfg cfg_file=/etc/nagios/objects/templates.cfg # Definitions for monitoring the local (Linux) host cfg_file=/etc/nagios/objects/localhost.cfg cfg_file=/etc/nagios/ansible-managed-services.cfg cfg_dir=/etc/nagios/ansible-managed # OBJECT CACHE FILE # This option determines where object definitions are cached when # Nagios starts/restarts. The CGIs read object definitions from # this cache file (rather than looking at the object config files # directly) in order to prevent inconsistencies that can occur # when the config files are modified after Nagios starts. object_cache_file=/var/log/nagios/objects.cache # PRE-CACHED OBJECT FILE # This options determines the location of the precached object file. # If you run Nagios with the -p command line option, it will preprocess # your object configuration file(s) and write the cached config to this # file. You can then start Nagios with the -u option to have it read # object definitions from this precached file, rather than the standard # object configuration files (see the cfg_file and cfg_dir options above). # Using a precached object file can speed up the time needed to (re)start # the Nagios process if you've got a large and/or complex configuration. # Read the documentation section on optimizing Nagios to find our more # about how this feature works. precached_object_file=/var/log/nagios/objects.precache # RESOURCE FILE # This is an optional resource file that contains $USERx$ macro # definitions. Multiple resource files can be specified by using # multiple resource_file definitions. The CGIs will not attempt to # read the contents of resource files, so information that is # considered to be sensitive (usernames, passwords, etc) can be # defined as macros in this file and restrictive permissions (600) # can be placed on this file. resource_file=/etc/nagios/private/resource.cfg # STATUS FILE # This is where the current status of all monitored services and # hosts is stored. Its contents are read and processed by the CGIs. # The contents of the status file are deleted every time Nagios # restarts. status_file=/var/log/nagios/status.dat # STATUS FILE UPDATE INTERVAL # This option determines the frequency (in seconds) that # Nagios will periodically dump program, host, and # service status data. status_update_interval=10 # NAGIOS USER # This determines the effective user that Nagios should run as. # You can either supply a username or a UID. nagios_user=nagios # NAGIOS GROUP # This determines the effective group that Nagios should run as. # You can either supply a group name or a GID. nagios_group=nagios # EXTERNAL COMMAND OPTION # This option allows you to specify whether or not Nagios should check # for external commands (in the command file defined below). By default # Nagios will *not* check for external commands, just to be on the # cautious side. If you want to be able to use the CGI command interface # you will have to enable this. # Values: 0 = disable commands, 1 = enable commands check_external_commands=1 # EXTERNAL COMMAND CHECK INTERVAL # This is the interval at which Nagios should check for external commands. # This value works of the interval_length you specify later. If you leave # that at its default value of 60 (seconds), a value of 1 here will cause # Nagios to check for external commands every minute. If you specify a # number followed by an "s" (i.e. 15s), this will be interpreted to mean # actual seconds rather than a multiple of the interval_length variable. # Note: In addition to reading the external command file at regularly # scheduled intervals, Nagios will also check for external commands after # event handlers are executed. # NOTE: Setting this value to -1 causes Nagios to check the external # command file as often as possible. #command_check_interval=15s command_check_interval=-1 # EXTERNAL COMMAND FILE # This is the file that Nagios checks for external command requests. # It is also where the command CGI will write commands that are submitted # by users, so it must be writeable by the user that the web server # is running as (usually 'nobody'). Permissions should be set at the # directory level instead of on the file, as the file is deleted every # time its contents are processed. command_file=/var/spool/nagios/cmd/nagios.cmd # EXTERNAL COMMAND BUFFER SLOTS # This settings is used to tweak the number of items or "slots" that # the Nagios daemon should allocate to the buffer that holds incoming # external commands before they are processed. As external commands # are processed by the daemon, they are removed from the buffer. external_command_buffer_slots=4096 # LOCK FILE # This is the lockfile that Nagios will use to store its PID number # in when it is running in daemon mode. lock_file=/var/run/nagios.pid # TEMP FILE # This is a temporary file that is used as scratch space when Nagios # updates the status log, cleans the comment file, etc. This file # is created, used, and deleted throughout the time that Nagios is # running. temp_file=/var/log/nagios/nagios.tmp # TEMP PATH # This is path where Nagios can create temp files for service and # host check results, etc. temp_path=/tmp # EVENT BROKER OPTIONS # Controls what (if any) data gets sent to the event broker. # Values: 0 = Broker nothing # -1 = Broker everything # = See documentation event_broker_options=-1 # EVENT BROKER MODULE(S) # This directive is used to specify an event broker module that should # by loaded by Nagios at startup. Use multiple directives if you want # to load more than one module. Arguments that should be passed to # the module at startup are seperated from the module path by a space. # #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # # Do NOT overwrite modules while they are being used by Nagios or Nagios # will crash in a fiery display of SEGFAULT glory. This is a bug/limitation # either in dlopen(), the kernel, and/or the filesystem. And maybe Nagios... # # The correct/safe way of updating a module is by using one of these methods: # 1. Shutdown Nagios, replace the module file, restart Nagios # 2. Delete the original module file, move the new module file into place, restart Nagios # # Example: # # broker_module= [moduleargs] #broker_module=/somewhere/module1.o #broker_module=/somewhere/module2.o arg1 arg2=3 debug=0 # LOG ROTATION METHOD # This is the log rotation method that Nagios should use to rotate # the main log file. Values are as follows.. # n = None - don't rotate the log # h = Hourly rotation (top of the hour) # d = Daily rotation (midnight every day) # w = Weekly rotation (midnight on Saturday evening) # m = Monthly rotation (midnight last day of month) log_rotation_method=d # LOG ARCHIVE PATH # This is the directory where archived (rotated) log files should be # placed (assuming you've chosen to do log rotation). log_archive_path=/var/log/nagios/archives # LOGGING OPTIONS # If you want messages logged to the syslog facility, as well as the # Nagios log file set this option to 1. If not, set it to 0. use_syslog=1 # NOTIFICATION LOGGING OPTION # If you don't want notifications to be logged, set this value to 0. # If notifications should be logged, set the value to 1. log_notifications=1 # SERVICE RETRY LOGGING OPTION # If you don't want service check retries to be logged, set this value # to 0. If retries should be logged, set the value to 1. log_service_retries=1 # HOST RETRY LOGGING OPTION # If you don't want host check retries to be logged, set this value to # 0. If retries should be logged, set the value to 1. log_host_retries=1 # EVENT HANDLER LOGGING OPTION # If you don't want host and service event handlers to be logged, set # this value to 0. If event handlers should be logged, set the value # to 1. log_event_handlers=1 # INITIAL STATES LOGGING OPTION # If you want Nagios to log all initial host and service states to # the main log file (the first time the service or host is checked) # you can enable this option by setting this value to 1. If you # are not using an external application that does long term state # statistics reporting, you do not need to enable this option. In # this case, set the value to 0. log_initial_states=0 # EXTERNAL COMMANDS LOGGING OPTION # If you don't want Nagios to log external commands, set this value # to 0. If external commands should be logged, set this value to 1. # Note: This option does not include logging of passive service # checks - see the option below for controlling whether or not # passive checks are logged. log_external_commands=1 # PASSIVE CHECKS LOGGING OPTION # If you don't want Nagios to log passive host and service checks, set # this value to 0. If passive checks should be logged, set # this value to 1. log_passive_checks=1 # GLOBAL HOST AND SERVICE EVENT HANDLERS # These options allow you to specify a host and service event handler # command that is to be run for every host or service state change. # The global event handler is executed immediately prior to the event # handler that you have optionally specified in each host or # service definition. The command argument is the short name of a # command definition that you define in your host configuration file. # Read the HTML docs for more information. #global_host_event_handler=somecommand #global_service_event_handler=somecommand # SERVICE INTER-CHECK DELAY METHOD # This is the method that Nagios should use when initially # "spreading out" service checks when it starts monitoring. The # default is to use smart delay calculation, which will try to # space all service checks out evenly to minimize CPU load. # Using the dumb setting will cause all checks to be scheduled # at the same time (with no delay between them)! This is not a # good thing for production, but is useful when testing the # parallelization functionality. # n = None - don't use any delay between checks # d = Use a "dumb" delay of 1 second between checks # s = Use "smart" inter-check delay calculation # x.xx = Use an inter-check delay of x.xx seconds service_inter_check_delay_method=s # MAXIMUM SERVICE CHECK SPREAD # This variable determines the timeframe (in minutes) from the # program start time that an initial check of all services should # be completed. Default is 30 minutes. max_service_check_spread=30 # SERVICE CHECK INTERLEAVE FACTOR # This variable determines how service checks are interleaved. # Interleaving the service checks allows for a more even # distribution of service checks and reduced load on remote # hosts. Setting this value to 1 is equivalent to how versions # of Nagios previous to 0.0.5 did service checks. Set this # value to s (smart) for automatic calculation of the interleave # factor unless you have a specific reason to change it. # s = Use "smart" interleave factor calculation # x = Use an interleave factor of x, where x is a # number greater than or equal to 1. service_interleave_factor=s # HOST INTER-CHECK DELAY METHOD # This is the method that Nagios should use when initially # "spreading out" host checks when it starts monitoring. The # default is to use smart delay calculation, which will try to # space all host checks out evenly to minimize CPU load. # Using the dumb setting will cause all checks to be scheduled # at the same time (with no delay between them)! # n = None - don't use any delay between checks # d = Use a "dumb" delay of 1 second between checks # s = Use "smart" inter-check delay calculation # x.xx = Use an inter-check delay of x.xx seconds host_inter_check_delay_method=s # MAXIMUM HOST CHECK SPREAD # This variable determines the timeframe (in minutes) from the # program start time that an initial check of all hosts should # be completed. Default is 30 minutes. max_host_check_spread=30 # MAXIMUM CONCURRENT SERVICE CHECKS # This option allows you to specify the maximum number of # service checks that can be run in parallel at any given time. # Specifying a value of 1 for this variable essentially prevents # any service checks from being parallelized. A value of 0 # will not restrict the number of concurrent checks that are # being executed. max_concurrent_checks=0 # HOST AND SERVICE CHECK REAPER FREQUENCY # This is the frequency (in seconds!) that Nagios will process # the results of host and service checks. check_result_reaper_frequency=10 # MAX CHECK RESULT REAPER TIME # This is the max amount of time (in seconds) that a single # check result reaper event will be allowed to run before # returning control back to Nagios so it can perform other # duties. max_check_result_reaper_time=30 # CHECK RESULT PATH # This is directory where Nagios stores the results of host and # service checks that have not yet been processed. # # Note: Make sure that only one instance of Nagios has access # to this directory! check_result_path=/var/log/nagios/spool/checkresults # MAX CHECK RESULT FILE AGE # This option determines the maximum age (in seconds) which check # result files are considered to be valid. Files older than this # threshold will be mercilessly deleted without further processing. max_check_result_file_age=3600 # CACHED HOST CHECK HORIZON # This option determines the maximum amount of time (in seconds) # that the state of a previous host check is considered current. # Cached host states (from host checks that were performed more # recently that the timeframe specified by this value) can immensely # improve performance in regards to the host check logic. # Too high of a value for this option may result in inaccurate host # states being used by Nagios, while a lower value may result in a # performance hit for host checks. Use a value of 0 to disable host # check caching. cached_host_check_horizon=15 # CACHED SERVICE CHECK HORIZON # This option determines the maximum amount of time (in seconds) # that the state of a previous service check is considered current. # Cached service states (from service checks that were performed more # recently that the timeframe specified by this value) can immensely # improve performance in regards to predictive dependency checks. # Use a value of 0 to disable service check caching. cached_service_check_horizon=15 # ENABLE PREDICTIVE HOST DEPENDENCY CHECKS # This option determines whether or not Nagios will attempt to execute # checks of hosts when it predicts that future dependency logic test # may be needed. These predictive checks can help ensure that your # host dependency logic works well. # Values: # 0 = Disable predictive checks # 1 = Enable predictive checks (default) enable_predictive_host_dependency_checks=1 # ENABLE PREDICTIVE SERVICE DEPENDENCY CHECKS # This option determines whether or not Nagios will attempt to execute # checks of service when it predicts that future dependency logic test # may be needed. These predictive checks can help ensure that your # service dependency logic works well. # Values: # 0 = Disable predictive checks # 1 = Enable predictive checks (default) enable_predictive_service_dependency_checks=1 # SOFT STATE DEPENDENCIES # This option determines whether or not Nagios will use soft state # information when checking host and service dependencies. Normally # Nagios will only use the latest hard host or service state when # checking dependencies. If you want it to use the latest state (regardless # of whether its a soft or hard state type), enable this option. # Values: # 0 = Don't use soft state dependencies (default) # 1 = Use soft state dependencies soft_state_dependencies=0 # TIME CHANGE ADJUSTMENT THRESHOLDS # These options determine when Nagios will react to detected changes # in system time (either forward or backwards). #time_change_threshold=900 # AUTO-RESCHEDULING OPTION # This option determines whether or not Nagios will attempt to # automatically reschedule active host and service checks to # "smooth" them out over time. This can help balance the load on # the monitoring server. # WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE # PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY auto_reschedule_checks=0 # AUTO-RESCHEDULING INTERVAL # This option determines how often (in seconds) Nagios will # attempt to automatically reschedule checks. This option only # has an effect if the auto_reschedule_checks option is enabled. # Default is 30 seconds. # WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE # PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY auto_rescheduling_interval=30 # AUTO-RESCHEDULING WINDOW # This option determines the "window" of time (in seconds) that # Nagios will look at when automatically rescheduling checks. # Only host and service checks that occur in the next X seconds # (determined by this variable) will be rescheduled. This option # only has an effect if the auto_reschedule_checks option is # enabled. Default is 180 seconds (3 minutes). # WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE # PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY auto_rescheduling_window=180 # SLEEP TIME # This is the number of seconds to sleep between checking for system # events and service checks that need to be run. sleep_time=0.25 # TIMEOUT VALUES # These options control how much time Nagios will allow various # types of commands to execute before killing them off. Options # are available for controlling maximum time allotted for # service checks, host checks, event handlers, notifications, the # ocsp command, and performance data commands. All values are in # seconds. service_check_timeout=60 host_check_timeout=30 event_handler_timeout=30 notification_timeout=30 ocsp_timeout=5 perfdata_timeout=5 # RETAIN STATE INFORMATION # This setting determines whether or not Nagios will save state # information for services and hosts before it shuts down. Upon # startup Nagios will reload all saved service and host state # information before starting to monitor. This is useful for # maintaining long-term data on state statistics, etc, but will # slow Nagios down a bit when it (re)starts. Since its only # a one-time penalty, I think its well worth the additional # startup delay. retain_state_information=1 # STATE RETENTION FILE # This is the file that Nagios should use to store host and # service state information before it shuts down. The state # information in this file is also read immediately prior to # starting to monitor the network when Nagios is restarted. # This file is used only if the retain_state_information # variable is set to 1. state_retention_file=/var/log/nagios/retention.dat # RETENTION DATA UPDATE INTERVAL # This setting determines how often (in minutes) that Nagios # will automatically save retention data during normal operation. # If you set this value to 0, Nagios will not save retention # data at regular interval, but it will still save retention # data before shutting down or restarting. If you have disabled # state retention, this option has no effect. retention_update_interval=60 # USE RETAINED PROGRAM STATE # This setting determines whether or not Nagios will set # program status variables based on the values saved in the # retention file. If you want to use retained program status # information, set this value to 1. If not, set this value # to 0. use_retained_program_state=1 # USE RETAINED SCHEDULING INFO # This setting determines whether or not Nagios will retain # the scheduling info (next check time) for hosts and services # based on the values saved in the retention file. If you # If you want to use retained scheduling info, set this # value to 1. If not, set this value to 0. use_retained_scheduling_info=1 # RETAINED ATTRIBUTE MASKS (ADVANCED FEATURE) # The following variables are used to specify specific host and # service attributes that should *not* be retained by Nagios during # program restarts. # # The values of the masks are bitwise ANDs of values specified # by the "MODATTR_" definitions found in include/common.h. # For example, if you do not want the current enabled/disabled state # of flap detection and event handlers for hosts to be retained, you # would use a value of 24 for the host attribute mask... # MODATTR_EVENT_HANDLER_ENABLED (8) + MODATTR_FLAP_DETECTION_ENABLED (16) = 24 # This mask determines what host attributes are not retained retained_host_attribute_mask=0 # This mask determines what service attributes are not retained retained_service_attribute_mask=0 # These two masks determine what process attributes are not retained. # There are two masks, because some process attributes have host and service # options. For example, you can disable active host checks, but leave active # service checks enabled. retained_process_host_attribute_mask=0 retained_process_service_attribute_mask=0 # These two masks determine what contact attributes are not retained. # There are two masks, because some contact attributes have host and # service options. For example, you can disable host notifications for # a contact, but leave service notifications enabled for them. retained_contact_host_attribute_mask=0 retained_contact_service_attribute_mask=0 # INTERVAL LENGTH # This is the seconds per unit interval as used in the # host/contact/service configuration files. Setting this to 60 means # that each interval is one minute long (60 seconds). Other settings # have not been tested much, so your mileage is likely to vary... interval_length=60 # CHECK FOR UPDATES # This option determines whether Nagios will automatically check to # see if new updates (releases) are available. It is recommend that you # enable this option to ensure that you stay on top of the latest critical # patches to Nagios. Nagios is critical to you - make sure you keep it in # good shape. Nagios will check once a day for new updates. Data collected # by Nagios Enterprises from the update check is processed in accordance # with our privacy policy - see http://api.nagios.org for details. check_for_updates=1 # BARE UPDATE CHECK # This option deterines what data Nagios will send to api.nagios.org when # it checks for updates. By default, Nagios will send information on the # current version of Nagios you have installed, as well as an indicator as # to whether this was a new installation or not. Nagios Enterprises uses # this data to determine the number of users running specific version of # Nagios. Enable this option if you do not want this information to be sent. bare_update_check=0 # AGGRESSIVE HOST CHECKING OPTION # If you don't want to turn on aggressive host checking features, set # this value to 0 (the default). Otherwise set this value to 1 to # enable the aggressive check option. Read the docs for more info # on what aggressive host check is or check out the source code in # base/checks.c use_aggressive_host_checking=0 # SERVICE CHECK EXECUTION OPTION # This determines whether or not Nagios will actively execute # service checks when it initially starts. If this option is # disabled, checks are not actively made, but Nagios can still # receive and process passive check results that come in. Unless # you're implementing redundant hosts or have a special need for # disabling the execution of service checks, leave this enabled! # Values: 1 = enable checks, 0 = disable checks execute_service_checks=1 # PASSIVE SERVICE CHECK ACCEPTANCE OPTION # This determines whether or not Nagios will accept passive # service checks results when it initially (re)starts. # Values: 1 = accept passive checks, 0 = reject passive checks accept_passive_service_checks=1 # HOST CHECK EXECUTION OPTION # This determines whether or not Nagios will actively execute # host checks when it initially starts. If this option is # disabled, checks are not actively made, but Nagios can still # receive and process passive check results that come in. Unless # you're implementing redundant hosts or have a special need for # disabling the execution of host checks, leave this enabled! # Values: 1 = enable checks, 0 = disable checks execute_host_checks=1 # PASSIVE HOST CHECK ACCEPTANCE OPTION # This determines whether or not Nagios will accept passive # host checks results when it initially (re)starts. # Values: 1 = accept passive checks, 0 = reject passive checks accept_passive_host_checks=1 # NOTIFICATIONS OPTION # This determines whether or not Nagios will sent out any host or # service notifications when it is initially (re)started. # Values: 1 = enable notifications, 0 = disable notifications enable_notifications=1 # EVENT HANDLER USE OPTION # This determines whether or not Nagios will run any host or # service event handlers when it is initially (re)started. Unless # you're implementing redundant hosts, leave this option enabled. # Values: 1 = enable event handlers, 0 = disable event handlers enable_event_handlers=1 # PROCESS PERFORMANCE DATA OPTION # This determines whether or not Nagios will process performance # data returned from service and host checks. If this option is # enabled, host performance data will be processed using the # host_perfdata_command (defined below) and service performance # data will be processed using the service_perfdata_command (also # defined below). Read the HTML docs for more information on # performance data. # Values: 1 = process performance data, 0 = do not process performance data process_performance_data=0 # HOST AND SERVICE PERFORMANCE DATA PROCESSING COMMANDS # These commands are run after every host and service check is # performed. These commands are executed only if the # enable_performance_data option (above) is set to 1. The command # argument is the short name of a command definition that you # define in your host configuration file. Read the HTML docs for # more information on performance data. #host_perfdata_command=process-host-perfdata #service_perfdata_command=process-service-perfdata # HOST AND SERVICE PERFORMANCE DATA FILES # These files are used to store host and service performance data. # Performance data is only written to these files if the # enable_performance_data option (above) is set to 1. #host_perfdata_file=/tmp/host-perfdata #service_perfdata_file=/tmp/service-perfdata # HOST AND SERVICE PERFORMANCE DATA FILE TEMPLATES # These options determine what data is written (and how) to the # performance data files. The templates may contain macros, special # characters (\t for tab, \r for carriage return, \n for newline) # and plain text. A newline is automatically added after each write # to the performance data file. Some examples of what you can do are # shown below. #host_perfdata_file_template=[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$ #service_perfdata_file_template=[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$ # HOST AND SERVICE PERFORMANCE DATA FILE MODES # This option determines whether or not the host and service # performance data files are opened in write ("w") or append ("a") # mode. If you want to use named pipes, you should use the special # pipe ("p") mode which avoid blocking at startup, otherwise you will # likely want the defult append ("a") mode. #host_perfdata_file_mode=a #service_perfdata_file_mode=a # HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING INTERVAL # These options determine how often (in seconds) the host and service # performance data files are processed using the commands defined # below. A value of 0 indicates the files should not be periodically # processed. #host_perfdata_file_processing_interval=0 #service_perfdata_file_processing_interval=0 # HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING COMMANDS # These commands are used to periodically process the host and # service performance data files. The interval at which the # processing occurs is determined by the options above. #host_perfdata_file_processing_command=process-host-perfdata-file #service_perfdata_file_processing_command=process-service-perfdata-file # HOST AND SERVICE PERFORMANCE DATA PROCESS EMPTY RESULTS # THese options determine wether the core will process empty perfdata # results or not. This is needed for distributed monitoring, and intentionally # turned on by default. # If you don't require empty perfdata - saving some cpu cycles # on unwanted macro calculation - you can turn that off. Be careful! # Values: 1 = enable, 0 = disable #host_perfdata_process_empty_results=1 #service_perfdata_process_empty_results=1 # OBSESS OVER SERVICE CHECKS OPTION # This determines whether or not Nagios will obsess over service # checks and run the ocsp_command defined below. Unless you're # planning on implementing distributed monitoring, do not enable # this option. Read the HTML docs for more information on # implementing distributed monitoring. # Values: 1 = obsess over services, 0 = do not obsess (default) obsess_over_services=0 # OBSESSIVE COMPULSIVE SERVICE PROCESSOR COMMAND # This is the command that is run for every service check that is # processed by Nagios. This command is executed only if the # obsess_over_services option (above) is set to 1. The command # argument is the short name of a command definition that you # define in your host configuration file. Read the HTML docs for # more information on implementing distributed monitoring. #ocsp_command=somecommand # OBSESS OVER HOST CHECKS OPTION # This determines whether or not Nagios will obsess over host # checks and run the ochp_command defined below. Unless you're # planning on implementing distributed monitoring, do not enable # this option. Read the HTML docs for more information on # implementing distributed monitoring. # Values: 1 = obsess over hosts, 0 = do not obsess (default) obsess_over_hosts=0 # OBSESSIVE COMPULSIVE HOST PROCESSOR COMMAND # This is the command that is run for every host check that is # processed by Nagios. This command is executed only if the # obsess_over_hosts option (above) is set to 1. The command # argument is the short name of a command definition that you # define in your host configuration file. Read the HTML docs for # more information on implementing distributed monitoring. #ochp_command=somecommand # TRANSLATE PASSIVE HOST CHECKS OPTION # This determines whether or not Nagios will translate # DOWN/UNREACHABLE passive host check results into their proper # state for this instance of Nagios. This option is useful # if you have distributed or failover monitoring setup. In # these cases your other Nagios servers probably have a different # "view" of the network, with regards to the parent/child relationship # of hosts. If a distributed monitoring server thinks a host # is DOWN, it may actually be UNREACHABLE from the point of # this Nagios instance. Enabling this option will tell Nagios # to translate any DOWN or UNREACHABLE host states it receives # passively into the correct state from the view of this server. # Values: 1 = perform translation, 0 = do not translate (default) translate_passive_host_checks=0 # PASSIVE HOST CHECKS ARE SOFT OPTION # This determines whether or not Nagios will treat passive host # checks as being HARD or SOFT. By default, a passive host check # result will put a host into a HARD state type. This can be changed # by enabling this option. # Values: 0 = passive checks are HARD, 1 = passive checks are SOFT passive_host_checks_are_soft=0 # ORPHANED HOST/SERVICE CHECK OPTIONS # These options determine whether or not Nagios will periodically # check for orphaned host service checks. Since service checks are # not rescheduled until the results of their previous execution # instance are processed, there exists a possibility that some # checks may never get rescheduled. A similar situation exists for # host checks, although the exact scheduling details differ a bit # from service checks. Orphaned checks seem to be a rare # problem and should not happen under normal circumstances. # If you have problems with service checks never getting # rescheduled, make sure you have orphaned service checks enabled. # Values: 1 = enable checks, 0 = disable checks check_for_orphaned_services=1 check_for_orphaned_hosts=1 # SERVICE FRESHNESS CHECK OPTION # This option determines whether or not Nagios will periodically # check the "freshness" of service results. Enabling this option # is useful for ensuring passive checks are received in a timely # manner. # Values: 1 = enabled freshness checking, 0 = disable freshness checking check_service_freshness=1 # SERVICE FRESHNESS CHECK INTERVAL # This setting determines how often (in seconds) Nagios will # check the "freshness" of service check results. If you have # disabled service freshness checking, this option has no effect. service_freshness_check_interval=60 # SERVICE CHECK TIMEOUT STATE # This setting determines the state Nagios will report when a # service check times out - that is does not respond within # service_check_timeout seconds. This can be useful if a # machine is running at too high a load and you do not want # to consider a failed service check to be critical (the default). # Valid settings are: # c - Critical (default) # u - Unknown # w - Warning # o - OK service_check_timeout_state=c # HOST FRESHNESS CHECK OPTION # This option determines whether or not Nagios will periodically # check the "freshness" of host results. Enabling this option # is useful for ensuring passive checks are received in a timely # manner. # Values: 1 = enabled freshness checking, 0 = disable freshness checking check_host_freshness=0 # HOST FRESHNESS CHECK INTERVAL # This setting determines how often (in seconds) Nagios will # check the "freshness" of host check results. If you have # disabled host freshness checking, this option has no effect. host_freshness_check_interval=60 # ADDITIONAL FRESHNESS THRESHOLD LATENCY # This setting determines the number of seconds that Nagios # will add to any host and service freshness thresholds that # it calculates (those not explicitly specified by the user). additional_freshness_latency=15 # FLAP DETECTION OPTION # This option determines whether or not Nagios will try # and detect hosts and services that are "flapping". # Flapping occurs when a host or service changes between # states too frequently. When Nagios detects that a # host or service is flapping, it will temporarily suppress # notifications for that host/service until it stops # flapping. Flap detection is very experimental, so read # the HTML documentation before enabling this feature! # Values: 1 = enable flap detection # 0 = disable flap detection (default) enable_flap_detection=1 # FLAP DETECTION THRESHOLDS FOR HOSTS AND SERVICES # Read the HTML documentation on flap detection for # an explanation of what this option does. This option # has no effect if flap detection is disabled. low_service_flap_threshold=5.0 high_service_flap_threshold=20.0 low_host_flap_threshold=5.0 high_host_flap_threshold=20.0 # DATE FORMAT OPTION # This option determines how short dates are displayed. Valid options # include: # us (MM-DD-YYYY HH:MM:SS) # euro (DD-MM-YYYY HH:MM:SS) # iso8601 (YYYY-MM-DD HH:MM:SS) # strict-iso8601 (YYYY-MM-DDTHH:MM:SS) # date_format=us # TIMEZONE OFFSET # This option is used to override the default timezone that this # instance of Nagios runs in. If not specified, Nagios will use # the system configured timezone. # # NOTE: In order to display the correct timezone in the CGIs, you # will also need to alter the Apache directives for the CGI path # to include your timezone. Example: # # # SetEnv TZ "Australia/Brisbane" # ... # #use_timezone=US/Mountain #use_timezone=Australia/Brisbane # P1.PL FILE LOCATION # This value determines where the p1.pl perl script (used by the # embedded Perl interpreter) is located. If you didn't compile # Nagios with embedded Perl support, this option has no effect. p1_file=/usr/sbin/p1.pl # EMBEDDED PERL INTERPRETER OPTION # This option determines whether or not the embedded Perl interpreter # will be enabled during runtime. This option has no effect if Nagios # has not been compiled with support for embedded Perl. # Values: 0 = disable interpreter, 1 = enable interpreter enable_embedded_perl=1 # EMBEDDED PERL USAGE OPTION # This option determines whether or not Nagios will process Perl plugins # and scripts with the embedded Perl interpreter if the plugins/scripts # do not explicitly indicate whether or not it is okay to do so. Read # the HTML documentation on the embedded Perl interpreter for more # information on how this option works. use_embedded_perl_implicitly=1 # ILLEGAL OBJECT NAME CHARACTERS # This option allows you to specify illegal characters that cannot # be used in host names, service descriptions, or names of other # object types. illegal_object_name_chars=`~!$%^&*|'"<>?,()= # ILLEGAL MACRO OUTPUT CHARACTERS # This option allows you to specify illegal characters that are # stripped from macros before being used in notifications, event # handlers, etc. This DOES NOT affect macros used in service or # host check commands. # The following macros are stripped of the characters you specify: # $HOSTOUTPUT$ # $HOSTPERFDATA$ # $HOSTACKAUTHOR$ # $HOSTACKCOMMENT$ # $SERVICEOUTPUT$ # $SERVICEPERFDATA$ # $SERVICEACKAUTHOR$ # $SERVICEACKCOMMENT$ illegal_macro_output_chars=`~$&|'"<> # REGULAR EXPRESSION MATCHING # This option controls whether or not regular expression matching # takes place in the object config files. Regular expression # matching is used to match host, hostgroup, service, and service # group names/descriptions in some fields of various object types. # Values: 1 = enable regexp matching, 0 = disable regexp matching use_regexp_matching=0 # "TRUE" REGULAR EXPRESSION MATCHING # This option controls whether or not "true" regular expression # matching takes place in the object config files. This option # only has an effect if regular expression matching is enabled # (see above). If this option is DISABLED, regular expression # matching only occurs if a string contains wildcard characters # (* and ?). If the option is ENABLED, regexp matching occurs # all the time (which can be annoying). # Values: 1 = enable true matching, 0 = disable true matching use_true_regexp_matching=0 # ADMINISTRATOR EMAIL/PAGER ADDRESSES # The email and pager address of a global administrator (likely you). # Nagios never uses these values itself, but you can access them by # using the $ADMINEMAIL$ and $ADMINPAGER$ macros in your notification # commands. admin_email=nagios@localhost admin_pager=pagenagios@localhost # DAEMON CORE DUMP OPTION # This option determines whether or not Nagios is allowed to create # a core dump when it runs as a daemon. Note that it is generally # considered bad form to allow this, but it may be useful for # debugging purposes. Enabling this option doesn't guarantee that # a core file will be produced, but that's just life... # Values: 1 - Allow core dumps # 0 - Do not allow core dumps (default) daemon_dumps_core=0 # LARGE INSTALLATION TWEAKS OPTION # This option determines whether or not Nagios will take some shortcuts # which can save on memory and CPU usage in large Nagios installations. # Read the documentation for more information on the benefits/tradeoffs # of enabling this option. # Values: 1 - Enabled tweaks # 0 - Disable tweaks (default) use_large_installation_tweaks=0 # ENABLE ENVIRONMENT MACROS # This option determines whether or not Nagios will make all standard # macros available as environment variables when host/service checks # and system commands (event handlers, notifications, etc.) are # executed. Enabling this option can cause performance issues in # large installations, as it will consume a bit more memory and (more # importantly) consume more CPU. # Values: 1 - Enable environment variable macros (default) # 0 - Disable environment variable macros enable_environment_macros=1 # CHILD PROCESS MEMORY OPTION # This option determines whether or not Nagios will free memory in # child processes (processed used to execute system commands and host/ # service checks). If you specify a value here, it will override # program defaults. # Value: 1 - Free memory in child processes # 0 - Do not free memory in child processes #free_child_process_memory=1 # CHILD PROCESS FORKING BEHAVIOR # This option determines how Nagios will fork child processes # (used to execute system commands and host/service checks). Normally # child processes are fork()ed twice, which provides a very high level # of isolation from problems. Fork()ing once is probably enough and will # save a great deal on CPU usage (in large installs), so you might # want to consider using this. If you specify a value here, it will # program defaults. # Value: 1 - Child processes fork() twice # 0 - Child processes fork() just once #child_processes_fork_twice=1 # DEBUG LEVEL # This option determines how much (if any) debugging information will # be written to the debug file. OR values together to log multiple # types of information. # Values: # -1 = Everything # 0 = Nothing # 1 = Functions # 2 = Configuration # 4 = Process information # 8 = Scheduled events # 16 = Host/service checks # 32 = Notifications # 64 = Event broker # 128 = External commands # 256 = Commands # 512 = Scheduled downtime # 1024 = Comments # 2048 = Macros debug_level=0 # DEBUG VERBOSITY # This option determines how verbose the debug log out will be. # Values: 0 = Brief output # 1 = More detailed # 2 = Very detailed debug_verbosity=1 # DEBUG FILE # This option determines where Nagios should write debugging information. debug_file=/var/log/nagios/nagios.debug # MAX DEBUG FILE SIZE # This option determines the maximum size (in bytes) of the debug file. If # the file grows larger than this size, it will be renamed with a .old # extension. If a file already exists with a .old extension it will # automatically be deleted. This helps ensure your disk space usage doesn't # get out of control when debugging Nagios. max_debug_file_size=1000000 ================================================ FILE: lamp_haproxy/roles/nagios/handlers/main.yml ================================================ --- # handlers for nagios - name: restart httpd service: name=httpd state=restarted - name: restart nagios service: name=nagios state=restarted ================================================ FILE: lamp_haproxy/roles/nagios/tasks/main.yml ================================================ --- # This will install nagios - name: install nagios yum: pkg={{ item }} state=present with_items: - nagios - nagios-plugins - nagios-plugins-nrpe - nagios-plugins-ping - nagios-plugins-ssh - nagios-plugins-http - nagios-plugins-mysql - nagios-devel notify: restart httpd - name: create nagios config dir file: path=/etc/nagios/ansible-managed state=directory - name: configure nagios copy: src=nagios.cfg dest=/etc/nagios/nagios.cfg notify: restart nagios - name: configure localhost monitoring copy: src=localhost.cfg dest=/etc/nagios/objects/localhost.cfg notify: restart nagios - name: configure nagios services copy: src=ansible-managed-services.cfg dest=/etc/nagios/ - name: create the nagios object files template: src={{ item + ".j2" }} dest=/etc/nagios/ansible-managed/{{ item }} with_items: - webservers.cfg - dbservers.cfg - lbservers.cfg notify: restart nagios - name: start nagios service: name=nagios state=started enabled=yes ================================================ FILE: lamp_haproxy/roles/nagios/templates/dbservers.cfg.j2 ================================================ # {{ ansible_managed }} define hostgroup { hostgroup_name dbservers alias Database Servers } {% for host in groups.dbservers %} define host { use linux-server host_name {{ host }} alias {{ host }} address {{ hostvars[host].ansible_default_ipv4.address }} hostgroups dbservers } {% endfor %} #define service { # use local-service # hostgroup_name dbservers # service_description MySQL Database Server # check_command check_mysql # notifications_enabled 0 #} ================================================ FILE: lamp_haproxy/roles/nagios/templates/lbservers.cfg.j2 ================================================ # {{ ansible_managed }} define hostgroup { hostgroup_name loadbalancers alias Load Balancers } {% for host in groups.lbservers %} define host { use linux-server host_name {{ host }} alias {{ host }} address {{ hostvars[host].ansible_default_ipv4.address }} hostgroups loadbalancers } define service { use local-service host_name {{ host }} service_description HAProxy Load Balancer check_command check_http!-p{{ hostvars[host].listenport }} } {% endfor %} ================================================ FILE: lamp_haproxy/roles/nagios/templates/webservers.cfg.j2 ================================================ # {{ ansible_managed }} define hostgroup { hostgroup_name webservers alias Web Servers } {% for host in groups.webservers %} define host { use linux-server host_name {{ host }} alias {{ host }} address {{ hostvars[host].ansible_default_ipv4.address }} hostgroups webservers } {% endfor %} # service checks to be applied to the web server define service { use local-service hostgroup_name webservers service_description webserver check_command check_http notifications_enabled 0 } ================================================ FILE: lamp_haproxy/roles/web/tasks/main.yml ================================================ --- - name: Copy the code from repository git: repo={{ repository }} version={{ webapp_version }} dest=/var/www/html/ ================================================ FILE: lamp_haproxy/rolling_update.yml ================================================ --- # This playbook does a rolling update for all webservers serially (one at a time). # Change the value of serial: to adjust the number of server to be updated. # # The three roles that apply to the webserver hosts will be applied: common, # base-apache, and web. So any changes to configuration, package updates, etc, # will be applied as part of the rolling update process. # # gather facts from monitoring nodes for iptables rules - hosts: monitoring tasks: [] - hosts: webservers serial: 1 # These are the tasks to run before applying updates: pre_tasks: - name: disable nagios alerts for this host webserver service nagios: 'action=disable_alerts host={{ inventory_hostname }} services=webserver' delegate_to: "{{ item }}" with_items: "{{ groups.monitoring }}" - name: disable the server in haproxy haproxy: 'state=disabled backend=myapplb host={{ inventory_hostname }} socket=/var/lib/haproxy/stats' delegate_to: "{{ item }}" with_items: "{{ groups.lbservers }}" roles: - common - base-apache - web # These tasks run after the roles: post_tasks: - name: wait for webserver to come up wait_for: 'host={{ inventory_hostname }} port=80 state=started timeout=80' - name: enable the server in haproxy haproxy: 'state=enabled backend=myapplb host={{ inventory_hostname }} socket=/var/lib/haproxy/stats' delegate_to: "{{ item }}" with_items: "{{ groups.lbservers }}" - name: re-enable nagios alerts nagios: 'action=enable_alerts host={{ inventory_hostname }} services=webserver' delegate_to: "{{ item }}" with_items: "{{ groups.monitoring }}" ================================================ FILE: lamp_haproxy/site.yml ================================================ --- ## This playbook deploys the whole application stack in this site. # Apply common configuration to all hosts - hosts: all roles: - common # Configure and deploy database servers. - hosts: dbservers roles: - db tags: - db # Configure and deploy the web servers. Note that we include two roles here, # the 'base-apache' role which simply sets up Apache, and 'web' which includes # our example web application. - hosts: webservers roles: - base-apache - web tags: - web # Configure and deploy the load balancer(s). - hosts: lbservers roles: - haproxy tags: - lb # Configure and deploy the Nagios monitoring node(s). - hosts: monitoring roles: - base-apache - nagios tags: - monitoring ================================================ FILE: lamp_simple/LICENSE.md ================================================ Copyright (C) 2013 AnsibleWorks, Inc. This work is licensed under the Creative Commons Attribution 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/deed.en_US. ================================================ FILE: lamp_simple/README.md ================================================ Building a simple LAMP stack and deploying Application using Ansible Playbooks. ------------------------------------------- These playbooks require Ansible 1.2. These playbooks are meant to be a reference and starter's guide to building Ansible Playbooks. These playbooks were tested on CentOS 6.x so we recommend that you use CentOS or RHEL to test these modules. This LAMP stack can be on a single node or multiple nodes. The inventory file 'hosts' defines the nodes in which the stacks should be configured. [webservers] localhost [dbservers] bensible Here the webserver would be configured on the local host and the dbserver on a server called `bensible`. The stack can be deployed using the following command: ansible-playbook -i hosts site.yml Once done, you can check the results by browsing to http://localhost/index.php. You should see a simple test page and a list of databases retrieved from the database server. ================================================ FILE: lamp_simple/group_vars/all ================================================ --- # Variables listed here are applicable to all host groups httpd_port: 80 ntpserver: 192.168.1.2 repository: https://github.com/bennojoy/mywebapp.git ================================================ FILE: lamp_simple/group_vars/dbservers ================================================ --- # The variables file used by the playbooks in the dbservers group. # These don't have to be explicitly imported by vars_files: they are autopopulated. mysqlservice: mysqld mysql_port: 3306 dbuser: foouser dbname: foodb upassword: abc ================================================ FILE: lamp_simple/hosts ================================================ [webservers] web3 [dbservers] web2 ================================================ FILE: lamp_simple/roles/common/handlers/main.yml ================================================ --- # Handler to handle common notifications. Handlers are called by other plays. # See http://docs.ansible.com/playbooks_intro.html for more information about handlers. - name: restart ntp service: name: ntpd state: restarted ================================================ FILE: lamp_simple/roles/common/tasks/main.yml ================================================ --- # This playbook contains common plays that will be run on all nodes. - name: Install ntp yum: name: ntp state: present tags: ntp - name: Configure ntp file template: src: ntp.conf.j2 dest: /etc/ntp.conf tags: ntp notify: restart ntp - name: Start the ntp service service: name: ntpd state: started enabled: yes tags: ntp - name: test to see if selinux is running command: getenforce register: sestatus changed_when: false ================================================ FILE: lamp_simple/roles/common/templates/ntp.conf.j2 ================================================ driftfile /var/lib/ntp/drift restrict 127.0.0.1 restrict -6 ::1 server {{ ntpserver }} includefile /etc/ntp/crypto/pw keys /etc/ntp/keys ================================================ FILE: lamp_simple/roles/db/handlers/main.yml ================================================ --- # Handler to handle DB tier notifications - name: restart mysql service: name: mysqld state: restarted - name: restart iptables service: name: iptables state: restarted ================================================ FILE: lamp_simple/roles/db/tasks/main.yml ================================================ --- # This playbook will install mysql and create db user and give permissions. - name: Install Mysql package yum: name: "{{ item }}" state: installed with_items: - mysql-server - MySQL-python - libselinux-python - libsemanage-python - name: Configure SELinux to start mysql on any port seboolean: name: mysql_connect_any state: true persistent: yes when: sestatus.rc != 0 - name: Create Mysql configuration file template: src: my.cnf.j2 dest: /etc/my.cnf notify: - restart mysql - name: Start Mysql Service service: name: mysqld state: started enabled: yes - name: insert iptables rule lineinfile: dest: /etc/sysconfig/iptables state: present regexp: "{{ mysql_port }}" insertafter: "^:OUTPUT " line: "-A INPUT -p tcp --dport {{ mysql_port }} -j ACCEPT" notify: restart iptables - name: Create Application Database mysql_db: name: "{{ dbname }}" state: present - name: Create Application DB User mysql_user: name: "{{ dbuser }}" password: "{{ upassword }}" priv: "*.*:ALL" host: '%' state: present ================================================ FILE: lamp_simple/roles/db/templates/my.cnf.j2 ================================================ [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 port={{ mysql_port }} [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid ================================================ FILE: lamp_simple/roles/web/handlers/main.yml ================================================ --- # Handler for the webtier: handlers are called by other plays. # See http://docs.ansible.com/playbooks_intro.html for more information about handlers. - name: restart iptables service: name: iptables state: restarted ================================================ FILE: lamp_simple/roles/web/tasks/copy_code.yml ================================================ --- # These tasks are responsible for copying the latest dev/production code from # the version control system. - name: Copy the code from repository git: repo: "{{ repository }}" dest: /var/www/html/ - name: Creates the index.php file template: src: index.php.j2 dest: /var/www/html/index.php ================================================ FILE: lamp_simple/roles/web/tasks/install_httpd.yml ================================================ --- # These tasks install http and the php modules. - name: Install http and php etc yum: name: "{{ item }}" state: present with_items: - httpd - php - php-mysql - git - libsemanage-python - libselinux-python - name: insert iptables rule for httpd lineinfile: dest: /etc/sysconfig/iptables create: yes state: present regexp: "{{ httpd_port }}" insertafter: "^:OUTPUT " line: "-A INPUT -p tcp --dport {{ httpd_port }} -j ACCEPT" notify: restart iptables - name: http service state service: name: httpd state: started enabled: yes - name: Configure SELinux to allow httpd to connect to remote database seboolean: name: httpd_can_network_connect_db state: true persistent: yes when: sestatus.rc != 0 ================================================ FILE: lamp_simple/roles/web/tasks/main.yml ================================================ --- - include: install_httpd.yml - include: copy_code.yml ================================================ FILE: lamp_simple/roles/web/templates/index.php.j2 ================================================ Ansible Application
Homepage
"; echo "List of Databases:
"; {% for host in groups['dbservers'] %} $link = mysqli_connect('{{ hostvars[host].ansible_default_ipv4.address }}', '{{ hostvars[host].dbuser }}', '{{ hostvars[host].upassword }}') or die(mysqli_connect_error($link)); {% endfor %} $res = mysqli_query($link, "SHOW DATABASES;"); while ($row = mysqli_fetch_assoc($res)) { echo $row['Database'] . "\n"; } ?> ================================================ FILE: lamp_simple/site.yml ================================================ --- # This playbook deploys the whole application stack in this site. - name: apply common configuration to all nodes hosts: all remote_user: root roles: - common - name: configure and deploy the webservers and application code hosts: webservers remote_user: root roles: - web - name: deploy MySQL and configure the databases hosts: dbservers remote_user: root roles: - db ================================================ FILE: lamp_simple_rhel7/LICENSE.md ================================================ Copyright (C) 2015 Eugene Varnavsky (varnavruz@gmail.com) This work is licensed under the Creative Commons Attribution 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/deed.en_US. ================================================ FILE: lamp_simple_rhel7/README.md ================================================ Building a simple LAMP stack and deploying Application using Ansible Playbooks. ------------------------------------------- These playbooks require Ansible 1.2. These playbooks are meant to be a reference and starter's guide to building Ansible Playbooks. These playbooks were tested on CentOS 7.x so we recommend that you use CentOS or RHEL to test these modules. RHEL7 version reflects changes in Red Hat Enterprise Linux and CentOS 7: 1. Network device naming scheme has changed 2. iptables is replaced with firewalld 3. MySQL is replaced with MariaDB This LAMP stack can be on a single node or multiple nodes. The inventory file 'hosts' defines the nodes in which the stacks should be configured. [webservers] localhost [dbservers] bensible Here the webserver would be configured on the local host and the dbserver on a server called `bensible`. The stack can be deployed using the following command: ansible-playbook -i hosts site.yml Once done, you can check the results by browsing to http://localhost/index.php. You should see a simple test page and a list of databases retrieved from the database server. ================================================ FILE: lamp_simple_rhel7/group_vars/all ================================================ --- # Variables listed here are applicable to all host groups httpd_port: 80 ntpserver: 192.168.1.2 repository: https://github.com/bennojoy/mywebapp.git ================================================ FILE: lamp_simple_rhel7/group_vars/dbservers ================================================ --- # The variables file used by the playbooks in the dbservers group. # These don't have to be explicitly imported by vars_files: they are autopopulated. mysqlservice: mysqld mysql_port: 3306 dbuser: foouser dbname: foodb upassword: abc ================================================ FILE: lamp_simple_rhel7/hosts ================================================ [webservers] webserver.local [dbservers] dbserver.local ================================================ FILE: lamp_simple_rhel7/roles/common/handlers/main.yml ================================================ --- # Handler to handle common notifications. Handlers are called by other plays. # See http://docs.ansible.com/playbooks_intro.html for more information about handlers. - name: restart ntp service: name=ntpd state=restarted ================================================ FILE: lamp_simple_rhel7/roles/common/tasks/main.yml ================================================ --- # This playbook contains common plays that will be run on all nodes. - name: Install ntp yum: name=ntp state=present tags: ntp - name: Install common dependencies yum: name={{ item }} state=installed with_items: - libselinux-python - libsemanage-python - firewalld - name: Configure ntp file template: src=ntp.conf.j2 dest=/etc/ntp.conf tags: ntp notify: restart ntp - name: Start the ntp service service: name=ntpd state=started enabled=yes tags: ntp ================================================ FILE: lamp_simple_rhel7/roles/common/templates/ntp.conf.j2 ================================================ driftfile /var/lib/ntp/drift restrict 127.0.0.1 restrict -6 ::1 server {{ ntpserver }} includefile /etc/ntp/crypto/pw keys /etc/ntp/keys ================================================ FILE: lamp_simple_rhel7/roles/db/handlers/main.yml ================================================ --- # Handler to handle DB tier notifications - name: restart mariadb service: name=mariadb state=restarted ================================================ FILE: lamp_simple_rhel7/roles/db/tasks/main.yml ================================================ --- # This playbook will install MariaDB and create db user and give permissions. - name: Install MariaDB package yum: name={{ item }} state=installed with_items: - mariadb-server - MySQL-python - name: Configure SELinux to start mysql on any port seboolean: name=mysql_connect_any state=true persistent=yes - name: Create Mysql configuration file template: src=my.cnf.j2 dest=/etc/my.cnf notify: - restart mariadb - name: Create MariaDB log file file: path=/var/log/mysqld.log state=touch owner=mysql group=mysql mode=0775 - name: Create MariaDB PID directory file: path=/var/run/mysqld state=directory owner=mysql group=mysql mode=0775 - name: Start MariaDB Service service: name=mariadb state=started enabled=yes - name: Start firewalld service: name=firewalld state=started enabled=yes - name: insert firewalld rule firewalld: port={{ mysql_port }}/tcp permanent=true state=enabled immediate=yes - name: Create Application Database mysql_db: name={{ dbname }} state=present - name: Create Application DB User mysql_user: name={{ dbuser }} password={{ upassword }} priv=*.*:ALL host='%' state=present ================================================ FILE: lamp_simple_rhel7/roles/db/templates/my.cnf.j2 ================================================ [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 port={{ mysql_port }} [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid ================================================ FILE: lamp_simple_rhel7/roles/web/tasks/copy_code.yml ================================================ --- # These tasks are responsible for copying the latest dev/production code from # the version control system. - name: Copy the code from repository git: repo={{ repository }} dest=/var/www/html/ - name: Creates the index.php file template: src=index.php.j2 dest=/var/www/html/index.php ================================================ FILE: lamp_simple_rhel7/roles/web/tasks/install_httpd.yml ================================================ --- # These tasks install http and the php modules. - name: Install httpd and php yum: name={{ item }} state=present with_items: - httpd - php - php-mysql - name: Install web role specific dependencies yum: name={{ item }} state=installed with_items: - git - name: Start firewalld service: name=firewalld state=started enabled=yes - name: insert firewalld rule for httpd firewalld: port={{ httpd_port }}/tcp permanent=true state=enabled immediate=yes - name: http service state service: name=httpd state=started enabled=yes - name: Configure SELinux to allow httpd to connect to remote database seboolean: name=httpd_can_network_connect_db state=true persistent=yes ================================================ FILE: lamp_simple_rhel7/roles/web/tasks/main.yml ================================================ --- - include: install_httpd.yml - include: copy_code.yml ================================================ FILE: lamp_simple_rhel7/roles/web/templates/index.php.j2 ================================================ Ansible Application
Homepage
"; echo "List of Databases:
"; {% for host in groups['dbservers'] %} $link = mysqli_connect('{{ hostvars[host].ansible_default_ipv4.address }}', '{{ hostvars[host].dbuser }}', '{{ hostvars[host].upassword }}') or die(mysqli_connect_error($link)); {% endfor %} $res = mysqli_query($link, "SHOW DATABASES;"); while ($row = mysqli_fetch_assoc($res)) { echo $row['Database'] . "\n"; } ?> ================================================ FILE: lamp_simple_rhel7/site.yml ================================================ --- # This playbook deploys the whole application stack in this site. - name: apply common configuration to all nodes hosts: all remote_user: root roles: - common - name: configure and deploy the webservers and application code hosts: webservers remote_user: root roles: - web - name: deploy MySQL and configure the databases hosts: dbservers remote_user: root roles: - db ================================================ FILE: language_features/ansible_pull.yml ================================================ # ansible-pull setup # # on remote hosts, set up ansible to run periodically using the latest code # from a particular checkout, in pull based fashion, inverting Ansible's # usual push-based operating mode. # # This particular pull based mode is ideal for: # # (A) massive scale out # (B) continual system remediation # # DO NOT RUN THIS AGAINST YOUR HOSTS WITHOUT CHANGING THE repo_url # TO SOMETHING YOU HAVE PERSONALLY VERIFIED # # --- - hosts: pull_mode_hosts remote_user: root vars: # schedule is fed directly to cron schedule: '*/15 * * * *' # User to run ansible-pull as from cron cron_user: root # File that ansible will use for logs logfile: /var/log/ansible-pull.log # Directory to where repository will be cloned workdir: /var/lib/ansible/local # Repository to check out -- YOU MUST CHANGE THIS # repo must contain a local.yml file at top level #repo_url: git://github.com/sfromm/ansible-playbooks.git repo_url: SUPPLY_YOUR_OWN_GIT_URL_HERE tasks: - name: Install ansible yum: pkg=ansible state=installed - name: Create local directory to work from file: path={{workdir}} state=directory owner=root group=root mode=0751 - name: Copy ansible inventory file to client copy: src=/etc/ansible/hosts dest=/etc/ansible/hosts owner=root group=root mode=0644 - name: Create crontab entry to clone/pull git repository template: src=templates/etc_cron.d_ansible-pull.j2 dest=/etc/cron.d/ansible-pull owner=root group=root mode=0644 - name: Create logrotate entry for ansible-pull.log template: src=templates/etc_logrotate.d_ansible-pull.j2 dest=/etc/logrotate.d/ansible-pull owner=root group=root mode=0644 ================================================ FILE: language_features/batch_size_control.yml ================================================ # ordinarily, without the 'serial' keyword set, ansible will control all of your machines in a play at once, in parallel. # if you want to perform a rolling update, so that each play completes all the way through on a certain number of hosts # before moving on to the remaining hosts, use the 'serial' keyword like so: --- - hosts: all serial: 3 # now each of the tasks below will complete on 3 hosts before moving on to the next 3, regardless of how many # hosts are selected by the "hosts:" line tasks: - name: ping ping: - name: ping2 ping: ================================================ FILE: language_features/cloudformation.yaml ================================================ --- # This playbook demonstrates how to use the ansible cloudformation module to launch an AWS CloudFormation stack. # # This module requires that the boto python library is installed, and that you have your AWS credentials # in $HOME/.boto #The thought here is to bring up a bare infrastructure with CloudFormation, but use ansible to configure it. #I generally do this in 2 different playbook runs as to allow the ec2.py inventory to be updated. #This module also uses "complex arguments" which were introduced in ansible 1.1 allowing you to specify the #Cloudformation template parameters #This example launches a 3 node AutoScale group, with a security group, and an InstanceProfile with root permissions. #If a stack does not exist, it will be created. If it does exist and the template file has changed, the stack will be updated. #If the parameters are different, the stack will also be updated. #CloudFormation stacks can take awhile to provision, if you are curious about its status, use the AWS #web console or one of the CloudFormation CLI's. #Example update -- try first launching the stack with 3 as the ClusterSize. After it is launched, change it to 4 #and run the playbook again. - name: provision stack hosts: localhost connection: local gather_facts: false # Launch the cloudformation-example.json template. Register the output. tasks: - name: launch ansible cloudformation example cloudformation: > stack_name="ansible-cloudformation" state=present region=us-east-1 disable_rollback=true template=files/cloudformation-example.json args: template_parameters: KeyName: jmartin DiskType: ephemeral InstanceType: m1.small ClusterSize: 3 register: stack - name: show stack outputs debug: msg="My stack outputs are {{stack.stack_outputs}}" ================================================ FILE: language_features/complex_args.yml ================================================ --- # this is a bit of an advanced topic. # # generally Ansible likes to pass simple key=value arguments to modules. It # occasionally comes up though that you might want to write a module that takes # COMPLEX arguments, like lists and dictionaries. # # In order for this to happen, at least right now, it should be a Python # module, so it can leverage some common code in Ansible that makes this easy. # If you write a non-Python module, you can still pass data across, but only # hashes that do not contain lists or other hashes. If you write the Python # module, you can do anything. # # note that if you were to use BOTH the key=value form and the 'args' form for # passing data in, the behaviour is currently undefined. Ansible is working to # standardize on returning a duplicate parameter failure in this case but # modules which don't use the common module framework may do something # different. - hosts: localhost gather_facts: no vars: complex: ghostbusters: [ 'egon', 'ray', 'peter', 'winston' ] mice: [ 'pinky', 'brain', 'larry' ] tasks: - name: this is the basic way data passing works for any module action: ping data='Hi Mom' - name: of course this can also be written like so, which is shorter ping: data='Hi Mom' - name: but what if you have a complex module that needs complicated data? ping: data: moo: cow asdf: [1,2,3,4] - name: can we make that cleaner? sure! ping: data: "{{ complex }}" ================================================ FILE: language_features/conditionals_part1.yml ================================================ --- # this is a demo of conditional imports. This is a powerful concept # and can be used to use the same recipe for different types of hosts, # based on variables that bubble up from the hosts from tools such # as ohai or facter. # # Here's an example use case: # # what to do if the service for apache is named 'httpd' on CentOS # but is named 'apache' on Debian? # there is only one play in this playbook, it runs on all hosts # as root - hosts: all remote_user: root # we have a common list of variables stored in /vars/external_vars.yml # that we will always import # next, we want to import files that are different per operating system # and if no per operating system file is found, load a defaults file. # for instance, if the OS was "CentOS", we'd try to load vars/CentOS.yml. # if that was found, we would immediately stop. However if that wasn't # present, we'd try to load vars/defaults.yml. If that in turn was not # found, we would fail immediately, because we had gotten to the end of # the list without importing anything. vars_files: - "vars/external_vars.yml" - [ "vars/{{ facter_operatingsystem }}.yml", "vars/defaults.yml" ] # and this is just a regular task line from a playbook, as we're used to. # but with variables in it that come from above. Note that the variables # from above are *also* available in templates tasks: - name: ensure apache is latest action: "{{ packager }} pkg={{ apache }} state=latest" - name: ensure apache is running service: name={{ apache }} state=running ================================================ FILE: language_features/conditionals_part2.yml ================================================ --- # this is a demo of conditional executions using 'when' statements, which can skip # certain tasks on machines/platforms/etc where they do not apply. - hosts: all remote_user: root vars: favcolor: "red" dog: "fido" cat: "whiskers" ssn: 8675309 tasks: - name: "do this if my favcolor is blue, and my dog is named fido" shell: /bin/false when: favcolor == 'blue' and dog == 'fido' - name: "do this if my favcolor is not blue, and my dog is named fido" shell: /bin/true when: favcolor != 'blue' and dog == 'fido' - name: "do this if my SSN is over 9000" shell: /bin/true when: ssn > 9000 - name: "do this if I have one of these SSNs" shell: /bin/true when: ssn in [ 8675309, 8675310, 8675311 ] - name: "do this if a variable named hippo is NOT defined" shell: /bin/true when: hippo is not defined - name: "do this if a variable named hippo is defined" shell: /bin/true when: hippo is defined ================================================ FILE: language_features/custom_filters.yml ================================================ --- - name: Demonstrate custom jinja2 filters hosts: all tasks: - template: src=templates/custom-filters.j2 dest=/tmp/custom-filters.txt ================================================ FILE: language_features/delegation.yml ================================================ --- # this is an example of how we can perform actions on a given host on behalf of all the hosts # in a play. # # The two main uses of this would be signalling an outage window for hosts that # we are going to start upgrading, or to take a machine out of rotation by talking to a load # balancer. # # This example cheats by replacing the load balancer script with the 'echo' command, # leaving actual communication with the load balancer as an exercise to the reader. In reality, # you could call anything you want, the main thing is that it should do something with # {{inventory_hostname}} # NOTE: see batch_size_control.yml for an example of the 'serial' keyword, which you almost certainly # want to use in this kind of example. Here we have a mocked up example that does something to # 5 hosts at a time - hosts: all serial: 5 tasks: - name: take the machine out of rotation command: echo taking out of rotation {{inventory_hostname}} delegate_to: 127.0.0.1 # here's an alternate notation if you are delegating to 127.0.0.1, you can use 'local_action' # instead of 'action' and leave off the 'delegate_to' part. # # - local_action: command echo taking out of rotation {{inventory_hostname}} - name: do several things on the actual host command: echo hi mom {{inventory_hostname}} - name: put machine back into rotation command: echo inserting into rotation {{inventory_hostname}} delegate_to: 127.0.0.1 ================================================ FILE: language_features/environment.yml ================================================ --- # it is often useful to be able to set the environment for one command and have that environment be totally # different for another. An example is you might use a HTTP proxy for some packages but not for others. # # in Ansible 1.1 and later, you can pass the environment to any module using either a dictionary variable # or a dictionary itself. - hosts: all remote_user: root # here we make a variable named "env" that is a dictionary vars: env: HI: test2 http_proxy: http://proxy.example.com:8080 tasks: # here we just define the dictionary directly and use it # (here $HI is the shell variable as nothing in Ansible will replace it) - shell: echo $HI environment: HI: test1 # here we are using the "env" map variable above - shell: echo $HI environment: "{{ env }}" ================================================ FILE: language_features/eucalyptus-ec2.yml ================================================ --- # This playbook is an example for deploying multiple instances into # EC2/Euca and "doing something" with them. # # - uses the ec2 and ec2_vol module. # # Run this with ansible-playbook and supply the private key for your # EC2/Euca user (to access the instance in the second play), e.g: # # ansible-playbook eucalyptus-ec2-deploy.yml -v --private-key=/path/to/ec2/pri/key # # The play operates on the local (Ansible control) machine. - name: Stage instance(s) hosts: local connection: local remote_user: root gather_facts: false vars: keypair: mykeypair instance_type: m1.small security_group: default image: emi-048B3A37 # Launch 5 instances with the following parameters. Register the output. tasks: - name: Launch instance ec2: keypair={{keypair}} group={{security_group}} instance_type={{instance_type}} image={{image}} wait=true count=5 register: ec2 # Use with_items to add each instances public IP to a new hostgroup for use in the next play. - name: Add new instances to host group add_host: hostname={{item.public_ip}} groupname=deploy with_items: ec2.instances - name: Wait for the instances to boot by checking the ssh port wait_for: host={{item.public_dns_name}} port=22 delay=60 timeout=320 state=started with_items: ec2.instances # Use the ec2_vol module to create volumes for attachment to each instance. # Use with_items to attach to each instance (by returned id) launched previously. - name: Create a volume and attach ec2_vol: volume_size=20 instance={{item.id}} with_items: ec2.instances # This play targets the new host group - name: Configure instance hosts: deploy remote_user: root # Do some stuff on each instance .... tasks: - name: Ensure NTP is up and running service: name=ntpd state=started - name: Install Apache Web Server yum: pkg=httpd state=latest ================================================ FILE: language_features/file_secontext.yml ================================================ --- # This is a demo of how to manage the selinux context using the file module - hosts: test remote_user: root tasks: - name: Change setype of /etc/exports to non-default value file: path=/etc/exports setype=etc_t - name: Change seuser of /etc/exports to non-default value file: path=/etc/exports seuser=unconfined_u - name: Set selinux context back to default value file: path=/etc/exports context=default - name: Create empty file command: /bin/touch /tmp/foo - name: Change setype of /tmp/foo file: path=/tmp/foo setype=default_t - name: Try to set secontext to default, but this will fail because of the lack of a default in the policy file: path=/tmp/foo context=default ================================================ FILE: language_features/files/cloudformation-example.json ================================================ { "Outputs" : { "ClusterSecGroup" : { "Description" : "Name of RegionalManagerSecGroup", "Value" : { "Ref" : "InstanceSecurityGroup" } } }, "AWSTemplateFormatVersion" : "2010-09-09", "Description" : "Launches an example cluster", "Mappings" : { "ebs" : { "ap-northeast-1" : { "AMI" : "ami-4e6cd34f" }, "ap-southeast-1" : { "AMI" : "ami-a6a7e7f4" }, "eu-west-1" : { "AMI" : "ami-c37474b7" }, "sa-east-1" : { "AMI" : "ami-1e08d103" }, "us-east-1" : { "AMI" : "ami-1624987f" }, "us-west-1" : { "AMI" : "ami-1bf9de5e" }, "us-west-2" : { "AMI" : "ami-2a31bf1a" } }, "ephemeral" : { "ap-northeast-1" : { "AMI" : "ami-5a6cd35b" }, "ap-southeast-1" : { "AMI" : "ami-a8a7e7fa" }, "eu-west-1" : { "AMI" : "ami-b57474c1" }, "sa-east-1" : { "AMI" : "ami-1608d10b" }, "us-east-1" : { "AMI" : "ami-e8249881" }, "us-west-1" : { "AMI" : "ami-21f9de64" }, "us-west-2" : { "AMI" : "ami-2e31bf1e" } } }, "Parameters" : { "ClusterSize" : { "Description" : "Number of nodes in the cluster", "Type" : "String" }, "DiskType" : { "AllowedValues" : [ "ephemeral", "ebs" ], "Default" : "ephemeral", "Description" : "Type of Disk to use ( ephemeral/ebs )", "Type" : "String" }, "InstanceType" : { "AllowedValues" : [ "t1.micro", "m1.small", "m1.medium", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "c1.medium", "c1.xlarge", "cc1.4xlarge" ], "ConstraintDescription" : "must be valid instance type. ", "Default" : "m1.large", "Description" : "Type of EC2 instance for cluster", "Type" : "String" }, "KeyName" : { "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the cluster", "Type" : "String" } }, "Resources" : { "ApplicationWaitCondition" : { "DependsOn" : "ClusterServerGroup", "Properties" : { "Handle" : { "Ref" : "ApplicationWaitHandle" }, "Timeout" : "4500" }, "Type" : "AWS::CloudFormation::WaitCondition" }, "ApplicationWaitHandle" : { "Type" : "AWS::CloudFormation::WaitConditionHandle" }, "CFNInitUser" : { "Properties" : { "Path" : "/", "Policies" : [ { "PolicyDocument" : { "Statement" : [ { "Action" : [ "cloudformation:DescribeStackResource", "s3:GetObject" ], "Effect" : "Allow", "Resource" : "*" } ] }, "PolicyName" : "AccessForCFNInit" } ] }, "Type" : "AWS::IAM::User" }, "CFNKeys" : { "Properties" : { "UserName" : { "Ref" : "CFNInitUser" } }, "Type" : "AWS::IAM::AccessKey" }, "ClusterCommunication1" : { "Properties" : { "FromPort" : "-1", "GroupName" : { "Ref" : "InstanceSecurityGroup" }, "IpProtocol" : "icmp", "SourceSecurityGroupName" : { "Ref" : "InstanceSecurityGroup" }, "ToPort" : "-1" }, "Type" : "AWS::EC2::SecurityGroupIngress" }, "ClusterCommunication2" : { "Properties" : { "FromPort" : "1", "GroupName" : { "Ref" : "InstanceSecurityGroup" }, "IpProtocol" : "tcp", "SourceSecurityGroupName" : { "Ref" : "InstanceSecurityGroup" }, "ToPort" : "65356" }, "Type" : "AWS::EC2::SecurityGroupIngress" }, "ClusterCommunication3" : { "Properties" : { "FromPort" : "1", "GroupName" : { "Ref" : "InstanceSecurityGroup" }, "IpProtocol" : "udp", "SourceSecurityGroupName" : { "Ref" : "InstanceSecurityGroup" }, "ToPort" : "65356" }, "Type" : "AWS::EC2::SecurityGroupIngress" }, "InstanceSecurityGroup" : { "Properties" : { "GroupDescription" : "Enable SSH access via port 22", "SecurityGroupIngress" : [ { "CidrIp" : "0.0.0.0/0", "FromPort" : "22", "IpProtocol" : "tcp", "ToPort" : "22" } ] }, "Type" : "AWS::EC2::SecurityGroup" }, "LaunchConfig" : { "Properties" : { "IamInstanceProfile" : { "Ref" : "RootInstanceProfile" }, "ImageId" : { "Fn::FindInMap" : [ { "Ref" : "DiskType" }, { "Ref" : "AWS::Region" }, "AMI" ] }, "InstanceType" : { "Ref" : "InstanceType" }, "KeyName" : { "Ref" : "KeyName" }, "SecurityGroups" : [ { "Ref" : "InstanceSecurityGroup" } ], "UserData" : { "Fn::Base64" : { "Fn::Join" : [ "\n", [ "#!/bin/bash -v", "exec > >(tee /var/log/cfn-data.log|logger -t user-data -s 2>/dev/console) 2>&1", "", "sleep 10", "", "function retry {", " nTrys=0", " maxTrys=5", " status=256", " until [ $status == 0 ] ; do", " $1", " status=$?", " nTrys=$(($nTrys + 1))", " if [ $nTrys -gt $maxTrys ] ; then", " echo \"Number of re-trys exceeded. Exit code: $status\"", " exit $status", " fi", " if [ $status != 0 ] ; then", " echo \"Failed (exit code $status)... retry $nTrys\"", " sleep 10", " fi", " done", "}", "", "yum update -y aws-cfn-bootstrap", "", "#for all the stuff that complains about sudo and tty", "sed -i 's,Defaults requiretty,#Defaults requiretty,g' /etc/sudoers", "", "function error_exit", "{", { "Fn::Join" : [ "", [ " /opt/aws/bin/cfn-signal -e 1 -r \"$1\" '", { "Ref" : "ApplicationWaitHandle" }, "'" ] ] }, "}", "yum update -y aws-cfn-bootstrap", "#this runs the first stage of cfinit", { "Fn::Join" : [ "", [ "#/opt/aws/bin/cfn-init -c ascending -v --region ", { "Ref" : "AWS::Region" }, " -s ", { "Ref" : "AWS::StackName" }, " -r ", "LaunchConfig", " --access-key ", { "Ref" : "CFNKeys" }, " --secret-key ", { "Fn::GetAtt" : [ "CFNKeys", "SecretAccessKey" ] }, " || error_exit 'Failed to initialize client using cfn-init'" ] ] }, "", "", "", "result_code=$?", { "Fn::Join" : [ "", [ "/opt/aws/bin/cfn-signal -e $result_code '", { "Ref" : "ApplicationWaitHandle" }, "'" ] ] } ] ] } } }, "Type" : "AWS::AutoScaling::LaunchConfiguration" }, "ClusterServerGroup" : { "Properties" : { "AvailabilityZones" : { "Fn::GetAZs" : "" }, "LaunchConfigurationName" : { "Ref" : "LaunchConfig" }, "MaxSize" : { "Ref" : "ClusterSize" }, "MinSize" : { "Ref" : "ClusterSize" } }, "Type" : "AWS::AutoScaling::AutoScalingGroup" }, "RolePolicies" : { "Properties" : { "PolicyDocument" : { "Statement" : [ { "Action" : "*", "Effect" : "Allow", "Resource" : "*" } ] }, "PolicyName" : "root", "Roles" : [ { "Ref" : "RootRole" } ] }, "Type" : "AWS::IAM::Policy" }, "RootInstanceProfile" : { "Properties" : { "Path" : "/", "Roles" : [ { "Ref" : "RootRole" } ] }, "Type" : "AWS::IAM::InstanceProfile" }, "RootRole" : { "Properties" : { "AssumeRolePolicyDocument" : { "Statement" : [ { "Action" : [ "sts:AssumeRole" ], "Effect" : "Allow", "Principal" : { "Service" : [ "ec2.amazonaws.com" ] } } ] }, "Path" : "/" }, "Type" : "AWS::IAM::Role" } } } ================================================ FILE: language_features/filter_plugins/custom_plugins.py ================================================ # (c) 2012, Jeroen Hoekx # # This file is part of Ansible # # Ansible is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ansible is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . class FilterModule(object): ''' Custom filters are loaded by FilterModule objects ''' def filters(self): ''' FilterModule objects return a dict mapping filter names to filter functions. ''' return { 'generate_answer': self.generate_answer, } def generate_answer(self, value): return '42' ================================================ FILE: language_features/get_url.yml ================================================ --- - hosts: webservers vars: - jquery_directory: /var/www/html/javascript - person: 'Susie%20Smith' tasks: - name: Create directory for jQuery file: dest={{jquery_directory}} state=directory mode=0755 - name: Grab a bunch of jQuery stuff get_url: url=http://code.jquery.com/{{item}} dest={{jquery_directory}} mode=0444 with_items: - jquery.min.js - mobile/latest/jquery.mobile.min.js - ui/jquery-ui-git.css #- name: Pass urlencoded name to CGI # get_url: url=http://example.com/name.cgi?name='{{person}}' dest=/tmp/test ================================================ FILE: language_features/group_by.yml ================================================ --- # Example playbook to demonstrate the group_by action plugin. # # as we know, the setup module will automatically run in each play, and sets up various # facts. We can then create temporary (in memory only) groups based on those facts, which # are useful ways of selecting similar sets of hosts. # # Additionally, we can use the 'register' keyword in Ansible to set similar variables # and use those for grouping. This is not shown in this example. - hosts: all tasks: - name: Create a group of all hosts by operating system group_by: key={{ansible_distribution}}-{{ansible_distribution_version}} # the following host group does not exist in inventory and was created by the group_by # module. - hosts: CentOS-6.2 tasks: - name: ping all CentOS 6.2 hosts ping: - hosts: CentOS-6.3 tasks: - name: ping all CentOS 6.3 hosts ping: ================================================ FILE: language_features/group_commands.yml ================================================ --- # This is a demo of how the group command works. - hosts: all remote_user: root become: yes become_method: sudo tasks: # Walk through group creation, modification, and deletion - name: create a group group: name=tset # You can only modify the group's gid - group: name=tset gid=7777 # And finally remove the group - group: name=tset state=absent ================================================ FILE: language_features/handlers/handlers.yml ================================================ --- # this is an example to show that handlers can be included from yaml files, # to promote reuse between different plays or even playbooks. They work # just like normal handlers. - name: restart apache service: name=httpd state=restarted - name: restart memcached service: name=memcached state=restarted ================================================ FILE: language_features/intermediate_example.yml ================================================ --- # see intro_example.yml first! # This file explains some more advanced features of playbooks. # because of the comments it's less concise than it normally is. But feel # free to comment your playbooks if you like. - hosts: all # we can define variables the normal way... vars: release: 2.0 # but they can also come from other files. This can be a relative # or absolute path. This is a good way to store 'secret' variable # files but still keep the playbook in public source control vars_files: - vars/external_vars.yml # as with before, every play has a list of tasks in it tasks: # tasks can be written the normal way... - name: arbitrary command command: /bin/true # or we can promote reuse and simplicity by including tasks # from other files, for instance, to reuse common tasks - include: tasks/base.yml # we could also have done something like: # - include: wordpress.yml user=timmy # and had access to the template variable $user in the # included file, if we wanted to. Variables from vars # and vars_files are also available inside include files handlers: # handlers can also be included from files, to promote reuse # and simpler recipes, you may wish to only have one # handler file for all your plays and playbooks. This example really # doesn't notify any handlers, it is just showing you how they would # be included (see intro_example for usage). - include: handlers/handlers.yml # you can mix things that are directly in the file with things # that are included. Order is executed as written, but only # handlers that have been notified get executed - name: restart foo service: name=foo state=restarted # =============================================================== # Here's a second play in the same playbook. This will be run # after the first playbook completes on all hosts. You may want # a different play for each class of systems, or may want a different # play for each stage in a complex multi-node deployment push # process. How you use them are up to you. # any play in a playbook can be executed by a user other than root # if you want. sudo support is coming too. - hosts: webservers remote_user: mdehaan # vars must be specified again for the next play in the playbook # but can be reused by including from vars_files if you want # you can use vars, vars_files, or both. vars_files overrides # those set in vars. vars: release: 2.0 vars_files: - vars/external_vars.yml # these all runs as the user 'mdehaan'. If there were any handlers # they would as well. tasks: - name: some random command command: /bin/true ================================================ FILE: language_features/intro_example.yml ================================================ --- # this is an annotated example of some features available in playbooks # it shows how to make sure packages are updated, how to make sure # services are running, and how to template files. It also demos # change handlers that can restart things (or trigger other actions) # when resources change. For more advanced examples, see example2.yml # on all hosts, run as the user root... - name: example play hosts: all remote_user: root # could have also have done: # remote_user: mdehaan # become: yes # become_method: sudo # make these variables available inside of templates # for when we use the 'template' action/module later on... vars: http_port: 80 max_clients: 200 # define the tasks that are part of this play... tasks: # task #1 is to run an arbitrary command # we'll simulate a long running task, wait for up to 45 seconds, poll every 5 # obviously this does nothing useful but you get the idea - name: longrunner command: /bin/sleep 15 async: 45 poll: 5 # let's demo file operations. # # We can 'copy' files or 'template' them instead, using jinja2 # as the templating engine. This is done using the variables # from the vars section above mixed in with variables bubbled up # automatically from tools like facter and ohai. 'copy' # works just like 'template' but does not do variable subsitution. # # If and only if the file changes, restart apache at the very # end of the playbook run - name: write some_random_foo configuration template: src=templates/foo.j2 dest=/etc/some_random_foo.conf notify: - restart apache # make sure httpd is installed at the latest version - name: install httpd yum: pkg=httpd state=latest # make sure httpd is running - name: httpd start service: name=httpd state=running # handlers are only run when things change, at the very end of each # play. Let's define some. The names are significant and must # match the 'notify' sections above handlers: # this particular handler is run when some_random_foo.conf # is changed, and only then - name: restart apache service: name=httpd state=restarted ================================================ FILE: language_features/loop_nested.yml ================================================ --- # this is a trivial example of how to do a nested loop. - hosts: all tasks: - shell: echo "nested test a={{ item[0] }} b={{ item[1] }} c={{ item[2] }}" with_nested: - [ 'red', 'blue', 'green' ] - [ 1, 2, 3 ] - [ 'up', 'down', 'strange'] # you can reference a raw variable name without putting it in {{ brackets }} - hosts: all vars: listvar1: - 'a' - 'b' - 'c' tasks: - shell: echo "nested test a={{ item[0] }} b={{ item[1] }}" with_nested: - listvar1 - [ 1, 2, 3 ] ================================================ FILE: language_features/loop_plugins.yml ================================================ --- # in addition to loop_with_items, the loop that works over a variable, ansible can do more sophisticated looping. # developer types: these are powered by 'lookup_plugins' should you ever decide to write your own # see lib/ansible/runner/lookup_plugins/fileglob.py -- they can do basically anything! - hosts: all gather_facts: no tasks: # this will copy a bunch of config files over -- dir must be created first - file: dest=/etc/fooapp state=directory - copy: src={{ item }} dest=/etc/fooapp/ owner=root mode=600 with_fileglob: /playbooks/files/fooapp/* ================================================ FILE: language_features/loop_with_items.yml ================================================ --- # this is an example of how to run repeated task elements over lists # of items, for example, installing multiple packages or configuring # multiple users - hosts: all remote_user: root tasks: - name: install packages yum: name={{ item }} state=installed with_items: - cobbler - httpd - name: configure users user: name={{ item }} state=present groups=wheel with_items: - testuser1 - testuser2 - name: remove users user: name={{ item }} state=absent with_items: - testuser1 - testuser2 - name: copy templates template: src={{ item.src }} dest={{ item.dest }} with_items: - src: templates/testsource1 dest: /example/dest1/test.conf - src: templates/testsource2 dest: /example/dest2/test.conf ================================================ FILE: language_features/mysql.yml ================================================ ## # Example Ansible playbook that uses the MySQL module. # --- - hosts: all remote_user: root tasks: - name: Create database user mysql_user: user=bob password=12345 priv=*.*:ALL state=present - name: Create database mysql_db: db=bobdata state=present - name: Ensure no user named 'sally' exists and delete if found. mysql_user: user=sally state=absent ================================================ FILE: language_features/nested_playbooks.yml ================================================ --- # it is possible to have top level playbook files import other playbook # files. For example, a playbook called could include three # different playbooks, such as webservers, workers, dbservers, etc. # # Running the site playbook would run all playbooks, while individual # playbooks could still be run directly. This is somewhat like # the tag feature and can be used in conjunction for very fine grained # control over what you want to target when running ansible. - name: this is a play at the top level of a file hosts: all remote_user: root tasks: - name: say hi tags: foo shell: echo "hi..." # and this is how we include another playbook, be careful and # don't recurse infinitely or anything. Note you can't use # any variables in the include path here. - include: intro_example.yml # and if we wanted, we can continue with more includes here, # or more plays inline in this file ================================================ FILE: language_features/netscaler.yml ================================================ --- # # NetScaler module example # - hosts: web-pool serial: 3 vars: nsc_host: nsc.example.com nsc_user: admin nsc_pass: nimda # type of the netscaler object you want to manipulate type: service # netscaler object name name: "{{facter_fqdn}}:8080" tasks: - name: disable service in the lb netscaler: nsc_host={{nsc_host}} user={{nsc_user}} password={{nsc_pass}} name={{name}} type={{type}} action=disable - name: deploy new code shell: yum upgrade -y - name: enable in the lb netscaler: nsc_host={{nsc_host}} user={{nsc_user}} password={{nsc_pass}} name={{name}} type={{type}} action=enable ================================================ FILE: language_features/postgresql.yml ================================================ ## # Example Ansible playbook that uses the PostgreSQL module. # # This installs PostgreSQL on an Ubuntu system, creates a database called # "myapp" and a user called "django" with password "mysupersecretpassword" # with access to the "myapp" database. # --- - hosts: webservers become: yes gather_facts: no tasks: - name: ensure apt cache is up to date apt: update_cache=yes - name: ensure packages are installed apt: name={{item}} with_items: - postgresql - libpq-dev - python-psycopg2 - hosts: webservers become: yes become_user: postgres gather_facts: no vars: dbname: myapp dbuser: django dbpassword: mysupersecretpassword tasks: - name: ensure database is created postgresql_db: name={{dbname}} - name: ensure user has access to database postgresql_user: db={{dbname}} name={{dbuser}} password={{dbpassword}} priv=ALL - name: ensure user does not have unnecessary privilege postgresql_user: name={{dbuser}} role_attr_flags=NOSUPERUSER,NOCREATEDB - name: ensure no other user can access the database postgresql_privs: db={{dbname}} role=PUBLIC type=database priv=ALL state=absent ================================================ FILE: language_features/prompts.yml ================================================ --- # it is possible to ask for variables from the user at the start # of a playbook run, for example, as part of a release script. - hosts: all remote_user: root # regular variables are a dictionary of keys and values vars: this_is_a_regular_var: 'moo' so_is_this: 'quack' # alternatively, they can ALSO be passed in from the outside: # ansible-playbook foo.yml --extra-vars="foo=100 bar=101" # or through external inventory scripts (see online API docs) # here's basic mode prompting. Specify a hash of variable names and a prompt for # each. # # vars_prompt: # release_version: "product release version" # prompts can also be specified like this, allowing for hiding the prompt as # entered. In the future, this may also be used to support crypted variables vars_prompt: - name: "some_password" prompt: "Enter password" private: yes - name: "release_version" prompt: "Product release version" default: "my_default_version" private: no - name: "my_password2" prompt: "Enter password2" private: yes encrypt: "md5_crypt" confirm: yes salt_size: 7 salt: "foo" # this is just a simple example to show that vars_prompt works, but # you might ask for a tag to use with the git module or perhaps # a package version to use with the yum module. tasks: - name: imagine this did something interesting with {{release_version}} shell: echo foo >> /tmp/{{release_version}}-alpha - name: look we crypted a password shell: echo my password is {{my_password2}} ================================================ FILE: language_features/rabbitmq.yml ================================================ --- - hosts: rabbitmq become: true become_method: sudo vars: rabbitmq_version: 3.0.2-1 tasks: - name: ensure python-software-properties is installed apt: pkg=python-software-properties state=installed - name: add rabbitmq official apt repository apt_repository: repo='deb http://www.rabbitmq.com/debian/ testing main' state=present - name: add trusted key apt_key: url=https://www.rabbitmq.com/rabbitmq-signing-key-public.asc state=present - name: install package apt: name={{ item }} update_cache=yes state=installed with_items: - rabbitmq-server - name: enable rabbitmq plugins rabbitmq_plugin: names=rabbitmq_management,rabbitmq_tracing,rabbitmq_federation state=enabled notify: - restart rabbitmq - name: add users rabbitmq_user: user={{item.username}} password={{item.password}} tags=administrator,{{item.username}} vhost=/ configure_priv=.* write_priv=.* read_priv=.* state=present with_items: - { username: user1, password: changeme } - { username: user2, password: changeme } - name: remove default guest user rabbitmq_user: user=guest state=absent - name: ensure vhost /test is present rabbitmq_vhost: name=/test state=present handlers: - name: restart rabbitmq service: name=rabbitmq-server state=restarted ================================================ FILE: language_features/register_logic.yml ================================================ # here's a cool advanced topic about how to perform conditional logic in ansible without resorting # to writing your own module that defines facts. You can do that too, and it's easy to do, but # often you just want to run a command and then decide whether to run some steps or not. That's # easy to do, and here we'll show you how. - name: test playbook remote_user: root hosts: all tasks: # it is possible to save the result of any command in a named register. This variable will be made # available to tasks and templates made further down in the execution flow. - shell: grep hi /etc/motd ignore_errors: yes register: motd_result # and here we access the register. Note that variable is structured data because # it is a return from the command module. The shell module makes available variables such as # as 'stdout', 'stderr', and 'rc'. # here we run the next action only if the previous grep returned true - shell: echo "motd contains the word hi" when: motd_result.rc == 0 # alternatively: - shell: echo "motd contains the word hi" when: motd_result.stdout.find('hi') != -1 # or also: - shell: echo "motd contains word hi" when: "'hi' in motd_result.stdout" # you can use 'stdout_lines' to loop over the registered output lines - name: motd lines matching 'hi' shell: echo "{{ item }}" with_items: motd_result.stdout_lines # you can also split 'stdout' yourself - name: motd lines matching 'hi' shell: echo "{{ item }}" with_items: motd_result.stdout.split('\n') ================================================ FILE: language_features/roles/foo/files/foo.txt ================================================ This is a file ================================================ FILE: language_features/roles/foo/handlers/main.yml ================================================ --- - name: blippy shell: echo notifier called, and the value of x is '{{ x }}' # within a role, it's possible to include other task files as well. By default, we # can reference files in the same directory without doing anything special: # - include: other.yml ================================================ FILE: language_features/roles/foo/tasks/main.yml ================================================ --- - name: copy operation copy: src=foo.txt dest=/tmp/roles_test1.txt - name: template operation template: src=foo.j2 dest=/tmp/roles_test2.txt notify: - blippy - name: demo that parameterized roles work shell: echo just FYI, param1={{ param1 }}, param2 ={{ param2 }} ================================================ FILE: language_features/roles/foo/templates/foo.j2 ================================================ I am a {{ ansible_os_family }} distribution. ================================================ FILE: language_features/roles/foo/vars/main.yml ================================================ --- x: '{{ ansible_machine }}' ================================================ FILE: language_features/roletest.yml ================================================ # in Ansible 1.2 and later, roles allow easy best-practices organization of content # and maximize shareability of ansible building blocks. # # suppose a playbook applied to a group of hosts includes two roles, foo and bar. # # what do roles do in this case? # # listing the roles as foo and bar will auto include the following: # # tasks from ./roles/foo/tasks/main.yml, then ./roles/bar/tasks/main.yml # handlers from ./roles/foo/handlers/main.yml, then ./roles/bar/handlers/main.yml # vars from ./roles/foo/vars/main.yml, then ./roles/bar/vars/main.yml # # should any of these files not exist, that is ok, and they will simply not be loaded. # # should the task file in foo/tasks/main.yml want to include subtasks in other files, that # is also permitted. # # templates and copy operations also get smarter about where to look for content when using # roles. # # as an example, a task in foo/tasks/main.yml could copy or template a file by # referencing a "src=foo.j2" rather than having to explicitly path src=roles/foo/templates/foo.j2. --- - hosts: all pre_tasks: # these tasks are executed prior to roles. # this might be a good time to signal an outage window or take a host out of a load balanced pool - local_action: shell echo "hi this is a pre_task step about {{ inventory_hostname }}" roles: # a role can be listed flat like this: # # - common # - webservers # but you can also pass variables to them, so they can be parameterized. You can call # a role more than once with different parameters too. It might look like the section # below. Note I can also declare tags at this time. - { role: foo, param1: 1000, param2: 2000, tags: [ 'foo', 'bar' ] } - { role: foo, param1: 8000, param2: 9000, tags: [ 'baz' ] } # add as many roles as you like, roles takes a list of roles names # these paths can be qualified, but if bare, it will look from them in # roles/{{rolename}} relative to the playbook # explicit tasks and handlers can be used, but are not required. # they will run after the roles if present. tasks: # you can still have loose tasks/handlers and they will execute after roles are applied - shell: echo 'this is a loose task' post_tasks: # just to provide a syntactic mirroring to 'pre_tasks', these run absolute last in the play. # this might be a good time to put a host back in a load balanced pool or end an outage window - local_action: shell echo 'this is a post_task about {{ inventory_hostname }}' ================================================ FILE: language_features/roletest2.yml ================================================ # in Ansible 1.2 and later, roles allow easy best-practices organization of content # and maximize shareability of ansible building blocks. # # suppose a playbook applied to a group of hosts includes two roles, foo and bar. # # what do roles do in this case? # # listing the roles as foo and bar will auto include the following: # # tasks from ./roles/foo/tasks/main.yml, then ./roles/bar/tasks/main.yml # handlers from ./roles/foo/handlers/main.yml, then ./roles/bar/handlers/main.yml # vars from ./roles/foo/vars/main.yml, then ./roles/bar/vars/main.yml # # should any of these files not exist, that is ok, and they will simply not be loaded. # # should the task file in foo/tasks/main.yml want to include subtasks in other files, that # is also permitted. # # templates and copy operations also get smarter about where to look for content when using # roles. # # as an example, a task in foo/tasks/main.yml could copy or template a file by # referencing a "src=foo.j2" rather than having to explicitly path src=roles/foo/templates/foo.j2. --- - hosts: all roles: # a role can be listed flat like this: # # - common # - webservers # but you can also pass variables to them, so they can be parameterized. You can call # a role more than once with different parameters too. It might look like this: - role: foo param1: '{{ foo }}' param2: '{{ some_var1 + "/" + some_var2 }}' when: ansible_os_family == 'RedHat' # add as many roles as you like, roles takes a list of roles names # these paths can be qualified, but if bare, it will look from them in # roles/{{rolename}} relative to the playbook # explicit tasks and handlers can be used, but are not required. # they will run after the roles if present. tasks: # you can still have loose tasks/handlers and they will execute after roles - shell: echo 'this is a loose task' ================================================ FILE: language_features/selective_file_sources.yml ================================================ --- # this is an example of how to template a file over using some variables derived # from the system. For instance, if you wanted to have different configuration # templates by OS version, this is a neat way to do it. Any Ansible facts, facter facts, # or ohai facts could be used to do this. - hosts: all tasks: - name: template a config file template: dest=/etc/imaginary_file.conf first_available_file: # first see if we have a file for this specific host - /srv/whatever/{{ansible_hostname}}.conf # next try to load something like CentOS6.2.conf - /srv/whatever/{{ansible_distribution}}{{ansible_distribution_version}}.conf # next see if there's a CentOS.conf - /srv/whatever/{{ansible_distribution}}.conf # finally give up and just use something generic - /srv/whatever/default ================================================ FILE: language_features/tags.yml ================================================ --- # tags allow us to run all of a playbook or part of it. # # assume: ansible-playbook tags.yml --tags foo # # try this with: # --tags foo # --tags bar # --tags extra # # the value of a 'tags:' element can be a string or list # of tag names. Variables are not usable in tag names. - name: example play one hosts: all remote_user: root # any tags applied to the play are shorthand to applying # the tag to all tasks in it. Here, each task is given # the tag extra tags: - extra tasks: # this task will run if you don't specify any tags, # if you specify 'foo' or if you specify 'extra' - name: hi tags: ['foo'] shell: echo "first task ran" - name: example play two hosts: all remote_user: root tasks: - name: hi tags: - bar shell: echo "second task ran" - include: tasks/base.yml tags: - base ================================================ FILE: language_features/tasks/base.yml ================================================ --- # this is the example of an included tasks file. It contains a flat list of tasks # they can notify other tasks, and have full access to variables from 'vars' # or 'vars_files' directives. Further, if ohai or facter were installed on # the remote machines, variables from those tools can be accessed on the 'action' # line or in templates. Just prefix with 'facter_' or 'ohai_' before the particular # variable. # possible uses for a included yaml file might be to represent a 'class' of a system # like defining what makes up a webserver, or you might have a common 'base.yml' # (like this) that might be applied to all your systems as well. - name: no selinux command: /usr/sbin/setenforce 0 - name: no iptables service: name=iptables state=stopped - name: made up task just to show variables work here command: /bin/echo release is $release ================================================ FILE: language_features/templates/custom-filters.j2 ================================================ 1 + 1 = {{ '1+1' | generate_answer }} ================================================ FILE: language_features/templates/etc_cron.d_ansible-pull.j2 ================================================ # Cron job to git clone/pull a repo and then run locally {{ schedule }} {{ cron_user }} ansible-pull -d {{ workdir }} -U {{ repo_url }} >>{{ logfile }} 2>&1 ================================================ FILE: language_features/templates/etc_logrotate.d_ansible-pull.j2 ================================================ {{ logfile }} { rotate 7 daily compress missingok notifempty } ================================================ FILE: language_features/templates/foo.j2 ================================================ # This is a very simple Jinja2 template representing an imaginary configuration file # for an imaginary app. # this is an example of loading a fact from the setup module system={{ ansible_system }} # here is a variable that could be set in a playbook or inventory file http_port={{ http_port }} ================================================ FILE: language_features/templates/hostvars.j2 ================================================ # example of how to get the ipaddress of every machine in the webservers group # for use in a template {% for host in groups['webservers'] %} HOST: {{ host }} IP: {{ hostvars[host]['ansible_all_ipv4_addresses'][0] }} {% endfor %} ================================================ FILE: language_features/upgraded_vars.yml ================================================ # this just shows some tricks possible with variables in Ansible 1.2 and later. --- - hosts: all vars: a_list: - a - b - c tasks: - debug: msg="hello {{ ansible_hostname.upper() }}" - shell: echo match when: 2 == 2 - shell: echo no match when: 2 == 2 + 1 - debug: msg="{{ ansible_os_family }}" - shell: echo {{ item }} with_items: a_list - shell: echo 'RedHat' when: ansible_os_family == 'RedHat' ================================================ FILE: language_features/user_commands.yml ================================================ --- # this is a demo of how the user commands work and how to reference salted passwords # in vars sections. You could also use vars_files if you like (see other examples) - hosts: all remote_user: root vars: # created with: # python -c 'import crypt; print crypt.crypt("This is my Password", "$1$SomeSalt$")' password: $1$SomeSalt$UqddPX3r4kH3UL5jq5/ZI. tasks: # Walk through account creation, modification, and deletion - name: test basic user account creation user: name=tset comment=TsetUser group=users shell=/sbin/nologin createhome=no # the following is just a simple example of how you don't have to include # the 'name' element for each task - user: name=tset comment=NyetUser - user: name=tset password={{password}} # The following will add the user to supplementary groups. # Add the user to the groups dialout and uucp. - user: name=tset groups=dialout,uucp # Add the user to the groups dialout and wheel, # This will remove tset from the group uucp. - user: name=tset groups=dialout,wheel # Add the user to the group uucp. Because append=yes, the user # will not be removed from the groups dialout and wheel. - user: name=tset groups=uucp append=yes # Finally, remove the user. - user: name=tset state=absent ================================================ FILE: language_features/vars/CentOS.yml ================================================ --- apache: httpd packager: yum ================================================ FILE: language_features/vars/defaults.yml ================================================ --- packager: apt apache: apache ================================================ FILE: language_features/vars/external_vars.yml ================================================ --- alpha: one beta: two ================================================ FILE: language_features/zfs.yml ================================================ --- ## # Example Ansible playbook that uses the Zfs module. # - hosts: webservers gather_facts: no become: yes become_method: sudo vars: pool: rpool tasks: - name: Create a zfs file system zfs: name={{pool}}/var/log/httpd state=present - name: Create a zfs file system with quota of 10GiB and visible snapdir zfs: name={{pool}}/ansible quota='10G' snapdir=visible state=present - name: Create zfs snapshot of the above file system zfs: name={{pool}}/ansible@mysnapshot state=present - name: Create zfs volume named smallvol with a size of 10MiB zfs: name={{pool}}/smallvol volsize=10M state=present - name: Removes snapshot of rpool/oldfs zfs: name={{pool}}/oldfs@oldsnapshot state=absent - name: Removes file system rpool/oldfs zfs: name={{pool}}/oldfs state=absent ================================================ FILE: mongodb/LICENSE.md ================================================ Copyright (C) 2013 AnsibleWorks, Inc. This work is licensed under the Creative Commons Attribution 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/deed.en_US. ================================================ FILE: mongodb/README.md ================================================ ## Deploying a sharded, production-ready MongoDB cluster with Ansible ------------------------------------------------------------------------------ - Requires Ansible 1.2 - Expects CentOS/RHEL 6 hosts ### A Primer --------------------------------------------- ![Alt text](images/nosql_primer.png "Primer NoSQL") The above diagram shows how MongoDB differs from the traditional relational database model. In an RDBMS, the data associated with 'user' is stored in a table, and the records of users are stored in rows and columns. In MongoDB, the 'table' is replaced by a 'collection' and the individual 'records' are called 'documents'. One thing to notice is that the data is stored as key/value pairs in BJSON format. Another thing to notice is that NoSQL-style databases have a looser consistency model. As an example, the second document in the users collection has an additional field of 'last name'. ### Data Replication ------------------------------------ ![Alt text](images/replica_set.png "Replica Set") Data backup is achieved in MongoDB via _replica sets_. As the figure above shows, a single replication set consists of a replication master (active) and several other replications slaves (passive). All the database operations like add/delete/update happen on the replication master and the master replicates the data to the slave nodes. _mongod_ is the process which is responsible for all the database activities as well as replication processes. The minimum recommended number of slave servers are 3. ### Sharding (Horizontal Scaling) . ------------------------------------------------ ![Alt text](images/sharding.png "Sharding") Sharding works by partitioning the data into separate chunks and allocating different ranges of chunks to different shard servers. The figure above shows a collection which has 90 documents which have been sharded across the three servers: the first shard getting ranges from 1-29, and so on. When a client wants to access a certain document, it contacts the query router (mongos process), which in turn contacts the 'configuration node', a lightweight mongod process) that keeps a record of which ranges of chunks are distributed across which shards. Please do note that every shard server should be backed by a replica set, so that when data is written/queried copies of the data are available. So in a three-shard deployment we would require 3 replica sets and primaries of each would act as the sharding server. Here are the basic steps of how sharding works: 1) A new database is created, and collections are added. 2) New documents get updated when clients update, and all the new documents goes into a single shard. 3) When the size of collection in a shard exceeds the 'chunk_size' the collection is split and balanced across shards. ### Deploying MongoDB Ansible -------------------------------------------- #### Deploy the Cluster ---------------------------- ![Alt text](images/site.png "Site") The diagram above illustrates the deployment model for a MongoDB cluster deployed by Ansible. This deployment model focuses on deploying three shard servers, each having a replica set, with the backup replica servers serving as the other two shard primaries. The configuration servers are co-located with the shards. The _mongos_ servers are best deployed on separate servers. This is the minimum recommended configuration for a production-grade MongoDB deployment. Please note that the playbooks are capable of deploying N node clusters, not limited to three. Also, all the processes are secured using keyfiles. #### Prerequisite Edit the group_vars/all file to reflect the below variables. 1) `iface: 'eth1' # the interface to be used for all communication`. 2) Set a unique `mongod_port` variable in the inventory file for each MongoDB server. 3) The default directory for storing data is `/data`, please do change it if required. Make sure it has sufficient space: 10G is recommended. ### Deployment Example The inventory file looks as follows: #The site wide list of mongodb servers [mongo_servers] mongo1 mongod_port=2700 mongo2 mongod_port=2701 mongo3 mongod_port=2702 #The list of servers where replication should happen, including the master server. [replication_servers] mongo3 mongo1 mongo2 #The list of mongodb configuration servers, make sure it is 1 or 3 [mongoc_servers] mongo1 mongo2 mongo3 #The list of servers where mongos servers would run. [mongos_servers] mongos1 mongos2 Build the site with the following command: ansible-playbook -i hosts site.yml #### Verifying the Deployment --------------------------------------------- Once configuration and deployment has completed we can check replication set availability by connecting to individual primary replication set nodes, `mongo --host 192.168.1.1 --port 2700` and issue the command to query the status of replication set, we should get a similar output. web2:PRIMARY> rs.status() { "set" : "web2", "date" : ISODate("2013-03-19T10:26:35Z"), "myState" : 1, "members" : [ { "_id" : 0, "name" : "web2:2013", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 102, "optime" : Timestamp(1363688755000, 1), "optimeDate" : ISODate("2013-03-19T10:25:55Z"), "self" : true }, { "_id" : 1, "name" : "web3:2013", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 40, "optime" : Timestamp(1363688755000, 1), "optimeDate" : ISODate("2013-03-19T10:25:55Z"), "lastHeartbeat" : ISODate("2013-03-19T10:26:33Z"), "pingMs" : 1 } ], "ok" : 1 } We can check the status of the shards as follows: connect to the mongos service `mongo localhost:8888/admin -u admin -p 123456` and issue the following command to get the status of the Shards: mongos> sh.status() --- Sharding Status --- sharding version: { "_id" : 1, "version" : 3 } shards: { "_id" : "web2", "host" : "web2/web2:2013,web3:2013" } { "_id" : "web3", "host" : "web3/web2:2014,web3:2014" } databases: { "_id" : "admin", "partitioned" : false, "primary" : "config" } We can also make sure the sharding works by creating a database, a collection, and populate it with documents and check if the chunks of the collection are balanced equally across nodes. The below diagram illustrates the verification step. ------------------------------------------------------------------------------------------------------------------------------------------------------------- ![Alt text](images/check.png "check") The above mentioned steps can be tested with an automated playbook. Issue the following command to run the test. Pass one of the _mongos_ servers in the _servername_ variable. ansible-playbook -i hosts playbooks/testsharding.yml -e servername=server1 Once the playbook completes, we check if the sharding has succeeded by logging on to any mongos server and issuing the following command. The output displays the number of chunks spread across the shards. mongos> sh.status() --- Sharding Status --- sharding version: { "_id" : 1, "version" : 3 } shards: { "_id" : "bensible", "host" : "bensible/bensible:20103,web2:20103,web3:20103" } { "_id" : "web2", "host" : "web2/bensible:20105,web2:20105,web3:20105" } { "_id" : "web3", "host" : "web3/bensible:20102,web2:20102,web3:20102" } databases: { "_id" : "admin", "partitioned" : false, "primary" : "config" } { "_id" : "test", "partitioned" : true, "primary" : "web3" } test.test_collection chunks: bensible 7 web2 6 web3 7 ### Scaling the Cluster --------------------------------------- ![Alt text](images/scale.png "scale") To add a new node to the existing MongoDB Cluster, modify the inventory file as follows: #The site wide list of mongodb servers [mongoservers] mongo1 mongod_port=2700 mongo2 mongod_port=2701 mongo3 mongod_port=2702 mongo4 mongod_port=2703 #The list of servers where replication should happen, make sure the new node is listed here. [replicationservers] mongo4 mongo3 mongo1 mongo2 #The list of mongodb configuration servers, make sure it is 1 or 3 [mongoc_servers] mongo1 mongo2 mongo3 #The list of servers where mongos servers would run. [mongos_servers] mongos1 mongos2 Make sure you have the new node added in the _replicationservers_ section and execute the following command: ansible-playbook -i hosts site.yml ### Verification ----------------------------- The newly added node can be easily verified by checking the sharding status and seeing the chunks being rebalanced to the newly added node. $/usr/bin/mongo localhost:8888/admin -u admin -p 123456 mongos> sh.status() --- Sharding Status --- sharding version: { "_id" : 1, "version" : 3 } shards: { "_id" : "bensible", "host" : "bensible/bensible:20103,web2:20103,web3:20103" } { "_id" : "web2", "host" : "web2/bensible:20105,web2:20105,web3:20105" } { "_id" : "web3", "host" : "web3/bensible:20102,web2:20102,web3:20102" } { "_id" : "web4", "host" : "web4/bensible:20101,web3:20101,web4:20101" } databases: { "_id" : "admin", "partitioned" : false, "primary" : "config" } { "_id" : "test", "partitioned" : true, "primary" : "bensible" } test.test_collection chunks: web4 3 web3 6 web2 6 bensible 5 ================================================ FILE: mongodb/group_vars/all ================================================ # The global variable file mongodb installation # The chunksize for shards in MB mongos_chunk_size: 1 # The port in which mongos server should listen on mongos_port: 8888 # The port for mongo config server mongoc_port: 7777 # The directory prefix where the database files would be stored mongodb_datadir_prefix: /data/ # The interface where the mongodb process should listen on. # Defaults to the first interface. Change this to: # # iface: eth1 # # ...to override. # iface: '{{ ansible_default_ipv4.interface }}' # The password for admin user mongo_admin_pass: 123456 ================================================ FILE: mongodb/hosts ================================================ #The site wide list of mongodb servers # the mongo servers need a mongod_port variable set, and they must not conflict. [mongo_servers] mongo1 mongod_port=2700 mongo2 mongod_port=2701 mongo3 mongod_port=2702 mongo4 mongod_port=2703 #The list of servers where replication should happen, by default include all servers [replication_servers] mongo4 mongo3 mongo1 mongo2 #The list of mongodb configuration servers, make sure it is 1 or 3 [mongoc_servers] mongo1 mongo2 mongo3 #The list of servers where mongos servers would run. [mongos_servers] mongo1 mongo2 ================================================ FILE: mongodb/playbooks/testsharding.yml ================================================ --- # The playbook creates a new database test and populates data in the database to test the sharding. - hosts: $servername remote_user: root tasks: - name: Create a new database and user mongodb_user: login_user=admin login_password=${mongo_admin_pass} login_port=${mongos_port} database=test user=admin password=${mongo_admin_pass} state=present - name: Pause for the user to get created and replicated pause: minutes=3 - name: Execute the collection creation script command: /usr/bin/mongo localhost:${mongos_port}/test -u admin -p ${mongo_admin_pass} /tmp/testsharding.js - name: Enable sharding on the database and collection command: /usr/bin/mongo localhost:${mongos_port}/admin -u admin -p ${mongo_admin_pass} /tmp/enablesharding.js ================================================ FILE: mongodb/roles/common/files/10gen.repo.j2 ================================================ [10gen] name=10gen Repository baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64 gpgcheck=0 enabled=1 ================================================ FILE: mongodb/roles/common/files/RPM-GPG-KEY-EPEL-6 ================================================ -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.5 (GNU/Linux) mQINBEvSKUIBEADLGnUj24ZVKW7liFN/JA5CgtzlNnKs7sBg7fVbNWryiE3URbn1 JXvrdwHtkKyY96/ifZ1Ld3lE2gOF61bGZ2CWwJNee76Sp9Z+isP8RQXbG5jwj/4B M9HK7phktqFVJ8VbY2jfTjcfxRvGM8YBwXF8hx0CDZURAjvf1xRSQJ7iAo58qcHn XtxOAvQmAbR9z6Q/h/D+Y/PhoIJp1OV4VNHCbCs9M7HUVBpgC53PDcTUQuwcgeY6 pQgo9eT1eLNSZVrJ5Bctivl1UcD6P6CIGkkeT2gNhqindRPngUXGXW7Qzoefe+fV QqJSm7Tq2q9oqVZ46J964waCRItRySpuW5dxZO34WM6wsw2BP2MlACbH4l3luqtp Xo3Bvfnk+HAFH3HcMuwdaulxv7zYKXCfNoSfgrpEfo2Ex4Im/I3WdtwME/Gbnwdq 3VJzgAxLVFhczDHwNkjmIdPAlNJ9/ixRjip4dgZtW8VcBCrNoL+LhDrIfjvnLdRu vBHy9P3sCF7FZycaHlMWP6RiLtHnEMGcbZ8QpQHi2dReU1wyr9QgguGU+jqSXYar 1yEcsdRGasppNIZ8+Qawbm/a4doT10TEtPArhSoHlwbvqTDYjtfV92lC/2iwgO6g YgG9XrO4V8dV39Ffm7oLFfvTbg5mv4Q/E6AWo/gkjmtxkculbyAvjFtYAQARAQAB tCFFUEVMICg2KSA8ZXBlbEBmZWRvcmFwcm9qZWN0Lm9yZz6JAjYEEwECACAFAkvS KUICGw8GCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRA7Sd8qBgi4lR/GD/wLGPv9 qO39eyb9NlrwfKdUEo1tHxKdrhNz+XYrO4yVDTBZRPSuvL2yaoeSIhQOKhNPfEgT 9mdsbsgcfmoHxmGVcn+lbheWsSvcgrXuz0gLt8TGGKGGROAoLXpuUsb1HNtKEOwP Q4z1uQ2nOz5hLRyDOV0I2LwYV8BjGIjBKUMFEUxFTsL7XOZkrAg/WbTH2PW3hrfS WtcRA7EYonI3B80d39ffws7SmyKbS5PmZjqOPuTvV2F0tMhKIhncBwoojWZPExft HpKhzKVh8fdDO/3P1y1Fk3Cin8UbCO9MWMFNR27fVzCANlEPljsHA+3Ez4F7uboF p0OOEov4Yyi4BEbgqZnthTG4ub9nyiupIZ3ckPHr3nVcDUGcL6lQD/nkmNVIeLYP x1uHPOSlWfuojAYgzRH6LL7Idg4FHHBA0to7FW8dQXFIOyNiJFAOT2j8P5+tVdq8 wB0PDSH8yRpn4HdJ9RYquau4OkjluxOWf0uRaS//SUcCZh+1/KBEOmcvBHYRZA5J l/nakCgxGb2paQOzqqpOcHKvlyLuzO5uybMXaipLExTGJXBlXrbbASfXa/yGYSAG iVrGz9CE6676dMlm8F+s3XXE13QZrXmjloc6jwOljnfAkjTGXjiB7OULESed96MR XtfLk0W5Ab9pd7tKDR6QHI7rgHXfCopRnZ2VVQ== =V/6I -----END PGP PUBLIC KEY BLOCK----- ================================================ FILE: mongodb/roles/common/files/epel.repo.j2 ================================================ [epel] name=Extra Packages for Enterprise Linux 6 - $basearch baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch #mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch failovermethod=priority enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 [epel-debuginfo] name=Extra Packages for Enterprise Linux 6 - $basearch - Debug #baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch/debug mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-6&arch=$basearch failovermethod=priority enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 gpgcheck=1 [epel-source] name=Extra Packages for Enterprise Linux 6 - $basearch - Source #baseurl=http://download.fedoraproject.org/pub/epel/6/SRPMS mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-6&arch=$basearch failovermethod=priority enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 gpgcheck=1 ================================================ FILE: mongodb/roles/common/handlers/main.yml ================================================ --- # Handler for mongod - name: restart iptables service: name=iptables state=restarted ================================================ FILE: mongodb/roles/common/tasks/main.yml ================================================ --- # This Playbook runs all the common plays in the deployment - name: Create the hosts file for all machines template: src=hosts.j2 dest=/etc/hosts - name: Create the repository for 10Gen copy: src=10gen.repo.j2 dest=/etc/yum.repos.d/10gen.repo - name: Create the EPEL Repository. copy: src=epel.repo.j2 dest=/etc/yum.repos.d/epel.repo - name: Create the GPG key for EPEL copy: src=RPM-GPG-KEY-EPEL-6 dest=/etc/pki/rpm-gpg - name: Create the mongod user user: name=mongod comment="MongoD" - name: Create the data directory for the namenode metadata file: path={{ mongodb_datadir_prefix }} owner=mongod group=mongod state=directory - name: Install the mongodb package yum: name={{ item }} state=installed with_items: - libselinux-python - mongo-10gen - mongo-10gen-server - bc - python-pip - name: Install the latest pymongo package pip: name=pymongo state=latest use_mirrors=no - name: Create the iptables file template: src=iptables.j2 dest=/etc/sysconfig/iptables notify: restart iptables ================================================ FILE: mongodb/roles/common/templates/hosts.j2 ================================================ 127.0.0.1 localhost {% for host in groups['all'] %} {{ hostvars[host]['ansible_' + iface].ipv4.address }} {{ host }} {% endfor %} ================================================ FILE: mongodb/roles/common/templates/iptables.j2 ================================================ # Firewall configuration written by system-config-firewall # Manual customization of this file is not recommended. *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] {% if 'mongoc_servers' in group_names %} -A INPUT -p tcp --dport 7777 -j ACCEPT {% endif %} {% if 'mongos_servers' in group_names %} -A INPUT -p tcp --dport 8888 -j ACCEPT {% endif %} {% if 'mongo_servers' in group_names %} {% for host in groups['mongo_servers'] %} -A INPUT -p tcp --dport {{ hostvars[host]['mongod_port'] }} -j ACCEPT {% endfor %} {% endif %} -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT ================================================ FILE: mongodb/roles/mongoc/files/secret ================================================ qGO6OYb64Uth9p9Tm8s9kqarydmAg1AUdgVz+ecjinaLZ1SlWxXMY1ug8AO7C/Vu D8kA3+rE37Gv1GuZyPYi87NSfDhKXo4nJWxI00BxTBppmv2PTzbi7xLCx1+8A1uQ 4XU0HA ================================================ FILE: mongodb/roles/mongoc/tasks/main.yml ================================================ --- # This playbook deploys the mongodb configurationdb servers - name: Create data directory for mongoc configuration server file: path={{ mongodb_datadir_prefix }}/configdb state=directory owner=mongod group=mongod - name: Create the mongo configuration server startup file template: src=mongoc.j2 dest=/etc/init.d/mongoc mode=0655 - name: Create the mongo configuration server file template: src=mongoc.conf.j2 dest=/etc/mongoc.conf - name: Copy the keyfile for authentication copy: src=roles/mongod/files/secret dest={{ mongodb_datadir_prefix }}/secret owner=mongod group=mongod mode=0400 - name: Start the mongo configuration server service command: creates=/var/lock/subsys/mongoc /etc/init.d/mongoc start - name: pause pause: seconds=20 - name: add the admin user mongodb_user: database=admin name=admin password={{ mongo_admin_pass }} login_port={{ mongoc_port }} state=present ignore_errors: yes ================================================ FILE: mongodb/roles/mongoc/templates/adduser.j2 ================================================ db.addUser('admin','{{ mongo_admin_pass }}') ================================================ FILE: mongodb/roles/mongoc/templates/mongoc.conf.j2 ================================================ #where to log logpath=/var/log/mongo/mongod-config.log logappend=true # fork and run in background fork = true port = {{ mongoc_port }} dbpath={{ mongodb_datadir_prefix }}configdb keyFile={{ mongodb_datadir_prefix }}secret # location of pidfile pidfilepath = /var/run/mongo/mongoc.pid configsvr=true ================================================ FILE: mongodb/roles/mongoc/templates/mongoc.j2 ================================================ #!/bin/bash # mongod - Startup script for mongod # chkconfig: 35 85 15 # description: Mongo is a scalable, document-oriented database. # processname: mongod # config: /etc/mongod.conf # pidfile: /var/run/mongo/mongod.pid . /etc/rc.d/init.d/functions # things from mongod.conf get there by mongod reading it export LC_ALL="C" # NOTE: if you change any OPTIONS here, you get what you pay for: # this script assumes all options are in the config file. CONFIGFILE="/etc/mongoc.conf" OPTIONS=" -f $CONFIGFILE" SYSCONFIG="/etc/sysconfig/mongod" # FIXME: 1.9.x has a --shutdown flag that parses the config file and # shuts down the correct running pid, but that's unavailable in 1.8 # for now. This can go away when this script stops supporting 1.8. DBPATH=`awk -F= '/^dbpath=/{print $2}' "$CONFIGFILE"` PIDFILE=`awk -F= '/^dbpath\s=\s/{print $2}' "$CONFIGFILE"` mongod=${MONGOD-/usr/bin/mongod} MONGO_USER=mongod MONGO_GROUP=mongod if [ -f "$SYSCONFIG" ]; then . "$SYSCONFIG" fi # Handle NUMA access to CPUs (SERVER-3574) # This verifies the existence of numactl as well as testing that the command works NUMACTL_ARGS="--interleave=all" if which numactl >/dev/null 2>/dev/null && numactl $NUMACTL_ARGS ls / >/dev/null 2>/dev/null then NUMACTL="numactl $NUMACTL_ARGS" else NUMACTL="" fi start() { echo -n $"Starting mongod: " daemon --user "$MONGO_USER" $NUMACTL $mongod $OPTIONS RETVAL=$? echo [ $RETVAL -eq 0 ] && touch /var/lock/subsys/mongoc } stop() { echo -n $"Stopping mongod: " killproc -p "$PIDFILE" -d 300 /usr/bin/mongod RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/mongoc } restart () { stop start } ulimit -n 12000 RETVAL=0 case "$1" in start) start ;; stop) stop ;; restart|reload|force-reload) restart ;; condrestart) [ -f /var/lock/subsys/mongod ] && restart || : ;; status) status $mongod RETVAL=$? ;; *) echo "Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}" RETVAL=1 esac exit $RETVAL ================================================ FILE: mongodb/roles/mongod/files/secret ================================================ qGO6OYb64Uth9p9Tm8s9kqarydmAg1AUdgVz+ecjinaLZ1SlWxXMY1ug8AO7C/Vu D8kA3+rE37Gv1GuZyPYi87NSfDhKXo4nJWxI00BxTBppmv2PTzbi7xLCx1+8A1uQ 4XU0HA ================================================ FILE: mongodb/roles/mongod/tasks/main.yml ================================================ --- # This role deploys the mongod processes and sets up the replication set. - name: create data directory for mongodb file: path={{ mongodb_datadir_prefix }}/mongo-{{ inventory_hostname }} state=directory owner=mongod group=mongod delegate_to: '{{ item }}' with_items: groups.replication_servers - name: create log directory for mongodb file: path=/var/log/mongo state=directory owner=mongod group=mongod - name: create run directory for mongodb file: path=/var/run/mongo state=directory owner=mongod group=mongod - name: Create the mongodb startup file template: src=mongod.j2 dest=/etc/init.d/mongod-{{ inventory_hostname }} mode=0655 delegate_to: '{{ item }}' with_items: groups.replication_servers - name: Create the mongodb configuration file template: src=mongod.conf.j2 dest=/etc/mongod-{{ inventory_hostname }}.conf delegate_to: '{{ item }}' with_items: groups.replication_servers - name: Copy the keyfile for authentication copy: src=secret dest={{ mongodb_datadir_prefix }}/secret owner=mongod group=mongod mode=0400 - name: Start the mongodb service command: creates=/var/lock/subsys/mongod-{{ inventory_hostname }} /etc/init.d/mongod-{{ inventory_hostname }} start delegate_to: '{{ item }}' with_items: groups.replication_servers - name: Create the file to initialize the mongod replica set template: src=repset_init.j2 dest=/tmp/repset_init.js - name: Pause for a while pause: seconds=20 - name: Initialize the replication set shell: /usr/bin/mongo --port "{{ mongod_port }}" /tmp/repset_init.js ================================================ FILE: mongodb/roles/mongod/tasks/shards.yml ================================================ --- #This Playbooks adds shards to the mongos servers once everythig is added - name: Create the file to initialize the mongod Shard template: src=shard_init.j2 dest=/tmp/shard_init_{{ inventory_hostname }}.js delegate_to: '{{ item }}' with_items: groups.mongos_servers - name: Add the shard to the mongos shell: /usr/bin/mongo localhost:{{ mongos_port }}/admin -u admin -p {{ mongo_admin_pass }} /tmp/shard_init_{{ inventory_hostname }}.js delegate_to: '{{ item }}' with_items: groups.mongos_servers ================================================ FILE: mongodb/roles/mongod/templates/mongod.conf.j2 ================================================ # mongo.conf smallfiles=true #where to log logpath=/var/log/mongo/mongod-{{ inventory_hostname }}.log logappend=true # fork and run in background fork = true port = {{ mongod_port }} dbpath={{ mongodb_datadir_prefix }}mongo-{{ inventory_hostname }} keyFile={{ mongodb_datadir_prefix }}/secret # location of pidfile pidfilepath = /var/run/mongo/mongod-{{ inventory_hostname }}.pid # Ping interval for Mongo monitoring server. #mms-interval = # Replication Options replSet={{ inventory_hostname }} ================================================ FILE: mongodb/roles/mongod/templates/mongod.j2 ================================================ #!/bin/bash # mongod - Startup script for mongod # chkconfig: 35 85 15 # description: Mongo is a scalable, document-oriented database. # processname: mongod # config: /etc/mongod.conf # pidfile: /var/run/mongo/mongod.pid . /etc/rc.d/init.d/functions # things from mongod.conf get there by mongod reading it export LC_ALL="C" # NOTE: if you change any OPTIONS here, you get what you pay for: # this script assumes all options are in the config file. CONFIGFILE="/etc/mongod-{{ inventory_hostname }}.conf" OPTIONS=" -f $CONFIGFILE" SYSCONFIG="/etc/sysconfig/mongod" # FIXME: 1.9.x has a --shutdown flag that parses the config file and # shuts down the correct running pid, but that's unavailable in 1.8 # for now. This can go away when this script stops supporting 1.8. DBPATH=`awk -F= '/^dbpath=/{print $2}' "$CONFIGFILE"` PIDFILE=`awk -F= '/^dbpath\s=\s/{print $2}' "$CONFIGFILE"` mongod=${MONGOD-/usr/bin/mongod} MONGO_USER=mongod MONGO_GROUP=mongod if [ -f "$SYSCONFIG" ]; then . "$SYSCONFIG" fi # Handle NUMA access to CPUs (SERVER-3574) # This verifies the existence of numactl as well as testing that the command works NUMACTL_ARGS="--interleave=all" if which numactl >/dev/null 2>/dev/null && numactl $NUMACTL_ARGS ls / >/dev/null 2>/dev/null then NUMACTL="numactl $NUMACTL_ARGS" else NUMACTL="" fi start() { echo -n $"Starting mongod: " daemon --user "$MONGO_USER" $NUMACTL $mongod $OPTIONS RETVAL=$? echo [ $RETVAL -eq 0 ] && touch /var/lock/subsys/mongod-{{ inventory_hostname }} } stop() { echo -n $"Stopping mongod: " killproc -p "$PIDFILE" -d 300 /usr/bin/mongod RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/mongod-{{ inventory_hostname }} } restart () { stop start } ulimit -n 12000 RETVAL=0 case "$1" in start) start ;; stop) stop ;; restart|reload|force-reload) restart ;; condrestart) [ -f /var/lock/subsys/mongod ] && restart || : ;; status) status $mongod RETVAL=$? ;; *) echo "Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}" RETVAL=1 esac exit $RETVAL ================================================ FILE: mongodb/roles/mongod/templates/repset_init.j2 ================================================ rs.initiate() sleep(13000) {% for host in groups['replication_servers'] %} rs.add("{{ host }}:{{ mongod_port }}") sleep(8000) {% endfor %} printjson(rs.status()) ================================================ FILE: mongodb/roles/mongod/templates/shard_init.j2 ================================================ sh.addShard("{{ inventory_hostname}}/{{ inventory_hostname }}:{{ mongod_port }}") printjson(rs.status()) ================================================ FILE: mongodb/roles/mongos/files/secret ================================================ qGO6OYb64Uth9p9Tm8s9kqarydmAg1AUdgVz+ecjinaLZ1SlWxXMY1ug8AO7C/Vu D8kA3+rE37Gv1GuZyPYi87NSfDhKXo4nJWxI00BxTBppmv2PTzbi7xLCx1+8A1uQ 4XU0HA ================================================ FILE: mongodb/roles/mongos/tasks/main.yml ================================================ --- #This Playbook configures the mongos service of mongodb - name: Create the mongos startup file template: src=mongos.j2 dest=/etc/init.d/mongos mode=0655 - name: Create the mongos configuration file template: src=mongos.conf.j2 dest=/etc/mongos.conf - name: Copy the keyfile for authentication copy: src=roles/mongod/files/secret dest={{ mongodb_datadir_prefix }}/secret owner=mongod group=mongod mode=0400 - name: Start the mongos service command: creates=/var/lock/subsys/mongos /etc/init.d/mongos start - name: pause pause: seconds=20 - name: copy the file for shard test template: src=testsharding.j2 dest=/tmp/testsharding.js - name: copy the file enable sharding template: src=enablesharding.j2 dest=/tmp/enablesharding.js ================================================ FILE: mongodb/roles/mongos/templates/enablesharding.j2 ================================================ db.runCommand( { enableSharding : "test" } ) db.runCommand( { shardCollection : "test.test_collection", key : {"number":1} }) ================================================ FILE: mongodb/roles/mongos/templates/mongos.conf.j2 ================================================ #where to log logpath=/var/log/mongo/mongos.log logappend=true # fork and run in background fork = true port = {{ mongos_port }} {% set hosts = '' %} {% for host in groups['mongoc_servers'] %} {% if loop.last %} {% set hosts = hosts + host + ':' ~ mongoc_port %} configdb = {{ hosts }} {% else %} {% set hosts = hosts + host + ':' ~ mongoc_port + ',' %} {% endif %} {% endfor %} # location of pidfile pidfilepath = /var/run/mongodb/mongos.pid keyFile={{ mongodb_datadir_prefix }}/secret chunkSize={{ mongos_chunk_size }} ================================================ FILE: mongodb/roles/mongos/templates/mongos.j2 ================================================ #!/bin/bash # mongod - Startup script for mongod # chkconfig: 35 85 15 # description: Mongo is a scalable, document-oriented database. # processname: mongod # config: /etc/mongod.conf # pidfile: /var/run/mongo/mongod.pid . /etc/rc.d/init.d/functions # things from mongod.conf get there by mongod reading it export LC_ALL="C" # NOTE: if you change any OPTIONS here, you get what you pay for: # this script assumes all options are in the config file. CONFIGFILE="/etc/mongos.conf" OPTIONS=" -f $CONFIGFILE" SYSCONFIG="/etc/sysconfig/mongod" # FIXME: 1.9.x has a --shutdown flag that parses the config file and # shuts down the correct running pid, but that's unavailable in 1.8 # for now. This can go away when this script stops supporting 1.8. DBPATH=`awk -F= '/^dbpath=/{print $2}' "$CONFIGFILE"` PIDFILE=`awk -F= '/^dbpath\s=\s/{print $2}' "$CONFIGFILE"` mongod=${MONGOD-/usr/bin/mongos} MONGO_USER=mongod MONGO_GROUP=mongod if [ -f "$SYSCONFIG" ]; then . "$SYSCONFIG" fi # Handle NUMA access to CPUs (SERVER-3574) # This verifies the existence of numactl as well as testing that the command works NUMACTL_ARGS="--interleave=all" if which numactl >/dev/null 2>/dev/null && numactl $NUMACTL_ARGS ls / >/dev/null 2>/dev/null then NUMACTL="numactl $NUMACTL_ARGS" else NUMACTL="" fi start() { echo -n $"Starting mongod: " daemon --user "$MONGO_USER" $NUMACTL $mongod $OPTIONS RETVAL=$? echo [ $RETVAL -eq 0 ] && touch /var/lock/subsys/mongos } stop() { echo -n $"Stopping mongod: " killproc -p "$PIDFILE" -d 300 /usr/bin/mongos RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/mongos } restart () { stop start } ulimit -n 12000 RETVAL=0 case "$1" in start) start ;; stop) stop ;; restart|reload|force-reload) restart ;; condrestart) [ -f /var/lock/subsys/mongod ] && restart || : ;; status) status $mongod RETVAL=$? ;; *) echo "Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}" RETVAL=1 esac exit $RETVAL ================================================ FILE: mongodb/roles/mongos/templates/testsharding.j2 ================================================ people = ["Marc", "Bill", "George", "Eliot", "Matt", "Trey", "Tracy", "Greg", "Steve", "Kristina", "Katie", "Jeff"]; for(var i=0; i<100000; i++){ name = people[Math.floor(Math.random()*people.length)]; user_id = i; boolean = [true, false][Math.floor(Math.random()*2)]; added_at = new Date(); number = Math.floor(Math.random()*10001); db.test_collection.save({"name":name, "user_id":user_id, "boolean": boolean, "added_at":added_at, "number":number }); } db.test_collection.ensureIndex({number:1}) ================================================ FILE: mongodb/site.yml ================================================ --- # This Playbook would deploy the whole mongodb cluster with replication and sharding. - hosts: all roles: - role: common - hosts: mongo_servers roles: - role: mongod - hosts: mongoc_servers roles: - role: mongoc - hosts: mongos_servers roles: - role: mongos - hosts: mongo_servers tasks: - include: roles/mongod/tasks/shards.yml ================================================ FILE: phillips_hue/README.md ================================================ ## HUE LIGHTS WITH ANSIBLE This README written on September 5th, 2018 by [Sean Cavanaugh](https://github.com/ipvsean). The original username feature seems to have been disabled since James Cammarata wrote the original modules and URI based Playbooks in 2016. I updated my Phillips Hue Bulbs to the latest firmware as of this post and made some new Playbooks based off the original Cammarata URI playbooks :) ## PREREQUISITES - Ansible - [Install Guide](https://www.amazon.com/gp/product/B07D1J5QC7/ref=oh_aui_detailpage_o01_s00?ie=UTF8&psc=1) - Phillips Hue Lights - The kit used for this particular demo was a Philips Hue White and Color Ambiance A19 60W Equivalent LED Smart Light Bulb Starter Kit. The link on Amazon can [be found here](https://www.amazon.com/gp/product/B07D1J5QC7/ref=oh_aui_detailpage_o01_s00?ie=UTF8&psc=1) - IP Address of the Hue Controller (known as the bridge). - Most home networks will allow you to pin a static IP address to the Hue bridge. I use Google Wifi and this took a couple clicks on my iPhone. Also make sure that you can control the lights normally from the free iPhone or Android app. This may require you adding the serial numbers manually which can be found on the side of the bulbs. ## SETUP ### Step 1 Open up the [username_info.yml](username_info.yml) file and change the IP Address to the IP address of your Hue bridge. ```nano username_info.yml``` ```yaml --- username: FmAXS-XpnLIxBQwyaw1tkIw04YzIt-BIG4YL0v8X ip_address: "192.168.86.30" body_info: devicetype: "Ansible!" ``` Ignore the `username` and `body_info` fields. The `username` is automatically generated by the Hue bridge and updated in this file in the following step. The `body_info` is just used to register this particular computer (the computer you are executing Ansible from) in the following step, the `devicetype` could be anything. Please refer to the [getting started guide](https://www.developers.meethue.com/documentation/getting-started) from Phillips for more information. ### Step 2 For the Playbooks to work correctly you must run the `register.yml` playbook first: ```ansible-playbook register.yml``` The playbook will run and then prompt you on the terminal window: ``` [PROMPT USER TO PRESS PHYSICAL BUTTON HUE HUB] Press the button on the hub now...: ``` You must physically touch the button on the Hue bridge (the top of it where the word PHILLIPS is clearly printed) as a security measure. Press enter on the terminal window after you have pressed the Hue bridge button. This will save a unique Hue generated authorized user to `username_info` which will look like a long string of text (e.g. `elY1xx9p5twUBYDjELgMUuQT99kLaVqGT1p0eDrl`). ## PLAYBOOKS There are three demo playbooks included. All three of them use the [include_vars](https://docs.ansible.com/ansible/latest/modules/include_vars_module.html) task to grab the IP address and username information from `username_info.yml`. Run them with `ansible-playbook .yml` e.g. `ansible-playbook on_off.yml`. - `on_off.yml ` This playbook turns off all bulbs that are registered to the Hue bridge. It then prompts the user, and then turns them back on. - `ansible_colors.yml ` This playbook cycles all bulbs between Ansible mango and Ansible pool a couple times You can find the [official Ansible colors and logos here](https://www.ansible.com/logos). - `effect.yml` This playbook takes all bulbs and puts them into a mode called colorloop where the bulbs will randomly cycle colors. This will happen for 5 seconds then it will turn off the effect. ## DEMONSTRATION ![hue screencast](hue.gif) ## License GPLv3 ================================================ FILE: phillips_hue/ansible.cfg ================================================ # config file for ansible -- http://ansible.com/ # ============================================== # nearly all parameters can be overridden in ansible-playbook # or with command line flags. ansible will read ANSIBLE_CONFIG, # ansible.cfg in the current working directory, .ansible.cfg in # the home directory or /etc/ansible/ansible.cfg, whichever it # finds first [defaults] # some basic default values... inventory = hosts forks = 50 host_key_checking = False retry_files_enabled = False no_target_syslog = False callback_whitelist = time [ssh_connection] scp_if_ssh = True ================================================ FILE: phillips_hue/ansible_colors.yml ================================================ - hosts: localhost gather_facts: no connection: local vars: ansible_mango: "on": true "bri": 254 "xy": [0.5701, 0.313] ansible_pool: "on": true "bri": 254 "xy": [0.1593, 0.2522] tasks: - name: INCLUDE UNIQUE USERNAME FROM REGISTER.YML include_vars: file: username_info.yml - name: GRAB HUE LIGHT INFORMATION uri: url: "http://{{ip_address}}/api/{{username}}" method: GET body: '{{body_info|to_json}}' register: light_info - name: TURN LIGHTS TO MANGO uri: url: "http://{{ip_address}}/api/{{username}}/lights/{{item}}/state" method: PUT body: '{{ansible_mango|to_json}}' loop: "{{ range(1, light_info.json.lights | length + 1)|list }}" - name: TURN LIGHTS TO POOL uri: url: "http://{{ip_address}}/api/{{username}}/lights/{{item}}/state" method: PUT body: '{{ansible_pool|to_json}}' loop: "{{ range(1, light_info.json.lights | length + 1)|list }}" - name: TURN LIGHTS TO MANGO uri: url: "http://{{ip_address}}/api/{{username}}/lights/{{item}}/state" method: PUT body: '{{ansible_mango|to_json}}' loop: "{{ range(1, light_info.json.lights | length + 1)|list }}" - name: TURN LIGHTS TO POOL uri: url: "http://{{ip_address}}/api/{{username}}/lights/{{item}}/state" method: PUT body: '{{ansible_pool|to_json}}' loop: "{{ range(1, light_info.json.lights | length + 1)|list }}" ================================================ FILE: phillips_hue/effect.yml ================================================ - hosts: localhost gather_facts: no connection: local vars: ansible_effect: "on": true "effect": "colorloop" ansible_none: "on": true "effect": "none" tasks: - name: INCLUDE UNIQUE USERNAME FROM REGISTER.YML include_vars: file: username_info.yml - name: GRAB HUE LIGHT INFORMATION uri: url: "http://{{ip_address}}/api/{{username}}" method: GET body: '{{body_info|to_json}}' register: light_info - name: TURN LIGHTS INTO COLORLOOP EFFECT uri: url: "http://{{ip_address}}/api/{{username}}/lights/{{item}}/state" method: PUT body: '{{ansible_effect|to_json}}' loop: "{{ range(1, light_info.json.lights | length + 1)|list }}" # Pause for 10 seconds - pause: seconds: 5 - name: TURN LIGHTS INTO COLORLOOP EFFECT uri: url: "http://{{ip_address}}/api/{{username}}/lights/{{item}}/state" method: PUT body: '{{ansible_none|to_json}}' loop: "{{ range(1, light_info.json.lights | length + 1)|list }}" ================================================ FILE: phillips_hue/hosts ================================================ localhost ================================================ FILE: phillips_hue/on_off.yml ================================================ - hosts: localhost gather_facts: no connection: local vars: off_state: "on": false on_state: "on": true tasks: - name: INCLUDE UNIQUE USERNAME FROM REGISTER.YML include_vars: file: username_info.yml - name: GRAB HUE LIGHT INFORMATION uri: url: "http://{{ip_address}}/api/{{username}}" method: GET body: '{{body_info|to_json}}' register: light_info - name: PRINT DATA TO TERMINAL WINDOW debug: var: light_info.json.lights - name: PRINT AMOUNT OF LIGHTS TO TERMINAL WINDOW debug: msg: "THERE ARE {{light_info.json.lights | length}} HUE LIGHTS PRESENT" # - name: PRINT OUT LOOP VARS # debug: # msg: "http://{{ip_address}}/api/{{username}}/lights/{{item}}/state" # loop: "{{ range(1, light_info.json.lights | length + 1)|list }}" - name: TURN LIGHTS OFF uri: url: "http://{{ip_address}}/api/{{username}}/lights/{{item}}/state" method: PUT body: '{{off_state|to_json}}' loop: "{{ range(1, light_info.json.lights | length + 1)|list }}" - name: PROMPT USER TO TURN BACK ON pause: prompt: "Turn them back on?" - name: TURN LIGHTS ON uri: url: "http://{{ip_address}}/api/{{username}}/lights/{{item}}/state" method: PUT body: '{{on_state|to_json}}' loop: "{{ range(1, light_info.json.lights | length + 1)|list }}" ================================================ FILE: phillips_hue/register.yml ================================================ - hosts: localhost gather_facts: no connection: local tasks: - name: PROMPT USER TO PRESS PHYSICAL BUTTON HUE HUB pause: prompt: "Press the button on the hub now..." - name: INCLUDE IP ADDRESS FROM username_info.yml include_vars: file: username_info.yml - name: GRAB UNIQUE USERNAME uri: url: "http://{{ip_address}}/api" method: POST body: '{{body_info|to_json}}' register: username_info - name: PRINT DATA TO TERMINAL WINDOW debug: var: username_info.json - lineinfile: path: "./username_info.yml" regexp: '^username' insertafter: EOF line: 'username: {{username_info.json[0]["success"]["username"]}}' ================================================ FILE: phillips_hue/username_info.yml ================================================ --- username: elY1xx9p5twUBYDjELgMUuQT99kLaVqGT1p0eDrl ip_address: "192.168.86.30" body_info: devicetype: "Ansible!" ================================================ FILE: rust-module-hello-world/Makefile ================================================ .PHONY: all clean rust all: rust clean: rm -f library/rust_helloworld cd module-src && \ cargo clean rust: cd module-src && \ cargo build && \ cp -v target/debug/helloworld ../library/rust_helloworld ================================================ FILE: rust-module-hello-world/library/.gitignore ================================================ !/.gitignore /.* /* ================================================ FILE: rust-module-hello-world/module-src/Cargo.toml ================================================ [package] name = "helloworld" version = "0.1.0" authors = ["Sviatoslav Sydorenko "] [dependencies] serde = "1.0.66" serde_derive = "1.0.66" serde_json = "1.0.20" ================================================ FILE: rust-module-hello-world/module-src/src/main.rs ================================================ extern crate serde; extern crate serde_json; use std::env; use std::fs::File; use std::io::prelude::*; use std::process; #[macro_use] extern crate serde_derive; use serde_json::Error; fn default_name_arg() -> String { String::from("World") } #[derive(Serialize, Deserialize)] struct ModuleArgs { #[serde(default = "default_name_arg")] name: String, } #[derive(Clone, Serialize, Deserialize)] struct Response { msg: String, changed: bool, failed: bool, } fn exit_json(response_body: Response) { return_response(response_body) } fn fail_json(response_body: Response) { let failed_response = &mut response_body.clone(); failed_response.failed = true; return_response(failed_response.clone()) } fn return_response(resp: Response) { println!("{}", serde_json::to_string(&resp).unwrap()); process::exit(resp.failed as i32); } fn read_file_contents(file_name: &str) -> Result> { let mut json_string = String::new(); File::open(file_name)?.read_to_string(&mut json_string)?; Ok(json_string) } fn parse_module_args(json_input: String) -> Result { Ok( ModuleArgs::from( serde_json::from_str( json_input.as_str() )? ) ) } fn main() { let args: Vec = env::args().collect(); let program = &args[0]; let input_file_name = match args.len() { 2 => &args[1], _ => { eprintln!("module '{}' expects exactly one argument!", program); fail_json(Response { msg: "No module arguments file provided".to_owned(), changed: false, failed: true, }); "" } }; let json_input = read_file_contents(input_file_name).map_err(|err| { eprintln!("Could not read file '{}': {}", input_file_name, err); fail_json(Response { msg: format!("Could not read input JSON file '{}': {}", input_file_name, err), changed: false, failed: true, }) }).unwrap(); let module_args = parse_module_args(json_input).map_err(|err| { eprintln!("Error during parsing JSON module arguments: {}", err); fail_json(Response { msg: format!("Malformed input JSON module arguments: {}", err), changed: false, failed: true, }) }).unwrap(); exit_json(Response { msg: format!("Hello, {}!", module_args.name.as_str()), changed: true, failed: false, }); } ================================================ FILE: rust-module-hello-world/module-src/target/.gitignore ================================================ !/.gitignore /.* /* ================================================ FILE: rust-module-hello-world/rust.yml ================================================ --- - hosts: localhost tasks: - debug: msg: Testing a binary module written in Rust - debug: var: ansible_system - name: ping ping: - name: Hello, World! rust_helloworld: register: hello_world - assert: that: - > hello_world.msg == "Hello, World!" - name: Hello, Ansible! rust_helloworld: name: Ansible register: hello_ansible - assert: that: - > hello_ansible.msg == "Hello, Ansible!" - name: Async Hello, World! rust_helloworld: async: 10 poll: 1 register: async_hello_world - assert: that: - > async_hello_world.msg == "Hello, World!" - name: Async Hello, Ansible! rust_helloworld: name: Ansible async: 10 poll: 1 register: async_hello_ansible - assert: that: - > async_hello_ansible.msg == "Hello, Ansible!" ================================================ FILE: tomcat-memcached-failover/LICENSE.md ================================================ Copyright (c) 2015 Cuong Nguyen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: tomcat-memcached-failover/README.md ================================================ ## Tomcat failover with Memcached + Memcached Session Manager + Nginx (load balancer) - Tested on Ansible 1.9.3 for Debian - Expects hosts: CentOS 6.x This playbook deploys a failover solution for clustered Tomcat using Nginx as load balancer and Memcached + MSM as session manager. - Nginx: balances the requests by round robin. - Memcached: stores `sessionid` of tomcat. - MSM: manages tomcat session. For more detail about session management, see https://github.com/magro/memcached-session-manager This playbook also deploys a [demo web app](https://github.com/magro/msm-sample-webapp) to test the session management. ## Initial setup of inventory file ``` [lb_servers] lbserver [backend_servers] tomcat_server_1 tomcat_server_2 [memcached_servers] cached_server1 cached_server2 ``` Edit inventory file `hosts` to suit your requirements and run playbook: ``` $ ansible-playbook -i hosts site.yml ``` When finished, open web browser and access to http://nginx_ip/ to start testing. ## Ideas and improvements - Setup SSL for load balancer. - HA load balancer. - Hardening iptables rules. Pull requests are welcome. ## License This work is licensed under MIT license. ================================================ FILE: tomcat-memcached-failover/group_vars/all ================================================ # Java variables # Nginx variables nginx_http_port: 80 # nginx_https_port: 443 # Tomcat variables tomcat_http_port: 8080 tomcat_https_port: 8443 # Memcached variables memcached_port: 11211 ================================================ FILE: tomcat-memcached-failover/hosts ================================================ [lb_servers] lbserver [backend_servers] tomcat_server_1 tomcat_server_2 [memcached_servers] cached_server1 cached_server2 ================================================ FILE: tomcat-memcached-failover/roles/common/handlers/main.yml ================================================ --- - name: restart iptables service: name=iptables state=restarted ================================================ FILE: tomcat-memcached-failover/roles/common/tasks/main.yml ================================================ --- - name: Install libselinux-python yum: name=libselinux-python state=present - name: Install GPG key for EPEL get_url: url=https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6 dest=/etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 - name: Install EPEL repository yum: name=https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm state=present - name: Setup Iptables rules template: src=iptables.j2 dest=/etc/sysconfig/iptables notify: restart iptables ================================================ FILE: tomcat-memcached-failover/roles/common/templates/iptables.j2 ================================================ # {{ ansible_managed }} # Manual customization of this file is not recommended. *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] {% if (inventory_hostname in groups['lb_servers']) %} -A INPUT -p tcp --dport {{ nginx_http_port }} -j ACCEPT {% endif %} {% if inventory_hostname in groups['backend_servers'] %} -A INPUT -p tcp --dport {{ tomcat_http_port }} -j ACCEPT -A INPUT -p tcp --dport {{ tomcat_https_port }} -j ACCEPT {% endif %} {% if inventory_hostname in groups['memcached_servers'] %} -A INPUT -p tcp --dport {{ memcached_port }} -j ACCEPT {% endif %} -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT COMMIT ================================================ FILE: tomcat-memcached-failover/roles/lb-nginx/handlers/main.yml ================================================ --- - name: restart nginx service: name=nginx state=restarted ================================================ FILE: tomcat-memcached-failover/roles/lb-nginx/tasks/main.yml ================================================ --- - name: Install nginx yum: name=nginx state=present - name: Deliver main configuration file template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf notify: restart nginx - name: Copy configuration file to nginx/sites-avaiable template: src=default.conf.j2 dest=/etc/nginx/conf.d/default.conf notify: restart nginx - name: Make sure nginx start with boot service: name=nginx state=started enabled=yes ================================================ FILE: tomcat-memcached-failover/roles/lb-nginx/templates/default.conf.j2 ================================================ upstream tomcat { {% for host in groups['backend_servers'] %} server {{ host }}:{{ tomcat_http_port }}; {% endfor %} } server { listen 80 default_server; server_name {{ inventory_hostname }}; include /etc/nginx/default.d/*.conf; location / { proxy_pass http://tomcat; } } ================================================ FILE: tomcat-memcached-failover/roles/lb-nginx/templates/nginx.conf.j2 ================================================ # For more information on configuration, see: # * Official English Documentation: http://nginx.org/en/docs/ # * Official Russian Documentation: http://nginx.org/ru/docs/ user nginx; worker_processes 1; error_log /var/log/nginx/error.log; #error_log /var/log/nginx/error.log notice; #error_log /var/log/nginx/error.log info; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; 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; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; # Load config files from the /etc/nginx/conf.d directory # The default server is in conf.d/default.conf include /etc/nginx/conf.d/*.conf; } ================================================ FILE: tomcat-memcached-failover/roles/memcached/handlers/main.yml ================================================ --- - name: restart memcached service: name=memcached state=restarted ================================================ FILE: tomcat-memcached-failover/roles/memcached/tasks/main.yml ================================================ --- - name: Install memcached yum: name=memcached state=present - name: Deliver configuration file template: src=memcached.conf.j2 dest=/etc/sysconfig/memcached backup=yes notify: restart memcached - name: Deliver init script template: src=init.sh.j2 dest=/etc/init.d/memcached mode=0755 notify: restart memcached - name: Start memcached service service: name=memcached state=started enabled=yes ================================================ FILE: tomcat-memcached-failover/roles/memcached/templates/init.sh.j2 ================================================ #! /bin/sh # # chkconfig: - 55 45 # description: The memcached daemon is a network memory cache service. # processname: memcached # config: /etc/sysconfig/memcached # pidfile: /var/run/memcached/memcached.pid # Standard LSB functions #. /lib/lsb/init-functions # Source function library. . /etc/init.d/functions PORT=11211 USER=memcached MAXCONN=1024 CACHESIZE=64 OPTIONS="" if [ -f /etc/sysconfig/memcached ];then . /etc/sysconfig/memcached fi # Check that networking is up. . /etc/sysconfig/network if [ "$NETWORKING" = "no" ] then exit 0 fi RETVAL=0 prog="memcached" pidfile=${PIDFILE-/var/run/memcached/memcached.pid} lockfile=${LOCKFILE-/var/lock/subsys/memcached} start () { echo -n $"Starting $prog: " # Ensure that /var/run/memcached has proper permissions if [ "`stat -c %U /var/run/memcached`" != "$USER" ]; then chown $USER /var/run/memcached fi # daemon --pidfile ${pidfile} memcached -d -p $PORT -u $USER -m $CACHESIZE -c $MAXCONN -P ${pidfile} $OPTIONS daemon --pidfile ${pidfile} memcached -d -p $PORT -u $USER -m $CACHESIZE -c $MAXCONN -P ${pidfile} $OPTIONS -vv > $LOGFILE 2>&1 RETVAL=$? echo [ $RETVAL -eq 0 ] && touch ${lockfile} } stop () { echo -n $"Stopping $prog: " killproc -p ${pidfile} /usr/bin/memcached RETVAL=$? echo if [ $RETVAL -eq 0 ] ; then rm -f ${lockfile} ${pidfile} fi } restart () { stop start } # See how we were called. case "$1" in start) start ;; stop) stop ;; status) status -p ${pidfile} memcached RETVAL=$? ;; restart|reload|force-reload) restart ;; condrestart|try-restart) [ -f ${lockfile} ] && restart || : ;; *) echo $"Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart|try-restart}" RETVAL=2 ;; esac exit $RETVAL ================================================ FILE: tomcat-memcached-failover/roles/memcached/templates/memcached.conf.j2 ================================================ # Running on Port 11211 PORT="{{ memcached_port }}" # Start as memcached daemon USER="memcached" # Set max simultaneous connections to 1024 MAXCONN="1024" # Set log file LOGFILE="/var/log/memcached.log" # Set Memory size to half of all memory CACHESIZE="{{ ansible_memtotal_mb / 2 }}" #Set server IP address OPTIONS="-l {{ ansible_default_ipv4['address'] }}" ================================================ FILE: tomcat-memcached-failover/roles/tomcat/handlers/main.yml ================================================ --- - name: restart tomcat service: name=tomcat state=restarted ================================================ FILE: tomcat-memcached-failover/roles/tomcat/tasks/main.yml ================================================ --- - name: Install OpenJDK yum: name=java-1.7.0-openjdk state=present - name: Install Tomcat yum: name=tomcat state=present - name: Deliver configuration files for tomcat template: src={{ item.src }} dest={{ item.dest }} backup=yes with_items: - { src: 'default.j2', dest: '/etc/tomcat/default' } - { src: 'server.xml.j2', dest: '/etc/tomcat/server.xml' } - { src: 'context.xml.j2', dest: '/etc/tomcat/context.xml' } notify: restart tomcat - name: Deliver libraries support memcached get_url: url="{{ item }}" dest=/usr/share/tomcat/lib/ with_items: - http://repo1.maven.org/maven2/de/javakaffee/msm/memcached-session-manager/1.8.0/memcached-session-manager-1.8.0.jar - http://repo1.maven.org/maven2/de/javakaffee/msm/memcached-session-manager-tc7/1.8.0/memcached-session-manager-tc7-1.8.0.jar - https://spymemcached.googlecode.com/files/spymemcached-2.10.2.jar - name: Deploy sample app copy: src=msm-sample-webapp-1.0-SNAPSHOT.war dest=/var/lib/tomcat/webapps/ROOT.war owner=tomcat group=tomcat - name: Start tomcat service service: name=tomcat state=started enabled=yes ================================================ FILE: tomcat-memcached-failover/roles/tomcat/templates/context.xml.j2 ================================================ WEB-INF/web.xml ================================================ FILE: tomcat-memcached-failover/roles/tomcat/templates/default.j2 ================================================ # Service-specific configuration file for tomcat. This will be sourced by # the SysV init script after the global configuration file # /etc/tomcat/tomcat.conf, thus allowing values to be overridden in # a per-service manner. # # NEVER change the init script itself. To change values for all services make # your changes in /etc/tomcat/tomcat.conf # # To change values for a specific service make your edits here. # To create a new service create a link from /etc/init.d/ to # /etc/init.d/tomcat (do not copy the init script) and make a copy of the # /etc/sysconfig/tomcat file to /etc/sysconfig/ and change # the property values so the two services won't conflict. Register the new # service in the system as usual (see chkconfig and similars). # # Where your java installation lives #JAVA_HOME="/usr/lib/jvm/java" # Where your tomcat installation lives #CATALINA_BASE="/usr/share/tomcat" #CATALINA_HOME="/usr/share/tomcat" #JASPER_HOME="/usr/share/tomcat" #CATALINA_TMPDIR="/var/cache/tomcat/temp" # You can pass some parameters to java here if you wish to #JAVA_OPTS="-Xminf0.1 -Xmaxf0.3" # Use JAVA_OPTS to set java.library.path for libtcnative.so #JAVA_OPTS="-Djava.library.path=/usr/lib" # What user should run tomcat #TOMCAT_USER="tomcat" # You can change your tomcat locale here #LANG="en_US" # Run tomcat under the Java Security Manager #SECURITY_MANAGER="false" # Time to wait in seconds, before killing process #SHUTDOWN_WAIT="30" # Whether to annoy the user with "attempting to shut down" messages or not #SHUTDOWN_VERBOSE="false" # Set the TOMCAT_PID location #CATALINA_PID="/var/run/tomcat.pid" # Connector port is 8080 for this tomcat instance #CONNECTOR_PORT="8080" # If you wish to further customize your tomcat environment, # put your own definitions here # (i.e. LD_LIBRARY_PATH for some jdbc drivers) ================================================ FILE: tomcat-memcached-failover/roles/tomcat/templates/server.xml.j2 ================================================ ================================================ FILE: tomcat-memcached-failover/site.yml ================================================ --- - hosts: all remote_user: root roles: - common - hosts: lb_servers remote_user: root roles: - lb-nginx - hosts: backend_servers remote_user: root roles: - tomcat - hosts: memcached_servers remote_user: root roles: - memcached ================================================ FILE: tomcat-standalone/LICENSE.md ================================================ Copyright (C) 2013 AnsibleWorks, Inc. This work is licensed under the Creative Commons Attribution 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/deed.en_US. ================================================ FILE: tomcat-standalone/README.md ================================================ ## Standalone Tomcat Deployment - Requires Ansible 1.2 or newer - Expects CentOS/RHEL 6.x hosts These playbooks deploy a very basic implementation of Tomcat Application Server, version 7. To use them, first edit the `hosts` inventory file to contain the hostnames of the machines on which you want Tomcat deployed, and edit the group_vars/tomcat-servers file to set any Tomcat configuration parameters you need. Then run the playbook, like this: ansible-playbook -i hosts site.yml When the playbook run completes, you should be able to see the Tomcat Application Server running on the ports you chose, on the target machines. This is a very simple playbook and could serve as a starting point for more complex Tomcat-based projects. ### Ideas for Improvement Here are some ideas for ways that these playbooks could be extended: - Write a playbook to deploy an actual application into the server. - Deploy Tomcat clustered with a load balancer in front. We would love to see contributions and improvements, so please fork this repository on GitHub and send us your changes via pull requests. ================================================ FILE: tomcat-standalone/group_vars/tomcat-servers ================================================ # Here are variables related to the Tomcat installation http_port: 8080 https_port: 8443 # This will configure a default manager-gui user: admin_username: admin admin_password: adminsecret ================================================ FILE: tomcat-standalone/hosts ================================================ [tomcat-servers] webserver1 ================================================ FILE: tomcat-standalone/roles/selinux/tasks/main.yml ================================================ --- # Download and install EPEL for Centos/RHEL version 6 - name: Download EPEL Repo - Centos/RHEL 6 get_url: url=http://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm dest=/tmp/epel-release-latest-6.noarch.rpm when: "ansible_os_family == 'RedHat' and ansible_distribution_major_version == '6'" - name: Install EPEL Repo - Centos/RHEL 6 command: rpm -ivh /tmp/epel-release-latest-6.noarch.rpm creates=/etc/yum.repos.d/epel.repo when: "ansible_os_family == 'RedHat' and ansible_distribution_major_version == '6'" # Download and install EPEL for Centos/RHEL version 7 - name: Download EPEL Repo - Centos/RHEL 7 get_url: url=http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm dest=/tmp/epel-release-latest-7.noarch.rpm when: "ansible_os_family == 'RedHat' and ansible_distribution_major_version == '7'" - name: Install EPEL Repo - Centos/RHEL 7 command: rpm -ivh /tmp/epel-release-latest-7.noarch.rpm creates=/etc/yum.repos.d/epel.repo when: "ansible_os_family == 'RedHat' and ansible_distribution_major_version == '7'" - name: Install libselinux-python yum: name=libselinux-python ================================================ FILE: tomcat-standalone/roles/tomcat/files/tomcat-initscript.sh ================================================ #!/bin/bash # # chkconfig: 345 99 28 # description: Starts/Stops Apache Tomcat # # Tomcat 7 start/stop/status script # Forked from: https://gist.github.com/valotas/1000094 # @author: Miglen Evlogiev # # Release updates: # Updated method for gathering pid of the current proccess # Added usage of CATALINA_BASE # Added coloring and additional status # Added check for existence of the tomcat user # #Location of JAVA_HOME (bin files) export JAVA_HOME=/usr/lib/jvm/jre #Add Java binary files to PATH export PATH=$JAVA_HOME/bin:$PATH #CATALINA_HOME is the location of the bin files of Tomcat export CATALINA_HOME=/usr/share/tomcat #CATALINA_BASE is the location of the configuration files of this instance of Tomcat export CATALINA_BASE=/usr/share/tomcat #TOMCAT_USER is the default user of tomcat export TOMCAT_USER=tomcat #TOMCAT_USAGE is the message if this script is called without any options TOMCAT_USAGE="Usage: $0 {\e[00;32mstart\e[00m|\e[00;31mstop\e[00m|\e[00;32mstatus\e[00m|\e[00;31mrestart\e[00m}" #SHUTDOWN_WAIT is wait time in seconds for java proccess to stop SHUTDOWN_WAIT=20 tomcat_pid() { echo `ps -fe | grep $CATALINA_BASE | grep -v grep | tr -s " "|cut -d" " -f2` } start() { pid=$(tomcat_pid) if [ -n "$pid" ] then echo -e "\e[00;31mTomcat is already running (pid: $pid)\e[00m" else # Start tomcat echo -e "\e[00;32mStarting tomcat\e[00m" #ulimit -n 100000 #umask 007 #/bin/su -p -s /bin/sh tomcat if [ `user_exists $TOMCAT_USER` = "1" ] then su $TOMCAT_USER -c $CATALINA_HOME/bin/startup.sh else sh $CATALINA_HOME/bin/startup.sh fi status fi return 0 } status(){ pid=$(tomcat_pid) if [ -n "$pid" ]; then echo -e "\e[00;32mTomcat is running with pid: $pid\e[00m" else echo -e "\e[00;31mTomcat is not running\e[00m" fi } stop() { pid=$(tomcat_pid) if [ -n "$pid" ] then echo -e "\e[00;31mStoping Tomcat\e[00m" #/bin/su -p -s /bin/sh tomcat sh $CATALINA_HOME/bin/shutdown.sh let kwait=$SHUTDOWN_WAIT count=0; until [ `ps -p $pid | grep -c $pid` = '0' ] || [ $count -gt $kwait ] do echo -n -e "\n\e[00;31mwaiting for processes to exit\e[00m"; sleep 1 let count=$count+1; done if [ $count -gt $kwait ]; then echo -n -e "\n\e[00;31mkilling processes which didn't stop after $SHUTDOWN_WAIT seconds\e[00m" kill -9 $pid fi else echo -e "\e[00;31mTomcat is not running\e[00m" fi return 0 } user_exists(){ if id -u $1 >/dev/null 2>&1; then echo "1" else echo "0" fi } case $1 in start) start ;; stop) stop ;; restart) stop start ;; status) status ;; *) echo -e $TOMCAT_USAGE ;; esac exit 0 ================================================ FILE: tomcat-standalone/roles/tomcat/handlers/main.yml ================================================ --- - name: restart tomcat service: name=tomcat state=restarted - name: restart iptables service: name=iptables state=restarted ================================================ FILE: tomcat-standalone/roles/tomcat/tasks/main.yml ================================================ --- - name: Install Java 1.7 yum: name=java-1.7.0-openjdk state=present - name: add group "tomcat" group: name=tomcat - name: add user "tomcat" user: name=tomcat group=tomcat home=/usr/share/tomcat createhome=no become: True become_method: sudo - name: Download Tomcat get_url: url=http://archive.apache.org/dist/tomcat/tomcat-7/v7.0.61/bin/apache-tomcat-7.0.61.tar.gz dest=/opt/apache-tomcat-7.0.61.tar.gz - name: Extract archive command: chdir=/usr/share /bin/tar xvf /opt/apache-tomcat-7.0.61.tar.gz -C /opt/ creates=/opt/apache-tomcat-7.0.61 - name: Symlink install directory file: src=/opt/apache-tomcat-7.0.61 path=/usr/share/tomcat state=link - name: Change ownership of Tomcat installation file: path=/usr/share/tomcat/ owner=tomcat group=tomcat state=directory recurse=yes - name: Configure Tomcat server template: src=server.xml dest=/usr/share/tomcat/conf/ notify: restart tomcat - name: Configure Tomcat users template: src=tomcat-users.xml dest=/usr/share/tomcat/conf/ notify: restart tomcat - name: Install Tomcat init script copy: src=tomcat-initscript.sh dest=/etc/init.d/tomcat mode=0755 - name: Start Tomcat service: name=tomcat state=started enabled=yes - name: deploy iptables rules template: src=iptables-save dest=/etc/sysconfig/iptables when: "ansible_os_family == 'RedHat' and ansible_distribution_major_version == '6'" notify: restart iptables - name: insert firewalld rule for tomcat http port firewalld: port={{ http_port }}/tcp permanent=true state=enabled immediate=yes when: "ansible_os_family == 'RedHat' and ansible_distribution_major_version == '7'" - name: insert firewalld rule for tomcat https port firewalld: port={{ https_port }}/tcp permanent=true state=enabled immediate=yes when: "ansible_os_family == 'RedHat' and ansible_distribution_major_version == '7'" - name: wait for tomcat to start wait_for: port={{http_port}} ================================================ FILE: tomcat-standalone/roles/tomcat/templates/iptables-save ================================================ # {{ ansible_managed }} *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [4:512] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport {{ http_port }} -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport {{ https_port }} -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT ================================================ FILE: tomcat-standalone/roles/tomcat/templates/server.xml ================================================ ================================================ FILE: tomcat-standalone/roles/tomcat/templates/tomcat-users.xml ================================================ ================================================ FILE: tomcat-standalone/site.yml ================================================ --- # This playbook deploys a simple standalone Tomcat 7 server. - hosts: tomcat-servers remote_user: root become: yes become_method: sudo roles: - selinux - tomcat ================================================ FILE: windows/create-user.yml ================================================ --- - name: Add a user hosts: all gather_facts: false tasks: - name: Add User win_user: name: ansible password: "@ns1bl3" state: present ================================================ FILE: windows/deploy-site.yml ================================================ --- # This playbook uses the win_get_url module to download a simple HTML file for IIS - name: Download simple web site hosts: all gather_facts: false tasks: - name: Download simple web site to 'C:\inetpub\wwwroot\ansible.html' win_get_url: url: 'https://raw.githubusercontent.com/thisdavejohnson/mywebapp/master/index.html' dest: 'C:\inetpub\wwwroot\ansible.html' ================================================ FILE: windows/enable-iis.yml ================================================ --- # This playbook installs and enables IIS on Windows hosts - name: Install IIS hosts: all gather_facts: false tasks: - name: Install IIS win_feature: name: "Web-Server" state: present restart: yes include_sub_features: yes include_management_tools: yes ================================================ FILE: windows/files/helloworld.ps1 ================================================ # Filename: helloworld.ps1 Write-Host Write-Host 'Hello World!' Write-Host "Good-bye World! `n" # end of script ================================================ FILE: windows/install-msi.yml ================================================ --- - name: Install Apache from an MSI hosts: all tasks: - name: Download the Apache installer win_get_url: url: 'http://mirror.cc.columbia.edu/pub/software/apache//httpd/binaries/win32/httpd-2.2.25-win32-x86-no_ssl.msi' dest: 'C:\Users\Administrator\Downloads\httpd-2.2.25-win32-x86-no_ssl.msi' - name: Install MSI win_package: path: 'C:\Users\Administrator\Downloads\httpd-2.2.25-win32-x86-no_ssl.msi' state: present ================================================ FILE: windows/ping.yml ================================================ --- # This playbook uses the win_ping module to test connectivity to Windows hosts - name: Ping hosts: all tasks: - name: ping win_ping: ================================================ FILE: windows/run-powershell.yml ================================================ --- # This playbook tests the script module on Windows hosts - name: Run powershell script hosts: all gather_facts: false tasks: - name: Run powershell script script: files/helloworld.ps1 ================================================ FILE: windows/test.yml ================================================ --- - name: test raw module hosts: all tasks: - name: run ipconfig raw: ipconfig register: ipconfig - debug: var=ipconfig - name: test stat module hosts: windows tasks: - name: test stat module on file win_stat: path="C:/Windows/win.ini" register: stat_file - debug: var=stat_file - name: check stat_file result assert: that: - "stat_file.stat.exists" - "not stat_file.stat.isdir" - "stat_file.stat.size > 0" - "stat_file.stat.md5" ================================================ FILE: windows/wamp_haproxy/demo-aws-wamp-launch.yml ================================================ --- #Provision some instances: - hosts: localhost connection: local gather_facts: False vars_files: - group_vars/all tasks: - name: Launch webserver instances ec2: > access_key="{{ ec2_access_key }}" secret_key="{{ ec2_secret_key }}" keypair="{{ ec2_keypair }}" group="{{ ec2_security_group }}" type="{{ ec2_instance_type }}" image="ami-0d789266" region="{{ ec2_region }}" instance_tags="{'ansible_group':'windows_webservers', 'type':'{{ ec2_instance_type }}', 'group':'{{ ec2_security_group }}', 'Name':'demo_''{{ tower_user_name }}'}" count="{{ ec2_instance_count }}" wait=true register: ec2 tags: - web - name: Launch database instance ec2: > access_key="{{ ec2_access_key }}" secret_key="{{ ec2_secret_key }}" keypair="{{ ec2_keypair }}" group="{{ ec2_security_group }}" type="{{ ec2_instance_type }}" image="ami-17d66f7c" region="{{ ec2_region }}" instance_tags="{'ansible_group':'windows_dbservers', 'type':'{{ ec2_instance_type }}', 'group':'{{ ec2_security_group }}', 'Name':'demo_''{{ tower_user_name }}'}" count="1" wait=true register: ec2 tags: - db - name: Wait for WinRM to come up local_action: wait_for host={{ item.public_dns_name }} port=5986 delay=60 timeout=320 state=started with_items: ec2.instances tags: - web - db ================================================ FILE: windows/wamp_haproxy/group_vars/all ================================================ --- ec2_access_key: ec2_secret_key: ec2_region: us-east-1 ec2_zone: ec2_image: ami-bc8131d4 ec2_instance_type: m1.small ec2_keypair: djohnson ec2_security_group: default ec2_instance_count: 3 tower_user_name: admin ================================================ FILE: windows/wamp_haproxy/group_vars/windows_dbservers ================================================ --- # The variables file used by the playbooks in the dbservers group. # These don't have to be explicitly imported by vars_files: they are autopopulated. sql_port: 3306 dbuser: root dbname: foodb upassword: abc ================================================ FILE: windows/wamp_haproxy/group_vars/windows_webservers ================================================ --- # Variables for the web server configuration # Ethernet interface on which the web server should listen. # Defaults to the first interface. Change this to: # # iface: eth1 # # ...to override. # iface: '{{ ansible_default_ipv4.interface }}' # this is the repository that holds our sample webapp repository: https://github.com/bennojoy/mywebapp.git # this is the sha1sum of V5 of the test webapp. webapp_version: 351e47276cc66b018f4890a04709d4cc3d3edb0d ================================================ FILE: windows/wamp_haproxy/roles/elb/tasks/main.yml ================================================ --- # This role creates the AWS ELB and configures it. - name: Create the ELB in AWS ec2_elb_lb: name: "ansible-windows-demo-lb" state: present region: us-east-1 zones: - us-east-1b - us-east-1d - us-east-1e listeners: - protocol: http # options are http, https, ssl, tcp load_balancer_port: 80 instance_port: 80 ================================================ FILE: windows/wamp_haproxy/roles/iis/tasks/main.yml ================================================ --- # This playbook installs and enables IIS on Windows hosts - name: Install IIS win_feature: name: "Web-Server" state: present restart: yes include_sub_features: yes include_management_tools: yes ================================================ FILE: windows/wamp_haproxy/roles/mssql/files/create-db.ps1 ================================================ # Create the database set-psdebug -strict $error[0]|format-list -force [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null $srv = new-Object Microsoft.SqlServer.Management.Smo.Server("(local)") $db = New-Object Microsoft.SqlServer.Management.Smo.Database($srv, "Ansible Demo DB") $db.Create() ================================================ FILE: windows/wamp_haproxy/roles/mssql/tasks/main.yml ================================================ --- # This role will create the DB for MS SQL #- name: Copy the database creation script # win_copy: src=create-db.ps1 dest=c:\create-db.ps1 - name: Create Application Database script: "create-db.ps1" ================================================ FILE: windows/wamp_haproxy/roles/web/tasks/main.yml ================================================ --- # This playbook uses the win_get_url module to download a simple HTML file for IIS - name: Download simple web site to 'C:\inetpub\wwwroot\ansible.html' win_get_url: url: 'https://raw.githubusercontent.com/thisdavejohnson/mywebapp/master/index.html' dest: 'C:\inetpub\wwwroot\ansible.html' ================================================ FILE: windows/wamp_haproxy/rolling_update.yml ================================================ --- # This playbook does a rolling update for all webservers serially (one at a time). # Change the value of serial: to adjust the number of server to be updated. # # The three roles that apply to the webserver hosts will be applied: web - hosts: tag_ansible_group_windows_webservers serial: 1 gather_facts: False connection: winrm vars: ansible_ssh_port : 5986 # These are the tasks to run before applying updates: pre_tasks: - name: Remove host from load balancing pool local_action: module: ec2_elb region: us-east-1 instance_id: "{{ ec2_id }}" ec2_elbs: "ansible-windows-demo-lb" wait_timeout: 330 state: 'absent' roles: # - iis - web # These tasks run after the roles: post_tasks: - name: Wait for webserver to come up local_action: wait_for host={{ inventory_hostname }} port=80 state=started timeout=80 - name: Add host to load balancing pool local_action: module: ec2_elb region: us-east-1 instance_id: "{{ ec2_id }}" ec2_elbs: "ansible-windows-demo-lb" wait_timeout: 330 state: 'present' ================================================ FILE: windows/wamp_haproxy/site.yml ================================================ --- ## This playbook deploys the whole application stack in this site. # Configure and deploy database servers. - hosts: tag_ansible_group_windows_dbservers connection: winrm vars: ansible_ssh_port : 5986 roles: - mssql tags: - db # Configure and deploy the web servers. Note that we include two roles here, # the 'base-apache' role which simply sets up Apache, and 'web' which includes # our example web application. - hosts: tag_ansible_group_windows_webservers connection: winrm vars: ansible_ssh_port : 5986 roles: - iis - web tags: - web # Configure and deploy the load balancer(s). - hosts: localhost connection: local gather_facts: False roles: - elb tags: - lb # Add the webservers to the load balancer(s) - hosts: tag_ansible_group_windows_webservers connection: winrm gather_facts: False vars: ansible_ssh_port : 5986 tasks: - name: Wait for webserver to come up local_action: wait_for host={{ inventory_hostname }} port=80 state=started timeout=80 - name: Add host to load balancing pool local_action: module: ec2_elb region: us-east-1 instance_id: "{{ ec2_id }}" ec2_elbs: "ansible-windows-demo-lb" wait_timeout: 330 state: 'present' tags: - lb ================================================ FILE: wordpress-nginx/LICENSE.md ================================================ Copyright (C) 2013 AnsibleWorks, Inc. This work is licensed under the Creative Commons Attribution 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/deed.en_US. ================================================ FILE: wordpress-nginx/README.md ================================================ ## WordPress+Nginx+PHP-FPM Deployment - Requires Ansible 1.2 or newer - Expects CentOS/RHEL 6.x hosts These playbooks deploy a simple all-in-one configuration of the popular WordPress blogging platform and CMS, frontend by the Nginx web server and the PHP-FPM process manager. To use, copy the `hosts.example` file to `hosts` and edit the `hosts` inventory file to include the names or URLs of the servers you want to deploy. Then run the playbook, like this: ansible-playbook -i hosts site.yml The playbooks will configure MySQL, WordPress, Nginx, and PHP-FPM. When the run is complete, you can hit access server to begin the WordPress configuration. ### Ideas for Improvement Here are some ideas for ways that these playbooks could be extended: - Parameterize the WordPress deployment to handle multi-site configurations. - Separate the components (PHP-FPM, MySQL, Nginx) onto separate hosts and handle the configuration appropriately. - Handle WordPress upgrades automatically. We would love to see contributions and improvements, so please fork this repository on GitHub and send us your changes via pull requests. ================================================ FILE: wordpress-nginx/group_vars/all ================================================ --- # Which version of WordPress to deploy wp_version: 4.2.4 wp_sha256sum: 42ca594afc709cbef8528a6096f5a1efe96dcf3164e7ce321e87d57ae015cc82 # These are the WordPress database settings wp_db_name: wordpress wp_db_user: wordpress wp_db_password: secret # You shouldn't need to change this. mysql_port: 3306 # This is used for the nginx server configuration, but access to the # WordPress site is not restricted by a named host. server_hostname: www.example.com # Disable All Updates # By default automatic updates are enabled, set this value to true to disable all automatic updates auto_up_disable: false #Define Core Update Level #true = Development, minor, and major updates are all enabled #false = Development, minor, and major updates are all disabled #minor = Minor updates are enabled, development, and major updates are disabled core_update_level: true ================================================ FILE: wordpress-nginx/hosts.example ================================================ [wordpress-server] webserver2 ================================================ FILE: wordpress-nginx/roles/common/files/RPM-GPG-KEY-EPEL-6 ================================================ -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.5 (GNU/Linux) mQINBEvSKUIBEADLGnUj24ZVKW7liFN/JA5CgtzlNnKs7sBg7fVbNWryiE3URbn1 JXvrdwHtkKyY96/ifZ1Ld3lE2gOF61bGZ2CWwJNee76Sp9Z+isP8RQXbG5jwj/4B M9HK7phktqFVJ8VbY2jfTjcfxRvGM8YBwXF8hx0CDZURAjvf1xRSQJ7iAo58qcHn XtxOAvQmAbR9z6Q/h/D+Y/PhoIJp1OV4VNHCbCs9M7HUVBpgC53PDcTUQuwcgeY6 pQgo9eT1eLNSZVrJ5Bctivl1UcD6P6CIGkkeT2gNhqindRPngUXGXW7Qzoefe+fV QqJSm7Tq2q9oqVZ46J964waCRItRySpuW5dxZO34WM6wsw2BP2MlACbH4l3luqtp Xo3Bvfnk+HAFH3HcMuwdaulxv7zYKXCfNoSfgrpEfo2Ex4Im/I3WdtwME/Gbnwdq 3VJzgAxLVFhczDHwNkjmIdPAlNJ9/ixRjip4dgZtW8VcBCrNoL+LhDrIfjvnLdRu vBHy9P3sCF7FZycaHlMWP6RiLtHnEMGcbZ8QpQHi2dReU1wyr9QgguGU+jqSXYar 1yEcsdRGasppNIZ8+Qawbm/a4doT10TEtPArhSoHlwbvqTDYjtfV92lC/2iwgO6g YgG9XrO4V8dV39Ffm7oLFfvTbg5mv4Q/E6AWo/gkjmtxkculbyAvjFtYAQARAQAB tCFFUEVMICg2KSA8ZXBlbEBmZWRvcmFwcm9qZWN0Lm9yZz6JAjYEEwECACAFAkvS KUICGw8GCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRA7Sd8qBgi4lR/GD/wLGPv9 qO39eyb9NlrwfKdUEo1tHxKdrhNz+XYrO4yVDTBZRPSuvL2yaoeSIhQOKhNPfEgT 9mdsbsgcfmoHxmGVcn+lbheWsSvcgrXuz0gLt8TGGKGGROAoLXpuUsb1HNtKEOwP Q4z1uQ2nOz5hLRyDOV0I2LwYV8BjGIjBKUMFEUxFTsL7XOZkrAg/WbTH2PW3hrfS WtcRA7EYonI3B80d39ffws7SmyKbS5PmZjqOPuTvV2F0tMhKIhncBwoojWZPExft HpKhzKVh8fdDO/3P1y1Fk3Cin8UbCO9MWMFNR27fVzCANlEPljsHA+3Ez4F7uboF p0OOEov4Yyi4BEbgqZnthTG4ub9nyiupIZ3ckPHr3nVcDUGcL6lQD/nkmNVIeLYP x1uHPOSlWfuojAYgzRH6LL7Idg4FHHBA0to7FW8dQXFIOyNiJFAOT2j8P5+tVdq8 wB0PDSH8yRpn4HdJ9RYquau4OkjluxOWf0uRaS//SUcCZh+1/KBEOmcvBHYRZA5J l/nakCgxGb2paQOzqqpOcHKvlyLuzO5uybMXaipLExTGJXBlXrbbASfXa/yGYSAG iVrGz9CE6676dMlm8F+s3XXE13QZrXmjloc6jwOljnfAkjTGXjiB7OULESed96MR XtfLk0W5Ab9pd7tKDR6QHI7rgHXfCopRnZ2VVQ== =V/6I -----END PGP PUBLIC KEY BLOCK----- ================================================ FILE: wordpress-nginx/roles/common/files/epel.repo ================================================ [epel] name=Extra Packages for Enterprise Linux 6 - $basearch #baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch failovermethod=priority enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 [epel-debuginfo] name=Extra Packages for Enterprise Linux 6 - $basearch - Debug #baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch/debug mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-6&arch=$basearch failovermethod=priority enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 gpgcheck=1 [epel-source] name=Extra Packages for Enterprise Linux 6 - $basearch - Source #baseurl=http://download.fedoraproject.org/pub/epel/6/SRPMS mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-6&arch=$basearch failovermethod=priority enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 gpgcheck=1 ================================================ FILE: wordpress-nginx/roles/common/files/iptables-save ================================================ # {{ ansible_managed }} *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [37:13960] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT ================================================ FILE: wordpress-nginx/roles/common/handlers/main.yml ================================================ --- - name: restart iptables service: name=iptables state=restarted ================================================ FILE: wordpress-nginx/roles/common/tasks/main.yml ================================================ --- - name: Install libselinux-python yum: name=libselinux-python state=present - name: Reload ansible_facts setup: - name: Copy the EPEL repository definition copy: src=epel.repo dest=/etc/yum.repos.d/epel.repo - name: Create the GPG key for EPEL copy: src=RPM-GPG-KEY-EPEL-6 dest=/etc/pki/rpm-gpg - name: Set up iptables rules copy: src=iptables-save dest=/etc/sysconfig/iptables notify: restart iptables ================================================ FILE: wordpress-nginx/roles/mysql/handlers/main.yml ================================================ --- - name: restart mysql service: name=mysqld state=restarted ================================================ FILE: wordpress-nginx/roles/mysql/tasks/main.yml ================================================ --- - name: Install Mysql package yum: name={{ item }} state=present with_items: - mysql-server - MySQL-python - libselinux-python - libsemanage-python - name: Configure SELinux to start mysql on any port seboolean: name=mysql_connect_any state=true persistent=yes when: ansible_selinux.status == "enabled" - name: Create Mysql configuration file template: src=my.cnf.j2 dest=/etc/my.cnf notify: - restart mysql - name: Start Mysql Service service: name=mysqld state=started enabled=yes ================================================ FILE: wordpress-nginx/roles/mysql/templates/my.cnf.j2 ================================================ [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 port={{ mysql_port }} [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid ================================================ FILE: wordpress-nginx/roles/nginx/handlers/main.yml ================================================ --- - name: restart nginx service: name=nginx state=restarted enabled=yes ================================================ FILE: wordpress-nginx/roles/nginx/tasks/main.yml ================================================ --- - name: Install nginx yum: name=nginx state=present - name: Copy nginx configuration for wordpress template: src=default.conf dest=/etc/nginx/conf.d/default.conf notify: restart nginx ================================================ FILE: wordpress-nginx/roles/nginx/templates/default.conf ================================================ server { listen 80 default_server; server_name {{ server_hostname }}; root /srv/wordpress/ ; client_max_body_size 64M; # Deny access to any files with a .php extension in the uploads directory location ~* /(?:uploads|files)/.*\.php$ { deny all; } location / { index index.php index.html index.htm; try_files $uri $uri/ /index.php?$args; } location ~* \.(gif|jpg|jpeg|png|css|js)$ { expires max; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_index index.php; fastcgi_pass unix:/var/run/php-fpm/wordpress.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } ================================================ FILE: wordpress-nginx/roles/php-fpm/handlers/main.yml ================================================ --- - name: restart php-fpm service: name=php-fpm state=restarted ================================================ FILE: wordpress-nginx/roles/php-fpm/tasks/main.yml ================================================ --- - name: Install php-fpm and deps yum: name={{ item }} state=present with_items: - php - php-fpm - php-enchant - php-IDNA_Convert - php-mbstring - php-mysql - php-PHPMailer - php-process - php-simplepie - php-xml - name: Disable default pool command: mv /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.disabled creates=/etc/php-fpm.d/www.disabled notify: restart php-fpm - name: Copy php-fpm configuration template: src=wordpress.conf dest=/etc/php-fpm.d/ notify: restart php-fpm ================================================ FILE: wordpress-nginx/roles/php-fpm/templates/wordpress.conf ================================================ [wordpress] listen = /var/run/php-fpm/wordpress.sock listen.owner = nginx listen.group = nginx listen.mode = 0660 user = wordpress group = wordpress pm = dynamic pm.max_children = 10 pm.start_servers = 1 pm.min_spare_servers = 1 pm.max_spare_servers = 3 pm.max_requests = 500 chdir = /srv/wordpress/ php_admin_value[open_basedir] = /srv/wordpress/:/tmp ================================================ FILE: wordpress-nginx/roles/wordpress/tasks/main.yml ================================================ --- - name: Download WordPress get_url: url=http://wordpress.org/wordpress-{{ wp_version }}.tar.gz dest=/srv/wordpress-{{ wp_version }}.tar.gz sha256sum="{{ wp_sha256sum }}" - name: Extract archive unarchive: creates: /srv/wordpress src: /srv/wordpress-{{ wp_version }}.tar.gz dest: /srv/wordpress - name: Add group "wordpress" group: name=wordpress - name: Add user "wordpress" user: name=wordpress group=wordpress home=/srv/wordpress/ - name: Fetch random salts for WordPress config get_url: url: https://api.wordpress.org/secret-key/1.1/salt/ register: "wp_salt" become: no become_method: sudo changed_when: true delegate_to: localhost - name: Create WordPress database mysql_db: name={{ wp_db_name }} state=present - name: Create WordPress database user mysql_user: name={{ wp_db_user }} password={{ wp_db_password }} priv={{ wp_db_name }}.*:ALL host='localhost' state=present - name: Copy WordPress config file template: src=wp-config.php dest=/srv/wordpress/ - name: Change ownership of WordPress installation file: path=/srv/wordpress/ owner=wordpress group=wordpress state=directory recurse=yes setype=httpd_sys_content_t - name: Start php-fpm Service service: name=php-fpm state=started enabled=yes ================================================ FILE: wordpress-nginx/roles/wordpress/templates/wp-config.php ================================================