├── .ansible-lint ├── templates ├── plugin.conf.j2 ├── td-agent.conf.j2 ├── source.conf.j2 ├── match.conf.j2 └── filter.conf.j2 ├── .github ├── lock.yml ├── stale.yml ├── workflows │ ├── labeler.yml │ └── labels.yml ├── labeler.yml └── labels.yml ├── .gitignore ├── molecule └── default │ ├── prepare.yml │ ├── playbook.yml │ ├── destroy.yml │ ├── tests │ └── test_default.py │ ├── create.yml │ └── molecule.yml ├── vars ├── redhat.yml ├── debian.yml ├── redhat-7.yml └── main.yml ├── test-requirements.txt ├── handlers └── main.yml ├── .travis ├── images.sh ├── test.sh └── releaser.sh ├── .yamllint ├── tox.ini ├── .mergify.yml ├── .travis.yml ├── tasks ├── plugins.yml ├── main.yml ├── configure.yml ├── install.yml └── preflight.yml ├── meta └── main.yml ├── LICENSE ├── filter_plugins └── fluentd_params.py ├── defaults └── main.yml ├── README.md ├── CONTRIBUTING.md └── CHANGELOG.md /.ansible-lint: -------------------------------------------------------------------------------- 1 | --- 2 | skip_list: 3 | - '204' 4 | -------------------------------------------------------------------------------- /templates/plugin.conf.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | -------------------------------------------------------------------------------- /.github/lock.yml: -------------------------------------------------------------------------------- 1 | --- 2 | _extends: auto-maintenance 3 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | --- 2 | _extends: auto-maintenance 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.retry 2 | *.log 3 | .molecule 4 | .cache 5 | __pycache__/ 6 | .pytest_cache 7 | .tox 8 | -------------------------------------------------------------------------------- /molecule/default/prepare.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Prepare 3 | hosts: all 4 | gather_facts: false 5 | tasks: [] 6 | -------------------------------------------------------------------------------- /vars/redhat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | fluentd_dependencies: 3 | - python3-libselinux 4 | 5 | fluentd_plugins_dependencies: [] 6 | -------------------------------------------------------------------------------- /test-requirements.txt: -------------------------------------------------------------------------------- 1 | molecule>=2.15.0 2 | docker 3 | ansible-lint>=3.4.0 4 | testinfra>=1.7.0 5 | jmespath 6 | selinux 7 | -------------------------------------------------------------------------------- /vars/debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | fluentd_dependencies: 3 | - apt-transport-https 4 | 5 | fluentd_plugins_dependencies: [] 6 | -------------------------------------------------------------------------------- /vars/redhat-7.yml: -------------------------------------------------------------------------------- 1 | --- 2 | fluentd_dependencies: 3 | - libselinux-python 4 | 5 | fluentd_plugins_dependencies: [] 6 | -------------------------------------------------------------------------------- /vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | go_arch_map: 3 | i386: '386' 4 | x86_64: 'amd64' 5 | aarch64: 'arm64' 6 | armv7l: 'armv7' 7 | armv6l: 'armv6' 8 | -------------------------------------------------------------------------------- /templates/td-agent.conf.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | 4 | workers {{ ansible_processor_vcpus }} 5 | 6 | 7 | @include /etc/td-agent/conf.d/*.conf 8 | -------------------------------------------------------------------------------- /handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: reload td-agent 3 | service: 4 | name: td-agent 5 | state: reloaded 6 | 7 | - name: restart td-agent 8 | service: 9 | name: td-agent 10 | state: restarted 11 | -------------------------------------------------------------------------------- /.travis/images.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | for i in ubuntu-molecule:18.04 ubuntu-molecule:16.04 debian-molecule:9 debian-molecule:8 centos-molecule:7 fedora-molecule:27 3 | do 4 | docker pull paulfantom/$i & 5 | done 6 | 7 | wait 8 | -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | extends: default 2 | ignore: | 3 | .travis/ 4 | .travis.yml 5 | .github/ 6 | meta/ 7 | 8 | rules: 9 | braces: 10 | max-spaces-inside: 1 11 | level: error 12 | brackets: 13 | max-spaces-inside: 1 14 | level: error 15 | line-length: disable 16 | -------------------------------------------------------------------------------- /molecule/default/playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | any_errors_fatal: true 4 | roles: 5 | - ansible-fluentd 6 | vars: 7 | fluentd_plugins: 8 | - name: fluent-plugin-secure-forward 9 | - url: "https://raw.githubusercontent.com/emsearcy/fluent-plugin-gelf/master/lib/fluent/plugin/out_gelf.rb" 10 | -------------------------------------------------------------------------------- /templates/source.conf.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | {% for source in fluentd_sources_conf %} 4 | 5 | @type {{ source.type }} 6 | {% for key, value in source.items()|sort(attribute='0') %} 7 | {% if key != "type" %} 8 | {{ value |fluentd_params_to_text }} 9 | {% endif %} 10 | {% endfor %} 11 | 12 | {% endfor %} 13 | -------------------------------------------------------------------------------- /templates/match.conf.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | {% for output in fluentd_outputs_conf %} 4 | 5 | @type {{ output.type }} 6 | {% for key, value in output.items()|sort(attribute='0') %} 7 | {% if key == "params" %} 8 | {{ value |fluentd_params_to_text }} 9 | {% endif %} 10 | {% endfor %} 11 | 12 | {% endfor %} 13 | 14 | -------------------------------------------------------------------------------- /templates/filter.conf.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | {% for filter in fluentd_filters_conf %} 4 | 5 | @type {{ filter.type }} 6 | {% for key, value in filter.items()|sort(attribute='0') %} 7 | {% if key == "params" %} 8 | {{ value |fluentd_params_to_text }} 9 | {% endif %} 10 | {% endfor %} 11 | 12 | {% endfor %} 13 | 14 | -------------------------------------------------------------------------------- /.github/workflows/labeler.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Pull request labeler 3 | on: 4 | schedule: 5 | - cron: '*/15 * * * *' 6 | jobs: 7 | labeler: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: paulfantom/periodic-labeler@master 11 | env: 12 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 13 | GITHUB_REPOSITORY: ${{ github.repository }} 14 | -------------------------------------------------------------------------------- /.travis/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | if [ ! -d "./molecule/latest" ]; then 6 | tox -- molecule test --all 7 | exit 0 8 | fi 9 | 10 | if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then 11 | tox -- molecule test --all --destroy always 12 | else 13 | tox -- molecule test -s default --destroy always 14 | if [ -d "./molecule/alternative" ]; then 15 | tox -- molecule test -s alternative --destroy never 16 | fi 17 | fi 18 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | minversion = 1.8 3 | envlist = py{35}-ansible{27,28,29} 4 | skipsdist = true 5 | 6 | [travis:env] 7 | ANSIBLE= 8 | 2.7: ansible27 9 | 2.8: ansible28 10 | 2.9: ansible29 11 | 12 | [testenv] 13 | passenv = * 14 | deps = 15 | -rtest-requirements.txt 16 | ansible27: ansible<2.8 17 | ansible28: ansible<2.9 18 | ansible29: ansible<2.10 19 | commands = 20 | {posargs:molecule test --all --destroy always} 21 | -------------------------------------------------------------------------------- /.github/workflows/labels.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Sync labels in the declarative way 3 | on: 4 | push: 5 | branches: 6 | - master 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@1.0.0 12 | - uses: micnncim/action-label-syncer@v0.3.1 13 | env: 14 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 15 | GITHUB_REPOSITORY: ${{ github.repository }} 16 | with: 17 | manifest: .github/labels.yml 18 | -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | --- 2 | pull_request_rules: 3 | - name: automatic merge and new release from cloudalchemybot 4 | conditions: 5 | - "status-success=Travis CI - Pull Request" 6 | - status-success=WIP 7 | - head~=autoupdate|skeleton 8 | - author=cloudalchemybot 9 | actions: 10 | merge: 11 | method: squash 12 | strict: true 13 | - name: delete head branch after merge 14 | conditions: [] 15 | actions: 16 | delete_head_branch: {} 17 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dist: xenial 3 | sudo: required 4 | language: python 5 | python: 6 | - 3.5 7 | cache: pip 8 | services: 9 | - docker 10 | env: 11 | - ANSIBLE=2.7 12 | - ANSIBLE=2.8 13 | - ANSIBLE=2.9 14 | matrix: 15 | fast_finish: true 16 | install: 17 | - pip3 install tox-travis git-semver 18 | script: 19 | - ./.travis/test.sh 20 | deploy: 21 | provider: script 22 | skip_cleanup: true 23 | script: .travis/releaser.sh 24 | on: 25 | branch: master 26 | branches: 27 | only: 28 | - master 29 | notifications: 30 | webhooks: https://galaxy.ansible.com/api/v1/notifications/ 31 | -------------------------------------------------------------------------------- /tasks/plugins.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install plugins via name 3 | gem: 4 | name: "{{ item.name }}" 5 | executable: /opt/td-agent/embedded/bin/fluent-gem 6 | state: present 7 | user_install: false 8 | version: "{{ item.version | default(omit) }}" 9 | with_items: "{{ fluentd_plugins | selectattr('url', 'undefined') | list }}" 10 | notify: restart td-agent 11 | 12 | - name: Install plugins via url 13 | get_url: 14 | url: "{{ item }}" 15 | dest: /etc/td-agent/plugin 16 | with_items: "{{ fluentd_plugins | selectattr('name', 'undefined') | map(attribute='url') | list }}" 17 | notify: restart td-agent 18 | -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # configuration spec at https://github.com/actions/labeler/blob/master/README.md 3 | area/docs: 4 | - meta/* 5 | - CHANGELOG.md 6 | - CONTRIBUTING.md 7 | - LICENSE 8 | - README.md 9 | area/tests: 10 | - molecule/* 11 | - molecule/**/* 12 | - .ansible-lint 13 | - test-requirements.txt 14 | - tox.ini 15 | area/automation: 16 | - .travis/* 17 | - .github/* 18 | - .github/**/* 19 | - .travis.yml 20 | - .mergify.yml 21 | area/vars: 22 | - defaults/* 23 | - vars/* 24 | - vars/**/* 25 | area/tasks: 26 | - handlers/* 27 | - tasks/* 28 | - tasks/**/* 29 | area/jinja: 30 | - templates/* 31 | - templates/**/* 32 | -------------------------------------------------------------------------------- /meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: Paweł Krupa 4 | description: Install Fluentd (td-agent version) 5 | license: MIT 6 | company: none 7 | min_ansible_version: 2.7 8 | platforms: 9 | - name: Ubuntu 10 | versions: 11 | - bionic 12 | - xenial 13 | - name: Debian 14 | versions: 15 | - stretch 16 | - buster 17 | - name: EL 18 | versions: 19 | - 7 20 | - 8 21 | - name: Fedora 22 | versions: 23 | - 30 24 | - 31 25 | galaxy_tags: 26 | - system 27 | - logging 28 | - logs 29 | - tdagent 30 | - fluentd 31 | - monitoring 32 | 33 | dependencies: [] 34 | -------------------------------------------------------------------------------- /tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Gather variables for each operating system 3 | include_vars: "{{ item }}" 4 | with_first_found: 5 | - "{{ ansible_distribution | lower }}-{{ ansible_distribution_version | lower }}.yml" 6 | - "{{ ansible_distribution | lower }}-{{ ansible_distribution_major_version | lower }}.yml" 7 | - "{{ ansible_os_family | lower }}-{{ ansible_distribution_major_version | lower }}.yml" 8 | - "{{ ansible_distribution_file_variety | lower }}.yml" 9 | - "{{ ansible_distribution | lower }}.yml" 10 | - "{{ ansible_os_family | lower }}.yml" 11 | tags: 12 | - always 13 | 14 | - include: preflight.yml 15 | when: ansible_virtualization_type != "docker" 16 | 17 | - include: install.yml 18 | 19 | - include: plugins.yml 20 | 21 | - include: configure.yml 22 | 23 | - name: Ensure fluentd (td-agent) service is enabled 24 | service: 25 | name: td-agent 26 | enabled: true 27 | use: service 28 | -------------------------------------------------------------------------------- /tasks/configure.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create td-agent directories 3 | file: 4 | path: /etc/td-agent/conf.d 5 | state: directory 6 | owner: td-agent 7 | group: td-agent 8 | with_items: 9 | - /opt/td-agent 10 | - /etc/td-agent/conf.d 11 | 12 | - name: Create main configuration file 13 | template: 14 | src: td-agent.conf.j2 15 | dest: /etc/td-agent/td-agent.conf 16 | owner: td-agent 17 | group: td-agent 18 | notify: restart td-agent 19 | 20 | - name: Create additional configuration files 21 | template: 22 | src: "{{ item }}.conf.j2" 23 | dest: "/etc/td-agent/conf.d/{{ item }}.conf" 24 | owner: td-agent 25 | group: td-agent 26 | with_items: 27 | - source 28 | - filter 29 | - match 30 | - plugin 31 | notify: reload td-agent 32 | 33 | - name: Create custom configuration 34 | template: 35 | src: "{{ item }}.j2" 36 | dest: "/etc/td-agent/conf.d/{{ item.split('/')[-1] }}" 37 | owner: td-agent 38 | group: td-agent 39 | with_items: "{{ fluentd_custom_conf }}" 40 | notify: reload td-agent 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017-2018 Pawel Krupa 4 | 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /filter_plugins/fluentd_params.py: -------------------------------------------------------------------------------- 1 | from ansible.module_utils._text import to_text 2 | from collections import OrderedDict 3 | 4 | def fluentd_params_to_text(params): 5 | config = "" 6 | if type(params) == dict: 7 | params = OrderedDict(sorted(params.items(), key=lambda x: x[0], reverse=True)) 8 | else: 9 | raise ValueError("Params should be dictionary") 10 | for key, val in params.items(): 11 | if key == "type": 12 | key = "@type" 13 | if type(val) is list: 14 | if all([type(x) == dict for x in val]): 15 | for v in val: 16 | config += "<{0}>\n {1}\n ".format(key, fluentd_params_to_text(v)) 17 | else: 18 | config += "{0} {1}\n ".format(key, val.join(', ')) 19 | elif type(val) is dict: 20 | config += "<{0}>\n {1}\n ".format(key, fluentd_params_to_text(val)) 21 | else: 22 | config += "{0} {1}\n ".format(key, val) 23 | 24 | return to_text(config) 25 | 26 | 27 | class FilterModule(object): 28 | def filters(self): 29 | return {'fluentd_params_to_text': fluentd_params_to_text } 30 | -------------------------------------------------------------------------------- /molecule/default/destroy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Destroy 3 | hosts: localhost 4 | connection: local 5 | gather_facts: false 6 | no_log: "{{ not lookup('env', 'MOLECULE_DEBUG') | bool }}" 7 | tasks: 8 | - name: Destroy molecule instance(s) 9 | docker_container: 10 | name: "{{ item.name }}" 11 | docker_host: "{{ item.docker_host | default('unix://var/run/docker.sock') }}" 12 | state: absent 13 | force_kill: "{{ item.force_kill | default(true) }}" 14 | register: server 15 | with_items: "{{ molecule_yml.platforms }}" 16 | async: 7200 17 | poll: 0 18 | 19 | - name: Wait for instance(s) deletion to complete 20 | async_status: 21 | jid: "{{ item.ansible_job_id }}" 22 | register: docker_jobs 23 | until: docker_jobs.finished 24 | retries: 300 25 | with_items: "{{ server.results }}" 26 | 27 | - name: Delete docker network(s) 28 | docker_network: 29 | name: "{{ item }}" 30 | docker_host: "{{ item.docker_host | default('unix://var/run/docker.sock') }}" 31 | state: absent 32 | with_items: "{{ molecule_yml.platforms | molecule_get_docker_networks }}" 33 | -------------------------------------------------------------------------------- /.github/labels.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Default GitHub labels 3 | - color: d73a4a 4 | name: bug 5 | description: Something isn't working 6 | - color: cfd3d7 7 | name: duplicate 8 | description: This issue or pull request already exists 9 | - color: a2eeef 10 | name: enhancement 11 | description: New feature or request 12 | - color: 7057ff 13 | name: good first issue 14 | description: Good for newcomers 15 | - color: 008672 16 | name: help wanted 17 | description: Extra attention is needed 18 | - color: e4e669 19 | name: invalid 20 | description: This doesn't seem right 21 | - color: d876e3 22 | name: question 23 | description: Further information is requested 24 | - color: ffffff 25 | name: wontfix 26 | description: This will not be worked on 27 | 28 | # Labels specific to cloudalchemy 29 | - color: 0366d6 30 | name: area/docs 31 | description: Improvements or additions to documentation 32 | - color: 0366d6 33 | name: area/tests 34 | description: Everything related to molecule tests and linters 35 | - color: 0366d6 36 | name: area/automation 37 | description: Bots, bots everywhere 38 | - color: 0366d6 39 | name: area/vars 40 | description: Ansible variables used in role 41 | - color: 0366d6 42 | name: area/tasks 43 | description: Logic behind ansible role 44 | - color: 0366d6 45 | name: area/jinja 46 | description: Templates 47 | -------------------------------------------------------------------------------- /molecule/default/tests/test_default.py: -------------------------------------------------------------------------------- 1 | import os 2 | import testinfra.utils.ansible_runner 3 | 4 | testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( 5 | os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all') 6 | 7 | 8 | def test_directories(host): 9 | present = [ 10 | "/etc/td-agent" 11 | ] 12 | if present: 13 | for directory in present: 14 | d = host.file(directory) 15 | assert d.is_directory 16 | assert d.exists 17 | 18 | 19 | def test_files(host): 20 | present = [ 21 | "/etc/td-agent/td-agent.conf", 22 | "/etc/td-agent/plugin/out_gelf.rb", 23 | "/opt/td-agent/embedded/bin/secure-forward-ca-generate" 24 | ] 25 | if present: 26 | for file in present: 27 | f = host.file(file) 28 | assert f.exists 29 | assert f.is_file 30 | 31 | 32 | def test_service(host): 33 | present = [ 34 | "td-agent", 35 | ] 36 | if present: 37 | for service in present: 38 | s = host.service(service) 39 | assert s.is_enabled 40 | assert s.is_running 41 | 42 | 43 | def test_packages(host): 44 | present = [ 45 | "td-agent" 46 | ] 47 | if present: 48 | for package in present: 49 | p = host.package(package) 50 | assert p.is_installed 51 | -------------------------------------------------------------------------------- /molecule/default/create.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create 3 | hosts: localhost 4 | connection: local 5 | gather_facts: false 6 | no_log: "{{ not lookup('env', 'MOLECULE_DEBUG') | bool }}" 7 | tasks: 8 | - name: Create molecule instance(s) 9 | docker_container: 10 | name: "{{ item.name }}" 11 | docker_host: "{{ item.docker_host | default('unix://var/run/docker.sock') }}" 12 | hostname: "{{ item.name }}" 13 | image: "{{ item.image }}" 14 | state: started 15 | recreate: false 16 | log_driver: json-file 17 | command: "{{ item.command | default(omit) }}" 18 | privileged: "{{ item.privileged | default(omit) }}" 19 | volumes: "{{ item.volumes | default(omit) }}" 20 | capabilities: "{{ item.capabilities | default(omit) }}" 21 | exposed_ports: "{{ item.exposed_ports | default(omit) }}" 22 | published_ports: "{{ item.published_ports | default(omit) }}" 23 | ulimits: "{{ item.ulimits | default(omit) }}" 24 | networks: "{{ item.networks | default(omit) }}" 25 | dns_servers: "{{ item.dns_servers | default(omit) }}" 26 | register: server 27 | with_items: "{{ molecule_yml.platforms }}" 28 | async: 7200 29 | poll: 0 30 | 31 | - name: Wait for instance(s) creation to complete 32 | async_status: 33 | jid: "{{ item.ansible_job_id }}" 34 | register: docker_jobs 35 | until: docker_jobs.finished 36 | retries: 300 37 | with_items: "{{ server.results }}" 38 | -------------------------------------------------------------------------------- /tasks/install.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install dependencies 3 | package: 4 | name: "{{ item }}" 5 | state: present 6 | register: _install_dep_packages 7 | until: _install_dep_packages is success 8 | retries: 5 9 | delay: 2 10 | with_items: "{{ fluentd_dependencies }}" 11 | 12 | - block: 13 | - name: add APT signing key for td-agent 14 | apt_key: 15 | url: "https://packages.treasuredata.com/GPG-KEY-td-agent" 16 | state: present 17 | 18 | - name: add td-agent repository 19 | apt_repository: 20 | repo: "deb https://packages.treasuredata.com/3/{{ ansible_distribution|lower }}/{{ ansible_distribution_release|lower }}/ {{ ansible_distribution_release|lower }} contrib" 21 | state: present 22 | update_cache: true 23 | when: ansible_pkg_mgr == "apt" 24 | 25 | - block: 26 | - name: add GPG key from Treasure Data, Inc 27 | # command: rpm --import https://packages.treasuredata.com/GPG-KEY-td-agent 28 | rpm_key: 29 | key: https://packages.treasuredata.com/GPG-KEY-td-agent 30 | validate_certs: false 31 | state: present 32 | 33 | - name: add official repository 34 | yum_repository: 35 | name: treasuredata 36 | description: TreasureData 37 | baseurl: "http://packages.treasuredata.com/3/redhat/$releasever/$basearch" 38 | file: td 39 | gpgcheck: true 40 | gpgkey: https://packages.treasuredata.com/GPG-KEY-td-agent 41 | when: ansible_pkg_mgr == "yum" 42 | 43 | - name: Install fluentd (td-agent) and plugins dependencies 44 | package: 45 | name: "{{ item }}" 46 | state: present 47 | with_items: 48 | - td-agent 49 | - "{{ fluentd_plugins_dependencies }}" 50 | notify: restart td-agent 51 | -------------------------------------------------------------------------------- /tasks/preflight.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Check if time is synchronized (ntp test) 3 | command: "timedatectl status" 4 | register: time_synchronization 5 | changed_when: false 6 | tags: 7 | - skip_ansible_lint 8 | 9 | # ulimit needs full shell 10 | - name: Register number of file descriptors 11 | shell: "ulimit -n" 12 | register: file_descriptors 13 | changed_when: false 14 | tags: 15 | - skip_ansible_lint 16 | 17 | - name: Fail on desynchronized time 18 | fail: 19 | msg: "Synchronize time with NTP. Follow instructions at https://docs.fluentd.org/v1.0/articles/before-install" 20 | when: not time_synchronization.stdout_lines[5].split(":")[1].strip()|bool 21 | 22 | - name: Fail on too small number of file descriptors 23 | fail: 24 | msg: "Increase number of file descriptors to more than 1024. Follow instructions at https://docs.fluentd.org/v1.0/articles/before-install" 25 | when: file_descriptors.stdout|int < 1025 26 | 27 | - name: Fail on source not having type 28 | fail: 29 | msg: "Each of your input plugin should have its type defined" 30 | when: item.type is not defined 31 | loop: "{{ fluentd_sources_conf }}" 32 | 33 | - name: Fail on output not having type 34 | fail: 35 | msg: "Each of your output plugin should have its type defined" 36 | when: item.type is not defined 37 | loop: "{{ fluentd_outputs_conf }}" 38 | 39 | - name: Fail on output not having tag 40 | fail: 41 | msg: "Each of your output plugin should have its tag defined" 42 | when: item.tag is not defined 43 | loop: "{{ fluentd_outputs_conf }}" 44 | 45 | - name: Fail on filter not having tag 46 | fail: 47 | msg: "Each of your filter plugin should have its tag defined" 48 | when: item.tag is not defined 49 | loop: "{{ fluentd_filters_conf }}" 50 | -------------------------------------------------------------------------------- /defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | fluentd_sources_conf: [] 3 | # fluentd_sources_conf: 4 | # - "type": forward 5 | # "params": 6 | # "port": 24224 7 | # "bind": 0.0.0.0 8 | # - "type": dummy 9 | # "params": 10 | # "dummy": "{\"hello\":\"world\"}" 11 | # "tag": testi 12 | # - "type": exec 13 | # "params": 14 | # "command": cmd arg arg 15 | # "parse": 16 | # "keys": k1 k2 k3 17 | # "extract": 18 | # "tag_key": k1 19 | # "time_key": k2 20 | # "time_format": "%Y-%m-%d %H:%M:%S" 21 | # "run_interval": 10s 22 | 23 | fluentd_outputs_conf: [] 24 | # fluentd_outputs_conf: 25 | # - "type": file 26 | # "tag": "app.*" 27 | # "params": 28 | # "path": /tmp/myapp_log 29 | # "compress": gzip 30 | # "buffer": 31 | # "timekey": 1d 32 | # "timekey_use_utc": true 33 | # "timekey_wait": 10m 34 | # - "type": copy 35 | # "tag": "*" 36 | # "params": 37 | # "store": 38 | # - "type": file 39 | # "path": /tmp/myapp 40 | # "compress": gzip 41 | # "format": 42 | # "localtime": false 43 | # "buffer": 44 | # "timekey_wait": 10m 45 | # "timekey": 86400 46 | # "timekey_use_utc": true 47 | # "path": /tmp/myapp 48 | # "inject": 49 | # "time_format": "%Y-%m-%d %H:%M:%S" 50 | # "localtime": false 51 | # - "type": elasticsearch 52 | # "host": fluentd 53 | # "port": 9200 54 | # "index_name": fluentd 55 | # "type_name": fluentd 56 | fluentd_filters_conf: [] 57 | # fluentd_filters_conf: 58 | # - "type": grep 59 | # "tag": foo.bar 60 | # "params": 61 | # "regexp": 62 | # - "key": message 63 | # "pattern": /cool/ 64 | # - "key": hostname 65 | # "pattern": /^web\d+\.example\.com$/ 66 | # "exclude": 67 | # "key": message 68 | # "pattern": uncool 69 | # paths to custom configuration templates 70 | fluentd_custom_conf: [] 71 | 72 | fluentd_plugins: [] 73 | # - { url: "https://raw.githubusercontent.com/emsearcy/fluent-plugin-gelf/master/lib/fluent/plugin/out_gelf.rb" } 74 | # - { name: "fluent-plugin-secure-forward", 'version': 0.2.3 } 75 | -------------------------------------------------------------------------------- /molecule/default/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: galaxy 4 | driver: 5 | name: docker 6 | lint: 7 | name: yamllint 8 | platforms: 9 | - name: bionic 10 | image: quay.io/paulfantom/molecule-systemd:ubuntu-18.04 11 | docker_host: "${DOCKER_HOST:-unix://var/run/docker.sock}" 12 | privileged: true 13 | volumes: 14 | - /sys/fs/cgroup:/sys/fs/cgroup:ro 15 | - name: xenial 16 | image: quay.io/paulfantom/molecule-systemd:ubuntu-16.04 17 | docker_host: "${DOCKER_HOST:-unix://var/run/docker.sock}" 18 | privileged: true 19 | volumes: 20 | - /sys/fs/cgroup:/sys/fs/cgroup:ro 21 | - name: stretch 22 | image: quay.io/paulfantom/molecule-systemd:debian-9 23 | docker_host: "${DOCKER_HOST:-unix://var/run/docker.sock}" 24 | privileged: true 25 | volumes: 26 | - /sys/fs/cgroup:/sys/fs/cgroup:ro 27 | - name: buster 28 | image: quay.io/paulfantom/molecule-systemd:debian-10 29 | docker_host: "${DOCKER_HOST:-unix://var/run/docker.sock}" 30 | privileged: true 31 | volumes: 32 | - /sys/fs/cgroup:/sys/fs/cgroup:ro 33 | - name: centos7 34 | image: quay.io/paulfantom/molecule-systemd:centos-7 35 | docker_host: "${DOCKER_HOST:-unix://var/run/docker.sock}" 36 | privileged: true 37 | volumes: 38 | - /sys/fs/cgroup:/sys/fs/cgroup:ro 39 | - name: centos8 40 | image: quay.io/paulfantom/molecule-systemd:centos-8 41 | docker_host: "${DOCKER_HOST:-unix://var/run/docker.sock}" 42 | privileged: true 43 | volumes: 44 | - /sys/fs/cgroup:/sys/fs/cgroup:ro 45 | groups: 46 | - python3 47 | - name: fedora 48 | image: quay.io/paulfantom/molecule-systemd:fedora-30 49 | docker_host: "${DOCKER_HOST:-unix://var/run/docker.sock}" 50 | privileged: true 51 | volumes: 52 | - /sys/fs/cgroup:/sys/fs/cgroup:ro 53 | groups: 54 | - python3 55 | provisioner: 56 | name: ansible 57 | lint: 58 | name: ansible-lint 59 | playbooks: 60 | create: create.yml 61 | prepare: prepare.yml 62 | converge: playbook.yml 63 | destroy: destroy.yml 64 | inventory: 65 | group_vars: 66 | python3: 67 | ansible_python_interpreter: /usr/bin/python3 68 | scenario: 69 | name: default 70 | verifier: 71 | name: testinfra 72 | lint: 73 | name: flake8 74 | enabled: true 75 | -------------------------------------------------------------------------------- /.travis/releaser.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (C) 2018 Pawel Krupa (@paulfantom) - All Rights Reserved 4 | # Permission to copy and modify is granted under the MIT license 5 | # 6 | # Script to automatically do a couple of things: 7 | # - generate a new tag according to semver (https://semver.org/) 8 | # - generate CHANGELOG.md by using https://github.com/skywinder/github-changelog-generator 9 | # - sync CHANGELOG with GitHub releases by using https://github.com/mattbrictson/chandler 10 | # 11 | # Tags are generated by searching for a keyword in last commit message. Keywords are: 12 | # - [patch] or [fix] to bump patch number 13 | # - [minor], [feature] or [feat] to bump minor number 14 | # - [major] or [breaking change] to bump major number 15 | # All keywords MUST be surrounded with square braces. 16 | # 17 | # Script uses git mechanisms for locking, so it can be used in parallel builds 18 | # 19 | # Requirements: 20 | # - GH_TOKEN variable set with GitHub token. Access level: repo.public_repo 21 | # - docker 22 | # - git-semver python package (pip install git-semver) 23 | 24 | # Exit when latest commit is tagged 25 | [[ $(git tag --points-at) ]] && exit 0 26 | 27 | # Some basic variables 28 | GIT_MAIL="cloudalchemybot@gmail.com" 29 | GIT_USER="cloudalchemybot" 30 | ORGANIZATION=$(echo "$TRAVIS_REPO_SLUG" | awk -F '/' '{print $1}') 31 | PROJECT=$(echo "$TRAVIS_REPO_SLUG" | awk -F '/' '{print $2}') 32 | GALAXY_URL="https://galaxy.ansible.com/${ORGANIZATION}/${PROJECT#ansible-}" 33 | 34 | # Git config 35 | git config --global user.email "${GIT_MAIL}" 36 | git config --global user.name "${GIT_USER}" 37 | GIT_URL=$(git config --get remote.origin.url) 38 | GIT_URL=${GIT_URL#*//} 39 | 40 | # Generate TAG 41 | GIT_TAG=none 42 | echo "Last commit message: $TRAVIS_COMMIT_MESSAGE" 43 | case "${TRAVIS_COMMIT_MESSAGE}" in 44 | *"[patch]"*|*"[fix]"*|*"[bugfix]"* ) GIT_TAG=$(git semver --next-patch) ;; 45 | *"[minor]"*|*"[feat]"*|*"[feature]"* ) GIT_TAG=$(git semver --next-minor) ;; 46 | *"[major]"*|*"[breaking change]"* ) GIT_TAG=$(git semver --next-major) ;; 47 | *) echo "Keyword not detected. Doing nothing" ;; 48 | esac 49 | if [ "$GIT_TAG" != "none" ]; then 50 | echo "Assigning new tag: $GIT_TAG" 51 | git tag "$GIT_TAG" -a -m "Automatic tag generation for travis build no. $TRAVIS_BUILD_NUMBER" 52 | git push "https://${GH_TOKEN}:@${GIT_URL}" --tags || exit 0 53 | fi 54 | 55 | # Generate CHANGELOG.md 56 | git checkout master 57 | git pull 58 | docker run -it --rm -v "$(pwd)":/usr/local/src/your-app ferrarimarco/github-changelog-generator:1.14.3 \ 59 | -u "${ORGANIZATION}" -p "${PROJECT}" --token "${GH_TOKEN}" \ 60 | --release-url "${GALAXY_URL}" \ 61 | --unreleased-label "**Next release**" --no-compare-link 62 | 63 | git add CHANGELOG.md 64 | git commit -m '[ci skip] Automatic changelog update' 65 | 66 | git push "https://${GH_TOKEN}:@${GIT_URL}" || exit 0 67 | 68 | # Sync changelog to github releases 69 | if [ "$GIT_TAG" != "none" ]; then 70 | docker run -e CHANDLER_GITHUB_API_TOKEN="${GH_TOKEN}" -v "$(pwd)":/chandler -ti whizark/chandler push "${GIT_TAG}" 71 | fi 72 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | fluentd logo 3 | 4 | 5 | # Ansible Role: fluentd 6 | 7 | [![Build Status](https://travis-ci.org/cloudalchemy/ansible-fluentd.svg?branch=master)](https://travis-ci.org/cloudalchemy/ansible-fluentd) 8 | [![License: MIT](https://img.shields.io/badge/license-MIT%20License-brightgreen.svg)](https://opensource.org/licenses/MIT) 9 | [![Ansible Role](http://img.shields.io/badge/ansible%20role-cloudalchemy.fluentd-blue.svg)](https://galaxy.ansible.com/cloudalchemy/fluentd/) 10 | [![GitHub tag](https://img.shields.io/github/tag/cloudalchemy/ansible-fluentd.svg)](https://github.com/cloudalchemy/ansible-fluentd/tags) 11 | [![IRC](https://img.shields.io/badge/irc.freenode.net-%23cloudalchemy-yellow.svg)](https://kiwiirc.com/nextclient/#ircs://irc.freenode.net/#cloudalchemy) 12 | 13 | ## Important! 14 | 15 | We are no longer supporting this role, which means we will not accept and PRs nor new issues. We won't be removing this repository, but we strongly encourage you to switch to alternatives such as [idealista/fluentd-role](https://github.com/idealista/fluentd-role) 16 | 17 | ## Description 18 | 19 | Install and manage [fluentd](https://github.com/fluent/fluentd) log forwarder and agregator. 20 | 21 | ## Requirements 22 | 23 | - Ansible >= 2.7 (It might work on previous versions, but we cannot guarantee it) 24 | 25 | ## Role Variables 26 | 27 | All variables which can be overridden are stored in [defaults/main.yml](defaults/main.yml) file as well as in table below. 28 | 29 | | Name | Default Value | Description | 30 | | -------------- | ------------- | -----------------------------------| 31 | | `fluentd_custom_conf` | [] | Paths to custom configuration templates. [Configuration examples]( https://github.com/fluent/fluentd/tree/master/example). | 32 | | `fluentd_plugins` | [] | List of additional plugins | 33 | 34 | ## Example 35 | 36 | ### Playbook 37 | 38 | Use it in a playbook as follows: 39 | ```yaml 40 | - hosts: all 41 | become: true 42 | roles: 43 | - cloudalchemy.fluentd 44 | ``` 45 | 46 | ### Demo site 47 | 48 | We provide demo site for full monitoring solution based on prometheus and grafana. Repository with code and links to running instances is [available on github](https://github.com/cloudalchemy/demo-site) and site is hosted on DigitalOcean. 49 | 50 | ## Local Testing 51 | 52 | The preferred way of locally testing the role is to use Docker and [molecule](https://github.com/metacloud/molecule) (v2.x). You will have to install Docker on your system. See "Get started" for a Docker package suitable to for your system. 53 | We are using tox to simplify process of testing on multiple ansible versions. To install tox execute: 54 | ```sh 55 | pip3 install tox 56 | ``` 57 | To run tests on all ansible versions (WARNING: this can take some time) 58 | ```sh 59 | tox 60 | ``` 61 | To run a custom molecule command on custom environment with only default test scenario: 62 | ```sh 63 | tox -e py35-ansible28 -- molecule test -s default 64 | ``` 65 | For more information about molecule go to their [docs](http://molecule.readthedocs.io/en/latest/). 66 | 67 | If you would like to run tests on remote docker host just specify `DOCKER_HOST` variable before running tox tests. 68 | 69 | ## Travis CI 70 | 71 | Combining molecule and travis CI allows us to test how new PRs will behave when used with multiple ansible versions and multiple operating systems. This also allows use to create test scenarios for different role configurations. As a result we have a quite large test matrix which will take more time than local testing, so please be patient. 72 | 73 | ## Contributing 74 | 75 | See [contributor guideline](CONTRIBUTING.md). 76 | 77 | ## License 78 | 79 | This project is licensed under MIT License. See [LICENSE](/LICENSE) for more details. 80 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributor Guideline 2 | 3 | This document provides an overview of how you can participate in improving this project or extending it. We are 4 | grateful for all your help: bug reports and fixes, code contributions, documentation or ideas. Feel free to join, we 5 | appreciate your support!! 6 | 7 | ## Communication 8 | 9 | ### IRC 10 | 11 | You can talk with us on #cloudalchemy channel on freenode. 12 | 13 | ### GitHub repositories 14 | 15 | Much of the issues, goals and ideas are tracked in the respective projects in GitHub. Please use this channel to report 16 | bugs. 17 | 18 | ## git and GitHub 19 | 20 | In order to contribute code please: 21 | 22 | 1. Fork the project on GitHub 23 | 2. Clone the project 24 | 3. Add changes (and tests) 25 | 4. Commit and push 26 | 5. Create a merge-request 27 | 28 | To have your code merged, see the expectations listed below. 29 | 30 | You can find a well-written guide [here](https://help.github.com/articles/fork-a-repo). 31 | 32 | Please follow common commit best-practices. Be explicit, have a short summary, a well-written description and 33 | references. This is especially important for the merge-request. 34 | 35 | Some great guidelines can be found [here](https://wiki.openstack.org/wiki/GitCommitMessages) and 36 | [here](http://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message). 37 | 38 | ## Releases 39 | 40 | We try to stick to semantic versioning and our releases are automated. Release is created by assigning a keyword (in a 41 | way similar to travis [`[ci skip]`](https://docs.travis-ci.com/user/customizing-the-build#Skipping-a-build)) to a 42 | commit with merge request. Available keywords are (square brackets are important!): 43 | 44 | * `[patch]`, `[fix]` - for PATCH version release 45 | * `[minor]`, `[feature]`, `[feat]` - for MINOR version release 46 | * `[major]`, `[breaking change]` - for MAJOR version release 47 | 48 | ## Changelog 49 | 50 | Changelog is generateg automatically on every merged Pull Request and all information is taken from github issues, PRs 51 | and labels. 52 | 53 | ## Expectations 54 | 55 | ### Keep it simple 56 | 57 | We try to provide production ready ansible roles which should be as much zero-conf as possible but this doesn't mean to 58 | overcomplicate things. Just follow [KISS](https://en.wikipedia.org/wiki/KISS_principle). 59 | 60 | ### Be explicit 61 | 62 | * Please avoid using nonsensical property and variable names. 63 | * Use self-describing attribute names for user configuration. 64 | * In case of failures, communicate what happened and why a failure occurs to the user. Make it easy to track the code 65 | or action that produced the error. Try to catch and handle errors if possible to provide improved failure messages. 66 | 67 | 68 | ### Add tests 69 | 70 | We are striving to use at least two test scenarios located in [/molecule](molecule) directory. First one 71 | ([default](molecule/default)) is testing default configuration without any additional variables, second one 72 | ([alternative](molecule/alternative)) is testing what happens when many variables from 73 | [/defaults/main.yml](defaults/main.yml) are changed. When adding new functionalities please add tests to proper 74 | scenarios. Tests are written in testinfra framework and are located in `/tests` subdirectory of scenario directory 75 | (for example default tests are in [/molecule/default/tests](molecule/default/tests)). 76 | More information about: 77 | - [testinfra](http://testinfra.readthedocs.io/en/latest/index.html) 78 | - [molecule](https://molecule.readthedocs.io/en/latest/index.html) 79 | 80 | ### Follow best practices 81 | 82 | Please follow [ansible best practices](http://docs.ansible.com/ansible/latest/playbooks_best_practices.html) and 83 | especially provide meaningful names to tasks and even comments where needed. 84 | 85 | Our test framework automatically lints code with [`yamllint`](https://yamllint.readthedocs.io) and 86 | [`ansible-lint`](https://github.com/willthames/ansible-lint) programs so be sure to follow their rules. 87 | 88 | Remember: Code is generally read much more often than written. 89 | 90 | ### Use Markdown 91 | 92 | Wherever possible, please refrain from any other formats and stick to simple markdown. 93 | 94 | ## Requirements regarding roles design 95 | 96 | We are trying to create the best and most secure installation method for non-containerized prometheus stack components. 97 | To accomplish this all roles need to support: 98 | 99 | - current and at least one previous ansible version (wherever possible we try to support 2 previous ansible versions) 100 | - systemd as the only available process manager 101 | - at least latest debian and CentOS distributions 102 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## [**Next release**](https://galaxy.ansible.com/cloudalchemy/fluentd) 4 | 5 | **Implemented enhancements:** 6 | 7 | - Different apprach to monitoring fluentd [\#15](https://github.com/cloudalchemy/ansible-fluentd/issues/15) 8 | 9 | **Fixed bugs:** 10 | 11 | - `fail on too small number of file descriptors` [\#35](https://github.com/cloudalchemy/ansible-fluentd/issues/35) 12 | 13 | **Merged pull requests:** 14 | 15 | - Synchronize files from cloudalchemy/skeleton [\#38](https://github.com/cloudalchemy/ansible-fluentd/pull/38) ([cloudalchemybot](https://github.com/cloudalchemybot)) 16 | - remove fluentd\_exporter as this feature is already integrated by using fluentd plugin [\#37](https://github.com/cloudalchemy/ansible-fluentd/pull/37) ([paulfantom](https://github.com/paulfantom)) 17 | - tasks: cast number of fds to int before assertion [\#36](https://github.com/cloudalchemy/ansible-fluentd/pull/36) ([paulfantom](https://github.com/paulfantom)) 18 | - Synchronize files from cloudalchemy/skeleton [\#34](https://github.com/cloudalchemy/ansible-fluentd/pull/34) ([cloudalchemybot](https://github.com/cloudalchemybot)) 19 | - added restartsec and startlimitinterval configurations [\#33](https://github.com/cloudalchemy/ansible-fluentd/pull/33) ([oguzhaninan](https://github.com/oguzhaninan)) 20 | 21 | ## [0.1.0](https://galaxy.ansible.com/cloudalchemy/fluentd) (2019-05-04) 22 | **Implemented enhancements:** 23 | 24 | - Support plugins via jinja templates [\#2](https://github.com/cloudalchemy/ansible-fluentd/issues/2) 25 | 26 | **Merged pull requests:** 27 | 28 | - Synchronize files from cloudalchemy/skeleton [\#32](https://github.com/cloudalchemy/ansible-fluentd/pull/32) ([cloudalchemybot](https://github.com/cloudalchemybot)) 29 | - Wait for network to be online [\#31](https://github.com/cloudalchemy/ansible-fluentd/pull/31) ([paulfantom](https://github.com/paulfantom)) 30 | - Synchronize files from cloudalchemy/skeleton. [\#30](https://github.com/cloudalchemy/ansible-fluentd/pull/30) ([cloudalchemybot](https://github.com/cloudalchemybot)) 31 | - Make linter happy [\#29](https://github.com/cloudalchemy/ansible-fluentd/pull/29) ([jkrol2](https://github.com/jkrol2)) 32 | - Support configuration with jinja2 templates [\#28](https://github.com/cloudalchemy/ansible-fluentd/pull/28) ([jkrol2](https://github.com/jkrol2)) 33 | - Update preflight.yml [\#27](https://github.com/cloudalchemy/ansible-fluentd/pull/27) ([jkrol2](https://github.com/jkrol2)) 34 | - Remove Jinja2 templating delimiters under when [\#26](https://github.com/cloudalchemy/ansible-fluentd/pull/26) ([jkrol2](https://github.com/jkrol2)) 35 | - Modify gitignore [\#25](https://github.com/cloudalchemy/ansible-fluentd/pull/25) ([jkrol2](https://github.com/jkrol2)) 36 | - Update requirements in readme \[ci skip\] [\#24](https://github.com/cloudalchemy/ansible-fluentd/pull/24) ([jkrol2](https://github.com/jkrol2)) 37 | - Use tox for testing [\#23](https://github.com/cloudalchemy/ansible-fluentd/pull/23) ([jkrol2](https://github.com/jkrol2)) 38 | - \[ci skip\] Typo [\#21](https://github.com/cloudalchemy/ansible-fluentd/pull/21) ([jkrol2](https://github.com/jkrol2)) 39 | - Link to the documentation of v1.0 version [\#20](https://github.com/cloudalchemy/ansible-fluentd/pull/20) ([jkrol2](https://github.com/jkrol2)) 40 | 41 | ## [0.0.9](https://galaxy.ansible.com/cloudalchemy/fluentd) (2019-02-02) 42 | **Merged pull requests:** 43 | 44 | - Use 3 latest ansible versions for testing [\#22](https://github.com/cloudalchemy/ansible-fluentd/pull/22) ([jkrol2](https://github.com/jkrol2)) 45 | - Fix issue when comparing string with int [\#19](https://github.com/cloudalchemy/ansible-fluentd/pull/19) ([xeroc](https://github.com/xeroc)) 46 | 47 | ## [0.0.8](https://galaxy.ansible.com/cloudalchemy/fluentd) (2018-05-27) 48 | **Fixed bugs:** 49 | 50 | - fix architecture var parsing [\#18](https://github.com/cloudalchemy/ansible-fluentd/pull/18) ([paulfantom](https://github.com/paulfantom)) 51 | 52 | **Merged pull requests:** 53 | 54 | - upgrade to molecule 2.x [\#16](https://github.com/cloudalchemy/ansible-fluentd/pull/16) ([paulfantom](https://github.com/paulfantom)) 55 | - Allow specifying plugin version [\#13](https://github.com/cloudalchemy/ansible-fluentd/pull/13) ([paulfantom](https://github.com/paulfantom)) 56 | - use binaries for metrics exporter [\#12](https://github.com/cloudalchemy/ansible-fluentd/pull/12) ([paulfantom](https://github.com/paulfantom)) 57 | - CI update; typos; docs [\#11](https://github.com/cloudalchemy/ansible-fluentd/pull/11) ([paulfantom](https://github.com/paulfantom)) 58 | 59 | ## [0.0.7](https://galaxy.ansible.com/cloudalchemy/fluentd) (2018-01-12) 60 | **Merged pull requests:** 61 | 62 | - Plugins [\#10](https://github.com/cloudalchemy/ansible-fluentd/pull/10) ([jkrol2](https://github.com/jkrol2)) 63 | 64 | ## [0.0.6](https://galaxy.ansible.com/cloudalchemy/fluentd) (2018-01-02) 65 | **Implemented enhancements:** 66 | 67 | - Add fluentd metrics exporter [\#3](https://github.com/cloudalchemy/ansible-fluentd/issues/3) 68 | 69 | **Merged pull requests:** 70 | 71 | - fix configuration files path [\#8](https://github.com/cloudalchemy/ansible-fluentd/pull/8) ([paulfantom](https://github.com/paulfantom)) 72 | - add metrics exporter [\#5](https://github.com/cloudalchemy/ansible-fluentd/pull/5) ([paulfantom](https://github.com/paulfantom)) 73 | 74 | ## [0.0.5](https://galaxy.ansible.com/cloudalchemy/fluentd) (2018-01-01) 75 | ## [0.0.4](https://galaxy.ansible.com/cloudalchemy/fluentd) (2017-12-16) 76 | **Merged pull requests:** 77 | 78 | - fix tests; restart service when config changes [\#9](https://github.com/cloudalchemy/ansible-fluentd/pull/9) ([paulfantom](https://github.com/paulfantom)) 79 | 80 | ## [0.0.3](https://galaxy.ansible.com/cloudalchemy/fluentd) (2017-12-11) 81 | **Fixed bugs:** 82 | 83 | - Fix service enabling on centos [\#1](https://github.com/cloudalchemy/ansible-fluentd/issues/1) 84 | 85 | **Closed issues:** 86 | 87 | - Use yum\_repository module [\#7](https://github.com/cloudalchemy/ansible-fluentd/issues/7) 88 | 89 | **Merged pull requests:** 90 | 91 | - use service module [\#4](https://github.com/cloudalchemy/ansible-fluentd/pull/4) ([jkrol2](https://github.com/jkrol2)) 92 | 93 | ## [0.0.2](https://galaxy.ansible.com/cloudalchemy/fluentd) (2017-12-05) 94 | ## [0.0.1](https://galaxy.ansible.com/cloudalchemy/fluentd) (2017-12-04) 95 | 96 | 97 | \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* --------------------------------------------------------------------------------