如何使用一本剧本中的不同变量多次执行 Ansible 角色?

How can I execute an Ansible role multiple times with different vars from one playbook?

我有一个 Ansible 剧本,它有一个启动 EC2 实例的角色,并允许用户指定关于该实例的变量,例如名称、节点类型、实例大小等。我希望角色执行多次在同一个剧本中,每次执行都使用不同的变量,这样我就可以,例如,设置多个名称不同但在其他方面相似的 EC2 实例。当我多次包含该角色并更改变量(参见下面的示例)时,仅执行剧本中角色的第一个实例(在本例中为 "app-prod-01"),而跳过第二个实例。

如何从同一个剧本中多次执行角色任务,为每个任务使用不同的变量?

剧本如下所示:

production-site-prod.yml:

- hosts: localhost
  connection: local
  gather_facts: false
  vars_files:
    - vars/prod.yml
    - vars/vpc-cfn.yml
  roles:

    - role: app-aws-prod
      name: "app-prod-01"
      node_type: application
      instance_type: m4.xlarge
      subnet: "{{ subnetapp1 }}"
      elbs:
        - app-public
        - app-private

    - role: app-aws-prod
      name: "app-prod-02"
      node_type: application
      instance_type: m4.xlarge
      subnet: "{{ subnetapp2 }}"
      elbs:
        - app-public
        - app-private

角色 app-aws-prod 如下所示:

main.yml

- name: validate arguments 1/2 
  assert:
    that:
      - prefix == ""
      - suffixes == [""]
  when: name != ""

- name: validate arguments 2/2
  assert:
    that:
      - prefix != ""
      - suffixes != [""]
  when: name == ""

- include: sg.yml
- include: iam.yml
- include: ec2-instance.yml

我的 ec2-instance.yml 看起来像这样:

ec2-instance.yml

- name: launch instances
  ec2:
    key_name: "{{ key_name }}"
    group_id: "{{ sgcommon }},{{ project_sg.group_id }},{{ app_sg.group_id }}"
    instance_type: "{{ instance_type }}"
    image: "{{ image_ami }}"
    region: "{{ region }}"
    vpc_subnet_id: "{{ subnet }}"
    assign_public_ip: no
    exact_count: 1
    ebs_optimized: yes
    instance_profile_name: "{{ iam.stack_outputs.iamprofile }}"
    count_tag:
        Name: "{{ name }}{{ prefix }}{{ item }}"
        Environment: "{{ environment_name }}"
        Project: "{{ project_name }}"
        node_type: "{{ node_type }}"
    instance_tags:
        Name: "{{ name }}{{ prefix }}{{ item }}"
        Environment: "{{ environment_name }}"
        Project: "{{ project_name }}"
        node_type: "{{ node_type }}"
    wait: yes
    wait_timeout: 300
  with_items: "{{ suffixes }}"
  register: ec2_instance

- include: volume.yml
  vars:
    volume_type: 'temp'
    volume_size: "{{ temp_volume_size }}"
    device_name: '/dev/xvdf'
    volume_retention: 10 
- include: route53.yml 
- include: elb.yml

当我在 ansible-playbook 上使用 --list-tags 标志时,我看到了我期望的输出,每个角色都有相同的任务集,并且显示它们:

[ec2-user@fob production]$ ansible-playbook --list-tasks production-site-prod.yml

