From 8eb322709dc7ba28572a800ca501534aa3100154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Mass=C3=A9?= Date: Wed, 3 May 2017 11:40:40 +0200 Subject: [PATCH] Initial commit --- .gitignore | 2 + LICENSE | 21 +++++ README.md | 13 +++ allinone.hosts | 64 +++++++++++++++ allinone.yml | 14 ++++ ansible | 86 ++++++++++++++++++++ ansible.cfg | 3 + bootstrap.yml | 8 ++ group_vars/all | 7 ++ roles/base/handlers/main.yml | 4 + roles/base/tasks/main.yml | 64 +++++++++++++++ roles/bootstrap/tasks/main.yml | 30 +++++++ roles/bootstrap/templates/sudoers | 3 + roles/docker/tasks/main.yml | 65 +++++++++++++++ roles/docker/templates/docker-storage-setup | 9 ++ roles/iptables/tasks/main.yml | 11 +++ roles/name-resolution/tasks/main.yml | 48 +++++++++++ roles/name-resolution/templates/dnsmasq.conf | 28 +++++++ roles/name-resolution/templates/hosts | 9 ++ roles/name-resolution/templates/resolv.conf | 5 ++ roles/openshift-prereq/tasks/main.yml | 43 ++++++++++ roles/register-rhn/tasks/main.yml | 25 ++++++ 22 files changed, 562 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 allinone.hosts create mode 100644 allinone.yml create mode 100755 ansible create mode 100644 ansible.cfg create mode 100644 bootstrap.yml create mode 100644 group_vars/all create mode 100644 roles/base/handlers/main.yml create mode 100644 roles/base/tasks/main.yml create mode 100644 roles/bootstrap/tasks/main.yml create mode 100644 roles/bootstrap/templates/sudoers create mode 100644 roles/docker/tasks/main.yml create mode 100644 roles/docker/templates/docker-storage-setup create mode 100644 roles/iptables/tasks/main.yml create mode 100644 roles/name-resolution/tasks/main.yml create mode 100644 roles/name-resolution/templates/dnsmasq.conf create mode 100644 roles/name-resolution/templates/hosts create mode 100644 roles/name-resolution/templates/resolv.conf create mode 100644 roles/openshift-prereq/tasks/main.yml create mode 100644 roles/register-rhn/tasks/main.yml 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