diff --git a/.drone.jsonnet b/.drone.jsonnet
new file mode 100644
index 0000000..17dc3cd
--- /dev/null
+++ b/.drone.jsonnet
@@ -0,0 +1,109 @@
+local AnsibleVersions(version="latest", package="ansible") = {
+ name: "ansible-" + version,
+ image: "python:3.7",
+ pull: "always",
+ environment: {
+ PY_COLORS: 1
+ },
+ commands: [
+ "pip install " + package + " ansible-later~=0.2.0 -qq",
+ "git clone https://gitea.rknet.org/ansible/ansible-later-policy.git ~/policy",
+ "ansible-later -c ~/policy/config.yml"
+ ],
+ depends_on: [
+ "clone",
+ ],
+};
+
+local PipelineLinting = {
+ kind: "pipeline",
+ name: "linting",
+ platform: {
+ os: "linux",
+ arch: "amd64",
+ },
+ steps: [
+ AnsibleVersions(version="latest", package="ansible"),
+ AnsibleVersions(version="master", package="git+https://github.com/ansible/ansible.git@devel"),
+ ],
+ trigger: {
+ ref: ["refs/heads/master", "refs/tags/**", "refs/pull/**"],
+ },
+};
+
+local PipelineDeployment = {
+ kind: "pipeline",
+ name: "deployment",
+ platform: {
+ os: "linux",
+ arch: "amd64",
+ },
+ workspace: {
+ base: "/drone/src",
+ path: "xoxys.dnsmasq"
+ },
+ steps: [
+ {
+ name: "molecule",
+ image: "xoxys/molecule:ec2-linux-amd64",
+ pull: "always",
+ environment: {
+ ANSIBLE_ROLES_PATH: "/drone/src",
+ AWS_ACCESS_KEY_ID: { "from_secret": "aws_access_key_id" },
+ AWS_SECRET_ACCESS_KEY: { "from_secret": "aws_secret_access_key" },
+ AWS_REGION: "eu-central-1",
+ MOLECULE_CUSTOM_MODULES_REPO: "https://gitea.rknet.org/ansible/custom_modules",
+ MOLECULE_CUSTOM_FILTERS_REPO: "https://gitea.rknet.org/ansible/custom_filters",
+ PY_COLORS: 1
+ },
+ commands: [
+ "/bin/bash /docker-entrypoint.sh",
+ "molecule test --scenario-name ec2-centos-7",
+ ],
+ },
+ ],
+ depends_on: [
+ "linting",
+ ],
+ trigger: {
+ ref: ["refs/heads/master", "refs/tags/**"],
+ },
+};
+
+local PipelineNotifications = {
+ kind: "pipeline",
+ name: "notifications",
+ platform: {
+ os: "linux",
+ arch: "amd64",
+ },
+ clone: {
+ disable: true,
+ },
+ steps: [
+ {
+ name: "matrix",
+ image: "plugins/matrix",
+ settings: {
+ homeserver: "https://matrix.rknet.org",
+ roomid: "MtidqQXWWAtQcByBhH:rknet.org",
+ template: "Status: **{{ build.status }}**
Build: [{{ repo.Owner }}/{{ repo.Name }}]({{ build.link }}) ({{ build.branch }}) by {{ build.author }}
Message: {{ build.message }}",
+ username: { "from_secret": "matrix_username" },
+ password: { "from_secret": "matrix_password" },
+ },
+ },
+ ],
+ depends_on: [
+ "deployment",
+ ],
+ trigger: {
+ status: [ "success", "failure" ],
+ ref: ["refs/heads/master", "refs/tags/**"],
+ },
+};
+
+[
+ PipelineLinting,
+ PipelineDeployment,
+ PipelineNotifications,
+]
diff --git a/.drone.yml b/.drone.yml
index 289d224..05bb680 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -1,22 +1,116 @@
---
kind: pipeline
-name: default
+name: linting
+
+platform:
+ os: linux
+ arch: amd64
steps:
- - name: ansible-latest
- image: python:2.7
- pull: always
- commands:
- - pip install ansible ansible-later -q
- - git clone https://gitea.rknet.org/ansible/ansible-later-policy.git ~/policy
- - git ls-files *[^LICENSE,.md] | xargs ansible-later -c ~/policy/config.ini
- depends_on: [ clone ]
+- name: ansible-latest
+ pull: always
+ image: python:3.7
+ commands:
+ - pip install ansible ansible-later~=0.2.0 -qq
+ - git clone https://gitea.rknet.org/ansible/ansible-later-policy.git ~/policy
+ - ansible-later -c ~/policy/config.yml
+ environment:
+ PY_COLORS: 1
+ depends_on:
+ - clone
- - name: ansible-master
- image: python:2.7
- pull: always
- commands:
- - pip install ansible ansible-later -q
- - git clone https://gitea.rknet.org/ansible/ansible-later-policy.git ~/policy
- - git ls-files *[^LICENSE,.md] | xargs ansible-later -c ~/policy/config.ini
- depends_on: [ clone ]
+- name: ansible-master
+ pull: always
+ image: python:3.7
+ commands:
+ - "pip install git+https://github.com/ansible/ansible.git@devel ansible-later~=0.2.0 -qq"
+ - git clone https://gitea.rknet.org/ansible/ansible-later-policy.git ~/policy
+ - ansible-later -c ~/policy/config.yml
+ environment:
+ PY_COLORS: 1
+ depends_on:
+ - clone
+
+trigger:
+ ref:
+ - refs/heads/master
+ - "refs/tags/**"
+ - "refs/pull/**"
+
+---
+kind: pipeline
+name: deployment
+
+platform:
+ os: linux
+ arch: amd64
+
+workspace:
+ base: /drone/src
+ path: xoxys.dnsmasq
+
+steps:
+- name: molecule
+ pull: always
+ image: xoxys/molecule:ec2-linux-amd64
+ commands:
+ - /bin/bash /docker-entrypoint.sh
+ - molecule test --scenario-name ec2-centos-7
+ environment:
+ ANSIBLE_ROLES_PATH: /drone/src
+ AWS_ACCESS_KEY_ID:
+ from_secret: aws_access_key_id
+ AWS_REGION: eu-central-1
+ AWS_SECRET_ACCESS_KEY:
+ from_secret: aws_secret_access_key
+ MOLECULE_CUSTOM_FILTERS_REPO: https://gitea.rknet.org/ansible/custom_filters
+ MOLECULE_CUSTOM_MODULES_REPO: https://gitea.rknet.org/ansible/custom_modules
+ PY_COLORS: 1
+
+trigger:
+ ref:
+ - refs/heads/master
+ - "refs/tags/**"
+
+depends_on:
+- linting
+
+---
+kind: pipeline
+name: notifications
+
+platform:
+ os: linux
+ arch: amd64
+
+clone:
+ disable: true
+
+steps:
+- name: matrix
+ image: plugins/matrix
+ settings:
+ homeserver: https://matrix.rknet.org
+ password:
+ from_secret: matrix_password
+ roomid: MtidqQXWWAtQcByBhH:rknet.org
+ template: "Status: **{{ build.status }}**
Build: [{{ repo.Owner }}/{{ repo.Name }}]({{ build.link }}) ({{ build.branch }}) by {{ build.author }}
Message: {{ build.message }}"
+ username:
+ from_secret: matrix_username
+
+trigger:
+ ref:
+ - refs/heads/master
+ - "refs/tags/**"
+ status:
+ - success
+ - failure
+
+depends_on:
+- deployment
+
+---
+kind: signature
+hmac: a2a64dc690a24137ccf38e56d6a7499b30996f9ef531788d9817b7395bc411fd
+
+...
diff --git a/molecule/default/INSTALL.rst b/molecule/default/INSTALL.rst
new file mode 100644
index 0000000..f305f0b
--- /dev/null
+++ b/molecule/default/INSTALL.rst
@@ -0,0 +1,22 @@
+*******
+Amazon Web Services driver installation guide
+*******
+
+Requirements
+============
+
+* An AWS credentials rc file
+
+Install
+=======
+
+Please refer to the `Virtual environment`_ documentation for installation best
+practices. If not using a virtual environment, please consider passing the
+widely recommended `'--user' flag`_ when invoking ``pip``.
+
+.. _Virtual environment: https://virtualenv.pypa.io/en/latest/
+.. _'--user' flag: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site
+
+.. code-block:: bash
+
+ $ pip install 'molecule[ec2]'
diff --git a/molecule/default/create.yml b/molecule/default/create.yml
new file mode 100644
index 0000000..4ed1a0c
--- /dev/null
+++ b/molecule/default/create.yml
@@ -0,0 +1,125 @@
+---
+- name: Create
+ hosts: localhost
+ connection: local
+ gather_facts: false
+ no_log: "{{ not (lookup('env', 'MOLECULE_DEBUG') | bool or molecule_yml.provisioner.log|default(false) | bool) }}"
+ vars:
+ ssh_user: ubuntu
+ ssh_port: 22
+
+ security_group_name: molecule
+ security_group_description: Security group for testing Molecule
+ security_group_rules:
+ - proto: tcp
+ from_port: "{{ ssh_port }}"
+ to_port: "{{ ssh_port }}"
+ cidr_ip: '0.0.0.0/0'
+ - proto: icmp
+ from_port: 8
+ to_port: -1
+ cidr_ip: '0.0.0.0/0'
+ security_group_rules_egress:
+ - proto: -1
+ from_port: 0
+ to_port: 0
+ cidr_ip: '0.0.0.0/0'
+
+ keypair_name: molecule_key
+ keypair_path: "{{ lookup('env', 'MOLECULE_EPHEMERAL_DIRECTORY') }}/ssh_key"
+ tasks:
+ - name: Create security group
+ ec2_group:
+ name: "{{ security_group_name }}"
+ description: "{{ security_group_name }}"
+ rules: "{{ security_group_rules }}"
+ rules_egress: "{{ security_group_rules_egress }}"
+
+ - name: Test for presence of local keypair
+ stat:
+ path: "{{ keypair_path }}"
+ register: keypair_local
+
+ - name: Delete remote keypair
+ ec2_key:
+ name: "{{ keypair_name }}"
+ state: absent
+ when: not keypair_local.stat.exists
+
+ - name: Create keypair
+ ec2_key:
+ name: "{{ keypair_name }}"
+ register: keypair
+
+ - name: Persist the keypair
+ copy:
+ dest: "{{ keypair_path }}"
+ content: "{{ keypair.key.private_key }}"
+ mode: 0600
+ when: keypair.changed
+
+ - name: Create molecule instance(s)
+ ec2:
+ key_name: "{{ keypair_name }}"
+ image: "{{ item.image }}"
+ instance_type: "{{ item.instance_type }}"
+ vpc_subnet_id: "{{ item.vpc_subnet_id }}"
+ group: "{{ security_group_name }}"
+ instance_tags:
+ instance: "{{ item.name }}"
+ wait: true
+ assign_public_ip: true
+ exact_count: 1
+ count_tag:
+ instance: "{{ item.name }}"
+ register: server
+ with_items: "{{ molecule_yml.platforms }}"
+ async: 7200
+ poll: 0
+
+ - name: Wait for instance(s) creation to complete
+ async_status:
+ jid: "{{ item.ansible_job_id }}"
+ register: ec2_jobs
+ until: ec2_jobs.finished
+ retries: 300
+ with_items: "{{ server.results }}"
+
+ # Mandatory configuration for Molecule to function.
+
+ - name: Populate instance config dict
+ set_fact:
+ instance_conf_dict: {
+ 'instance': "{{ item.instances[0].tags.instance }}",
+ 'address': "{{ item.instances[0].public_ip }}",
+ 'user': "{{ ssh_user }}",
+ 'port': "{{ ssh_port }}",
+ 'identity_file': "{{ keypair_path }}",
+ 'instance_ids': "{{ item.instance_ids }}", }
+ with_items: "{{ ec2_jobs.results }}"
+ register: instance_config_dict
+ when: server.changed | bool
+
+ - name: Convert instance config dict to a list
+ set_fact:
+ instance_conf: "{{ instance_config_dict.results | map(attribute='ansible_facts.instance_conf_dict') | list }}"
+ when: server.changed | bool
+
+ - name: Dump instance config
+ copy:
+ content: "{{ instance_conf | to_json | from_json | molecule_to_yaml | molecule_header }}"
+ dest: "{{ molecule_instance_config }}"
+ when: server.changed | bool
+
+ - name: Wait for SSH
+ wait_for:
+ port: "{{ ssh_port }}"
+ host: "{{ item.address }}"
+ search_regex: SSH
+ delay: 10
+ timeout: 320
+ with_items: "{{ lookup('file', molecule_instance_config) | molecule_from_yaml }}"
+
+ - name: Wait for boot process to finish
+ pause:
+ minutes: 2
diff --git a/molecule/default/destroy.yml b/molecule/default/destroy.yml
new file mode 100644
index 0000000..b460c1e
--- /dev/null
+++ b/molecule/default/destroy.yml
@@ -0,0 +1,47 @@
+---
+- name: Destroy
+ hosts: localhost
+ connection: local
+ gather_facts: false
+ no_log: "{{ not (lookup('env', 'MOLECULE_DEBUG') | bool or molecule_yml.provisioner.log|default(false) | bool) }}"
+ tasks:
+ - block:
+ - name: Populate instance config
+ set_fact:
+ instance_conf: "{{ lookup('file', molecule_instance_config) | molecule_from_yaml }}"
+ skip_instances: false
+ rescue:
+ - name: Populate instance config when file missing
+ set_fact:
+ instance_conf: {}
+ skip_instances: true
+
+ - name: Destroy molecule instance(s)
+ ec2:
+ state: absent
+ instance_ids: "{{ item.instance_ids }}"
+ register: server
+ with_items: "{{ instance_conf }}"
+ when: not skip_instances
+ async: 7200
+ poll: 0
+
+ - name: Wait for instance(s) deletion to complete
+ async_status:
+ jid: "{{ item.ansible_job_id }}"
+ register: ec2_jobs
+ until: ec2_jobs.finished
+ retries: 300
+ with_items: "{{ server.results }}"
+
+ # Mandatory configuration for Molecule to function.
+
+ - name: Populate instance config
+ set_fact:
+ instance_conf: {}
+
+ - name: Dump instance config
+ copy:
+ content: "{{ instance_conf | to_json | from_json | molecule_to_yaml | molecule_header }}"
+ dest: "{{ molecule_instance_config }}"
+ when: server.changed | bool
diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml
new file mode 100644
index 0000000..6f88100
--- /dev/null
+++ b/molecule/default/molecule.yml
@@ -0,0 +1,20 @@
+---
+dependency:
+ name: galaxy
+driver:
+ name: ec2
+lint:
+ name: yamllint
+platforms:
+ - name: instance
+ image: ami-a5b196c0
+ instance_type: t2.micro
+ vpc_subnet_id: subnet-6456fd1f
+provisioner:
+ name: ansible
+ lint:
+ name: ansible-lint
+verifier:
+ name: testinfra
+ lint:
+ name: flake8
diff --git a/molecule/default/playbook.yml b/molecule/default/playbook.yml
new file mode 100644
index 0000000..8df6d60
--- /dev/null
+++ b/molecule/default/playbook.yml
@@ -0,0 +1,5 @@
+---
+- name: Converge
+ hosts: all
+ roles:
+ - role: xoxys.dnsmasq
diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml
new file mode 100644
index 0000000..ddb01fb
--- /dev/null
+++ b/molecule/default/prepare.yml
@@ -0,0 +1,9 @@
+---
+- name: Prepare
+ hosts: all
+ gather_facts: false
+ tasks:
+ - name: Install python for Ansible
+ raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal python-zipstream)
+ become: true
+ changed_when: false
diff --git a/molecule/default/tests/test_default.py b/molecule/default/tests/test_default.py
new file mode 100644
index 0000000..eedd64a
--- /dev/null
+++ b/molecule/default/tests/test_default.py
@@ -0,0 +1,14 @@
+import os
+
+import testinfra.utils.ansible_runner
+
+testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
+ os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')
+
+
+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/ec2-centos-7/INSTALL.rst b/molecule/ec2-centos-7/INSTALL.rst
new file mode 100644
index 0000000..f305f0b
--- /dev/null
+++ b/molecule/ec2-centos-7/INSTALL.rst
@@ -0,0 +1,22 @@
+*******
+Amazon Web Services driver installation guide
+*******
+
+Requirements
+============
+
+* An AWS credentials rc file
+
+Install
+=======
+
+Please refer to the `Virtual environment`_ documentation for installation best
+practices. If not using a virtual environment, please consider passing the
+widely recommended `'--user' flag`_ when invoking ``pip``.
+
+.. _Virtual environment: https://virtualenv.pypa.io/en/latest/
+.. _'--user' flag: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site
+
+.. code-block:: bash
+
+ $ pip install 'molecule[ec2]'
diff --git a/molecule/ec2-centos-7/create.yml b/molecule/ec2-centos-7/create.yml
new file mode 100644
index 0000000..d9ca3d9
--- /dev/null
+++ b/molecule/ec2-centos-7/create.yml
@@ -0,0 +1,124 @@
+---
+- name: Create
+ hosts: localhost
+ connection: local
+ gather_facts: false
+ no_log: "{{ not (lookup('env', 'MOLECULE_DEBUG') | bool or molecule_yml.provisioner.log|default(false) | bool) }}"
+ vars:
+ ssh_user: centos
+ ssh_port: 22
+
+ security_group_name: molecule
+ security_group_description: Security group for testing Molecule
+ security_group_rules:
+ - proto: tcp
+ from_port: "{{ ssh_port }}"
+ to_port: "{{ ssh_port }}"
+ cidr_ip: '0.0.0.0/0'
+ - proto: icmp
+ from_port: 8
+ to_port: -1
+ cidr_ip: '0.0.0.0/0'
+ security_group_rules_egress:
+ - proto: -1
+ from_port: 0
+ to_port: 0
+ cidr_ip: '0.0.0.0/0'
+
+ keypair_name: molecule_key_dnsmasq
+ keypair_path: "{{ lookup('env', 'MOLECULE_EPHEMERAL_DIRECTORY') }}/ssh_key"
+ tasks:
+ - name: Create security group
+ ec2_group:
+ name: "{{ security_group_name }}"
+ description: "{{ security_group_name }}"
+ rules: "{{ security_group_rules }}"
+ rules_egress: "{{ security_group_rules_egress }}"
+
+ - name: Delete remote keypair
+ ec2_key:
+ name: "{{ keypair_name }}"
+ state: absent
+
+ - name: Create keypair
+ ec2_key:
+ name: "{{ keypair_name }}"
+ register: keypair
+
+ - name: Persist the keypair
+ copy:
+ dest: "{{ keypair_path }}"
+ content: "{{ keypair.key.private_key }}"
+ mode: 0600
+ when: keypair.changed
+
+ - name: Create molecule instance(s)
+ ec2:
+ key_name: "{{ keypair_name }}"
+ image: "{{ item.image }}"
+ instance_type: "{{ item.instance_type }}"
+ vpc_subnet_id: "{{ item.vpc_subnet_id }}"
+ group: "{{ security_group_name }}"
+ instance_tags:
+ instance: "{{ item.name }}"
+ wait: true
+ assign_public_ip: true
+ exact_count: 1
+ count_tag:
+ instance: "{{ item.name }}"
+ volumes:
+ - device_name: /dev/sda1
+ volume_type: gp2
+ volume_size: 8
+ delete_on_termination: yes
+ register: server
+ with_items: "{{ molecule_yml.platforms }}"
+ async: 7200
+ poll: 0
+
+ - name: Wait for instance(s) creation to complete
+ async_status:
+ jid: "{{ item.ansible_job_id }}"
+ register: ec2_jobs
+ until: ec2_jobs.finished
+ retries: 300
+ with_items: "{{ server.results }}"
+
+ # Mandatory configuration for Molecule to function.
+
+ - name: Populate instance config dict
+ set_fact:
+ instance_conf_dict: {
+ 'instance': "{{ item.instances[0].tags.instance }}",
+ 'address': "{{ item.instances[0].public_ip }}",
+ 'user': "{{ ssh_user }}",
+ 'port': "{{ ssh_port }}",
+ 'identity_file': "{{ keypair_path }}",
+ 'instance_ids': "{{ item.instance_ids }}", }
+ with_items: "{{ ec2_jobs.results }}"
+ register: instance_config_dict
+ when: server.changed | bool
+
+ - name: Convert instance config dict to a list
+ set_fact:
+ instance_conf: "{{ instance_config_dict.results | map(attribute='ansible_facts.instance_conf_dict') | list }}"
+ when: server.changed | bool
+
+ - name: Dump instance config
+ copy:
+ content: "{{ instance_conf | to_json | from_json | molecule_to_yaml | molecule_header }}"
+ dest: "{{ molecule_instance_config }}"
+ when: server.changed | bool
+
+ - name: Wait for SSH
+ wait_for:
+ port: "{{ ssh_port }}"
+ host: "{{ item.address }}"
+ search_regex: SSH
+ delay: 10
+ timeout: 320
+ with_items: "{{ lookup('file', molecule_instance_config) | molecule_from_yaml }}"
+
+ - name: Wait for boot process to finish
+ pause:
+ minutes: 2
diff --git a/molecule/ec2-centos-7/destroy.yml b/molecule/ec2-centos-7/destroy.yml
new file mode 100644
index 0000000..b460c1e
--- /dev/null
+++ b/molecule/ec2-centos-7/destroy.yml
@@ -0,0 +1,47 @@
+---
+- name: Destroy
+ hosts: localhost
+ connection: local
+ gather_facts: false
+ no_log: "{{ not (lookup('env', 'MOLECULE_DEBUG') | bool or molecule_yml.provisioner.log|default(false) | bool) }}"
+ tasks:
+ - block:
+ - name: Populate instance config
+ set_fact:
+ instance_conf: "{{ lookup('file', molecule_instance_config) | molecule_from_yaml }}"
+ skip_instances: false
+ rescue:
+ - name: Populate instance config when file missing
+ set_fact:
+ instance_conf: {}
+ skip_instances: true
+
+ - name: Destroy molecule instance(s)
+ ec2:
+ state: absent
+ instance_ids: "{{ item.instance_ids }}"
+ register: server
+ with_items: "{{ instance_conf }}"
+ when: not skip_instances
+ async: 7200
+ poll: 0
+
+ - name: Wait for instance(s) deletion to complete
+ async_status:
+ jid: "{{ item.ansible_job_id }}"
+ register: ec2_jobs
+ until: ec2_jobs.finished
+ retries: 300
+ with_items: "{{ server.results }}"
+
+ # Mandatory configuration for Molecule to function.
+
+ - name: Populate instance config
+ set_fact:
+ instance_conf: {}
+
+ - name: Dump instance config
+ copy:
+ content: "{{ instance_conf | to_json | from_json | molecule_to_yaml | molecule_header }}"
+ dest: "{{ molecule_instance_config }}"
+ when: server.changed | bool
diff --git a/molecule/ec2-centos-7/molecule.yml b/molecule/ec2-centos-7/molecule.yml
new file mode 100644
index 0000000..6896e69
--- /dev/null
+++ b/molecule/ec2-centos-7/molecule.yml
@@ -0,0 +1,22 @@
+---
+dependency:
+ name: galaxy
+driver:
+ name: ec2
+platforms:
+ - name: centos-7-dnsmasq
+ image: ami-04cf43aca3e6f3de3
+ instance_type: t2.micro
+ vpc_subnet_id: subnet-9b6896f1
+lint:
+ name: yamllint
+ enabled: False
+provisioner:
+ name: ansible
+ lint:
+ name: ansible-lint
+ enabled: False
+verifier:
+ name: testinfra
+ lint:
+ name: flake8
diff --git a/molecule/ec2-centos-7/playbook.yml b/molecule/ec2-centos-7/playbook.yml
new file mode 100644
index 0000000..8df6d60
--- /dev/null
+++ b/molecule/ec2-centos-7/playbook.yml
@@ -0,0 +1,5 @@
+---
+- name: Converge
+ hosts: all
+ roles:
+ - role: xoxys.dnsmasq
diff --git a/molecule/ec2-centos-7/prepare.yml b/molecule/ec2-centos-7/prepare.yml
new file mode 100644
index 0000000..ddb01fb
--- /dev/null
+++ b/molecule/ec2-centos-7/prepare.yml
@@ -0,0 +1,9 @@
+---
+- name: Prepare
+ hosts: all
+ gather_facts: false
+ tasks:
+ - name: Install python for Ansible
+ raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal python-zipstream)
+ become: true
+ changed_when: false
diff --git a/molecule/ec2-centos-7/tests/test_default.py b/molecule/ec2-centos-7/tests/test_default.py
new file mode 100644
index 0000000..04253a1
--- /dev/null
+++ b/molecule/ec2-centos-7/tests/test_default.py
@@ -0,0 +1,20 @@
+import os
+
+import testinfra.utils.ansible_runner
+
+import warnings
+warnings.filterwarnings("ignore", category=DeprecationWarning)
+
+testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
+ os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')
+
+
+def test_dnsmasq_is_installed(host):
+ dnsmasq = host.package("dnsmasq")
+ assert dnsmasq.is_installed
+
+
+def test_dnsmasq_running_and_enabled(host):
+ dnsmasq = host.service("dnsmasq")
+ assert dnsmasq.is_running
+ assert dnsmasq.is_enabled
diff --git a/molecule/pytest.ini b/molecule/pytest.ini
new file mode 100644
index 0000000..c24fe5b
--- /dev/null
+++ b/molecule/pytest.ini
@@ -0,0 +1,3 @@
+[pytest]
+filterwarnings =
+ ignore::DeprecationWarning