playbook: production-site-prod.yml

  play #1 (localhost): localhost        TAGS: []
    tasks:
      app-aws-prod : validate arguments 1/2    TAGS: []
      app-aws-prod : validate arguments 2/2    TAGS: []
      app-aws-prod : project security group access from common TAGS: []
      app-aws-prod : app node security group access from office       TAGS: []
      app-aws-prod : app application security group access from ELBs  TAGS: []
      app-aws-prod : get db security group name        TAGS: []
      app-aws-prod : db security group access from project security group      TAGS: []
      app-aws-prod : get cache security group name     TAGS: []
      app-aws-prod : cache security group access from project security group   TAGS: []
      app-aws-prod : add iam role and managed policies TAGS: []
      app-aws-prod : launch instances  TAGS: []
      app-aws-prod : attach volume     TAGS: []
      app-aws-prod : tag volume        TAGS: []
      app-aws-prod : create dns record TAGS: []
      app-aws-prod : attach instance to elb    TAGS: []
      debug     TAGS: []
      app-aws-prod : validate arguments 1/2    TAGS: []
      app-aws-prod : validate arguments 2/2    TAGS: []
      app-aws-prod : project security group access from common TAGS: []
      app-aws-prod : app node security group access from office       TAGS: []
      app-aws-prod : app application security group access from ELBs  TAGS: []
      app-aws-prod : get db security group name        TAGS: []
      app-aws-prod : db security group access from project security group      TAGS: []
      app-aws-prod : get cache security group name     TAGS: []
      app-aws-prod : cache security group access from project security group   TAGS: []
      app-aws-prod : add iam role and managed policies TAGS: []
      app-aws-prod : launch instances  TAGS: []
      app-aws-prod : attach volume     TAGS: []
      app-aws-prod : tag volume        TAGS: []
      app-aws-prod : create dns record TAGS: []
      app-aws-prod : attach instance to elb    TAGS: []
      debug     TAGS: []

ansible-playbook 输出:

[ec2-user@fob ansible]$ ansible-playbook ./projects/app/production/production-site-prod.yml -v
Using /etc/ansible/ansible.cfg as config file

PLAY [localhost] ***************************************************************

TASK [app-aws-prod : validate arguments 1/2] **********************************
ok: [localhost] => {"changed": false, "msg": "all assertions passed"}

TASK [app-aws-prod : validate arguments 2/2] **********************************
skipping: [localhost] => {"changed": false, "skip_reason": "Conditional check failed", "skipped": true}

TASK [app-aws-prod : project security group access from common] ***************
[u'us-east-1/prod-vpc/output/sgcommon']
[u'us-east-1/prod-vpc/output/vpcId']
ok: [localhost] => {"changed": false, "group_id": "sg-3ddf0b47"}

TASK [app-aws-prod : app node security group access from office] *************
[u'us-east-1/prod-vpc/output/vpcId']
ok: [localhost] => {"changed": false, "group_id": "sg-1109a26b"}

TASK [app-aws-prod : app application security group access from ELBs] ********
[u'us-east-1/prod-app-public-elb/output/elbsg']
[u'us-east-1/prod-vpc/output/vpcId']
ok: [localhost] => (item=app-public) => {"changed": false, "group_id": "sg-1109a26b", "item": "app-public"}
[u'us-east-1/prod-app-private-elb/output/elbsg']
[u'us-east-1/prod-vpc/output/vpcId']
ok: [localhost] => (item=app-private) => {"changed": false, "group_id": "sg-1109a26b", "item": "app-private"}

TASK [app-aws-prod : get db security group name] ******************************
[u'us-east-1/prod-bash-prod/output/dbsg']
ok: [localhost] => {"changed": false, "cmd": "aws ec2 describe-security-groups --region us-east-1 --group-id sg-4c5ff136 --query 'SecurityGroups[*].{Name:GroupName}'", "delta": "0:00:00.610211", "end": "2016-08-30 16:04:38.280314", "rc": 0, "start": "2016-08-30 16:04:37.670103", "stderr": "", "stdout": "[\n    {\n        \"Name\": \"prod-bash-prod-dbSg-8HW8N2N5XBO6\"\n    }\n]", "stdout_lines": ["[", "    {", "        \"Name\": \"prod-bash-prod-dbSg-8HW8N2N5XBO6\"", "    }", "]"], "warnings": []}

TASK [app-aws-prod : db security group access from project security group] ****
[u'us-east-1/prod-vpc/output/vpcId']
ok: [localhost] => {"changed": false, "group_id": "sg-4c5ff136"}

