我正在尝试学习 Ansible。我正在创建一个实例并将文件上传到其中,我想要放入 ec2 实例的文件存储在 S3 中,但它一直说 c2 中的目标不存在,但它确实存在。
这是失败的,在此之前的所有其他操作(包括创建实例)都运行正常:
- name: Deploy war file
aws_s3:
bucket: "{{ war_bucket }}"
object: "{{ war_file }}"
dest: "{{ war_deploy_path }}/{{ war_file }}"
mode: get
overwrite: no
register: war_downloaded
这就是我声明变量的方式:
war_file: file.war
war_bucket: ansible-bucket
war_deploy_path: /opt/folder/file.war
这是我收到的错误:
[Errno 2] No such file or directory: '/opt/folder/file.war.1f1ccA91'
为什么要添加这个奇怪的代码“1f1cA91”?这会导致问题吗?
更新:我尝试将目标从“{{ war_deploy_path }}/{{ war_file }}”更改为“{{ war_deploy_path }}”,但同样的问题仍然存在,只是[Errno 2] No such file or directory: '/opt/folder.Ac2926c3'
现在出现错误。
重要更新2:好的,为了测试,我决定在本地机器上创建相同的路径,令我惊讶的是,这个脚本实际上是在我的本地机器上运行而不是在 ec2 实例上运行,所以现在,我如何让它在 ec2 实例上运行 xD。
答案1
在 ansible 中创建一个主机,然后在同一个剧本中对其进行操作是可能的,但需要对库存文件进行一些动态更改,并重新读取剧本中的库存。
首先,在您的库存文件中添加一个占位符,例如:
[local]
localhost ansible_connection=local ansible_python_interpreter=python
[new_ones]
其次,在您的剧本中,您将需要两个部分,一个部分用于运行本地作业,另一个部分用于针对您从第一部分创建的主机运行。在第一部分中,您将创建主机,然后将主机 IP 添加到您上面创建的清单中。然后,您将告诉 ansible 使用命令重新读取清单meta
,然后等待主机发出命令pause
。以下是一个例子:
---
- name: Testing Part One
hosts: local
become: yes
tasks:
- name: create an ec2 instance
local_action:
module: ec2
aws_secret_key: <redacted>
aws_access_key: <redacted>
group_id: sg-1234567
key_name: my_key
instance_type: t2.micro
image: ami-0123456789abcde
wait: yes
count: 1
vpc_subnet_id: subnet-987654321
assign_public_ip: no
region: us-east-1
register: ec2
# This part adds the IP address of the host that was created above to the
# inventory file
- name: Add instance to inventory
local_action:
module: lineinfile
path: inv/hosts_default
regexp: "{{ item.private_ip }}"
insertafter: "new_ones"
line: "{{ item.private_ip }}"
with_items: '{{ ec2.instances }}'
# Have the playbook reread the inventory file
- meta: refresh_inventory
# Wait for a bit to ensure SSH is enabled
- pause:
minutes: 5
然后,在同一个剧本中创建另一个条目来复制文件。默认情况下,我的主机上没有安装 pip,因此我添加了它,以防您遇到同样的情况:
- name: Testing Part Two
hosts: new_ones
become: yes
tasks:
# Install pip, boto, boto3, and botocore. You may not need this
- name: install pip
easy_install:
name: pip
state: latest
- name: install boto, boto3 and botocore
pip:
name: "{{ item }}"
loop:
- boto
- boto3
- botocore
# Finally we get to what you were trying to do to begin with...
- name: Deploy war file
aws_s3:
aws_secret_key: <redacted>
aws_access_key: <redacted>
bucket: "mybucketname"
object: "blah.txt"
dest: "/tmp/blah.txt"
mode: get
overwrite: no
register: war_downloaded
如果你仍然感到困惑,下面是完整的剧本:
---
- name: Testing Part 1
hosts: local
become: yes
tasks:
- name: create an ec2 instance
local_action:
module: ec2
aws_secret_key: <redacted>
aws_access_key: <redacted>
group_id: sg-1234567
key_name: my_key
instance_type: t2.micro
image: ami-0123456789abcde
wait: yes
count: 1
vpc_subnet_id: subnet-987654321
assign_public_ip: no
region: us-east-1
register: ec2
- name: Add instance to inventory
local_action:
module: lineinfile
path: inv/hosts_default
regexp: "{{ item.private_ip }}"
insertafter: "new_ones"
line: "{{ item.private_ip }}"
with_items: '{{ ec2.instances }}'
- meta: refresh_inventory
- pause:
minutes: 5
- name: Testing Part Two
hosts: new_ones
become: yes
tasks:
- name: install pip
easy_install:
name: pip
state: latest
- name: install boto, boto3 and botocore
pip:
name: "{{ item }}"
loop:
- boto
- boto3
- botocore
- name: Deploy war file
aws_s3:
aws_secret_key: <redacted>
aws_access_key: <redacted>
bucket: "mybucketname"
object: "blah.txt"
dest: "/tmp/blah.txt"
mode: get
overwrite: no
register: war_downloaded
参考
PS:我只测试了构建一个主机,如果你构建多个主机,你的里程可能会有所不同。