{"id":18601778,"url":"https://github.com/eficode/ansible-testing-example","last_synced_at":"2026-01-25T02:02:13.911Z","repository":{"id":152149585,"uuid":"123468169","full_name":"eficode/ansible-testing-example","owner":"eficode","description":"How to test ansible roles","archived":false,"fork":false,"pushed_at":"2018-03-21T08:36:22.000Z","size":11,"stargazers_count":1,"open_issues_count":0,"forks_count":2,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-05-16T17:44:34.231Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eficode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-01T17:25:20.000Z","updated_at":"2019-05-20T17:56:38.000Z","dependencies_parsed_at":null,"dependency_job_id":"047bb05d-28c9-45ee-b6e4-a5328baaf55c","html_url":"https://github.com/eficode/ansible-testing-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/eficode/ansible-testing-example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eficode%2Fansible-testing-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eficode%2Fansible-testing-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eficode%2Fansible-testing-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eficode%2Fansible-testing-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eficode","download_url":"https://codeload.github.com/eficode/ansible-testing-example/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eficode%2Fansible-testing-example/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28741632,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-25T01:40:51.112Z","status":"online","status_checked_at":"2026-01-25T02:00:06.841Z","response_time":113,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T02:09:21.983Z","updated_at":"2026-01-25T02:02:13.893Z","avatar_url":"https://github.com/eficode.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Testing ansible roles\n\nIt is a good practice to place roles into a public or private galaxy and automatically test that they work after every change.\n\n## Prerequisites\n- [Docker](https://www.docker.com/get-docker)\n- [Python](https://www.python.org/downloads/)\n- [Virtualenv](https://virtualenv.pypa.io/en/stable/installation/)\n\n## Preparations\nCreate and activate virtualenv\n```\nvirtualenv venv\nsource venv/bin/activate\n```\nInstall Ansible and Molecule\n```\npip install -r requirements.txt\n```\n## Getting started with molecule\n\n### Init role\n```\nmolecule init role --role-name complicated-nginx\ncd complicated-nginx\n```\n\n### Add a complicated template for nginx frontpage\n```\nmkdir templates\ncat \u003c\u003c'EOF' \u003e templates/index.html.j2\n\u003chtml\u003e\n\u003chead\u003e\n\u003ctitle\u003eWelcome to nginx!\u003c/title\u003e\n\u003cstyle\u003e\n    body {\n        width: 35em;\n        margin: 0 auto;\n        font-family: Tahoma, Verdana, Arial, sans-serif;\n    }\n\u003c/style\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n\u003ch1\u003eWelcome to nginx!\u003c/h1\u003e\n\u003cp\u003eIf you see this page, the nginx web server is successfully installed and\nworking. Further configuration is required.\n\n\u003cstrong\u003eAlso please mind that here's some overly complicated stuff that we might see for example in configuration files sometimes:\u003c/strong\u003e\n\n{% for c in raw_data if mapping[c] in \"deadbeef\" %}{{ c }}{% endfor %}\n\n\u003c/p\u003e\n\n\u003cp\u003eFor online documentation and support please refer to\n\u003ca href=\"http://nginx.org/\"\u003enginx.org\u003c/a\u003e.\u003cbr/\u003e\nCommercial support is available at\n\u003ca href=\"http://nginx.com/\"\u003enginx.com\u003c/a\u003e.\u003c/p\u003e\n\n\u003cp\u003e\u003cem\u003eThank you for using nginx.\u003c/em\u003e\u003c/p\u003e\n\u003c/body\u003e\n\u003c/html\u003e\nEOF\n```\n\n### Add some default variables\n```\ncat \u003c\u003c'EOF' \u003e defaults/main.yml\n---\nraw_data: \"eulmfkillcloldkue\"\nmapping:\n  q: o\n  c: d\n  e: d\n  o: b\n  i: a\n  d: e\n  p: u\n  r: k\n  a: l\n  m: o\n  f: e\n  l: u\n  k: z\n  u: w\nEOF\n```\n\n### Tasks for generating frontpage and running nginx\n```\ncat \u003c\u003c'EOF' \u003e tasks/main.yml\n---\n- name: generate index.html\n  template:\n    src: index.html.j2\n    dest: /usr/share/nginx/html/index.html\n\n- name: start nginx\n  shell: nginx\n  tags: skip_ansible_lint\n  register: start_nginx\n  failed_when: \"start_nginx.rc != 0 and 'Address in use' not in start_nginx.stderr\"\n  changed_when: false\nEOF\n```\n\n### Edit molecule file\n```\ncat \u003c\u003c'EOF' \u003e molecule/default/molecule.yml\n---\ndependency:\n  name: galaxy\ndriver:\n  name: docker\nlint:\n  name: yamllint\nplatforms:\n  - name: instance\n    image: nginx:alpine\n    published_ports:\n      - \"0.0.0.0:80:80/tcp\"\nprovisioner:\n  name: ansible\n  lint:\n    name: ansible-lint\nscenario:\n  name: default\nverifier:\n  name: testinfra\n  lint:\n    name: flake8\nEOF\n```\n\n### Converge\n**NOTE:** before converging, please look at defaults and the index template and try to figure out what it will result into. This is just an example but there are many cases where infra code is complicated and testing needs to be in place. For example iptable rules could be generated in similar manner.\n```\nmolecule converge\n```\n\n### See result\nOpen [localhost](http://localhost). Did you guess the answer?\n\n### Make tests\n```\ncat \u003c\u003c'EOF' \u003e molecule/default/tests/test_default.py\nimport os\n\nimport testinfra.utils.ansible_runner\n\ntestinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(\n    os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')\n\n\ndef test_index_file(host):\n    f = host.file('/usr/share/nginx/html/index.html')\n    assert \"lollerskates\" in f.content\nEOF\n```\nCan you spot the error in provided test case?\n\n### Run tests\n```\nmolecule verify\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feficode%2Fansible-testing-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feficode%2Fansible-testing-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feficode%2Fansible-testing-example/lists"}