TASK [app-aws-prod : get cache security group name] ***************************
[u'us-east-1/prod-c1/output/cachesg']
ok: [localhost] => {"changed": false, "cmd": "aws ec2 describe-security-groups --region us-east-1 --group-id sg-8962ccf3 --query 'SecurityGroups[*].{Name:GroupName}'", "delta": "0:00:00.606839", "end": "2016-08-30 16:04:39.781701", "rc": 0, "start": "2016-08-30 16:04:39.174862", "stderr": "", "stdout": "[\n    {\n        \"Name\": \"prod-c1-cacheSg-KNT3HMZ1ER2H\"\n    }\n]", "stdout_lines": ["[", "    {", "        \"Name\": \"prod-c1-cacheSg-KNT3HMZ1ER2H\"", "    }", "]"], "warnings": []}

TASK [app-aws-prod : cache security group access from project security group] *
[u'us-east-1/prod-vpc/output/vpcId']
ok: [localhost] => {"changed": false, "group_id": "sg-8962ccf3"}

TASK [app-aws-prod : add iam role and managed policies] ***********************
ok: [localhost] => {"changed": false, "output": "Stack is already up-to-date.", "stack_outputs": {"iamprofile": "prod-app-application-iam-iamprofile-19MNPICSTUPKD", "iamrole": "prod-app-application-iam-iamrole-1A7BZFODEXCBA"}, "stack_resources": [{"last_updated_time": null, "logical_resource_id": "iamprofile", "physical_resource_id": "prod-app-application-iam-iamprofile-19MNPICSTUPKD", "resource_type": "AWS::IAM::InstanceProfile", "status": "CREATE_COMPLETE", "status_reason": null}, {"last_updated_time": null, "logical_resource_id": "iamrole", "physical_resource_id": "prod-app-application-iam-iamrole-1A7BZFODEXCBA", "resource_type": "AWS::IAM::Role", "status": "CREATE_COMPLETE", "status_reason": null}, {"last_updated_time": null, "logical_resource_id": "s3DeployAccess", "physical_resource_id": "arn:aws:iam::498429009301:policy/prod-app-application-iam-s3DeployAccess-1A38BHBPXN2AI", "resource_type": "AWS::IAM::ManagedPolicy", "status": "CREATE_COMPLETE", "status_reason": null}]}

TASK [app-aws-prod : launch instances] ****************************************
[u'us-east-1/prod-vpc/output/subnetapp1']
[u'us-east-1/prod-vpc/output/sgcommon']
ok: [localhost] => (item=) => {"changed": false, "instance_ids": null, "instances": [], "item": "", "tagged_instances": [{"ami_launch_index": "0", "architecture": "x86_64", "block_device_mapping": {"/dev/xvda": {"delete_on_termination": true, "status": "attached", "volume_id": "vol-655aefc2"}, "/dev/xvdf": {"delete_on_termination": false, "status": "attached", "volume_id": "vol-2b45f08c"}}, "dns_name": "", "ebs_optimized": true, "groups": {"sg-1109a26b": "prod-app-application-sg", "sg-3ddf0b47": "prod-app-sg", "sg-c85791b2": "prod-vpc-sgcommon-XEW9RXT290FG"}, "hypervisor": "xen", "id": "i-76ce6a77", "image_id": "ami-60b6c60a", "instance_type": "m4.xlarge", "kernel": null, "key_name": "production", "launch_time": "2016-08-25T19:20:46.000Z", "placement": "us-east-1a", "private_dns_name": "ip-10-70-10-50.ec2.internal", "private_ip": "10.70.10.50", "public_dns_name": "", "public_ip": null, "ramdisk": null, "region": "us-east-1", "root_device_name": "/dev/xvda", "root_device_type": "ebs", "state": "running", "state_code": 16, "tags": {"Environment": "prod", "Name": "app-prod-01", "Project": "app", "node_type": "application"}, "tenancy": "default", "virtualization_type": "hvm"}]}

