我正在尝试使用 ansible playbook 启动 ec2 实例。
它能够启动一个实例,但随后。它不会等到公共 IP 分配给虚拟机。
- name: Start an instance with a public IP address
amazon.aws.ec2_instance:
name: "{{ ansible_test_instance_name }}"
key_name: "{{ ansible_keypair_name }}"
vpc_subnet_id: "{{ ansible_test_subnet }}"
region: "{{ region }}"
aws_access_key: "{{ lookup('env', 'aws_access_key_id') }}"
aws_secret_key: "{{ lookup('env', 'aws_secret_access_key') }}"
instance_type: "{{ ansible_test_instance_type }}"
security_group: "{{ ansible_security_group_name }}"
wait: true
wait_timeout: 20
count: 1
network:
assign_public_ip: true
image_id: "{{ ansible_test_image }}"
tags:
Environment: Testing
register: ec2
- name: Add the newly created EC2 instance(s) to host group
lineinfile: dest={{ hostpath }}
regexp={{ item.public_ip }}
insertafter="[local]"
line="{{ item.public_ip }} {{hoststring}}"
state=present
with_items: "{{ec2.instances}}"
当我运行这个时,我得到
TASK [ec2 : Add the newly created EC2 instance(s) to host group] ***************************************************************************************************************************************************
task path: /app/infra/roles/ec2/tasks/ec2.yml:21
fatal: [localhost]: FAILED! => {
"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'public_ip'\n\nThe error appears to be in '/app/infra/roles/ec2/tasks/ec2.yml': line 21, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Add the newly created EC2 instance(s) to host group\n ^ here\n"
}
寄存器变量输出
"private_ip_address": "172.31.3.218",
"product_codes": [],
"public_dns_name": "",
"root_device_name": "/dev/sda1",
"root_device_type": "ebs",
"security_groups": [
{
"group_id": "sg-0f3c9e97c545d3447",
"group_name": "ansible_test_sg"
}
虽然我们一直在等待,但我猜它不会等到公共 IP 分配给虚拟机。我也在 aws 控制台上看到一个 public_ip 。 我缺少什么?有人可以帮忙吗? 预先感谢
我也遇到了同样的问题,添加
state: running
解决了问题。
- name: Create ephemeral EC2 instance(s)
ec2_instance:
profile: "{{ item.aws_profile | default(omit) }}"
region: "{{ item.region | default(omit) }}"
filters: "{{ platform_filters }}"
instance_type: "{{ item.instance_type }}"
image_id: "{{ platform_image_id }}"
vpc_subnet_id: "{{ item.vpc_subnet_id }}"
security_groups: "{{ platform_security_groups }}"
network:
assign_public_ip: "{{ item.assign_public_ip }}"
volumes: "{{ item.volumes }}"
key_name: "{{ (item.key_inject_method == 'ec2') | ternary(item.key_name, omit) }}"
tags: "{{ platform_tags }}"
user_data: "{{ platform_user_data }}"
wait: true
state: running
带来了另一种解决方法。我做了以下事情。
- name: Pause for 30 seconds to start instance
ansible.builtin.pause:
seconds: 30
- name: Check if instance is available
amazon.aws.ec2_instance_info:
region: "{{ region }}"
aws_access_key: "{{ lookup('env', 'aws_access_key_id') }}"
aws_secret_key: "{{ lookup('env', 'aws_secret_access_key') }}"
instance_ids: "{{ ec2.instance_ids }}"
register: ec2_node_info
- name: Wait for SSH to come up
local_action: wait_for
host={{ item.public_ip_address }}
port=22
state=started
with_items: "{{ec2_node_info.instances}}"
并让它发挥作用
在
state: running
任务中使用 ec2_instance
,然后使用 wait_for
,似乎很稳健:
- name: Wait for EC2 instance(s) to be ready
ansible.builtin.wait_for:
host: "{{ item.public_dns_name }}"
port: 22
search_regex: OpenSSH
delay: 0
sleep: 5
loop: "{{ ec2.instances }}"
(Ansible:启动和运行书)