I’ve been using Ansible in a basic manner for sometime now and trying to get to grips with Molecule. I’m using the ec2 driver with my role and so far managed to create an ec2 instance in aws for molecule testing. Where its going wrong is when i try to do a molecule login. I end up with this error:
*Traceback (most recent call last):
File “/home/ansible/molecule_ec2/bin/molecule”, line 8, in
sys.exit(main())
File “/home/ansible/molecule_ec2/lib/python3.10/site-packages/click/core.py”, line 1157, in call
return self.main(*args, **kwargs)
File “/home/ansible/molecule_ec2/lib/python3.10/site-packages/click/core.py”, line 1078, in main
rv = self.invoke(ctx)
File “/home/ansible/molecule_ec2/lib/python3.10/site-packages/click/core.py”, line 1688, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File “/home/ansible/molecule_ec2/lib/python3.10/site-packages/click/core.py”, line 1434, in invoke
return ctx.invoke(self.callback, **ctx.params)
File “/home/ansible/molecule_ec2/lib/python3.10/site-packages/click/core.py”, line 783, in invoke
return __callback(*args, **kwargs)
File “/home/ansible/molecule_ec2/lib/python3.10/site-packages/click/decorators.py”, line 33, in new_func
return f(get_current_context(), *args, **kwargs)
File “/home/ansible/molecule_ec2/lib/python3.10/site-packages/molecule/command/login.py”, line 129, in login
base.execute_subcommand(scenario.config, subcommand)
File “/home/ansible/molecule_ec2/lib/python3.10/site-packages/molecule/command/base.py”, line 157, in execute_subcommand
return command(config).execute(args)
File “/home/ansible/molecule_ec2/lib/python3.10/site-packages/molecule/logger.py”, line 188, in wrapper
rt = func(*args, *kwargs)
File “/home/ansible/molecule_ec2/lib/python3.10/site-packages/molecule/command/login.py”, line 56, in execute
self._get_login(hostname)
File “/home/ansible/molecule_ec2/lib/python3.10/site-packages/molecule/command/login.py”, line 96, in _get_login
login_options = self._config.driver.login_options(hostname)
File “/
I’m a bit baffled here as the official molecule[ec2] driver documentation leaves much to be desired!
Here is my create.yml
---
- name: Create
hosts: localhost
connection: local
gather_facts: true
no_log: false
vars:
ami_id: "ami-0c1c30571d2dae5c9"
key_pair_name: molecule_key
key_pair_path: "~/.cache/molecule/{{ role_name }}/default"
role_name: someorg.ftp
security_group_name: molecule
security_group_rules:
- proto: tcp
from_port: "{{ ssh_port }}"
to_port: "{{ ssh_port }}"
cidr_ip: '10.1.0.0/16'
# - proto: tcp
# from_port: 5986 # for windows roles
# to_port: 5986
# cidr_ip: '10.1.0.0/16'
ssh_port: 22
ssh_user: ubuntu
tasks:
- name: Find the VPC for the subnet
amazon.aws.ec2_vpc_subnet_info:
subnet_ids: "{{ item.vpc_subnet_id }}"
loop: "{{ molecule_yml.platforms }}"
register: subnet_info
- name: Create molecule EC2 security group
amazon.aws.ec2_security_group:
vpc_id: "{{ item.subnets[0].vpc_id }}"
name: "{{ security_group_name }}"
description: "Temporary security group for Molecule testing"
rules: "{{ security_group_rules }}"
loop: "{{ subnet_info.results }}"
- name: Test for presence of local key pair
ansible.builtin.stat:
path: "{{ key_pair_path }}"
register: key_pair_local
- name: Create key pair
amazon.aws.ec2_key:
name: "{{ key_pair_name }}"
key_type: "rsa"
tags:
Name: molecule-temporary-keypair
no_log: false
register: key_pair
- name: Write the SSH key
ansible.builtin.copy:
content: >
{{ key_pair.key.private_key }}
dest: "{{ key_pair_path }}/{{ key_pair_name }}"
mode: "0600"
check_mode: false
delegate_to: localhost
no_log: false
run_once: true
- name: Create EC2 instance(s)
amazon.aws.ec2_instance:
instance_type: "{{ item.instance_type }}"
image_id: "{{ item.image_id }}"
key_name: "{{ key_pair_name }}"
security_group: "{{ security_group_name }}"
subnet_id: "{{ item.vpc_subnet_id }}"
tags:
Name: molecule-tmp-instance
wait: true
wait_timeout: 300
register: server
loop: "{{ molecule_yml.platforms }}"
# Mandatory configuration for Molecule to function.
- name: Populate instance config dict
ansible.builtin.set_fact:
instance_conf_dict: {
'instance': "{{ item.instances[0].tags.Name }}",
'address': "{{ item.instances[0].private_ip_address }}",
'user': "{{ ssh_user }}",
'port': "{{ ssh_port }}",
'identity_file': "{{ key_pair_path }}/{{ key_pair_name }}",
'instance_ids': "{{ item.instance_ids }}"
}
with_items: "{{ server.results }}"
register: instance_config_dict
when: server.changed | bool
- name: Convert instance config dict to a list
ansible.builtin.set_fact:
instance_conf: "{{ instance_config_dict.results | map(attribute='ansible_facts.instance_conf_dict') | list }}"
when: server.changed | bool
- name: Dump instance config
ansible.builtin.copy:
content: "{{ instance_conf | to_nice_yaml }}"
dest: "{{ molecule_instance_config }}"
mode: "0600"
when: server.changed | bool
- name: Wait for SSH
ansible.builtin.wait_for:
port: "{{ ssh_port }}"
host: "{{ item.address }}"
search_regex: SSH
delay: 10
timeout: 320
with_items: "{{ lookup('file', molecule_instance_config) | from_yaml }}"
Here is my molecule.yml
---
dependency:
name: galaxy
driver:
name: ec2
ssh_connection_options:
-o UserKnownHostsFile=/dev/null
-o StrictHostKeyChecking=no
-i ~/.cache/molecule/tmk.crushftp/default/molecule_key
platforms:
- name: instance
image_owner: "099720109477"
image_id: ami-0c1c30571d2dae5c9
region: eu-west-1
key_inject_method: cloud-init
instance_type: t2.micro
ssh_user: ubuntu
vpc_subnet_id: subnet-1234567xxxxxxxxxx
instance_tags:
- Name: molecule-tmp-instance
provisioner:
name: ansible
env:
ANSIBLE_HOST_KEY_CHECKING: false
playbooks:
create: create.yml
destroy: destroy.yml
lint:
name: ansible-lint
verifier:
name: testinfra
scenario:
name: default
Also just an fyi using the private key generated here I can manually connect to the instance fine. Its just when i use molecule login it fails 🙁
Has anybody got this working successfully? Any boilerplate, tips or pointers would be appreciated greatly!
Tried to follow the examples here:
https://github.com/ansible-community/molecule-ec2
And ended up where I am now.