TASK [app-aws-prod : attach volume] *******************************************
ok: [localhost] => (item={u'changed': False, '_ansible_no_log': False, u'instances': [], '_ansible_item_result': True, u'instance_ids': None, 'item': u'', u'tagged_instances': [{u'kernel': None, u'root_device_type': u'ebs', u'private_dns_name': u'ip-10-70-10-50.ec2.internal', u'public_ip': None, u'private_ip': u'10.70.10.50', u'id': u'i-76ce6a77', u'ebs_optimized': True, u'state': u'running', u'virtualization_type': u'hvm', u'architecture': u'x86_64', u'ramdisk': None, u'block_device_mapping': {u'/dev/xvda': {u'status': u'attached', u'delete_on_termination': True, u'volume_id': u'vol-655aefc2'}, u'/dev/xvdf': {u'status': u'attached', u'delete_on_termination': False, u'volume_id': u'vol-2b45f08c'}}, u'key_name': u'production', u'image_id': u'ami-60b6c60a', u'tenancy': u'default', u'groups': {u'sg-1109a26b': u'prod-app-application-sg', u'sg-3ddf0b47': u'prod-app-sg', u'sg-c85791b2': u'prod-vpc-sgcommon-XEW9RXT290FG'}, u'public_dns_name': u'', u'state_code': 16, u'tags': {u'Project': u'app', u'Environment': u'prod', u'node_type': u'application', u'Name': u'app-prod-01'}, u'placement': u'us-east-1a', u'ami_launch_index': u'0', u'dns_name': u'', u'region': u'us-east-1', u'launch_time': u'2016-08-25T19:20:46.000Z', u'instance_type': u'm4.xlarge', u'root_device_name': u'/dev/xvda', u'hypervisor': u'xen'}], 'invocation': {'module_name': u'ec2', u'module_args': {u'kernel': None, u'image': u'ami-60b6c60a', u'monitoring': False, u'user_data': None, u'count_tag': u"{'Environment': 'prod', 'Project': 'app', 'node_type': 'application', 'Name': 'app-prod-01'}", u'private_ip': None, u'spot_type': u'one-time', u'ec2_url': None, u'id': None, u'source_dest_check': True, u'aws_secret_key': None, u'spot_wait_timeout': u'600', u'group': None, u'zone': None, u'exact_count': 1, u'ebs_optimized': True, u'state': u'present', u'placement_group': None, u'spot_launch_group': None, u'ramdisk': None, u'key_name': u'production', u'vpc_subnet_id': u'subnet-15c8c44d', u'instance_ids': None, u'wait_timeout': u'300', u'profile': None, u'assign_public_ip': False, u'spot_price': None, u'wait': True, u'count': 1, u'aws_access_key': None, u'instance_profile_name': u'prod-app-application-iam-iamprofile-19MNPICSTUPKD', u'security_token': None, u'region': u'us-east-1', u'network_interfaces': None, u'termination_protection': False, u'instance_type': u'm4.xlarge', u'tenancy': u'default', u'volumes': None, u'instance_tags': {u'Environment': u'prod', u'Project': u'app', u'node_type': u'application', u'Name': u'app-prod-01'}, u'group_id': [u'sg-c85791b2', u'sg-3ddf0b47', u'sg-1109a26b'], u'validate_certs': True}}}) => {"changed": false, "device": "/dev/xvdf", "item": {"changed": false, "instance_ids": null, "instances": [], "invocation": {"module_args": {"assign_public_ip": false, "aws_access_key": null, "aws_secret_key": null, "count": 1, "count_tag": "{'Environment': 'prod', 'Project': 'app', 'node_type': 'application', 'Name': 'app-prod-01'}", "ebs_optimized": true, "ec2_url": null, "exact_count": 1, "group": null, "group_id": ["sg-c85791b2", "sg-3ddf0b47", "sg-1109a26b"], "id": null, "image": "ami-60b6c60a", "instance_ids": null, "instance_profile_name": "prod-app-application-iam-iamprofile-19MNPICSTUPKD", "instance_tags": {"Environment": "prod", "Name": "app-prod-01", "Project": "app", "node_type": "application"}, "instance_type": "m4.xlarge", "kernel": null, "key_name": "production", "monitoring": false, "network_interfaces": null, "placement_group": null, "private_ip": null, "profile": null, "ramdisk": null, "region": "us-east-1", "security_token": null, "source_dest_check": true, "spot_launch_group": null, "spot_price": null, "spot_type": "one-time", "spot_wait_timeout": "600", "state": "present", "tenancy": "default", "termination_protection": false, "user_data": null, "validate_certs": true, "volumes": null, "vpc_subnet_id": "subnet-15c8c44d", "wait": true, "wait_timeout": "300", "zone": null}, "module_name": "ec2"}, "item": "", "tagged_instances": [{"ami_launch_index": "0", "architecture": "x86_64", "block_device_mapping": {"/dev/xvda": {"delete_on_termination": true, "status": "attached", "volume_id": "vol-655aefc2"}, "/dev/xvdf": {"delete_on_termination": false, "status": "attached", "volume_id": "vol-2b45f08c"}}, "dns_name": "", "ebs_optimized": true, "groups": {"sg-1109a26b": "prod-app-application-sg", "sg-3ddf0b47": "prod-app-sg", "sg-c85791b2": "prod-vpc-sgcommon-XEW9RXT290FG"}, "hypervisor": "xen", "id": "i-76ce6a77", "image_id": "ami-60b6c60a", "instance_type": "m4.xlarge", "kernel": null, "key_name": "production", "launch_time": "2016-08-25T19:20:46.000Z", "placement": "us-east-1a", "private_dns_name": "ip-10-70-10-50.ec2.internal", "private_ip": "10.70.10.50", "public_dns_name": "", "public_ip": null, "ramdisk": null, "region": "us-east-1", "root_device_name": "/dev/xvda", "root_device_type": "ebs", "state": "running", "state_code": 16, "tags": {"Environment": "prod", "Name": "app-prod-01", "Project": "app", "node_type": "application"}, "tenancy": "default", "virtualization_type": "hvm"}]}, "msg": "Volume mapping for /dev/xvdf already exists on instance i-76ce6a77", "volume_id": "vol-2b45f08c"}

