commit 8eb322709dc7ba28572a800ca501534aa3100154 Author: Nicolas Massé Date: Wed May 3 11:40:40 2017 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2cc9421 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +admin.pub +*.retry diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3153fe0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Nicolas MASSE + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..38b594c --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# OpenShift-Lab +This project is the Ansible Playbook to install OpenShift in a Lab Environment. + +## Preparation work + +1. Review \*.hosts and change hostnames to target your Virtual Machines + +## Example + +‘‘‘ +./ansible bootstrap vm.openshift.test +./ansible play allinone +’’’ diff --git a/allinone.hosts b/allinone.hosts new file mode 100644 index 0000000..6c5f1b1 --- /dev/null +++ b/allinone.hosts @@ -0,0 +1,64 @@ +# +# Variables used by my playbook +# +[allinone:vars] +lab_dns_suffix=openshift.test +lab_openshift_version=3.5 +docker_storage_vg=docker + +[allinone:children] +masters + +# +# Shared variables used by both openshift-ansible and my playbook +# +[all:vars] +# Default route suffix +openshift_master_default_subdomain=app.openshift.test + +[masters] +openshift35.openshift.test + +[nodes] +openshift35.openshift.test openshift_node_labels='{ "workload": "infra", "workload": "app" }' + +# +# The rest is used only by the OpenShift installer playbook +# +[OSEv3:children] +masters +nodes + +[OSEv3:vars] +# Yes, we need to use sudo +ansible_become=yes + +# what to install +deployment_type=openshift-enterprise + +# New installation method : everything in containers ! +contenairized=true + +# Clustering method +openshift_master_cluster_method=native + +# Bypass Registry Security Checks +openshift_docker_insecure_registries=172.30.0.0/16 + +# Disable any authentication +openshift_master_identity_providers=[{'name': 'allow_all', 'login': 'true', 'challenge': 'true', 'kind': 'AllowAllPasswordIdentityProvider'}] + +# default project node selector +osm_default_node_selector='workload=app' + +# Make sure NTP is enabled +openshift_clock_enabled=true + +# default router +openshift_hosted_router_selector='workload=infra' + +# Do not create the default project "my-project" +openshift_additional_projects={} + +# Enable the multitenant SDN +os_sdn_network_plugin_name='redhat/openshift-ovs-multitenant' diff --git a/allinone.yml b/allinone.yml new file mode 100644 index 0000000..ddaab51 --- /dev/null +++ b/allinone.yml @@ -0,0 +1,14 @@ +--- + + - name: Prepare an "All-in-one" VM for OpenShift + hosts: allinone + become: yes + roles: + - { name: 'base', tags: 'base' } + - { name: 'iptables', tags: 'iptables' } + - { name: 'name-resolution', tags: 'name-resolution' } + - { name: 'docker', tags: 'docker' } + - { name: 'openshift-prereq', tags: 'openshift-prereq' } + + # Launch the OpenShift Installer Playbook + - include: "./openshift-ansible/playbooks/byo/config.yml" diff --git a/ansible b/ansible new file mode 100755 index 0000000..c899557 --- /dev/null +++ b/ansible @@ -0,0 +1,86 @@ +#!/bin/bash + +options="" +ssh_key="$HOME/.ssh/id_rsa" +initial_user="root" + +target="$1" +shift +case "$target" in + "bootstrap") + if [ -z "$1" ]; then + echo "Please specify the target host(s) !" + exit 1 + fi + echo "Bootstraping $@..." + echo + echo -n "Please enter the initial $initial_user password: " + read -s password + echo # Add a Line Feed since the "read -s" do not output it ! + + # Ask for Red Hat Network credentials + if [ -z "$RHN_LOGIN" ]; then + echo -n "Please enter your RHN login: " + read rhn_login + export RHN_LOGIN="$rhn_login" + fi + if [ -z "$RHN_PASSWORD" ]; then + echo -n "Please enter your RHN password: " + read -s rhn_password + export RHN_PASSWORD="$rhn_password" + echo # Add a Line Feed since the "read -s" do not output it ! + fi + if [ -z "$RHN_POOLID" ]; then + echo -n "Please enter your RHN Pool ID: " + read rhn_poolid + export RHN_POOLID="$rhn_poolid" + fi + echo + echo + + # Pre-register SSH Host Keys + for host; do + echo "Connecting to $host to register the SSH Host Key !" + LC_ALL=C sshpass -p "$password" ssh -i $ssh_key -o StrictHostKeyChecking=no "$initial_user@$host" /bin/true + done + + # Setup authentication + if [ -n "$password" ]; then + options="$options -e ansible_ssh_pass=$password" + else + options="$options -e ansible_ssh_private_key_file=$ssh_key" + fi + + # Setup the ssh user + options="$options -e ansible_ssh_user=$initial_user " + + # Generate an inventory file "on the fly" + echo "[bootstrap]" > "bootstrap.hosts" + for host; do + echo -e "$host" + done >> "bootstrap.hosts" + + ansible-playbook -i "bootstrap.hosts" $options bootstrap.yml + + rm -f "bootstrap.hosts" + ;; + "play") + if [ -z "$1" ]; then + echo "Please specify the playbook to run !" + exit 1 + fi + + playbook="$1" + shift + + ansible-playbook -i "$playbook.hosts" $options "$@" $playbook.yml + ;; + *) + echo "Usage: $0 {bootstrap|play} [options]" + echo + echo "Samples: " + echo " $0 bootstrap machine.example.com" + echo " $0 play allinone" + exit 1 + ;; +esac diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..ceb1027 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,3 @@ +[defaults] +# This is needed by the openshift-ansible installer +deprecation_warnings=False diff --git a/bootstrap.yml b/bootstrap.yml new file mode 100644 index 0000000..74bf96f --- /dev/null +++ b/bootstrap.yml @@ -0,0 +1,8 @@ +--- + + - name: Bootstrap one or more RHEL7 nodes + hosts: bootstrap + become: no + roles: + - bootstrap + - register-rhn diff --git a/group_vars/all b/group_vars/all new file mode 100644 index 0000000..5768d69 --- /dev/null +++ b/group_vars/all @@ -0,0 +1,7 @@ +--- + timezone: Europe/Paris + ansible_python_interpreter: /usr/bin/python2 + ansible_ssh_user: redhat + ansible_ssh_private_key_file: "{{ lookup('env','HOME') }}/.ssh/id_rsa" + ansible_ssh_public_key: "{{ lookup('file', ansible_ssh_private_key_file + '.pub' ) }}" + ansible_connection: ssh diff --git a/roles/base/handlers/main.yml b/roles/base/handlers/main.yml new file mode 100644 index 0000000..1e9c2c7 --- /dev/null +++ b/roles/base/handlers/main.yml @@ -0,0 +1,4 @@ +--- + + - name: restart sshd + service: name=sshd state=reloaded diff --git a/roles/base/tasks/main.yml b/roles/base/tasks/main.yml new file mode 100644 index 0000000..e5194e4 --- /dev/null +++ b/roles/base/tasks/main.yml @@ -0,0 +1,64 @@ +--- + - name: This module has only been tested on RHEL 7.3 x64 + assert: + that: + - "ansible_userspace_bits == '64'" + - "ansible_os_family == 'RedHat'" + - "ansible_distribution_version == '7.3'" + + - name: Tell SSHD not to use DNS + lineinfile: dest=/etc/ssh/sshd_config regexp="^#* *UseDNS +" line="UseDNS no" + notify: restart sshd + tags: config + + - name: Tell SSHD to forbid root accesses + lineinfile: dest=/etc/ssh/sshd_config regexp="^#* *PermitRootLogin +" line="PermitRootLogin no" + notify: restart sshd + tags: config + + - name: Tell SSHD to forbid password accesses + lineinfile: dest=/etc/ssh/sshd_config regexp="^#* *PasswordAuthentication +" line="PasswordAuthentication no" + notify: restart sshd + tags: config + + - name: Install some software + yum: name={{ item }} state=installed + with_items: + - vim-enhanced + - tmux + - unzip + - tcpdump + - telnet + - strace + - man-pages + - man + - iptraf + - wget + - openssh-clients + tags: rpm + + - name: Install Open-VM tools + yum: name=open-vm-tools state=installed + tags: rpm + + - name: Fix /etc/environment to include PATH + lineinfile: dest=/etc/environment regexp="^PATH=" line="PATH=/bin:/usr/bin:/sbin:/usr/sbin" + tags: config + + - name: Persist the hostname + lineinfile: dest=/etc/sysconfig/network regexp="^HOSTNAME=" line="HOSTNAME={{ inventory_hostname_short }}" + tags: + - config + - dns + + - name: Set the hostname + command: hostnamectl set-hostname {{ inventory_hostname_short }} --static + tags: + - config + - dns + + - name: Ensure consistent locale across systems (1/2) + lineinfile: dest=/etc/locale.conf regexp="^LANG=" line="LANG=en_US.utf8" + + - name: Ensure consistent locale across systems (2/2) + lineinfile: dest=/etc/locale.conf line="LC_CTYPE=en_US.utf8" diff --git a/roles/bootstrap/tasks/main.yml b/roles/bootstrap/tasks/main.yml new file mode 100644 index 0000000..aea1ef2 --- /dev/null +++ b/roles/bootstrap/tasks/main.yml @@ -0,0 +1,30 @@ +--- + + - name: This module has only been tested on RHEL and CentOS + assert: + that: + - "ansible_os_family == 'RedHat' or ansible_os_family == 'CentOS'" + + - name: Create user RedHat + user: name=redhat group=users groups=users,wheel state=present comment="RedHat privileged user" password="*" + tags: + - bootstrap + - user + + - name: Set SSH key for root + authorized_key: user=root key="{{ ansible_ssh_public_key }}" manage_dir=yes + tags: + - bootstrap + - user + + - name: Set SSH key for user RedHat + authorized_key: user=redhat key="{{ ansible_ssh_public_key }}" manage_dir=yes + tags: + - bootstrap + - user + + - name: Configure SUDO + template: src=sudoers dest=/etc/sudoers owner=root group=root mode=0440 validate="/usr/sbin/visudo -cf %s" + tags: + - bootstrap + - config diff --git a/roles/bootstrap/templates/sudoers b/roles/bootstrap/templates/sudoers new file mode 100644 index 0000000..697aecc --- /dev/null +++ b/roles/bootstrap/templates/sudoers @@ -0,0 +1,3 @@ +# {{ ansible_managed }} +%wheel ALL=(ALL) NOPASSWD: ALL +root ALL=(ALL) NOPASSWD: ALL diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml new file mode 100644 index 0000000..407cadc --- /dev/null +++ b/roles/docker/tasks/main.yml @@ -0,0 +1,65 @@ +--- + + - name: Check for mandatory variables required by this playbook + fail: + msg: "This playbook requires {{item}} to be set." + when: "{{ item }} is not defined or {{ item }} == ''" + with_items: + - docker_storage_vg + tags: docker-storage + + - name: Make sure the extra repos is enabled + command: subscription-manager repos --enable rhel-7-server-extras-rpms + when: "ansible_os_family == 'RedHat'" + tags: rpm + + - name: Install Docker + yum: name=docker state=installed + tags: rpm + + - name: Start docker + service: name=docker state=started + tags: docker-storage + + - name: Determine if docker storage driver == devicemapper + shell: docker info | grep 'Storage Driver:.*devicemapper' + register: correct_storage_driver + changed_when: false + ignore_errors: yes + + - debug: + var: correct_storage_driver + + - name: set docker_storage_setup_needs_to_run + set_fact: + docker_storage_setup_needs_to_run: '{{ correct_storage_driver.rc == 1 }}' + tags: docker-storage + + - name: stop docker + service: + name: docker + state: stopped + when: docker_storage_setup_needs_to_run + tags: docker-storage + + - name: delete /var/lib/docker + command: rm -rf /var/lib/docker + when: docker_storage_setup_needs_to_run + tags: docker-storage + + - name: Configure docker-storage-setup to use LVM + template: dest=/etc/sysconfig/docker-storage-setup src=docker-storage-setup + register: docker-storage-setup + when: docker_storage_setup_needs_to_run + tags: docker-storage + + - name: Run docker-storage-setup + command: docker-storage-setup + environment: + PATH: /bin:/usr/bin:/sbin:/usr/sbin # Fix buggy PATH on RHEL7 + when: docker_storage_setup_needs_to_run + tags: docker-storage + + - name: Start Docker + service: name=docker state=started enabled=yes + tags: docker-storage diff --git a/roles/docker/templates/docker-storage-setup b/roles/docker/templates/docker-storage-setup new file mode 100644 index 0000000..8519c7f --- /dev/null +++ b/roles/docker/templates/docker-storage-setup @@ -0,0 +1,9 @@ +STORAGE_DRIVER=devicemapper +DOCKER_ROOT_VOLUME=yes + +{% if docker_storage_disk is defined %} +DEVS={{ docker_storage_disk }} +{% endif %} +{% if docker_storage_vg is defined %} +VG={{ docker_storage_vg }} +{% endif %} diff --git a/roles/iptables/tasks/main.yml b/roles/iptables/tasks/main.yml new file mode 100644 index 0000000..3d2c277 --- /dev/null +++ b/roles/iptables/tasks/main.yml @@ -0,0 +1,11 @@ +--- + + - name: Install iptables-services + yum: name=iptables-services state=installed + tags: rpm + + - name: Disable firewalld + service: name=firewalld state=stopped enabled=no + + - name: Enable iptables + service: name=iptables state=started enabled=yes diff --git a/roles/name-resolution/tasks/main.yml b/roles/name-resolution/tasks/main.yml new file mode 100644 index 0000000..f161c37 --- /dev/null +++ b/roles/name-resolution/tasks/main.yml @@ -0,0 +1,48 @@ +--- + + - name: Check for mandatory variables required by this playbook + fail: + msg: "This playbook requires {{item}} to be set." + when: "{{ item }} is not defined or {{ item }} == ''" + with_items: + - lab_dns_suffix + - lab_route_suffix + + - name: Make sure each machine has an up-to-date /etc/hosts + template: dest=/etc/hosts src=hosts + tags: config + + - name: Install dnsmasq + yum: name=dnsmasq state=installed + when: "'name-server' in group_names" # Only on admin server + tags: rpm + + - name: Set dnsmasq config + template: src=dnsmasq.conf dest=/etc/dnsmasq.conf + when: "'name-server' in group_names" # Only on admin server + tags: config + + - name: Generate an /etc/hosts with all hosts + template: dest=/etc/hosts.dnsmasq src=hosts + when: "'name-server' in group_names" # Only on admin server + tags: config + + - name: Make sure dnsmasq daemon is enabled and started + service: name=dnsmasq state=started enabled=yes + when: "'name-server' in group_names" # Only on admin server + tags: config + + - name: Add an iptable rule to allow DNS queries from other hosts + lineinfile: dest=/etc/sysconfig/iptables line="-A INPUT -p udp --dport 53 -j ACCEPT" insertafter="-A INPUT -i lo -j ACCEPT" + when: "'name-server' in group_names" # Only on admin server + tags: iptables + + - name: Restart iptables + service: name=iptables enabled=yes state=restarted + when: "'name-server' in group_names" # Only on admin server + tags: iptables + + - name: Fix the /etc/resolv.conf of other hosts + template: dest=/etc/resolv.conf src=resolv.conf + when: "'name-server' in groups and 'name-server' not in group_names" # On all other nodes (if a name server has been setup) + tags: config diff --git a/roles/name-resolution/templates/dnsmasq.conf b/roles/name-resolution/templates/dnsmasq.conf new file mode 100644 index 0000000..0b066f1 --- /dev/null +++ b/roles/name-resolution/templates/dnsmasq.conf @@ -0,0 +1,28 @@ +# {{ ansible_managed }} + +domain-needed +bogus-priv +expand-hosts +log-queries +local-ttl=60 + +# Do not read the default /etc/hosts +no-hosts + +# But read this one... +addn-hosts=/etc/hosts.dnsmasq + +# Default suffix for all machines +domain={{ lab_dns_suffix }} + +# +# Wildcard DNS entries (see lab_route_suffix variable) +# +# note: will generate something like this : +# address=/app.openshift.test/192.168.23.20 +# +{% if 'lb' in groups %} +address=/{{ openshift_master_default_subdomain }}/{{ hostvars[groups['lb'][0]]['ansible_default_ipv4']['address'] }} +{% else %} +address=/{{ openshift_master_default_subdomain }}/{{ hostvars[groups['masters'][0]]['ansible_default_ipv4']['address'] }} +{% endif %} diff --git a/roles/name-resolution/templates/hosts b/roles/name-resolution/templates/hosts new file mode 100644 index 0000000..418d718 --- /dev/null +++ b/roles/name-resolution/templates/hosts @@ -0,0 +1,9 @@ +# {{ ansible_managed }} +127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 +::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 + +{% if "name-server" not in groups %} +{% for item in groups['all'] %} +{{ hostvars[item]['ansible_default_ipv4']['address'] }} {{ hostvars[item]['inventory_hostname']}} {{ hostvars[item]['inventory_hostname_short']}} +{% endfor %} +{% endif %} diff --git a/roles/name-resolution/templates/resolv.conf b/roles/name-resolution/templates/resolv.conf new file mode 100644 index 0000000..2b16196 --- /dev/null +++ b/roles/name-resolution/templates/resolv.conf @@ -0,0 +1,5 @@ +# {{ ansible_managed }} +search {{ lab_dns_suffix }} +{% for item in groups['name-server'] %} +nameserver {{ hostvars[item]['ansible_default_ipv4']['address'] }} +{% endfor %} diff --git a/roles/openshift-prereq/tasks/main.yml b/roles/openshift-prereq/tasks/main.yml new file mode 100644 index 0000000..58f671f --- /dev/null +++ b/roles/openshift-prereq/tasks/main.yml @@ -0,0 +1,43 @@ +--- + + - name: This module has only been tested on RHEL 7.3 x64 + assert: + that: + - "ansible_userspace_bits == '64'" + - "ansible_os_family == 'RedHat'" + - "ansible_distribution_version == '7.3'" + + - name: First, disable any repos (using subscription-manager) + command: subscription-manager repos --disable="*" + tags: rpm + + - name: Make sure mandatory repos are enabled + command: subscription-manager repos --enable {{ item }} + with_items: + - rhel-7-server-rpms + - rhel-7-server-optional-rpms + - rhel-7-server-extras-rpms + - rhel-7-server-ose-{{ lab_openshift_version }}-rpms + - rhel-7-fast-datapath-rpms # see https://access.redhat.com/solutions/3008401 + tags: rpm + + - name: Install nfs-utils + yum: name=nfs-utils state=installed + tags: rpm + + - name: Install bash-completion + yum: name=bash-completion state=installed + when: "'masters' in group_names" # Only on master server + tags: rpm + + - name: Install NetworkManager + yum: name=NetworkManager state=installed + tags: rpm + + - name: Install net-tools + yum: name=net-tools state=installed + tags: rpm + + - name: Install bind-utils + yum: name=bind-utils state=installed + tags: rpm diff --git a/roles/register-rhn/tasks/main.yml b/roles/register-rhn/tasks/main.yml new file mode 100644 index 0000000..6a2917b --- /dev/null +++ b/roles/register-rhn/tasks/main.yml @@ -0,0 +1,25 @@ +--- + - name: This module should only work on RHEL + assert: + that: + - "ansible_os_family == 'RedHat'" + + - name: Register this system on RHN + redhat_subscription: + state: present + username: "{{ lookup('env','RHN_LOGIN') }}" + password: "{{ lookup('env','RHN_PASSWORD') }}" + consumer_name: "{{ inventory_hostname }}" + autosubscribe: false + tags: rhn + +# +# To know which Pool ID you can use, run the following command on a registered host : +# +# sudo subscription-manager list --available --matches '*OpenShift*' +# + + - name: Attach the correct pool id to the new subscription + command: subscription-manager attach --pool={{ lookup('env','RHN_POOLID') }} + when: 'lookup("env","RHN_POOLID") != ""' + tags: rhn