diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..79776e8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.kitchen/*
diff --git a/.kitchen.yml b/.kitchen.yml
new file mode 100644
index 0000000..7a16e14
--- /dev/null
+++ b/.kitchen.yml
@@ -0,0 +1,27 @@
+---
+driver:
+  name: docker_cli
+
+transport:
+  name: docker_cli
+
+provisioner:
+  name: ansible_playbook
+  hosts: localhost
+  require_ansible_repo: false
+  require_ansible_omnibus: false
+  require_chef_for_busser: true
+  ansible_verbose: false
+  ansible_inventory: ./test/integration/inventory
+
+platforms:
+  - name: debian-9
+    driver_config:
+      image: "nishiki/debian9:ansible-<%= ENV['ANSIBLE_VERSION'] ? ENV['ANSIBLE_VERSION'] : '2.7' %>"
+      command: /bin/systemd
+      volume:
+        - /sys/fs/cgroup:/sys/fs/cgroup:ro
+      security_opt: seccomp=unconfined
+
+suites:
+  - name: default
diff --git a/.yamllint b/.yamllint
new file mode 100644
index 0000000..5465b58
--- /dev/null
+++ b/.yamllint
@@ -0,0 +1,12 @@
+---
+extends: default
+
+ignore: |
+  .kitchen/*
+  vendor/
+
+rules:
+  line-length:
+    max: 120
+    level: warning
+  truthy: false
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..016b6d1
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,8 @@
+# CHANGELOG
+
+This project adheres to [Semantic Versioning](http://semver.org/).
+Which is based on [Keep A Changelog](http://keepachangelog.com/)
+
+## [Unreleased]
+
+- first version
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..0d96441
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,8 @@
+source 'https://rubygems.org'
+
+group :development do
+  gem 'kitchen-ansible'
+  gem 'kitchen-docker_cli'
+  gem 'rubocop', '0.50.0'
+  gem 'test-kitchen'
+end
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 0000000..723a976
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,93 @@
+GEM
+  remote: https://rubygems.org/
+  specs:
+    ast (2.4.0)
+    builder (3.2.3)
+    erubis (2.7.0)
+    ffi (1.10.0)
+    gssapi (1.2.0)
+      ffi (>= 1.0.1)
+    gyoku (1.3.1)
+      builder (>= 2.1.2)
+    httpclient (2.8.3)
+    kitchen-ansible (0.47.4)
+      mixlib-shellout (>= 2.3.2)
+      net-ssh (>= 3)
+      test-kitchen (>= 1.17.0)
+    kitchen-docker_cli (0.19.0)
+      test-kitchen (>= 1.3)
+    little-plugger (1.1.4)
+    logging (2.2.2)
+      little-plugger (~> 1.1)
+      multi_json (~> 1.10)
+    mixlib-install (3.11.11)
+      mixlib-shellout
+      mixlib-versioning
+      thor
+    mixlib-shellout (2.4.4)
+    mixlib-versioning (1.2.7)
+    multi_json (1.13.1)
+    net-scp (2.0.0)
+      net-ssh (>= 2.6.5, < 6.0.0)
+    net-ssh (5.2.0)
+    net-ssh-gateway (2.0.0)
+      net-ssh (>= 4.0.0)
+    nori (2.6.0)
+    parallel (1.17.0)
+    parser (2.6.2.1)
+      ast (~> 2.4.0)
+    powerpack (0.1.2)
+    rainbow (2.2.2)
+      rake
+    rake (12.3.2)
+    rubocop (0.50.0)
+      parallel (~> 1.10)
+      parser (>= 2.3.3.1, < 3.0)
+      powerpack (~> 0.1)
+      rainbow (>= 2.2.2, < 3.0)
+      ruby-progressbar (~> 1.7)
+      unicode-display_width (~> 1.0, >= 1.0.1)
+    ruby-progressbar (1.10.0)
+    rubyntlm (0.6.2)
+    rubyzip (1.2.2)
+    test-kitchen (2.0.1)
+      mixlib-install (~> 3.6)
+      mixlib-shellout (>= 1.2, < 3.0)
+      net-scp (>= 1.1, < 3.0)
+      net-ssh (>= 2.9, < 6.0)
+      net-ssh-gateway (>= 1.2, < 3.0)
+      thor (~> 0.19)
+      winrm (~> 2.0)
+      winrm-elevated (~> 1.0)
+      winrm-fs (~> 1.1)
+    thor (0.20.3)
+    unicode-display_width (1.5.0)
+    winrm (2.3.1)
+      builder (>= 2.1.2)
+      erubis (~> 2.7)
+      gssapi (~> 1.2)
+      gyoku (~> 1.0)
+      httpclient (~> 2.2, >= 2.2.0.2)
+      logging (>= 1.6.1, < 3.0)
+      nori (~> 2.0)
+      rubyntlm (~> 0.6.0, >= 0.6.1)
+    winrm-elevated (1.1.1)
+      winrm (~> 2.0)
+      winrm-fs (~> 1.0)
+    winrm-fs (1.3.2)
+      erubis (~> 2.7)
+      logging (>= 1.6.1, < 3.0)
+      rubyzip (~> 1.1)
+      winrm (~> 2.0)
+
+PLATFORMS
+  ruby
+
+DEPENDENCIES
+  kitchen-ansible
+  kitchen-docker_cli
+  rubocop (= 0.50.0)
+  test-kitchen
+
+BUNDLED WITH
+   1.16.0
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..71326f8
--- /dev/null
+++ b/README.md
@@ -0,0 +1,93 @@
+# Ansible role: Influxdb
+
+[![Version](https://img.shields.io/badge/latest_version-1.0.0-green.svg)](https://git.yaegashi.fr/nishiki/ansible-role-influxdb/releases)
+[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://git.yaegashi.fr/nishiki/ansible-role-influxdb/src/branch/master/LICENSE)
+
+Install and configure InfluxDB
+
+## Requirements
+
+* Ansible >= 2.7
+* Debian Stretch
+
+## Role variables
+
+* `influxdb_databases` - array with the databases name
+* `influxdb_users` - array with the users informations
+
+```
+- name: test
+  password: secret
+  admin: true
+  state: present
+```
+
+* `influxdb_privileges` - array with the privileges
+
+```
+- user: test
+  database: metric
+  privilege: WRITE
+  state: present
+```
+
+* `influxdb_api_user` -  set the api user if you have enabled http authentification
+* `influxdb_api_password` - set the api password if you have enabled http authentification
+* `influxdb_api_port` - set the api port (default: `8086`)
+* `influxdb_config` - hash with the influxdb configuration (see [influxdb documentation](https://docs.influxdata.com/influxdb/v1.7/administration/config/))
+
+```
+  meta:
+    dir: /var/lib/influxdb/meta
+  data:
+    dir: /var/lib/influxdb/data
+    wal-dir: /var/lib/influxdb/wal
+```
+
+## How to use
+
+```
+- hosts: server
+  roles:
+    - influxdb
+```
+
+## Development
+
+### Test syntax with yamllint
+
+* install `python` and `python-pip`
+* install yamllint `pip install yamllint`
+* run `yamllint .`
+
+### Test syntax with ansible-lint
+
+* install `python` and `python-pip`
+* install yamllint `pip install ansible-lint`
+* run `ansible-lint .`
+
+### Tests with docker
+
+* install [docker](https://docs.docker.com/engine/installation/)
+* install ruby
+* install bundler `gem install bundler`
+* install dependencies `bundle install`
+* run the tests `kitchen test`
+
+## License
+
+```
+Copyright (c) 2019 Adrien Waksberg
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+```
diff --git a/defaults/main.yml b/defaults/main.yml
new file mode 100644
index 0000000..e019396
--- /dev/null
+++ b/defaults/main.yml
@@ -0,0 +1,15 @@
+---
+influxdb_databases: []
+influxdb_users: []
+influxdb_privileges: []
+influxdb_api_user: user
+influxdb_api_password: password
+influxdb_api_port: 8086
+influxdb_default_config:
+  meta:
+    dir: /var/lib/influxdb/meta
+  data:
+    dir: /var/lib/influxdb/data
+    wal-dir: /var/lib/influxdb/wal
+influxdb_config: {}
+influxdb_full_config: '{{ influxdb_default_config|combine(influxdb_config) }}'
diff --git a/handlers/main.yml b/handlers/main.yml
new file mode 100644
index 0000000..32777ab
--- /dev/null
+++ b/handlers/main.yml
@@ -0,0 +1,5 @@
+---
+- name: restart influxdb
+  systemd:
+    name: influxdb
+    state: restarted
diff --git a/library/influxdb_privilege.py b/library/influxdb_privilege.py
new file mode 100644
index 0000000..f957988
--- /dev/null
+++ b/library/influxdb_privilege.py
@@ -0,0 +1,94 @@
+#!/usr/bin/python
+
+from ansible.module_utils.basic import *
+import requests
+import json
+
+class InfluxdbPrivilege:
+  def __init__(self, user, database, privilege, api_host, api_port, api_user, api_password):
+    self.user = user
+    self.database = database
+    self.privilege = privilege
+    self.api_host = api_host
+    self.api_port = api_port
+    self.api_user = api_user
+    self.api_password = api_password
+    self.change = False
+    self.get_info()
+
+  def request(self, query):
+    url = 'http://{}:{}/query?q={}'.format(self.api_host, self.api_port, requests.utils.quote(query))
+    
+    if self.api_user is not None:
+      r = requests.get(url, auth=(self.api_user, self.api_password))
+    else:
+      r = requests.get(url)
+      
+    if r.status_code != 200:
+      raise Exception('Influxdb', 'Bad status code {}: {}'.format(r.status_code, r.text))
+    
+    return json.loads(r.text)
+
+  def get_info(self):
+    privileges = self.request(
+      'SHOW GRANTS FOR {}'.format(self.user),
+    )['results'][0]['series'][0]
+
+    if 'values' in privileges:
+      for privilege in privileges['values']:
+        if self.database == privilege[0]:
+          self.exist = True
+          if self.privilege != privilege[1]:
+            self.change = True
+          return
+
+    self.exist = False
+
+  def grant(self):
+    self.request(
+      'GRANT {} ON {} TO {}'.format(self.privilege, self.database, self.user)
+    )
+
+  def revoke(self):
+    self.request(
+      'REVOKE {} ON {} FROM {}'.format(self.privilege, self.database, self.user)
+    )
+  
+
+def main():
+  fields = {
+    'user':         { 'type': 'str', 'required': True },
+    'database':     { 'type': 'str', 'required': True },
+    'privilege':   { 'type': 'str', 'required': True, 'choices': ['ALL', 'WRITE', 'READ'] },
+    'api_user':     { 'type': 'str' },
+    'api_password': { 'type': 'str' },
+    'api_host':     { 'type': 'str', 'default': '127.0.0.1' },
+    'api_port':     { 'type': 'int', 'default': 8086 },
+    'state':        { 'type': 'str', 'default': 'present', 'choices': ['present', 'absent'] }
+  }
+  module = AnsibleModule(argument_spec=fields)
+  changed = False
+
+  influxdb_privilege = InfluxdbPrivilege(
+    module.params['user'],
+    module.params['database'],
+    module.params['privilege'],
+    module.params['api_host'],
+    module.params['api_port'],
+    module.params['api_user'],
+    module.params['api_password']
+  )
+
+  if module.params['state'] == 'present':
+    if not influxdb_privilege.exist or influxdb_privilege.change:
+      influxdb_privilege.grant()
+      changed = True
+  else:
+    if influxdb_privilege.exist:
+      influxdb_privilege.revoke()
+      changed = True
+ 
+  module.exit_json(changed=changed)
+
+if __name__ == '__main__':
+  main()
diff --git a/meta/main.yml b/meta/main.yml
new file mode 100644
index 0000000..c127d06
--- /dev/null
+++ b/meta/main.yml
@@ -0,0 +1,20 @@
+---
+galaxy_info:
+  role_name: Influxdb
+  author: Adrien Waksberg
+  company: Adrien Waksberg
+  description: Install and configure InfluxDB
+  license: Apache2
+  min_ansible_version: 2.7
+
+  platforms:
+    - name: Debian
+      versions:
+        - stretch
+
+  galaxy_tags:
+    - database
+    - influxdb
+    - timeseries
+
+dependencies: []
diff --git a/tasks/config.yml b/tasks/config.yml
new file mode 100644
index 0000000..99d36b7
--- /dev/null
+++ b/tasks/config.yml
@@ -0,0 +1,68 @@
+---
+- name: copy config file
+  template:
+    src: influxdb.conf.j2
+    dest: /etc/influxdb/influxdb.conf
+    owner: root
+    group: root
+    mode: 0644
+  notify: restart influxdb
+  tags: influxdb
+
+- name: start and enable service
+  systemd:
+    name: influxdb
+    state: started
+    enabled: yes
+  tags: influxdb
+
+- name: wait http api is up
+  wait_for:
+    port: 8086
+    timeout: 10
+  tags: influxdb
+
+- name: create users
+  influxdb_user:
+    user_name: '{{ item.name }}'
+    user_password: '{{ item.password }}'
+    admin: '{{ item.admin|default(false) }}'
+    username: '{{ influxdb_api_user }}'
+    password: '{{ influxdb_api_password }}'
+  loop: '{{ influxdb_users }}'
+  when: item.state is not defined or item.state != 'absent'
+  no_log: true
+  tags: influxdb
+
+- name: delete users
+  influxdb_user:
+    user_name: '{{ item.name }}'
+    username: '{{ influxdb_api_user }}'
+    password: '{{ influxdb_api_password }}'
+    state: absent
+  loop: '{{ influxdb_users }}'
+  when: item.state is defined and item.state == 'absent'
+  no_log: true
+  tags: influxdb
+
+- name: create databases
+  influxdb_database:
+    database_name: '{{ item }}'
+    username: '{{ influxdb_api_user }}'
+    password: '{{ influxdb_api_password }}'
+  loop: '{{ influxdb_databases }}'
+  no_log: true
+  tags: influxdb
+
+- name: create privileges
+  influxdb_privilege:
+    user: '{{ item.user }}'
+    database: '{{ item.database }}'
+    privilege: '{{ item.privilege }}'
+    api_user: '{{ influxdb_api_user }}'
+    api_password: '{{ influxdb_api_password }}'
+    api_port: '{{ influxdb_api_port }}'
+    state: '{{ item.state|default("present") }}'
+  loop: '{{ influxdb_privileges }}'
+  no_log: true
+  tags: influxdb
diff --git a/tasks/install.yml b/tasks/install.yml
new file mode 100644
index 0000000..a3212c6
--- /dev/null
+++ b/tasks/install.yml
@@ -0,0 +1,42 @@
+---
+- name: install depencies packages
+  apt:
+    name: '{{ packages }}'
+  vars:
+    packages:
+      - apt-transport-https
+      - collectd-core
+      - python-pip
+  register: result
+  until: result is succeeded
+  retries: 2
+  tags: influxdb
+
+- name: add key for influxdb repository
+  apt_key:
+    url: https://repos.influxdata.com/influxdb.key
+  register: result
+  until: result is succeeded
+  retries: 2
+  tags: influxdb
+
+- name: add influxdb repository
+  apt_repository:
+    repo: 'deb https://repos.influxdata.com/debian {{ ansible_distribution_release }} stable'
+  tags: influxdb
+
+- name: install influxdb package
+  apt:
+    name: influxdb
+  register: result
+  until: result is succeeded
+  retries: 2
+  tags: influxdb
+
+- name: install python-influxdb
+  pip:
+    name: influxdb
+  register: result
+  until: result is succeeded
+  retries: 2
+  tags: influxdb
diff --git a/tasks/main.yml b/tasks/main.yml
new file mode 100644
index 0000000..66e9a65
--- /dev/null
+++ b/tasks/main.yml
@@ -0,0 +1,3 @@
+---
+- import_tasks: install.yml
+- import_tasks: config.yml
diff --git a/templates/influxdb.conf.j2 b/templates/influxdb.conf.j2
new file mode 100644
index 0000000..1522e51
--- /dev/null
+++ b/templates/influxdb.conf.j2
@@ -0,0 +1,13 @@
+# {{ ansible_managed }}
+{% for section, options in influxdb_full_config.iteritems()  %}
+
+[{{ section }}]
+{% for option, value in options.iteritems() %}
+{{ option }} = {% if value is sameas true %}true
+{% elif value is sameas false %}false
+{% elif value is string %}"{{ value }}"
+{% elif value is number %}{{ value }}
+{% else %}["{{ value|join('", "') }}"]
+{% endif %}
+{% endfor %}
+{% endfor %}
diff --git a/test/integration/default/.kitchen/logs/kitchen.log b/test/integration/default/.kitchen/logs/kitchen.log
new file mode 100644
index 0000000..9c3145c
--- /dev/null
+++ b/test/integration/default/.kitchen/logs/kitchen.log
@@ -0,0 +1,28 @@
+E, [2019-01-17T09:43:25.055727 #24689] ERROR -- Kitchen: ------Exception-------
+E, [2019-01-17T09:43:25.055802 #24689] ERROR -- Kitchen: Class: Kitchen::UserError
+E, [2019-01-17T09:43:25.055823 #24689] ERROR -- Kitchen: Message: Kitchen YAML file /home/awaksberg/git/ansible-role-influxdb/test/integration/default/.kitchen.yml does not exist.
+E, [2019-01-17T09:43:25.055835 #24689] ERROR -- Kitchen: ----------------------
+E, [2019-01-17T09:43:25.055845 #24689] ERROR -- Kitchen: ------Backtrace-------
+E, [2019-01-17T09:43:25.055854 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/loader/yaml.rb:65:in `read'
+E, [2019-01-17T09:43:25.055863 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/config.rb:152:in `data'
+E, [2019-01-17T09:43:25.055872 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/config.rb:131:in `suites'
+E, [2019-01-17T09:43:25.055881 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/config.rb:182:in `filter_instances'
+E, [2019-01-17T09:43:25.055891 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/config.rb:141:in `build_instances'
+E, [2019-01-17T09:43:25.055900 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/config.rb:117:in `instances'
+E, [2019-01-17T09:43:25.055909 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/command.rb:112:in `filtered_instances'
+E, [2019-01-17T09:43:25.055918 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/command.rb:142:in `parse_subcommand'
+E, [2019-01-17T09:43:25.055927 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/command/list.rb:30:in `call'
+E, [2019-01-17T09:43:25.055936 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/cli.rb:52:in `perform'
+E, [2019-01-17T09:43:25.055947 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/cli.rb:120:in `list'
+E, [2019-01-17T09:43:25.055957 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/thor-0.20.3/lib/thor/command.rb:27:in `run'
+E, [2019-01-17T09:43:25.055966 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'
+E, [2019-01-17T09:43:25.055975 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/thor-0.20.3/lib/thor.rb:387:in `dispatch'
+E, [2019-01-17T09:43:25.055984 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/thor-0.20.3/lib/thor/base.rb:466:in `start'
+E, [2019-01-17T09:43:25.055993 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/bin/kitchen:13:in `block in <top (required)>'
+E, [2019-01-17T09:43:25.056002 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/errors.rb:171:in `with_friendly_errors'
+E, [2019-01-17T09:43:25.056011 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/bin/kitchen:13:in `<top (required)>'
+E, [2019-01-17T09:43:25.056020 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/bin/kitchen:23:in `load'
+E, [2019-01-17T09:43:25.056029 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/bin/kitchen:23:in `<main>'
+E, [2019-01-17T09:43:25.056039 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/bin/ruby_executable_hooks:24:in `eval'
+E, [2019-01-17T09:43:25.056048 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/bin/ruby_executable_hooks:24:in `<main>'
+E, [2019-01-17T09:43:25.056057 #24689] ERROR -- Kitchen: ----End Backtrace-----
diff --git a/test/integration/default/default.yml b/test/integration/default/default.yml
new file mode 100644
index 0000000..d992950
--- /dev/null
+++ b/test/integration/default/default.yml
@@ -0,0 +1,32 @@
+---
+- hosts: localhost
+  connection: local
+  vars:
+    influxdb_users:
+      - name: paul
+        password: test
+        admin: yes
+      - name: adrien
+        password: test2
+      - name: antoine
+        state: absent
+    influxdb_databases:
+      - new_database
+    influxdb_privileges:
+      - user: adrien
+        database: new_database
+        privilege: WRITE
+    influxdb_config:
+      '[collectd]':
+        enabled: true
+        port: 25826
+        database: collectd
+        typesdb: /usr/share/collectd/types.db
+
+  roles:
+    - ansible-role-influxdb
+
+  pre_tasks:
+    - name: install  collectd package
+      apt:
+        name: collectd-core
diff --git a/test/integration/default/serverspec/default_spec.rb b/test/integration/default/serverspec/default_spec.rb
new file mode 100644
index 0000000..631558a
--- /dev/null
+++ b/test/integration/default/serverspec/default_spec.rb
@@ -0,0 +1,50 @@
+require 'serverspec'
+
+set :backend, :exec
+
+puts
+puts '================================'
+puts %x(ansible --version)
+puts '================================'
+
+describe package('influxdb') do
+  it { should be_installed }
+end
+
+describe file('/etc/influxdb/influxdb.conf') do
+  it { should be_file }
+  it { should be_mode 644 }
+  it { should be_owned_by 'root' }
+  it { should be_grouped_into 'root' }
+  it { should contain 'enabled = true' }
+end
+
+describe service('influxdb') do
+  it { should be_enabled }
+  it { should be_running.under('systemd') }
+end
+
+describe port(8086) do
+  it { should be_listening.with('tcp6') }
+end
+
+describe port(25_826) do
+  it { should be_listening.with('udp6') }
+end
+
+describe command('influx -execute "SHOW USERS"') do
+  its(:exit_status) { should eq 0 }
+  its(:stdout) { should match(/paul\s+true/) }
+  its(:stdout) { should match(/adrien\s+false/) }
+  its(:stdout) { should_not match 'antoine' }
+end
+
+describe command('influx -execute "SHOW DATABASES"') do
+  its(:exit_status) { should eq 0 }
+  its(:stdout) { should match 'new_database' }
+end
+
+describe command('influx -execute "SHOW GRANTS FOR adrien"') do
+  its(:exit_status) { should eq 0 }
+  its(:stdout) { should match(/new_database\s+WRITE/) }
+end
diff --git a/test/integration/inventory b/test/integration/inventory
new file mode 100644
index 0000000..2fbb50c
--- /dev/null
+++ b/test/integration/inventory
@@ -0,0 +1 @@
+localhost