Introduction

The community.aws.ec2_instance module is one of the most commonly used Ansible modules for AWS automation. However, due to Ansible's collection reorganization, users frequently encounter "module could not be resolved" errors when trying to manage EC2 instances.

This guide explains why these errors occur and provides step-by-step solutions for every scenario.

The Error

When running a playbook with EC2 instance management, you may see:

ERROR! couldn't resolve module/action 'community.aws.ec2_instance'. This often indicates a misspelling, missing collection, or incorrect module path.

Or warnings like:

[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available

Root Causes

1. Missing Collection

The community.aws collection is not installed on your system.

Diagnosis:

ansible-galaxy collection list | grep aws

Fix:

# Install community.aws collection
ansible-galaxy collection install community.aws

# Or install the amazon.aws collection (newer, recommended)
ansible-galaxy collection install amazon.aws

2. Module Migration (community.aws → amazon.aws)

Starting with community.aws 7.0+, the ec2_instance module was migrated to the amazon.aws collection. The community.aws.ec2_instance now redirects to amazon.aws.ec2_instance.

Fix — Update your playbook to use the new FQCN:

# Old (may still work via redirect, but deprecated)
- community.aws.ec2_instance:
    name: my-instance
    instance_type: t3.micro

# New (recommended)
- amazon.aws.ec2_instance:
    name: my-instance
    instance_type: t3.micro

Install both collections to ensure compatibility:

ansible-galaxy collection install amazon.aws community.aws

3. Incorrect Module Name

Typos or using legacy module names that no longer exist:

# Wrong - old ec2 module (removed)
- ec2:
    instance_type: t3.micro

# Wrong - typo
- community.aws.ec2_instances:
    name: my-instance

# Correct
- amazon.aws.ec2_instance:
    name: my-instance
    instance_type: t3.micro
    image_id: ami-0123456789abcdef0

4. Collection Version Mismatch

Your installed collection version doesn't include the module you're trying to use.

Fix:

# Update to latest versions
ansible-galaxy collection install amazon.aws --upgrade
ansible-galaxy collection install community.aws --upgrade

5. Virtual Environment or Path Issues

The collection is installed in a different Python environment or path than what Ansible is using.

Diagnosis:

ansible --version  # Check collections_path
ansible-galaxy collection list  # Check what's installed and where

Fix:

# Install to a specific path
ansible-galaxy collection install amazon.aws -p ./collections

# Or set in ansible.cfg
[defaults]
collections_path = ./collections:/usr/share/ansible/collections

Complete Working Example

requirements.yml

---
collections:
  - name: amazon.aws
    version: ">=7.0.0"
  - name: community.aws
    version: ">=7.0.0"

Install:

ansible-galaxy collection install -r requirements.yml

inventory.yml

---
all:
  hosts:
    localhost:
      ansible_connection: local
      ansible_python_interpreter: "{{ ansible_playbook_python }}"

create_ec2.yml

---
- name: Create EC2 Instance
  hosts: localhost
  gather_facts: false
  vars:
    aws_region: us-east-1
    instance_name: my-web-server
    instance_type: t3.micro
    ami_id: ami-0123456789abcdef0
    key_name: my-keypair
    security_group: sg-0123456789abcdef0
    subnet_id: subnet-0123456789abcdef0
  tasks:
    - name: Create EC2 instance
      amazon.aws.ec2_instance:
        name: "{{ instance_name }}"
        instance_type: "{{ instance_type }}"
        image_id: "{{ ami_id }}"
        key_name: "{{ key_name }}"
        security_group: "{{ security_group }}"
        subnet_id: "{{ subnet_id }}"
        region: "{{ aws_region }}"
        network:
          assign_public_ip: true
        tags:
          Environment: production
          ManagedBy: ansible
        state: running
        wait: true
      register: ec2_result

    - name: Display instance details
      ansible.builtin.debug:
        msg: |
          Instance ID: {{ ec2_result.instances[0].instance_id }}
          Public IP: {{ ec2_result.instances[0].public_ip_address | default('pending') }}
          State: {{ ec2_result.instances[0].state.name }}

    - name: Wait for SSH to become available
      ansible.builtin.wait_for:
        host: "{{ ec2_result.instances[0].public_ip_address }}"
        port: 22
        delay: 30
        timeout: 300
      when: ec2_result.instances[0].public_ip_address is defined

AWS Credential Configuration

The module requires AWS credentials. Configure them in one of these ways:

Option 1: Environment Variables

export AWS_ACCESS_KEY_ID='AKIAIOSFODNN7EXAMPLE'
export AWS_SECRET_ACCESS_KEY='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
export AWS_DEFAULT_REGION='us-east-1'

Option 2: AWS Credentials File

# ~/.aws/credentials
[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

Option 3: Ansible Variables (with Vault)

# group_vars/all/aws.yml (encrypted with ansible-vault)
aws_access_key: "{{ vault_aws_access_key }}"
aws_secret_key: "{{ vault_aws_secret_key }}"
- amazon.aws.ec2_instance:
    name: my-instance
    aws_access_key: "{{ aws_access_key }}"
    aws_secret_key: "{{ aws_secret_key }}"
    region: us-east-1
    ...

No explicit credentials needed — Ansible uses the IAM role attached to the instance:

- amazon.aws.ec2_instance:
    name: my-instance
    region: us-east-1
    ...
    # No credentials specified - uses instance profile

Python Dependencies

The AWS modules require the boto3 and botocore Python libraries:

pip install boto3 botocore

# Verify
python -c "import boto3; print(boto3.__version__)"

If Ansible uses a different Python than your system default, install boto3 there:

# Check which Python Ansible uses
ansible --version | grep python

# Install boto3 for that Python
/usr/bin/python3 -m pip install boto3

Common Patterns

Stop/Start Instance

- name: Stop EC2 instance
  amazon.aws.ec2_instance:
    instance_ids:
      - i-0123456789abcdef0
    state: stopped
    region: us-east-1

- name: Start EC2 instance
  amazon.aws.ec2_instance:
    instance_ids:
      - i-0123456789abcdef0
    state: running
    region: us-east-1
    wait: true

Terminate Instance

- name: Terminate instance by name
  amazon.aws.ec2_instance:
    filters:
      "tag:Name": old-server
      instance-state-name: running
    state: terminated
    region: us-east-1

Find and Use Latest AMI

- name: Get latest Amazon Linux 2023 AMI
  amazon.aws.ec2_ami_info:
    owners:
      - amazon
    filters:
      name: "al2023-ami-*-x86_64"
      state: available
    region: us-east-1
  register: ami_info

- name: Launch with latest AMI
  amazon.aws.ec2_instance:
    name: my-server
    image_id: "{{ (ami_info.images | sort(attribute='creation_date') | last).image_id }}"
    instance_type: t3.micro
    region: us-east-1

Troubleshooting Checklist

  1. ✅ Collection installed: ansible-galaxy collection list | grep aws
  2. ✅ Correct FQCN: amazon.aws.ec2_instance (not community.aws)
  3. ✅ Python boto3 installed: python -c "import boto3"
  4. ✅ AWS credentials configured (env vars, profile, or vault)
  5. ✅ Correct region specified
  6. ✅ Inventory includes localhost with ansible_connection: local
  7. ✅ Collection versions are up-to-date

Conclusion

The community.aws.ec2_instance error is almost always caused by a missing collection installation or the module migration from community.aws to amazon.aws. The fix is straightforward: install the amazon.aws collection, update your playbook to use amazon.aws.ec2_instance, ensure boto3 is installed, and configure proper AWS credentials. Always use a requirements.yml file to declare collection dependencies for reproducible automation.