TASK [app-aws-prod : tag volume] **********************************************
ok: [localhost] => (item=(0, {u'changed': False, '_ansible_no_log': False, '_ansible_item_result': True, 'item': {u'changed': False, '_ansible_no_log': False, 'item': u'', '_ansible_item_result': True, u'instance_ids': None, u'instances': [], u'tagged_instances': [{u'kernel': None, u'root_device_type': u'ebs', u'private_dns_name': u'ip-10-70-10-50.ec2.internal', u'public_ip': None, u'private_ip': u'10.70.10.50', u'id': u'i-76ce6a77', u'ebs_optimized': True, u'state': u'running', u'virtualization_type': u'hvm', u'architecture': u'x86_64', u'ramdisk': None, u'block_device_mapping': {u'/dev/xvda': {u'status': u'attached', u'delete_on_termination': True, u'volume_id': u'vol-655aefc2'}, u'/dev/xvdf': {u'status': u'attached', u'delete_on_termination': False, u'volume_id': u'vol-2b45f08c'}}, u'key_name': u'production', u'image_id': u'ami-60b6c60a', u'tenancy': u'default', u'groups': {u'sg-1109a26b': u'prod-app-application-sg', u'sg-3ddf0b47': u'prod-app-sg', u'sg-c85791b2': u'prod-vpc-sgcommon-XEW9RXT290FG'}, u'public_dns_name': u'', u'state_code': 16, u'tags': {u'Project': u'app', u'Environment': u'prod', u'node_type': u'application', u'Name': u'app-prod-01'}, u'placement': u'us-east-1a', u'ami_launch_index': u'0', u'dns_name': u'', u'region': u'us-east-1', u'launch_time': u'2016-08-25T19:20:46.000Z', u'instance_type': u'm4.xlarge', u'root_device_name': u'/dev/xvda', u'hypervisor': u'xen'}], 'invocation': {'module_name': u'ec2', u'module_args': {u'kernel': None, u'image': u'ami-60b6c60a', u'user_data': None, u'count_tag': u"{'Environment': 'prod', 'Project': 'app', 'node_type': 'application', 'Name': 'app-prod-01'}", u'private_ip': None, u'spot_type': u'one-time', u'ec2_url': None, u'id': None, u'source_dest_check': True, u'aws_secret_key': None, u'spot_wait_timeout': u'600', u'monitoring': False, u'zone': None, u'exact_count': 1, u'ebs_optimized': True, u'state': u'present', u'placement_group': None, u'spot_launch_group': None, u'ramdisk': None, u'key_name': u'production', u'vpc_subnet_id': u'subnet-15c8c44d', u'instance_ids': None, u'spot_price': None, u'wait_timeout': u'300', u'profile': None, u'assign_public_ip': False, u'group': None, u'wait': True, u'count': 1, u'aws_access_key': None, u'instance_profile_name': u'prod-app-application-iam-iamprofile-19MNPICSTUPKD', u'security_token': None, u'region': u'us-east-1', u'network_interfaces': None, u'termination_protection': False, u'instance_type': u'm4.xlarge', u'tenancy': u'default', u'volumes': None, u'instance_tags': {u'Environment': u'prod', u'Project': u'app', u'node_type': u'application', u'Name': u'app-prod-01'}, u'group_id': [u'sg-c85791b2', u'sg-3ddf0b47', u'sg-1109a26b'], u'validate_certs': True}}}, u'device': u'/dev/xvdf', u'volume_id': u'vol-2b45f08c', 'invocation': {'module_name': u'ec2_vol', u'module_args': {u'aws_secret_key': None, u'profile': None, u'aws_access_key': None, u'name': None, u'zone': None, u'instance': u'i-76ce6a77', u'encrypted': False, u'region': u'us-east-1', u'volume_type': u'gp2', u'device_name': u'/dev/xvdf', u'volume_size': u'100', u'state': u'present', u'iops': None, u'snapshot': None, u'ec2_url': None, u'id': None, u'security_token': None, u'validate_certs': True, u'delete_on_termination': False}}, u'msg': u'Volume mapping for /dev/xvdf already exists on instance i-76ce6a77'})) => {"changed": false, "item": [0, {"_ansible_item_result": true, "_ansible_no_log": false, "changed": false, "device": "/dev/xvdf", "invocation": {"module_args": {"aws_access_key": null, "aws_secret_key": null, "delete_on_termination": false, "device_name": "/dev/xvdf", "ec2_url": null, "encrypted": false, "id": null, "instance": "i-76ce6a77", "iops": null, "name": null, "profile": null, "region": "us-east-1", "security_token": null, "snapshot": null, "state": "present", "validate_certs": true, "volume_size": "100", "volume_type": "gp2", "zone": null}, "module_name": "ec2_vol"}, "item": {"_ansible_item_result": true, "_ansible_no_log": false, "changed": false, "instance_ids": null, "instances": [], "invocation": {"module_args": {"assign_public_ip": false, "aws_access_key": null, "aws_secret_key": null, "count": 1, "count_tag": "{'Environment': 'prod', 'Project': 'app', 'node_type': 'application', 'Name': 'app-prod-01'}", "ebs_optimized": true, "ec2_url": null, "exact_count": 1, "group": null, "group_id": ["sg-c85791b2", "sg-3ddf0b47", "sg-1109a26b"], "id": null, "image": "ami-60b6c60a", "instance_ids": null, "instance_profile_name": "prod-app-application-iam-iamprofile-19MNPICSTUPKD", "instance_tags": {"Environment": "prod", "Name": "app-prod-01", "Project": "app", "node_type": "application"}, "instance_type": "m4.xlarge", "kernel": null, "key_name": "production", "monitoring": false, "network_interfaces": null, "placement_group": null, "private_ip": null, "profile": null, "ramdisk": null, "region": "us-east-1", "security_token": null, "source_dest_check": true, "spot_launch_group": null, "spot_price": null, "spot_type": "one-time", "spot_wait_timeout": "600", "state": "present", "tenancy": "default", "termination_protection": false, "user_data": null, "validate_certs": true, "volumes": null, "vpc_subnet_id": "subnet-15c8c44d", "wait": true, "wait_timeout": "300", "zone": null}, "module_name": "ec2"}, "item": "", "tagged_instances": [{"ami_launch_index": "0", "architecture": "x86_64", "block_device_mapping": {"/dev/xvda": {"delete_on_termination": true, "status": "attached", "volume_id": "vol-655aefc2"}, "/dev/xvdf": {"delete_on_termination": false, "status": "attached", "volume_id": "vol-2b45f08c"}}, "dns_name": "", "ebs_optimized": true, "groups": {"sg-1109a26b": "prod-app-application-sg", "sg-3ddf0b47": "prod-app-sg", "sg-c85791b2": "prod-vpc-sgcommon-XEW9RXT290FG"}, "hypervisor": "xen", "id": "i-76ce6a77", "image_id": "ami-60b6c60a", "instance_type": "m4.xlarge", "kernel": null, "key_name": "production", "launch_time": "2016-08-25T19:20:46.000Z", "placement": "us-east-1a", "private_dns_name": "ip-10-70-10-50.ec2.internal", "private_ip": "10.70.10.50", "public_dns_name": "", "public_ip": null, "ramdisk": null, "region": "us-east-1", "root_device_name": "/dev/xvda", "root_device_type": "ebs", "state": "running", "state_code": 16, "tags": {"Environment": "prod", "Name": "app-prod-01", "Project": "app", "node_type": "application"}, "tenancy": "default", "virtualization_type": "hvm"}]}, "msg": "Volume mapping for /dev/xvdf already exists on instance i-76ce6a77", "volume_id": "vol-2b45f08c"}], "msg": "Tags already exists in vol-2b45f08c."}

