2

I'm trying to learn Ansible. I'm working on creating an instance and uploading a file into it, the file i want to put into the ec2 instance is in stored in S3, but it keeps saying that the destination inside the c2 doesn't exist, it does exist though.

This is which is failing, everything else before that including the creation of instance is working fine :

- 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

And this is how i declared my variables :

war_file: file.war
war_bucket: ansible-bucket
war_deploy_path: /opt/folder/file.war

And this is the error I get :

[Errno 2] No such file or directory: '/opt/folder/file.war.1f1ccA91'

Why is it adding this weird code "1f1cA91" ? Is it causing the problem?

Update : I tried changing the destination from "{{ war_deploy_path }}/{{ war_file }}" to "{{ war_deploy_path }}" but the same problem persists, only the error is [Errno 2] No such file or directory: '/opt/folder.Ac2926c3' now.

Important Update 2 : Ok, so for the sake of testing, i decided to create the same path in my local machine, and to my surprise, this script is actually running it on my local machine instead of the ec2 instance lol, so now, how do i make it run on the ec2 instance xD.

  • 2
    It looks like you're telling Ansible to put file.war into /opt/folder/file.war/file.war and it's choking...change dest to dest: "{{war_deploy_path}}" or change war_deploy_path to /opt/folder/ – kenlukas Feb 28 at 17:17
  • That came to mind, but i didn't try it because it didn't make sense to me lol, i guess i should try it tomorrow and tell you the results, thank you for your response. – logax Mar 1 at 10:42
  • Does /opt/folder/ exist? – Gerald Schneider Mar 2 at 10:01
  • Yes, it does exist on the ec2 instance . – logax Mar 2 at 10:05
  • Please don't add stuff like "updated" to the title of your questions. The edit history can be easily visited. – Gerald Schneider Mar 2 at 14:32
0

To create a host in ansible and then work on it in the same playbook is possible but requires some on the fly changes to the inventory file and a re-read of the inventory in your playbook.

First, add a place holder to your inventory file like:

[local]
    localhost ansible_connection=local ansible_python_interpreter=python

[new_ones]

Second, in your playbook you're going to need two sections, one to run the local job and the second to run against the host(s) you created from the first section. In the first part, you'll create the hosts and then add the host IP to the inventory you created above. Then you'll tell ansible to re-read the inventory with the meta command and then wait for the host(s) to come up with a pause command. Here's an example:

---

- 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

Then you create another entry in the same playbook to copy your file. I don't have pip installed on my hosts by default so added that just in case you're in the same boat:

- 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

Here's the complete playbook in case you're still confused:

---

- 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

References

Ansible Meta Module

P.S. I only tested this building one host, if you build multiples your mileage may vary.

| improve this answer | |
  • That's actually true lol, i'm pretty new to ansible, and i have this in my hosts : [local] localhost ansible_connection=local ansible_python_interpreter=python Should i remove it ? – logax Mar 2 at 14:43
  • What else do you have in the inventory file? You can also bypass the need for an inventory file by using the -i switch with a list of IP addresses. If you only use one IP address add a trailing comma on the end e.g. ansible-playbook -i 10.0.0.2, play.yml – kenlukas Mar 2 at 15:13
  • The problem is that i want to create an ec2 instance and then upload war file to it in the same .yml file, so i do not want/can't know the ip address of the ec2 instance. – logax Mar 2 at 15:15
  • @logax, I see what you want now and adjusted my answer. – kenlukas Mar 2 at 18:08
  • Thank you for the answer, this code had some issues running on my setup, i fixed some stuff and now i'm stuck at installing pip lol, it won't install, but i want to ask about something else, pip: name: "{{ item }}" loop: - boto - boto3 - botocore Item is not declared in the variable, so how is it going to know what it is ? – logax Mar 4 at 10:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.