Search code examples
kubernetesansibleterraformkubernetes-helm

How to automate Kubernetes configuration?


I would like to automate my Kubernetes configuration, like Ansible for VMs.

A sample scenario:

  1. Create namespace harbor
  2. Deploy Harbor via Helm https://github.com/goharbor/harbor-helm

What kind tool is suitable for such as scenario? Can I also use terraform?


Solution

  • I totally agree with @P Ekambaram that kubernetes automation can be successfully done with ansible but at the same time I totally disagree with him when it comes to the way it should be done. Such "declarative" code isn't actually declarative at all. It turns into a mere wrapper for the set of imperative commands. Apart from that such playbook isn't idempotent (let's remind that an operation is idempotent if the result of performing it once is exactly the same as the result of performing it repeatedly without any intervening actions.). This approach is contrary to one of the key concepts present in ansible.

    shell or command modules should be used in ansible as last resort modules, only if there is no other way of performing required task e.g. when dedicated module doesn't exist or lacks some important functionalities.

    When it comes to automating kubernetes with ansible, such dedicated modules already exist.

    Take a quick look at k8s - ansible module for managing kubernetes objects and you'll see that the desired results can be achieved in much more elegant and clearer way:

    namespace creation:

    - name: Create a k8s namespace
      k8s:
        name: testing
        api_version: v1
        kind: Namespace
        state: present
    

    creating service based on yaml definition file

    - name: Create a Service object by reading the definition from a file
      k8s:
        state: present
        src: /testing/service.yml
    

    Have you just mentioned you're using helm for managing your kubernetes applications ? Take a look at helm module documentation. Any examples ? Here you are:

    - name: Install helm chart from a git repo
      helm:
        host: localhost
        chart:
          source:
            type: git
            location: https://github.com/user/helm-chart.git
        state: present
        name: my-example
        namespace: default
    

    update:

    To be able to run most Ansible modules on a certain host, you need to have installed on it two things:

    • python 2.7
    • ssh server

    While it is true for most modules, some of them have additional requirements that must be met before the module can be run on such host.

    When it comes to k8s module, as we can read in the its docs:

    The below requirements are needed on the host that executes this module.

    python >= 2.7
    openshift >= 0.6
    PyYAML >= 3.11
    

    It isn't true that it requires openshift (different kubernetes implementation). It wouldn't make much sense to install openshift to manage workload of our kubernetes cluster. So let's be precise to avoid spreading any potentially misleading information: It requires OpenShift python client library and it requires it to be installed on the host, on which the module is run (i.e. on the host on which we normally run our kubectl commands).

    The OpenShift Python client wraps the K8s Python client, providing full access to all of the APIS and models available on both platforms. For API version details and additional information visit https://github.com/openshift/openshift-restclient-python

    Important!: you don't have to install any additional modules on your kubernetes nodes. You need them only on the machine from which you manage your kubernetes workload.

    If we have our Ansible installed on the same host on which we have configured our kubectl tool and we want to run our playbooks on it directly without a need of using ssh or configuring ansible inventory, we simply need to refer to it in our ansible playbook as:

    hosts: localhost
    connection: local
    

    The whole playbook for creating new k8s namespace may look like this:

    ---
    - hosts: localhost
      connection: local
      tasks:
      - name: Create a k8s namespace
        k8s:
          name: testing
          api_version: v1
          kind: Namespace
          state: present
    

    And we can run it by simply executing:

    ansible-playbook playbook.yaml
    

    Before we can do that, however, we need to make sure we have all required dependencies installed which in fact arn't so many and they limit to python 2.7 and two above mentioned libraries (in required versions).

    Once you have Python installed on your host, the easiest way to install the rest of the required dependencies is by runnig:

    pip install openshift
    

    and

    pip install PyYAML
    

    You may encounter the following error:

    "msg": "Failed to import the required Python library (openshift) on ***** Python /usr/bin/python. Please read module documentation and install in the appropriate location. If the required library is installed, but Ansible is using the wrong Python interpreter, please consult the documentation on ansible_python_interpreter"
    

    If so, running:

    pip install --upgrade requests
    

    should fix it (at least it fixed it in my case) and after that our simple ansible playbook which creates new namespace in our kubernetes cluster should run smoothly. :)