From fa14b8c2182d55c7972360f6edcb46993d28c71c Mon Sep 17 00:00:00 2001
From: ericsysmin <eric.sysmin@gmail.com>
Date: Fri, 1 May 2020 19:16:48 -0700
Subject: [PATCH] gcloud role w/tests

---
 .ansible-lint                                 |  10 ++
 .github/workflows/gcloud.yml                  |  62 ++++++++++
 .yamllint                                     |  33 ++++++
 molecule/gcloud/Dockerfile.j2                 | 111 ++++++++++++++++++
 molecule/gcloud/archive_playbook.yml          |  15 +++
 molecule/gcloud/converge.yml                  |  23 ++++
 molecule/gcloud/files/override.conf           |   2 +
 molecule/gcloud/molecule.yml                  |  20 ++++
 molecule/gcloud/package_playbook.yml          |  13 ++
 molecule/gcloud/tests/test_default.py         |  20 ++++
 molecule/gcloud/verify.yml                    |   9 ++
 roles/gcloud/LICENSE                          |  21 ++++
 roles/gcloud/README.md                        |  60 ++++++++++
 roles/gcloud/defaults/main.yml                |  28 +++++
 roles/gcloud/meta/main.yml                    |  21 ++++
 .../gcloud/tasks/archive/archive_install.yml  |  50 ++++++++
 .../tasks/archive/command_completion.yml      |  32 +++++
 roles/gcloud/tasks/archive/main.yml           |  37 ++++++
 roles/gcloud/tasks/main.yml                   |  15 +++
 roles/gcloud/tasks/package/debian.yml         |  27 +++++
 roles/gcloud/tasks/package/main.yml           |   5 +
 roles/gcloud/tasks/package/redhat.yml         |  28 +++++
 roles/gcloud/vars/main.yml                    |   1 +
 23 files changed, 643 insertions(+)
 create mode 100644 .ansible-lint
 create mode 100644 .github/workflows/gcloud.yml
 create mode 100644 .yamllint
 create mode 100644 molecule/gcloud/Dockerfile.j2
 create mode 100644 molecule/gcloud/archive_playbook.yml
 create mode 100644 molecule/gcloud/converge.yml
 create mode 100644 molecule/gcloud/files/override.conf
 create mode 100644 molecule/gcloud/molecule.yml
 create mode 100644 molecule/gcloud/package_playbook.yml
 create mode 100644 molecule/gcloud/tests/test_default.py
 create mode 100644 molecule/gcloud/verify.yml
 create mode 100644 roles/gcloud/LICENSE
 create mode 100644 roles/gcloud/README.md
 create mode 100644 roles/gcloud/defaults/main.yml
 create mode 100644 roles/gcloud/meta/main.yml
 create mode 100644 roles/gcloud/tasks/archive/archive_install.yml
 create mode 100644 roles/gcloud/tasks/archive/command_completion.yml
 create mode 100644 roles/gcloud/tasks/archive/main.yml
 create mode 100644 roles/gcloud/tasks/main.yml
 create mode 100644 roles/gcloud/tasks/package/debian.yml
 create mode 100644 roles/gcloud/tasks/package/main.yml
 create mode 100644 roles/gcloud/tasks/package/redhat.yml
 create mode 100644 roles/gcloud/vars/main.yml