TASK [app-aws-prod : create dns record] ***************************************
ok: [localhost] => (item=(0, {u'changed': False, '_ansible_no_log': False, u'instances': [], '_ansible_item_result': True, u'instance_ids': None, 'item': u'', u'tagged_instances': [{u'kernel': None, u'root_device_type': u'ebs', u'private_dns_name': u'ip-10-70-10-50.ec2.internal', u'public_ip': None, u'private_ip': u'10.70.10.50', u'id': u'i-76ce6a77', u'ebs_optimized': True, u'state': u'running', u'virtualization_type': u'hvm', u'architecture': u'x86_64', u'ramdisk': None, u'block_device_mapping': {u'/dev/xvda': {u'status': u'attached', u'delete_on_termination': True, u'volume_id': u'vol-655aefc2'}, u'/dev/xvdf': {u'status': u'attached', u'delete_on_termination': False, u'volume_id': u'vol-2b45f08c'}}, u'key_name': u'production', u'image_id': u'ami-60b6c60a', u'tenancy': u'default', u'groups': {u'sg-1109a26b': u'prod-app-application-sg', u'sg-3ddf0b47': u'prod-app-sg', u'sg-c85791b2': u'prod-vpc-sgcommon-XEW9RXT290FG'}, u'public_dns_name': u'', u'state_code': 16, u'tags': {u'Project': u'app', u'Environment': u'prod', u'node_type': u'application', u'Name': u'app-prod-01'}, u'placement': u'us-east-1a', u'ami_launch_index': u'0', u'dns_name': u'', u'region': u'us-east-1', u'launch_time': u'2016-08-25T19:20:46.000Z', u'instance_type': u'm4.xlarge', u'root_device_name': u'/dev/xvda', u'hypervisor': u'xen'}], 'invocation': {'module_name': u'ec2', u'module_args': {u'kernel': None, u'image': u'ami-60b6c60a', u'monitoring': False, u'user_data': None, u'count_tag': u"{'Environment': 'prod', 'Project': 'app', 'node_type': 'application', 'Name': 'app-prod-01'}", u'private_ip': None, u'spot_type': u'one-time', u'ec2_url': None, u'id': None, u'source_dest_check': True, u'aws_secret_key': None, u'spot_wait_timeout': u'600', u'group': None, u'zone': None, u'exact_count': 1, u'ebs_optimized': True, u'state': u'present', u'placement_group': None, u'spot_launch_group': None, u'ramdisk': None, u'key_name': u'production', u'vpc_subnet_id': u'subnet-15c8c44d', u'instance_ids': None, u'wait_timeout': u'300', u'profile': None, u'assign_public_ip': False, u'spot_price': None, u'wait': True, u'count': 1, u'aws_access_key': None, u'instance_profile_name': u'prod-app-application-iam-iamprofile-19MNPICSTUPKD', u'security_token': None, u'region': u'us-east-1', u'network_interfaces': None, u'termination_protection': False, u'instance_type': u'm4.xlarge', u'tenancy': u'default', u'volumes': None, u'instance_tags': {u'Environment': u'prod', u'Project': u'app', u'node_type': u'application', u'Name': u'app-prod-01'}, u'group_id': [u'sg-c85791b2', u'sg-3ddf0b47', u'sg-1109a26b'], u'validate_certs': True}}})) => {"changed": false, "item": [0, {"_ansible_item_result": true, "_ansible_no_log": false, "changed": false, "instance_ids": null, "instances": [], "invocation": {"module_args": {"assign_public_ip": false, "aws_access_key": null, "aws_secret_key": null, "count": 1, "count_tag": "{'Environment': 'prod', 'Project': 'app', 'node_type': 'application', 'Name': 'app-prod-01'}", "ebs_optimized": true, "ec2_url": null, "exact_count": 1, "group": null, "group_id": ["sg-c85791b2", "sg-3ddf0b47", "sg-1109a26b"], "id": null, "image": "ami-60b6c60a", "instance_ids": null, "instance_profile_name": "prod-app-application-iam-iamprofile-19MNPICSTUPKD", "instance_tags": {"Environment": "prod", "Name": "app-prod-01", "Project": "app", "node_type": "application"}, "instance_type": "m4.xlarge", "kernel": null, "key_name": "production", "monitoring": false, "network_interfaces": null, "placement_group": null, "private_ip": null, "profile": null, "ramdisk": null, "region": "us-east-1", "security_token": null, "source_dest_check": true, "spot_launch_group": null, "spot_price": null, "spot_type": "one-time", "spot_wait_timeout": "600", "state": "present", "tenancy": "default", "termination_protection": false, "user_data": null, "validate_certs": true, "volumes": null, "vpc_subnet_id": "subnet-15c8c44d", "wait": true, "wait_timeout": "300", "zone": null}, "module_name": "ec2"}, "item": "", "tagged_instances": [{"ami_launch_index": "0", "architecture": "x86_64", "block_device_mapping": {"/dev/xvda": {"delete_on_termination": true, "status": "attached", "volume_id": "vol-655aefc2"}, "/dev/xvdf": {"delete_on_termination": false, "status": "attached", "volume_id": "vol-2b45f08c"}}, "dns_name": "", "ebs_optimized": true, "groups": {"sg-1109a26b": "prod-app-application-sg", "sg-3ddf0b47": "prod-app-sg", "sg-c85791b2": "prod-vpc-sgcommon-XEW9RXT290FG"}, "hypervisor": "xen", "id": "i-76ce6a77", "image_id": "ami-60b6c60a", "instance_type": "m4.xlarge", "kernel": null, "key_name": "production", "launch_time": "2016-08-25T19:20:46.000Z", "placement": "us-east-1a", "private_dns_name": "ip-10-70-10-50.ec2.internal", "private_ip": "10.70.10.50", "public_dns_name": "", "public_ip": null, "ramdisk": null, "region": "us-east-1", "root_device_name": "/dev/xvda", "root_device_type": "ebs", "state": "running", "state_code": 16, "tags": {"Environment": "prod", "Name": "app-prod-01", "Project": "app", "node_type": "application"}, "tenancy": "default", "virtualization_type": "hvm"}]}]}

NO MORE HOSTS LEFT *************************************************************

PLAY RECAP *********************************************************************
localhost                  : ok=13   changed=0    unreachable=0    failed=0

[ec2-user@fob ansible]$

根据评论中的附加信息回答:

There is an error which I have not included here because I didn't think it relevant -- the last task (which is not in the ansible-playbook output) is to attach the EC2 instance to an ELB, which fails...

如果主机上的任何任务失败(除非您指定 ignore_errors: yes),ansible 将此主机标记为失败并停止执行其余任务。

因此,您只有一台主机 localhost,当它被标记为失败时,剧本的执行将停止。