{"id":16179276,"url":"https://github.com/jonashackt/molecule-ansible-google-cloud","last_synced_at":"2026-03-06T15:02:00.976Z","repository":{"id":38395920,"uuid":"173297477","full_name":"jonashackt/molecule-ansible-google-cloud","owner":"jonashackt","description":"Example projects showing how to do test-driven development of Ansible roles and running those tests on multiple Cloud providers at the same time","archived":false,"fork":false,"pushed_at":"2022-06-23T14:34:51.000Z","size":470,"stargazers_count":3,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-07T11:47:16.340Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Jinja","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jonashackt.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}},"created_at":"2019-03-01T12:21:24.000Z","updated_at":"2022-06-23T14:34:56.000Z","dependencies_parsed_at":"2022-08-27T05:42:00.678Z","dependency_job_id":null,"html_url":"https://github.com/jonashackt/molecule-ansible-google-cloud","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jonashackt/molecule-ansible-google-cloud","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonashackt%2Fmolecule-ansible-google-cloud","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonashackt%2Fmolecule-ansible-google-cloud/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonashackt%2Fmolecule-ansible-google-cloud/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonashackt%2Fmolecule-ansible-google-cloud/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jonashackt","download_url":"https://codeload.github.com/jonashackt/molecule-ansible-google-cloud/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonashackt%2Fmolecule-ansible-google-cloud/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30182686,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T14:42:24.748Z","status":"ssl_error","status_checked_at":"2026-03-06T14:42:14.925Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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-10-10T05:26:33.250Z","updated_at":"2026-03-06T15:02:00.947Z","avatar_url":"https://github.com/jonashackt.png","language":"Jinja","funding_links":[],"categories":[],"sub_categories":[],"readme":"# molecule-ansible-google-cloud\n[![Build Status](https://travis-ci.org/jonashackt/molecule-ansible-google-cloud.svg?branch=master)](https://travis-ci.org/jonashackt/molecule-ansible-google-cloud)\n[![versionansible](https://img.shields.io/badge/ansible-2.8.4-brightgreen.svg)](https://docs.ansible.com/ansible/latest/index.html)\n[![versionmolecule](https://img.shields.io/badge/molecule-2.22-brightgreen.svg)](https://molecule.readthedocs.io/en/latest/)\n[![versiontestinfra](https://img.shields.io/badge/testinfra-3.1.0-brightgreen.svg)](https://testinfra.readthedocs.io/en/latest/)\n\nExample projects showing how to do test-driven development of Ansible roles and running those tests on multiple Cloud providers at the same time\n\nThis project build on top of [molecule-ansible-docker-vagrant](https://github.com/jonashackt/molecule-ansible-docker-vagrant), where all the basics on how to do test-driven development of Ansible roles with Molecule is described. Have a look into the blog series so far:\n\n* [Test-driven infrastructure development with Ansible \u0026 Molecule](https://blog.codecentric.de/en/2018/12/test-driven-infrastructure-ansible-molecule/)\n* [Continuous Infrastructure with Ansible, Molecule \u0026 TravisCI](https://blog.codecentric.de/en/2018/12/continuous-infrastructure-ansible-molecule-travisci/)\n* [Continuous cloud infrastructure with Ansible, Molecule \u0026 TravisCI on AWS](https://blog.codecentric.de/en/2019/01/ansible-molecule-travisci-aws/)\n\n## What about Multicloud?\n\nDeveloping infrastructure code according to prinicples like test-driven development and continuous integration is really great! But what about pushing this to the next level? As [Molecule](https://molecule.readthedocs.io/en/latest/) is able to handle everything Ansible is albe to access, why not run our test automatically on all major cloud platforms at the same time?\n\nWith this, we would not only have a security net for our infrastructure code, but would also be safe regarding a switch of our current cloud or data center provider. Lot's of people talk about the unclear costs of this switch. **** If our infrastructure code would be able to run on every cloud platform possible, we would simply be able to switch to whatever platform we want - and all with just the virtually no expenses.Why not just reduce these to zero?!\n\n\n## A selection of cloud providers: Azure, Google, AWS\n\nSo let's pick some more providers so that we can safely speak about going 'Multicloud':\n\n* [Molecule's Azure driver](https://molecule.readthedocs.io/en/latest/configuration.html#azure)\n* [Molecule's Google Compute Engine (GCE) driver](https://molecule.readthedocs.io/en/latest/configuration.html#gce)\n* We already know [how to use Molecule with AWS EC2](https://blog.codecentric.de/en/2019/01/ansible-molecule-travisci-aws/). \n\n\nLet's start with AWS by just forking [molecule-ansible-docker-vagrant](https://github.com/jonashackt/molecule-ansible-docker-vagrant), since there should be mostly everything needed to use Molecule with AWS.\n\nThis should run in no time :)\n\n\n## Add Google Cloud Platform to the game\n\nFirst you'll need a valid [Google Cloud Platform](https://cloud.google.com) account - you should have at least 300$ using a test account for free.\n\nThen we need to install Google Compute Engine (GCE) support for Molecule:\n\n```\npip3 install molecule[gce]\n```\n\nNow let's initialize a new Molecule scenario calles `gcp-gce-ubuntu` inside our Ansible role:\n\n```\ncd molecule-ansible-aws-gcp-azure/docker\n\nmolecule init scenario --driver-name gce --role-name docker --scenario-name gcp-gce-ubuntu\n```\n\nThat should create a new directory `gcp-gce-ubuntu` inside the `docker/molecule` folder.  We'll integrate the results into our multi scenario project in a second.\n\nNow let's dig into the generated [molecule.yml](docker/molecule/gcp-gce-ubuntu/molecule.yml):\n\n```yaml\ns---\n scenario:\n   name: gcp-gce-ubuntu\n \n driver:\n   name: gce\n platforms:\n   - name: gcp-gce-ubuntu\n     zone: europe-west3-a\n     machine_type: f1-micro\n     image: ubuntu-1804-bionic-v20190617 \n \n provisioner:\n   name: ansible\n   lint:\n     name: ansible-lint\n     enabled: false\n   playbooks:\n     converge: ../playbook.yml\n \n lint:\n   name: yamllint\n   enabled: false\n \n verifier:\n   name: testinfra\n   directory: ../tests/\n   env:\n     # get rid of the DeprecationWarning messages of third-party libs,\n     # see https://docs.pytest.org/en/latest/warnings.html#deprecationwarning-and-pendingdeprecationwarning\n     PYTHONWARNINGS: \"ignore:.*U.*mode is deprecated:DeprecationWarning\"\n   lint:\n     name: flake8\n   options:\n     # show which tests where executed in test output\n     v: 1\n```\n\nAs we already tuned the `molecule.yml` files for our other scenarios like `aws-ec2-ubuntu`, we know what to change here. `provisioner.playbook.converge` needs to be configured, so the one `playbook.yml` could be found.\n\nAlso the `verifier` section has to be enhanced to gain all the described advantages like supressed deprecation warnings and the better test result overview.\n\nAs you may noticed, the driver now uses `gce` and the platform is already pre-configured with a concrete `zone`, `machine_type` and a Google Compute Engine image. Here we just tune the instance name to `gcp-gce-ubuntu` and the `zone` according to our preferred region (see [available regions \u0026 zones here](https://cloud.google.com/compute/docs/regions-zones/regions-zones#available)).\n\nLet's also configure a suitable image (see [the Image list here](https://console.cloud.google.com/compute/images)) - for us using our \"Install Docker on Ubuntu use case\", we should choose `ubuntu-1804-bionic-v20190617`. The preconfigure [Machine Type](https://cloud.google.com/compute/docs/machine-types?hl=en) `f1-micro` should suffice for us.\n\n\n### Install needed Python packages: gcloud, apache-libcloud \u0026 pycrypto\n\nWe need to have `gcloud cli` installed, which is packaged with the Google Cloud SDK. BUT don't install it this way, again use Python package manager pip instead:\n\n```\npip3 install gcloud apache-libcloud pycrypto\n```\n\nWe also need to install [Apache Libcloud](https://libcloud.apache.org/), so it's already attached to the pip install command. Libcloud is used to interact with Google Compute Engine by Molecule. Also [PyCrypto](https://pypi.org/project/pycrypto/) needs to be installed in order to let Molecule connect to GCP successfully.\n\n\n### Create a Service Account inside GCE \u0026 configure Apache Libcloud\n\nAs [described in the docs](https://libcloud.readthedocs.io/en/latest/compute/drivers/gce.html#connecting-to-google-compute-engine) we need to [create a Service account](https://libcloud.readthedocs.io/en/latest/compute/drivers/gce.html#service-account) inside our Google Cloud Console:\n\n\u003e Select the existing or newly created project and go to IAM \u0026 Admin -\u003e Service Accounts -\u003e Create service account to create a new service account. \n\nProvide the service account with a speaking name like `molecule`, then click __NEXT__. Grant the service account the `Owner` role and again click __NEXT__.\n\nSelect the role `Owner` and at the tab `Grant users access to this service account (optional)` you should click on __create key__ to create and download new private key you will use to authenticate (I went with the `.json` format). Place the json file into a folder inside your profile:\n\n```\ncd ~\nmkdir .googlecloud\nmv ~/Downloads/yourprojectname-youridhere.json .googlecloud/yourprojectname-youridhere.json\n```\n\nNow the Google Cloud credentials json file should reside in `/Users/youruserhere/.googlecloud/yourprojectname-youridhere.json`.\n\nAt the end you're service account should be listed inside your projects settings:\n\n![google-cloud-service-account](screenshots/google-cloud-service-account.png)\n\n\n### Configure GCE credentials for Ansible gce Module\n\nIf we have a more detailed look into the [create.yml](docker/molecule/gcp-gce-ubuntu/create.yml) playbook we see, that Molecule use Ansible's [gce Module](https://docs.ansible.com/ansible/latest/modules/gce_module.html) to create Google Compute Engine instances.\n\nAnd the `create.yml` uses 3 environment variables, that we need to set in order to execute Molecule successfully:`\n \n* `GCE_SERVICE_ACCOUNT_EMAIL`: Copy the email address of the created service account.\n* `GCE_CREDENTIALS_FILE`: We need to place the path to the credentials file here (like `/Users/youruserhere/.googlecloud/yourprojectname-youridhere.json`)\n* `GCE_PROJECT_ID`: Copy the project Id from the project dashboard:\n\n![google-cloud-project-dashboard](screenshots/google-cloud-project-dashboard.png)\n\nNow set all those environment variables locally:\n\n```\nexport GCE_SERVICE_ACCOUNT_EMAIL=libcloud@yourprojectname-youridhere.iam.gserviceaccount.com\nexport GCE_CREDENTIALS_FILE=~/.googlecloud/yourprojectname-youridhere.json\nexport GCE_PROJECT_ID=yourprojectname-youridhere\n```\n\n\n### Creating a Google Compute Engine instance with Molecule\n\n\nNow we should have everything prepared. Let's try to run our first Molecule test on Google Compute Engine (including `--debug` so that we see what's going on):\n\n```\nmolecule --debug create --scenario-name gcp-gce-ubuntu\n```\n\nOpen your Google Cloud Compute Engine dashboard and you should see the instance beeing created by Molecule:\n\n![google-cloud-first-running-instance](screenshots/google-cloud-first-running-instance.png)\n\n\n### Prepare step fails with no such identity: /Users/yourUserHere/.ssh/google_compute_engine \u0026 user@yourIpHere: Permission denied (publickey).\n\nUntil here, we didn't need to have the [Google Cloud SDK](https://cloud.google.com/sdk/?hl=en) installed - although I was wondering all the time, when we will need it. And here we are, the [prepare.yml](docker/molecule/gcp-gce-ubuntu/prepare.yml) (and every other) playbook will need the file `/Users/yourUserHere/.ssh/google_compute_engine` to be present to be able to connect to your GCE instances. Otherwise the Molecule execution will fail with something like the following:\n\n```\nfatal: [gcp-gce-ubuntu]: UNREACHABLE! =\u003e {\n        \"changed\": false,\n        \"msg\": \"Failed to connect to the host via ssh: Warning: Permanently added '35.198.116.39' (ECDSA) to the list of known hosts.\\r\\nno such identity: /Users/yourUserHere/.ssh/google_compute_engine: No such file or directory\\r\\nyourUserHere@35.198.116.39: Permission denied (publickey).\",\n        \"unreachable\": true\n    }\n```\n\nSo now we need to install the Google Cloud SDK:\n\n```\nbrew cask install google-cloud-sdk\n```\n\nIf the SDK was successfully installed, we need to give our Google Cloud SDK the needed rights:\n\n```\ngcloud auth login\n```\n\nThis will open your Browser and you'll need to confirm all the occurring questions.\n\nNow configure your project Id in gcloud CLI:\n\n```\ngcloud config set project testproject-233213\n```\n\nWe're now also able to leverage the gcloud CLI for our needs. Let's have a look onto our running instances for example:\n\n```\n$ gcloud compute instances list\nNAME            ZONE            MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP    STATUS\ngcp-gce-ubuntu  europe-west3-a  f1-micro                   10.156.0.5   35.198.116.39  RUNNING\n```\n\nNow we're able to generate the necessary `/Users/yourUserHere/.ssh/google_compute_engine` along with `/Users/yourUserHere/.ssh/google_compute_known_hosts`:\n\n```\ngcloud compute ssh gcp-gce-ubuntu\n```\n\nFinally we should be able to run successfully locally:\n\n```\nmolecule --debug create --scenario-name gcp-gce-ubuntu\n```\n\n[![asciicast](https://asciinema.org/a/231709.svg)](https://asciinema.org/a/231709)\n\n\n\n### Configure Travis CI to run our Molecule test automatically on Google Cloud Platform\n\nThere are only very few sources on how to do that:\n\nhttps://cloud.google.com/solutions/continuous-delivery-with-travis-ci\n\n#### Install needed Python packages: gcloud, apache-libcloud \u0026 pycrypto\n\nLike as we're already used to locally, we need to have `gcloud cli` installed - alongside [Apache Libcloud](https://libcloud.apache.org/) \u0026  [PyCrypto](https://pypi.org/project/pycrypto/). So let's add that to our [.travis.yml](.travis.yml):\n\n```\npip install gcloud apache-libcloud pycrypto\n```\n\nNow this should output the `gcloud version` on TravisCI like you're used to locally:\n\n```\n$ gcloud version\nGoogle Cloud SDK 236.0.0\nbq 2.0.41\ncore 2019.02.22\ngsutil 4.36\n```\n\n\n#### Authenticate gcloud CLI against GCP\n\nAs we can't use the interactive mode of `gcloud auth login` on TravisCI, we use encrypted service account credentials to authenticate gcloud CLI non-interactively like this: `gcloud auth activate-service-account --key-file client-secret.json`\n\nSo let's do it! First we need to encrypt our service account .json key file. [There's a documentation on how to encrypt files in TravisCI](https://docs.travis-ci.com/user/encrypting-files/) - and here's the fast way:\n\nInstall TravisCI CLI on your local machine (__not on Travis!__):\n\n```\nbrew install travis\n```\n\nThen login the CLI to your Travis account locally:\n\n```\ntravis login\n```\n\nNow copy the service account .json key file `.googlecloud/yourprojectname-youridhere.json` to the project's root (__BUT don't check this into source control!__) and create an ignore entry in the [.gitignore](.gitignore) file:\n\n```\n# Google Cloud service account key file for TravisCI\ntestproject-233213-45d56e1b7fc5.json\n...\n```\n\nWe can now encrypt our json key file with the `travis encrypt-file` command:\n\n```\n$ travis encrypt-file testproject-233213-45d56e1b7fc5.json \nDetected repository as jonashackt/molecule-ansible-aws-gcp-azure, is this correct? |yes| yes\nencrypting testproject-233213-45d56e1b7fc5.json for jonashackt/molecule-ansible-aws-gcp-azure\nstoring result as testproject-233213-45d56e1b7fc5.json.enc\nstoring secure env variables for decryption\n\nPlease add the following to your build script (before_install stage in your .travis.yml, for instance):\n\n    openssl aes-256-cbc -K $encrypted_c0be5bd8086d_key -iv $encrypted_c0be5bd8086d_iv -in testproject-233213-45d56e1b7fc5.json.enc -out testproject-233213-45d56e1b7fc5.json -d\n\nPro Tip: You can add it automatically by running with --add.\n\nMake sure to add testproject-233213-45d56e1b7fc5.json.enc to the git repository.\nMake sure not to add testproject-233213-45d56e1b7fc5.json to the git repository.\nCommit all changes to your .travis.yml.\n```\n\nAs the output already states, we need to add the `openssl aes-256-cbc -K ...` command to our [.travis.yml](.travis.yml) right after the gcloud CLI installation:\n\n```\n...\n- gcloud version\n# Decrypt Google Cloud Platform service account json key file\n- openssl aes-256-cbc -K $encrypted_c0be5bd8086d_key -iv $encrypted_c0be5bd8086d_iv -in testproject-233213-45d56e1b7fc5.json.enc -out testproject-233213-45d56e1b7fc5.json -d\n...\n``` \n\nDon't forget to check in the __encrypted__ service account json key file `testproject-233213-45d56e1b7fc5.json.enc` into your Git repo.\n\nNow finally add the `gcloud auth activate-service-account` command to your [.travis.yml](.travis.yml):\n\n```\n- gcloud auth activate-service-account --key-file testproject-233213-45d56e1b7fc5.json\n```\n\n\n#### SSH config on TravisCI\n\nFirst we need to configure the GCE project id inside TravisCI settings as `GCP_GCE_PROJECT_ID` environment variable and configure the project to be used by `gcloud` CLI inside the [.travis.yml](.travis.yml):\n\n```\n- gcloud config set project $GCP_GCE_PROJECT_ID\n```\n\nJust as we are used to locally, we now need to generate the necessary `/Users/yourUserHere/.ssh/google_compute_engine` along with `/Users/yourUserHere/.ssh/google_compute_known_hosts` files - but this time on TravisCI!\n\nTherefore adding `gcloud compute ssh gcp-gce-ubuntu` into our [.travis.yml](.travis.yml) would be the an idea. But running this command before Molecule actually fires up our GCP instance will result in an error - because we cannot ssh into a non-existing machine! The following error would occur:\n\n```\nERROR: (gcloud.compute.ssh) Underspecified resource [gcp-gce-ubuntu].\n```\n\nWe need a non-interactive version of `gcloud compute ssh gcp-gce-ubuntu --zone=europe-west3-a` (we need the `--zone` flag, because we cannot choose the zone interactively here). And the trick here is really to just use the `--command` parameter and directly `exit` the prompt in the same command:\n\n```\ngcloud compute ssh gcp-gce-ubuntu --zone=europe-west3-a --command \"exit\"\n```\n\nBut as you need a running machine to ssh into it, we need to do this inside the standard Molecule process. After Molecule has fired up a machine, the `prepare.yml` is executed. This is our chance! If we could run the `gcloud compute ssh` command there, we should prevent ourselves from the dreaded `yourUserHere@35.198.116.39: Permission denied (publickey).` error!\n\nTherefore we add the following to the [prepare.yml](docker/molecule/gcp-gce-ubuntu/prepare.yml):\n\n```yaml\n- hosts: localhost\n  connection: local\n  gather_facts: false\n  tasks:\n    - name: Execute gcloud compute ssh to obtain needed files for ssh - and exit in the same command\n      shell: gcloud compute ssh gcp-gce-ubuntu --zone=europe-west3-a --command \"exit\"\n      changed_when: false\n\n...\n\n```\n\n#### Finally run Molecule on GCP\n\nNow there should be everything in place to finally run our Molecule test on Travis! Therefore add the well known `molecule test --scenario-name gcp-gce-ubuntu` into your Travis config. The [.travis.yml](.travis.yml) should now look something like this:\n\n```yaml\nsudo: false\nlanguage: python\n\nenv:\n- GCE_CREDENTIALS_FILE=$TRAVIS_BUILD_DIR/testproject-233213-45d56e1b7fc5.json GCE_SERVICE_ACCOUNT_EMAIL=molecule@testproject-233213.iam.gserviceaccount.com GCE_PROJECT_ID=testproject-233213\n\nservices:\n- docker\n\ncache: pip\n\ninstall:\n- pip install molecule\n- pip install docker-py\n- pip install gcloud apache-libcloud pycrypto\n\n# Was gcloud CLI successfully installed?\n- gcloud version\n# Decrypt Google Cloud Platform service account json key file\n- openssl aes-256-cbc -K $encrypted_c0be5bd8086d_key -iv $encrypted_c0be5bd8086d_iv -in testproject-233213-45d56e1b7fc5.json.enc -out testproject-233213-45d56e1b7fc5.json -d\n# Authenticate against GCP with decrypted key file\n- gcloud auth activate-service-account --key-file testproject-233213-45d56e1b7fc5.json\n  # Set GCP project id\n- gcloud config set project $GCP_GCE_PROJECT_ID\n\nscript:\n- cd docker\n# Run Molecule test on GCP\n- molecule create --scenario-name gcp-gce-ubuntu\n- molecule converge --scenario-name gcp-gce-ubuntu\n- molecule verify --scenario-name gcp-gce-ubuntu\n- molecule destroy --scenario-name gcp-gce-ubuntu\n```\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonashackt%2Fmolecule-ansible-google-cloud","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjonashackt%2Fmolecule-ansible-google-cloud","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonashackt%2Fmolecule-ansible-google-cloud/lists"}