diff --git a/.ansible-lint b/.ansible-lint
new file mode 100644
index 0000000..c77c6a8
--- /dev/null
+++ b/.ansible-lint
@@ -0,0 +1,10 @@
+---
+parseable: true
+skip_list:
+  - ANSIBLE0010
+use_default_rules: true
+verbosity: 1
+exclude_paths:
+  - ./roles/gcp_http_lb/
+  - ./tests/
+  - ./plugins
diff --git a/.github/workflows/gcloud.yml b/.github/workflows/gcloud.yml
new file mode 100644
index 0000000..341fb85
--- /dev/null
+++ b/.github/workflows/gcloud.yml
@@ -0,0 +1,62 @@
+name: "google.cloud.gcloud"
+on:
+  push:
+    paths:
+      - 'roles/gcloud/**'
+      - '.github/workflows/gcloud.yml'
+      - 'molecule/gcloud/**'
+  pull_request:
+    paths:
+      - 'roles/gcloud/**'
+      - '.github/workflows/gcloud.yml'
+      - 'molecule/gcloud/**'
+jobs:
+  molecule:
+    runs-on: ubuntu-18.04
+    env:
+      PY_COLORS: 1
+      ANSIBLE_FORCE_COLOR: 1
+    strategy:
+      fail-fast: true
+      matrix:
+        molecule_playbook:
+          - archive_playbook.yml
+          - package_playbook.yml
+        molecule_distro:
+          - distro: centos:7
+            command: /usr/sbin/init
+          - distro: centos:8
+            command: /usr/sbin/init
+          - distro: ubuntu:16.04
+            command: /sbin/init
+          - distro: ubuntu:18.04
+            command: /lib/systemd/systemd
+          - distro: debian:9
+            command: /lib/systemd/systemd
+        collection_role:
+          - gcloud
+    steps:
+      - name: Check out code
+        uses: actions/checkout@v1
+        with:
+          path: ansible_collections/google/cloud
+
+      - name: Set up Python 3.8
+        uses: actions/setup-python@v1
+        with:
+          python-version: 3.8
+
+      - name: Install dependencies
+        run: |
+          sudo apt install docker
+          python -m pip install --upgrade pip
+          pip install molecule yamllint ansible-lint docker
+
+      - name: Run role test
+        run: >-
+          molecule --version &&
+          ansible --version &&
+          MOLECULE_COMMAND=${{ matrix.molecule_distro.command }}
+          MOLECULE_DISTRO=${{ matrix.molecule_distro.distro }}
+          MOLECULE_PLAYBOOK=${{ matrix.molecule_playbook }}
+          molecule --debug test -s ${{ matrix.collection_role }}
diff --git a/.yamllint b/.yamllint
new file mode 100644
index 0000000..8827676
--- /dev/null
+++ b/.yamllint
@@ -0,0 +1,33 @@
+---
+# Based on ansible-lint config
+extends: default
+
+rules:
+  braces:
+    max-spaces-inside: 1
+    level: error
+  brackets:
+    max-spaces-inside: 1
+    level: error
+  colons:
+    max-spaces-after: -1
+    level: error
+  commas:
+    max-spaces-after: -1
+    level: error
+  comments: disable
+  comments-indentation: disable
+  document-start: disable
+  empty-lines:
+    max: 3
+    level: error
+  hyphens:
+    level: error
+  indentation: disable
+  key-duplicates: enable
+  line-length: disable
+  new-line-at-end-of-file: disable
+  new-lines:
+    type: unix
+  trailing-spaces: disable
+  truthy: disable
diff --git a/molecule/gcloud/Dockerfile.j2 b/molecule/gcloud/Dockerfile.j2
new file mode 100644
index 0000000..5c2401c
--- /dev/null
+++ b/molecule/gcloud/Dockerfile.j2
@@ -0,0 +1,111 @@
+# Molecule managed
+
+{% if item.registry is defined %}
+FROM {{ item.registry.url }}/{{ item.image }}
+{% else %}
+FROM {{ item.image }}
+{% endif %}
+ENV container=docker
+
+{# Initial Package Installs and Container Prep #}
+{% if item.image.split(':', 1)[0] in ["ubuntu"] %}
+RUN apt-get update \
+  && apt-get install -y --no-install-recommends \
+     locales software-properties-common rsyslog systemd systemd-cron sudo \
+     iproute2
+RUN sed -i 's/^\($ModLoad imklog\)/#\1/' /etc/rsyslog.conf
+{% elif item.image.split(':', 1)[0] in ["debian"] %}
+RUN apt-get update \
+    && apt-get install -y --no-install-recommends \
+       sudo systemd systemd-sysv \
+       build-essential wget
+{% elif item.image.split(':', 1)[0] in ["centos"] %}
+{% if item.image in ["centos:7"] %}
+RUN yum makecache fast && yum -y install deltarpm \
+{% elif item.image in ["centos:8"] %}
+RUN yum makecache --timer \
+{% endif %}
+    && yum -y install epel-release \
+    && yum -y update \
+    && yum -y install sudo which
+{% endif %}
+
+
+{# Install of Python2 #}
+{% if item.image in ["ubuntu:16.04"] %}
+RUN apt-get update \
+    && apt-get install -y --no-install-recommends python-setuptools wget \
+    && wget https://bootstrap.pypa.io/get-pip.py \
+    && python get-pip.py
+{% elif item.image in ["debian:9"] %}
+RUN apt-get update \
+    && apt-get install -y --no-install-recommends libffi-dev libssl-dev \
+       python-pip python-dev python-setuptools python-wheel
+{% elif item.image in ["centos:7"] %}
+RUN yum -y install python-pip
+{% endif %}
+
+{# Install of Python3 #}
+{% if item.image in ["ubuntu:18.04", "ubuntu:20.04", "debian:10"] %}
+RUN apt-get update \
+    && apt-get install -y --no-install-recommends \
+       apt-utils python3-setuptools python3-pip
+{% endif %}
+{% if item.image in ["centos:8"] %}
+RUN yum -y install hostname python3 python3-pip
+{% endif %}
+
+{# Steps for cleanup #}
+{% if item.image.split(':', 1)[0] in ["ubuntu", "debian"] %}
+RUN rm -Rf /var/lib/apt/lists/* \
+    && rm -Rf /usr/share/doc && rm -Rf /usr/share/man \
+    && apt-get clean
+{% elif item.image.split(':', 1)[0] in ["centos"] %}
+RUN yum clean all
+{% endif %}
+
+{# Steps for clenaup of systemd #}
+{% if item.image in ["centos:7", "centos:8", "debian:9"] %}
+RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \
+  systemd-tmpfiles-setup.service ] || rm -f $i; done); \
+  rm -f /lib/systemd/system/multi-user.target.wants/*;\
+  rm -f /etc/systemd/system/*.wants/*;\
+  rm -f /lib/systemd/system/local-fs.target.wants/*; \
+  rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
+  rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
+  rm -f /lib/systemd/system/basic.target.wants/*;\
+  rm -f /lib/systemd/system/anaconda.target.wants/*; \
+  mkdir -p /run/systemd/system
+{% endif %}
+{% if item.image in ["ubuntu:18.04", "ubuntu:20.04"] %}
+# Remove unnecessary getty and udev targets that result in high CPU usage when using
+# multiple containers with Molecule (https://github.com/ansible/molecule/issues/1104)
+RUN rm -f /lib/systemd/system/systemd*udev* \
+  && rm -f /lib/systemd/system/getty.target
+{% endif %}
+
+
+{% if item.image in ["centos:7", "centos:8"] %}
+# Disable requiretty.
+RUN sed -i -e 's/^\(Defaults\s*requiretty\)/#--- \1/'  /etc/sudoers
+{% endif %}
+
+{% if item.image.split(':', 1)[0] not in ["centos", "debian"] %}
+# Fix potential UTF-8 errors with ansible-test.
+RUN locale-gen en_US.UTF-8
+{% endif %}
+
+# Install Ansible inventory file.
+RUN mkdir -p /etc/ansible
+RUN echo "[local]\nlocalhost ansible_connection=local" > /etc/ansible/hosts
+
+{% if item.image in ["centos:7", "centos:8", "debian:9", "debian:10"] %}
+VOLUME ["/sys/fs/cgroup"]
+{% elif item.image in ["ubuntu:16.04", "ubuntu:18.04", "ubuntu:20.04"] %}
+VOLUME ["/sys/fs/cgroup", "/tmp", "/run"]
+{% endif %}
+{% if item.image in ["centos:7", "centos:8"] %}
+CMD ["/usr/sbin/init"]
+{% elif item.image in ["ubuntu:16.04", "ubuntu:18.04", "ubuntu:20.04", "debian:9", "debian:10"] %}
+CMD ["/lib/systemd/systemd"]
+{% endif %}
diff --git a/molecule/gcloud/archive_playbook.yml b/molecule/gcloud/archive_playbook.yml
new file mode 100644
index 0000000..52ab0de
--- /dev/null
+++ b/molecule/gcloud/archive_playbook.yml
@@ -0,0 +1,15 @@
+---
+- name: Converge
+  hosts: all
+  pre_tasks:
+    - name: Install gpg for apt_key
+      apt:
+        name: gnupg
+        update_cache: true
+      when: ansible_os_family|lower == "debian"
+  roles:
+    - role: google.cloud.gcloud
+      gcloud_install_type: archive
+      gcloud_command_completion: true
+      gcloud_additional_components:
+        - cloud-build-local
diff --git a/molecule/gcloud/converge.yml b/molecule/gcloud/converge.yml
new file mode 100644
index 0000000..6889b4b
--- /dev/null
+++ b/molecule/gcloud/converge.yml
@@ -0,0 +1,23 @@
+---
+- name: Converge
+  hosts: all
+  pre_tasks:
+    - name: Update package cache
+      package: update_cache=yes
+      changed_when: false
+      register: task_result
+      until: task_result is success
+      retries: 10
+      delay: 2
+    - name: create containerd folder
+      file:
+        path: /etc/systemd/system/containerd.service.d
+        state: directory
+      when: ansible_service_mgr == "systemd"
+    - name: override file for containerd
+      copy:
+        src: files/override.conf
+        dest: /etc/systemd/system/containerd.service.d/override.conf
+      when: ansible_service_mgr == "systemd"
+  roles:
+    - role: google.cloud.gcloud
diff --git a/molecule/gcloud/files/override.conf b/molecule/gcloud/files/override.conf
new file mode 100644
index 0000000..76864e2
--- /dev/null
+++ b/molecule/gcloud/files/override.conf
@@ -0,0 +1,2 @@
+[Service]
+ExecStartPre=
diff --git a/molecule/gcloud/molecule.yml b/molecule/gcloud/molecule.yml
new file mode 100644
index 0000000..da1ce65
--- /dev/null
+++ b/molecule/gcloud/molecule.yml
@@ -0,0 +1,20 @@
+---
+dependency:
+  name: galaxy
+driver:
+  name: docker
+lint: |
+  set -e
+  yamllint .
+  ansible-lint
+platforms:
+  - name: instance
+    image: ${MOLECULE_DISTRO:-ubuntu:xenial}
+    privileged: true
+    command: ${MOLECULE_COMMAND:-"sleep infinity"}
+    volumes:
+      - /sys/fs/cgroup:/sys/fs/cgroup:ro
+provisioner:
+  name: ansible
+  playbooks:
+    converge: ${MOLECULE_PLAYBOOK:-converge.yml}
diff --git a/molecule/gcloud/package_playbook.yml b/molecule/gcloud/package_playbook.yml
new file mode 100644
index 0000000..fab1d85
--- /dev/null
+++ b/molecule/gcloud/package_playbook.yml
@@ -0,0 +1,13 @@
+---
+- name: Converge
+  hosts: all
+  pre_tasks:
+    - name: Install gpg for apt_key
+      apt:
+        name: gnupg
+        update_cache: true
+      when: ansible_os_family|lower == "debian"
+  roles:
+    - role: google.cloud.gcloud
+      gcloud_additional_components:
+        - cloud-build-local
diff --git a/molecule/gcloud/tests/test_default.py b/molecule/gcloud/tests/test_default.py
new file mode 100644
index 0000000..0d98e7a
--- /dev/null
+++ b/molecule/gcloud/tests/test_default.py
@@ -0,0 +1,20 @@
+import os
+import testinfra.utils.ansible_runner
+
+testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
+    os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')
+
+
+def test_service(host):
+    service = host.service('docker')
+
+    assert service.is_running
+    assert service.is_enabled
+
+
+def test_hosts_file(host):
+    f = host.file('/etc/hosts')
+
+    assert f.exists
+    assert f.user == 'root'
+    assert f.group == 'root'
diff --git a/molecule/gcloud/verify.yml b/molecule/gcloud/verify.yml
new file mode 100644
index 0000000..a82dd6f
--- /dev/null
+++ b/molecule/gcloud/verify.yml
@@ -0,0 +1,9 @@
+---
+# This is an example playbook to execute Ansible tests.
+
+- name: Verify
+  hosts: all
+  tasks:
+  - name: Example assertion
+    assert:
+      that: true
diff --git a/roles/gcloud/LICENSE b/roles/gcloud/LICENSE
new file mode 100644
index 0000000..616fc1e
--- /dev/null
+++ b/roles/gcloud/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 Eric Anderson
+
+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/roles/gcloud/README.md b/roles/gcloud/README.md
new file mode 100644
index 0000000..dfc365a
--- /dev/null
+++ b/roles/gcloud/README.md
@@ -0,0 +1,60 @@
+# ericsysmin.gcloud
+
+[![Build Status](https://travis-ci.org/ericsysmin/ansible-role-gcloud.svg?branch=master)](https://travis-ci.org/ericsysmin/ansible-role-gcloud)
+
+This role installs the gcloud command-line tool on a linux system.
+
+## Requirements
+
+### Debian
+
+None
+
+### Ubuntu
+
+None
+
+### CentOS
+
+-   epel (if using archive installation)
+
+## Role Variables
+
+All variables which can be overridden are stored in defaults/main.yml file as well as in table below.
+
+| Variable                       | Required | Default                                                                                | Comments                                                   |
+| ------------------------------ | -------- | -------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
+| `gcloud_install_type`          | No       | `package`                                                                              | Type of install `package` or `archive`                     |
+| `gcloud_apt_url`               | No       | `http://packages.cloud.google.com/apt`                                                 | URL of the APT Repository                                  |
+| `gcloud_apt_key`               | No       | `https://packages.cloud.google.com/apt/doc/apt-key.gpg`                                | GPG Key for the APT Repository                             |
+| `gcloud_apt_repo`              | No       | `cloud-sdk-{{ ansible_distribution_release }}`                                         | Name of the APT Repository                                 |
+| `gcloud_yum_baseurl`           | No       | `https://packages.cloud.google.com/yum/repos/cloud-sdk-el7-x86_64`                     | URL of the YUM Repository                                  |
+| `gcloud_yum_key`               | No       | `https://packages.cloud.google.com/yum/doc/yum-key.gpg`                                | GPG Key for the YUM Repository                             |
+| `gcloud_version`               | No       | `268.0.0`                                                                              | Version of google-cloud-sdk to install                     |
+| `gcloud_archive_name`          | No       | `google-cloud-sdk-{{ gcloud_version }}-linux-{{ ansible_architecture }}.tar.gz`        | Full length name of gcloud archive                         |
+| `gcloud_archive_url`           | No       | `https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/{{ gcloud_archive_name }}` | URL to download the gcloud archive                         |
+| `gcloud_archive_path`          | No       | `/usr/lib`                                                                             | Where should we unpack the archive                         |
+| `gcloud_library_path`          | No       | `{{ gcloud_archive_path }}/google-cloud-sdk`                                           | Path of the library after archive unpack                   |
+| `gcloud_install_script`        | No       | `false`                                                                                | Boolean: Execute install.sh from archive                   |
+| `gcloud_usage_reporting`       | No       | `false`                                                                                | Boolean: Disable anonymous usage reporting.                |
+| `gcloud_profile_path`          | No       | `false`                                                                                | Profile to update with PATH and completion.                |
+| `gcloud_command_completion`    | No       | `false`                                                                                | Boolean: Add a line for command completion in the profile  |
+| `gcloud_update_path`           | No       | `false`                                                                                | Boolean: Add a line for path updating in the profile       |
+| `gcloud_override_components`   | No       | `[]`                                                                                   | Override the components that would be installed by default |
+| `gcloud_additional_components` | No       | `[]`                                                                                   | Additional components to installed                         |
+
+## Example Playbook
+
+```yaml
+- hosts: servers
+  roles:
+     - role: ericsysmin.gcloud
+```
+
+## License
+
+MIT
+
+## Author Information
+
+[ericsysmin](https://ericsysmin.com)
diff --git a/roles/gcloud/defaults/main.yml b/roles/gcloud/defaults/main.yml
new file mode 100644
index 0000000..b5c4534
--- /dev/null
+++ b/roles/gcloud/defaults/main.yml
@@ -0,0 +1,28 @@
+---
+# defaults file for gcloud
+gcloud_install_type: package
+
+# default values for gcloud apt installation
+gcloud_apt_key: https://packages.cloud.google.com/apt/doc/apt-key.gpg
+gcloud_apt_url: http://packages.cloud.google.com/apt
+gcloud_apt_repo: cloud-sdk-{{ ansible_distribution_release }}
+
+# default values for gcloud yum installation
+gcloud_yum_baseurl: https://packages.cloud.google.com/yum/repos/cloud-sdk-el7-x86_64
+gcloud_yum_key: https://packages.cloud.google.com/yum/doc/yum-key.gpg
+
+# default values for gcloud archive installation
+gcloud_version: 268.0.0
+gcloud_archive_name: google-cloud-sdk-{{ gcloud_version }}-linux-{{ ansible_architecture }}.tar.gz
+gcloud_archive_url: https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/{{ gcloud_archive_name }}
+gcloud_archive_path: /usr/lib
+gcloud_library_path: "{{ gcloud_archive_path }}/google-cloud-sdk"
+
+# values if you want to use the gcloud install script
+gcloud_install_script: false
+gcloud_usage_reporting: false
+gcloud_profile_path: false
+gcloud_command_completion: false
+gcloud_update_path: false
+gcloud_override_components: []
+gcloud_additional_components: []
diff --git a/roles/gcloud/meta/main.yml b/roles/gcloud/meta/main.yml
new file mode 100644
index 0000000..50918c4
--- /dev/null
+++ b/roles/gcloud/meta/main.yml
@@ -0,0 +1,21 @@
+---
+galaxy_info:
+  role_name: gcloud
+  author: Eric Anderson
+  description: Ansible role to install google-cloud-sdk
+  company: Avi Networks
+  license: MIT
+  min_ansible_version: 2.4
+  platforms:
+    - name: Ubuntu
+      versions:
+        - precise
+        - trusty
+        - xenial
+        - bionic
+  galaxy_tags:
+    - gcloud
+    - google
+    - cloud
+    - sdk
+dependencies: []
diff --git a/roles/gcloud/tasks/archive/archive_install.yml b/roles/gcloud/tasks/archive/archive_install.yml
new file mode 100644
index 0000000..b1a6606
--- /dev/null
+++ b/roles/gcloud/tasks/archive/archive_install.yml
@@ -0,0 +1,50 @@
+---
+- name: gcloud | Archive | Ensure temp path exists
+  file: path={{ gcloud_archive_path }} state=directory
+
+- name: gcloud | Archive | Extract Cloud SDK archive
+  unarchive:
+    src: "{{ gcloud_archive_url }}"
+    dest: "{{ gcloud_archive_path }}"
+    remote_src: yes
+    creates: "{{ gcloud_library_path }}"
+
+- name: gcloud | Archive | Link binaries to /usr/bin (like package install)
+  file:
+    src: "{{ gcloud_library_path }}/bin/{{ item }}"
+    dest: "/usr/bin/{{ item }}"
+    state: link
+  loop:
+    - bq
+    - docker-credential-gcloud
+    - gcloud
+    - git-credential-gcloud.sh
+    - gsutil
+  when: not gcloud_install_script
+
+- name: gcloud | Archive | Add command completion
+  include_tasks: command_completion.yml
+  when: gcloud_command_completion
+
+- name: gcloud | Archive | Install into Path
+  command: >-
+    {{ gcloud_archive_path }}/install.sh --quiet
+    --usage-reporting {{ gcloud_usage_reporting | lower }}
+    {% if gcloud_profile_path %}
+      --rc-path {{ gcloud_profile_path }}
+    {% endif %}
+    --command-completion {{ gcloud_command_completion | lower }}
+    --path-update {{ gcloud_update_path | lower }}
+    {% if gcloud_override_components | length > 0 %}--override-components
+      {% for component in gcloud_override_components %}{{ component }}
+        {% if loop.index < gcloud_override_components | length  %}
+        {% endif %}
+      {% endfor %}
+    {% endif %}
+    {% if gcloud_additional_components | length > 0 %}--additional-components
+      {% for component in gcloud_additional_components %}{{ component }}
+        {% if loop.index < gcloud_additional_components | length %}
+        {% endif %}
+      {% endfor %}
+    {% endif %}
+  when: gcloud_install_script
diff --git a/roles/gcloud/tasks/archive/command_completion.yml b/roles/gcloud/tasks/archive/command_completion.yml
new file mode 100644
index 0000000..866dbfb
--- /dev/null
+++ b/roles/gcloud/tasks/archive/command_completion.yml
@@ -0,0 +1,32 @@
+---
+# task file to configure bash completion for gcloud
+- name: gcloud | Archive | Debian | Ensure bash completion is installed
+  apt: name=bash-completion
+  register: task_result
+  until: task_result is success
+  retries: 10
+  delay: 2
+  when: ansible_os_family == "Debian"
+
+- name: gcloud | Archive | RedHat | Ensure bash completion is installed
+  yum:
+    name:
+      - bash-completion
+  register: task_result
+  until: task_result is success
+  retries: 10
+  delay: 2
+  when: ansible_os_family == "RedHat"
+
+- name: gcloud | Archive | Ensure bash_completion.d directory exists
+  file:
+    path: /etc/bash_completion.d
+    owner: root
+    group: root
+    state: directory
+
+- name: gcloud | Archive | Link binaries to /usr/bin (like package install)
+  file:
+    src: "{{ gcloud_library_path }}/completion.bash.inc"
+    dest: /etc/bash_completion.d/gcloud
+    state: link
diff --git a/roles/gcloud/tasks/archive/main.yml b/roles/gcloud/tasks/archive/main.yml
new file mode 100644
index 0000000..7fff493
--- /dev/null
+++ b/roles/gcloud/tasks/archive/main.yml
@@ -0,0 +1,37 @@
+---
+# tasks to install gcloud via archive
+- name: gcloud | Archive | Look for existing Google Cloud SDK installation
+  stat:
+    path: "{{ gcloud_archive_path }}/google-cloud-sdk/VERSION"
+  register: gcloud_status
+
+- debug: var=gcloud_status
+
+- name: gcloud | Archive | Set installed version if installation exists
+  block:
+    - name: gcloud | Archive | Importing contents of {{ gcloud_archive_path }}/google-cloud-sdk/VERSION
+      slurp:
+        src: "{{ gcloud_archive_path }}/google-cloud-sdk/VERSION"
+      register: gcloud_installed_version_data
+    - name: gcloud | Archive | Setting the gcloud_installed_version variable/fact
+      set_fact:
+        gcloud_installed_version: "{{ (gcloud_installed_version_data.content|b64decode|trim) }}"
+    - debug:
+        msg: "google-cloud-sdk: {{ gcloud_installed_version }} is installed"
+    - debug:
+        msg: >-
+          Skipping installation of google-cloud-sdk version {{ gcloud_version }} when
+          {{ gcloud_installed_version }} is already installed.
+      when: gcloud_version == gcloud_installed_version
+  when: gcloud_status.stat.exists
+
+- name: gcloud | Archive | Start installation
+  include_tasks: archive_install.yml
+  when: gcloud_installed_version is undefined or
+        gcloud_version is version(gcloud_installed_version, '>')
+
+- name: gcloud | Debian | Install the google-cloud-sdk additional components # noqa 301
+  command: gcloud components install {{ item }}
+  register: gcloud_install_comp_status
+  changed_when: "'All components are up to date.' not in gcloud_install_comp_status.stderr_lines"
+  loop: "{{ gcloud_additional_components }}"
diff --git a/roles/gcloud/tasks/main.yml b/roles/gcloud/tasks/main.yml
new file mode 100644
index 0000000..090852f
--- /dev/null
+++ b/roles/gcloud/tasks/main.yml
@@ -0,0 +1,15 @@
+---
+
+- name: gcloud | Load Distro and OS specific variables
+  include_vars: "{{ lookup('first_found', params) }}"
+  vars:
+    params:
+      files:
+        - "os/{{ ansible_distribution|lower }}.yml"
+        - "os/{{ ansible_os_family|lower }}.yml"
+        - main.yml
+      paths:
+        - 'vars'
+
+- name: gcloud | Install the google-cloud-sdk from {{ gcloud_install_type }}
+  include_tasks: "{{ gcloud_install_type }}/main.yml"
diff --git a/roles/gcloud/tasks/package/debian.yml b/roles/gcloud/tasks/package/debian.yml
new file mode 100644
index 0000000..f38df34
--- /dev/null
+++ b/roles/gcloud/tasks/package/debian.yml
@@ -0,0 +1,27 @@
+---
+# tasks that install gcloud on debian
+- name: gcloud | Debian | Add an Apt signing key, uses whichever key is at the URL
+  apt_key:
+    url: "{{ gcloud_apt_key }}"
+    state: present
+
+- name: gcloud | Debian | Add the gcloud repository
+  apt_repository:
+    repo: "deb {{ gcloud_apt_url }} {{ gcloud_apt_repo }} main"
+    state: present
+    filename: google-cloud-sdk
+
+- name: gcloud | Debian | Install the google-cloud-sdk package
+  apt: name=google-cloud-sdk update_cache=yes
+  register: task_result
+  until: task_result is success
+  retries: 10
+  delay: 2
+
+- name: gcloud | Debian | Install the google-cloud-sdk additional components
+  apt: name=google-cloud-sdk-{{ item }} update_cache=yes
+  register: task_result
+  until: task_result is success
+  retries: 10
+  delay: 2
+  loop: "{{ gcloud_additional_components }}"
diff --git a/roles/gcloud/tasks/package/main.yml b/roles/gcloud/tasks/package/main.yml
new file mode 100644
index 0000000..c9b64ee
--- /dev/null
+++ b/roles/gcloud/tasks/package/main.yml
@@ -0,0 +1,5 @@
+---
+# tasks file for gcloud
+
+- name: gcloud | Start package installation for specific distro
+  include_tasks: "{{ ansible_os_family|lower }}.yml"
diff --git a/roles/gcloud/tasks/package/redhat.yml b/roles/gcloud/tasks/package/redhat.yml
new file mode 100644
index 0000000..1a8a17c
--- /dev/null
+++ b/roles/gcloud/tasks/package/redhat.yml
@@ -0,0 +1,28 @@
+---
+- name: gcloud | RHEL | Add an Apt signing key, uses whichever key is at the URL
+  yum_repository:
+    name: google-cloud-sdk
+    description: Google Cloud SDK
+    file: google-cloud-sdk
+    baseurl: https://packages.cloud.google.com/yum/repos/cloud-sdk-el7-x86_64
+    enabled: yes
+    gpgcheck: yes
+    repo_gpgcheck: yes
+    gpgkey:
+      - https://packages.cloud.google.com/yum/doc/yum-key.gpg
+      - https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
+
+- name: gcloud | RHEL | Install the google-cloud-sdk package
+  yum: name=google-cloud-sdk update_cache=yes
+  register: task_result
+  until: task_result is success
+  retries: 10
+  delay: 2
+
+- name: gcloud | Debian | Install the google-cloud-sdk additional components
+  yum: name=google-cloud-sdk-{{ item }} update_cache=yes
+  register: task_result
+  until: task_result is success
+  retries: 10
+  delay: 2
+  loop: "{{ gcloud_additional_components }}"
diff --git a/roles/gcloud/vars/main.yml b/roles/gcloud/vars/main.yml
new file mode 100644
index 0000000..ed97d53
--- /dev/null
+++ b/roles/gcloud/vars/main.yml
@@ -0,0 +1 @@
+---