I have the below playbook. It correctly creates a security group in step. I can check via the AWS console that this really happens and the security group looks exactly as expected and has the ID sg-0dcf7ca7899835648.
But in step 2 I get the below error message which essentially states that the just created security group does not exist: "The security group 'sg-0dcf7ca7899835648' does not exist."
The same happens when I manually create SGs or manually insert the ID. The same happens with the group name.
How can I use the just created security group when launching a new EC2 instance?
The playbook:
---
- name: Create AWS EC2 instances and start them
hosts: localhost
gather_facts: false
vars:
instances_count: 1
tasks:
- name: Setup test security group
amazon.aws.ec2_group:
name: sg_conzone_test_01
description: "ConZone security group with access to several local ports. DONT USE FOR PRODUCTION!!!"
vpc_id: vpc-6a3ebe00
region: eu-central-1
profile: conzone_root
rules:
- proto: tcp
from_port: 3000
to_port: 3000
cidr_ip: 0.0.0.0/0
- proto: tcp
from_port: 22
to_port: 22
cidr_ip: 0.0.0.0/0
- proto: tcp
from_port: 8000
to_port: 8000
- proto: tcp
from_port: 8983
to_port: 8983
register: security_group
- name: Create AWS EC2 instance
amazon.aws.ec2:
profile: conzone_root
region: eu-central-1
key_name: ConZone-Testserver-Key01
instance_type: t2.large
image: ami-05f7491af5eef733a
wait: yes
group_id: "{{ security_group.group_id }}"
count: "{{ instances_count }}"
# vpc_subnet_id: vpc-6a3ebe00
assign_public_ip: yes
instance_tags:
Environment: test
os: ubuntu
ansible_user: ubuntu
db: postgres
solr: yes
register: ec2
The error message:
TASK [Create AWS EC2 instance] *************************************************************************************
task path: /Users/tkx/devel/conzone/conzone-config/playbooks/create_ec2.yml:32
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: <Response><Errors><Error><Code>InvalidGroup.NotFound</Code><Message>The security group 'sg-0dcf7ca7899835648' does not exist</Message></Error></Errors><RequestID>8241e3ea-5a59-4383-a5ac-f3a568f91960</RequestID></Response>
fatal: [localhost]: FAILED! => {"changed": false, "module_stderr": "Traceback (most recent call last):\n File \"<stdin>\", line 100, in <module>\n File \"<stdin>\", line 92, in _ansiballz_main\n File \"<stdin>\", line 40, in invoke_module\n File \"/usr/local/Caskroom/miniconda/base/lib/python3.9/runpy.py\", line 210, in run_module\n return _run_module_code(code, init_globals, run_name, mod_spec)\n File \"/usr/local/Caskroom/miniconda/base/lib/python3.9/runpy.py\", line 97, in _run_module_code\n _run_code(code, mod_globals, init_globals,\n File \"/usr/local/Caskroom/miniconda/base/lib/python3.9/runpy.py\", line 87, in _run_code\n exec(code, run_globals)\n File \"/var/folders/2w/g4gydjx960qbfxyvmbd3_sl00000gn/T/ansible_amazon.aws.ec2_payload_lpsz83a1/ansible_amazon.aws.ec2_payload.zip/ansible_collections/amazon/aws/plugins/modules/ec2.py\", line 1740, in <module>\n File \"/var/folders/2w/g4gydjx960qbfxyvmbd3_sl00000gn/T/ansible_amazon.aws.ec2_payload_lpsz83a1/ansible_amazon.aws.ec2_payload.zip/ansible_collections/amazon/aws/plugins/modules/ec2.py\", line 1724, in main\n File \"/var/folders/2w/g4gydjx960qbfxyvmbd3_sl00000gn/T/ansible_amazon.aws.ec2_payload_lpsz83a1/ansible_amazon.aws.ec2_payload.zip/ansible_collections/amazon/aws/plugins/modules/ec2.py\", line 1042, in create_instances\n File \"/usr/local/Caskroom/miniconda/base/lib/python3.9/site-packages/boto/ec2/connection.py\", line 2983, in get_all_security_groups\n return self.get_list('DescribeSecurityGroups', params,\n File \"/usr/local/Caskroom/miniconda/base/lib/python3.9/site-packages/boto/connection.py\", line 1186, in get_list\n raise self.ResponseError(response.status, response.reason, body)\nboto.exception.EC2ResponseError: EC2ResponseError: 400 Bad Request\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Response><Errors><Error><Code>InvalidGroup.NotFound</Code><Message>The security group 'sg-0dcf7ca7899835648' does not exist</Message></Error></Errors><RequestID>8241e3ea-5a59-4383-a5ac-f3a568f91960</RequestID></Response>\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}
It's because (as your commented code indicates) one needs to specify vpc_subnet_id: otherwise AWS will use the "default" VPC which is evidently not the vpc-6a3ebe00 in which you created the SG
Related
I have a playbook that starts an ec2 instance. But I keep getting the following error when I run it.
---
- name: Create an ec2 instance
hosts: localhost
gather_facts: false
vars:
region: us-east-1
instance_type: t2.micro
ami: ami-01ac7d9c1179d7b74
keypair: priyajdm
tasks:
- name: Create an ec2 instance
ec2:
key_name: "{{ keypair }}"
group: launch-wizard-31
instance_type: "{{ instance_type }}"
image: "{{ ami }}"
wait: true
region: "{{ region }}"
count: 1
vpc_subnet_id: subnet-02f498e16fd56c277
assign_public_ip: yes
register: ec2
Error:
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: AuthFailureAWS was not able to validate the provided access credentialscb70bd1a-b7ec-41aa-895a-fabf9e0b6cfe
fatal: [localhost]: FAILED! => {"changed": false, "module_stderr": "Traceback (most recent call last):\n File \"/root/.ansible/tmp/ansible-tmp-1553599571.08-120541135236553/AnsiballZ_ec2.py\", line 113, in \n _ansiballz_main()\n File \"/root/.ansible/tmp/ansible-tmp-1553599571.08-120541135236553/AnsiballZ_ec2.py\", line 105, in _ansiballz_main\n invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n File \"/root/.ansible/tmp/ansible-tmp-1553599571.08-120541135236553/AnsiballZ_ec2.py\", line 48, in invoke_module\n imp.load_module('main', mod, module, MOD_DESC)\n File \"/tmp/ansible_ec2_payload_hXpgWw/main.py\", line 1702, in \n File \"/tmp/ansible_ec2_payload_hXpgWw/main.py\", line 1686, in main\n File \"/tmp/ansible_ec2_payload_hXpgWw/main.py\", line 989, in create_instances\n File \"/home/ubuntu/.local/lib/python2.7/site-packages/boto/vpc/init.py\", line 1152, in get_all_subnets\n return self.get_list('DescribeSubnets', params, [('item', Subnet)])\n File \"/home/ubuntu/.local/lib/python2.7/site-packages/boto/connection.py\", line 1186, in get_list\n raise self.ResponseError(response.status, response.reason, body)\nboto.exception.EC2ResponseError: EC2ResponseError: 401 Unauthorized\n\nAuthFailureAWS was not able to validate the provided access credentialscb70bd1a-b7ec-41aa-895a-fabf9e0b6cfe\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}
Where do you keep your AWS credentials? You have 3 option:
Use boto configuration file
Set needed enviroment varaibles
Set EC2 module AWS credentials parameters in your task
Last options is the worst practice but easiest way to solve authentication problems.
Check the EC2 Module’s notes.
I've more than 100 running instances
Example I have 10 running instances with tag name dev-redis-slave. And now I want to create new tag -> tag ServiceName: redis-slave and tag ServiceGroup: redis
First of all, I try following this guide: https://aws.amazon.com/blogs/apn/getting-started-with-ansible-and-dynamic-amazon-ec2-inventory-management/
Then I try to excecute ec2.py --list | grep redis. Then the output is: tag_Name_dev_redis_slave. Also I try to ping: ansible -m ping tag_Name_dev_redis_slave and success.
Next I want to create new tag for dev-redis-slave using ansible.,
I create yaml file like this (playbook.yaml).
- hosts: localhost
gather_facts: yes
tasks:
- name: Adding tags
ec2_tag:
resource: tag_Name_dev_redis_slave
region: xxx
state: present
tags:
ServiceGroup: redis
ServiceName: redis-slave
I run ansible-playbook playbook.yaml But It give an error.
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: <Response><Errors><Error><Code>InvalidID</Code><Message>The ID 'tag_Name_dev_redis_slave' is not valid</Message></Error></Errors><RequestID>de51df48-df26-4312-8d03-4c8ca2b993bf</RequestID></Response>
fatal: [localhost]: FAILED! => {"changed": false, "module_stderr": "Traceback (most recent call last):\n File \"/var/folders/5b/hhh0h2fx2cxf7_24dmn05ht00000gq/T/ansible_460t6taz/ansible_module_ec2_tag.py\", line 183, in <module>\n main()\n File \"/var/folders/5b/hhh0h2fx2cxf7_24dmn05ht00000gq/T/ansible_460t6taz/ansible_module_ec2_tag.py\", line 160, in main\n ec2.create_tags(resource, dictadd)\n File \"/Users/fourirakbar/Documents/ansible/venv/lib/python3.6/site-packages/boto/ec2/connection.py\", line 4219, in create_tags\n return self.get_status('CreateTags', params, verb='POST')\n File \"/Users/fourirakbar/Documents/ansible/venv/lib/python3.6/site-packages/boto/connection.py\", line 1227, in get_status\n raise self.ResponseError(response.status, response.reason, body)\nboto.exception.EC2ResponseError: EC2ResponseError: 400 Bad Request\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Response><Errors><Error><Code>InvalidID</Code><Message>The ID 'tag_Name_dev_redis_slave' is not valid</Message></Error></Errors><RequestID>de51df48-df26-4312-8d03-4c8ca2b993bf</RequestID></Response>\n", "module_stdout": "", "msg": "MODULE FAILURE", "rc": 1}
I also try to follow this: http://ansible-manual.readthedocs.io/en/latest/ec2_tag_module.html#examples . But also error.
how to fix it?
sorry, I was wrong to define resource. I think resource=tag, but the correct one is resource=instance id. Thankyou for helping
so I change my playbook.yaml like this
- hosts: localhost
gather_facts: yes
vars:
development:
- YOUR INSTANCE ID
- YOUR INSTANCE ID
tasks:
- name: Adding tags
ec2_tag:
resource: "{{ item }}"
region: YOUR INSTANCE REGION
args:
tags:
ServiceGroup: redis
ServiceName: redis-slave
with_items: "{{ development }}"
but I was wondering, maybe next I don't need to describe instance id one by one (imagine if we've so many instance with different group tag).
guys if you have an answer, please let me know
thank you very much
This is my yml script which I want to run to create an ec2 instance. But i'm getting error in the first line no matter what I put in there.
SYNTAX CHECKED AND IS FINE.
error:
"ERROR! A malformed block was encountered.
The error appears to have been in '/root/aws-create/ec2c.yml': line 2, column 3, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
-
name: Stage instance(s)
^ here"
-
name: Stage instance(s)
hosts: aws
connection: ssh
remote_user: ec2-user
become: yes
gather_facts: false
vars:
keypair: newrhel_2
instance_type: t2.micro
security_group: default
image: ami-b55a51cc
aws_region: us-west-2
aws_access_key: xxxxxxxxxxxxxxxxxxxxxxxx
aws_secret_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
tasks:
ec2:
aws_access_key={{aws_access_key}}
aws_secret_key={{aws_secret_key}}
keypair={{keypair}}
group={{security_group}}
instance_type={{instance_type}}
image={{image}}
region={{aws_region}}
wait=true
count=1
tasks should contain a list, not a dictionary (and because you use Ansible notation, ec2 is not valid as a YAML dictionary). You need to add a hyphen before ec2:
tasks:
- ec2:
This question already has answers here:
How to set Linux environment variables with Ansible
(7 answers)
Closed 6 years ago.
I have the following playbook:
- hosts: localhost
connection: local
remote_user: test
gather_facts: no
vars_files:
- files/aws_creds.yml
- files/info.yml
tasks:
- name: Basic provisioning of EC2 instance
ec2:
assign_public_ip: no
aws_access_key: "{{ aws_id }}"
aws_secret_key: "{{ aws_key }}"
region: "{{ aws_region }}"
image: "{{ standard_ami }}"
instance_type: "{{ free_instance }}"
key_name: "{{ ssh_keyname }}"
count: 3
state: present
group_id: "{{ secgroup_id }}"
#vpc_subnet_id: "{{ private_subnet_id }}"
wait: no
#delete_on_termination: yes
instance_tags:
Name: Dawny33Template
register: ec2
- name: Add new instance to host group
add_host:
hostname: "{{ item.public_ip }}"
groupname: launched
with_items: "{{ ec2.instances }}"
- name: Wait for SSH to come up
wait_for:
host: "{{ item.public_dns_name }}"
port: 22
delay: 60
timeout: 320
state: started
with_items: "{{ ec2.instances }}"
- name: Install dependencies
yum:
name=git
state=present
sudo: yes
- name: Install Python libs
easy_install:
name: boto3
state: latest
sudo: yes
- name: check out a git repository
git: repo={{ repo_url }} dest=/home/ec2-user/AnsibleDir/GitRepo accept_hostkey=yes force=yes
vars:
repo_url: https://github.com/Dawny33/AnsibleExperiments
become: yes
- name: Go to the folder and execute command
command: chmod 0755 /home/ec2-user/AnsibleDir/GitRepo/processing.py
become: yes
become_user: root
- name: Set credentials
shell: export AWS_ACCESS_KEY_ID=''
become: yes
become_user: root
- name: Set credentials2
shell: export AWS_SECRET_ACCESS_KEY=''
become: yes
become_user: root
- name: Run Py script
command: /home/ec2-user/AnsibleDir/GitRepo/processing.py {{ N }} {{ bucket_name }}
become: yes
become_user: root
- name: Terminate instances that were previously launched
connection: local
become: false
ec2:
state: 'absent'
instance_ids: '{{ ec2.instance_ids }}'
region: '{{ aws_region }}'
In this, I checkout a git repo and run a py file, which uses boto.
So, how do I set up AWS credentials in the dynamically created EC2 instances? Is there an Ansible module for doing so?
PS: The shell modules for exporting the keys are not working. They are throwing the following error:
"stderr": "sh: s3cmd: command not found\nTraceback (most recent call last):\n File \"/home/ec2-user/AnsibleDir/GitRepo/processing.py\", line 48, in <module>\n print get_details(N, str(bucket_name))\n File \"/home/ec2-user/AnsibleDir/GitRepo/processing.py\", line 37, in get_details\n for obj in bucket.objects.all():\n File \"/usr/local/lib/python2.7/site-packages/boto3-1.4.4-py2.7.egg/boto3/resources/collection.py\", line 83, in __iter__\n for page in self.pages():\n File \"/usr/local/lib/python2.7/site-packages/boto3-1.4.4-py2.7.egg/boto3/resources/collection.py\", line 166, in pages\n for page in pages:\n File \"/usr/local/lib/python2.7/site-packages/botocore-1.5.7-py2.7.egg/botocore/paginate.py\", line 102, in __iter__\n response = self._make_request(current_kwargs)\n File \"/usr/local/lib/python2.7/site-packages/botocore-1.5.7-py2.7.egg/botocore/paginate.py\", line 174, in _make_request\n return self._method(**current_kwargs)\n File \"/usr/local/lib/python2.7/site-packages/botocore-1.5.7-py2.7.egg/botocore/client.py\", line 253, in _api_call\n return self._make_api_call(operation_name, kwargs)\n File \"/usr/local/lib/python2.7/site-packages/botocore-1.5.7-py2.7.egg/botocore/client.py\", line 530, in _make_api_call\n operation_model, request_dict)\n File \"/usr/local/lib/python2.7/site-packages/botocore-1.5.7-py2.7.egg/botocore/endpoint.py\", line 141, in make_request\n return self._send_request(request_dict, operation_model)\n File \"/usr/local/lib/python2.7/site-packages/botocore-1.5.7-py2.7.egg/botocore/endpoint.py\", line 166, in _send_request\n request = self.create_request(request_dict, operation_model)\n File \"/usr/local/lib/python2.7/site-packages/botocore-1.5.7-py2.7.egg/botocore/endpoint.py\", line 150, in create_request\n operation_name=operation_model.name)\n File \"/usr/local/lib/python2.7/site-packages/botocore-1.5.7-py2.7.egg/botocore/hooks.py\", line 227, in emit\n return self._emit(event_name, kwargs)\n File \"/usr/local/lib/python2.7/site-packages/botocore-1.5.7-py2.7.egg/botocore/hooks.py\", line 210, in _emit\n response = handler(**kwargs)\n File \"/usr/local/lib/python2.7/site-packages/botocore-1.5.7-py2.7.egg/botocore/signers.py\", line 90, in handler\n return self.sign(operation_name, request)\n File \"/usr/local/lib/python2.7/site-packages/botocore-1.5.7-py2.7.egg/botocore/signers.py\", line 147, in sign\n auth.add_auth(request)\n File \"/usr/local/lib/python2.7/site-packages/botocore-1.5.7-py2.7.egg/botocore/auth.py\", line 679, in add_auth\n raise NoCredentialsError\nbotocore.exceptions.NoCredentialsError: Unable to locate credentials",
"stdout": "",
"stdout_lines": [],
"warnings": []
}
The script is: https://github.com/Dawny33/AnsibleExperiments/blob/master/processing.py
You can do either of the following:
1) As suggested by #konstantin in the comment of your question you can export the keys as environment variables.
2) For AWS related deployments/AWS EC2 instances which require API keys, you could use the IAM instance roles which have the required access that your application needs.
I followed these 3 guides:
http://docs.ansible.com/ansible/guide_aws.html
http://docs.ansible.com/ansible/ec2_module.html
https://gist.github.com/tristanfisher/e5a306144a637dc739e7
and I wrote this Ansible play
---
- hosts: localhost
connection: local
gather_facts: false
tasks:
- include_vars: aws_credentials.yml
- name: Creating EC2 Ubuntu instance
ec2:
instance_type: t1.micro
image: ami-86e0ffe7
region: us-west-2
key_name: my-aws-key
zone: us-west-2a
vpc_subnet_id: subnet-04199d61
group_id: sg-cf6736aa
assign_public_ip: yes
count: 1
wait: true
volumes:
- device_name: /dev/sda1
volume_type: gp2
volume_size: 10
instance_tags:
Name: ansible-test
Project: test
Ansible: manageable
register: ec2
then I run ansible-playbook create-ec2.yml -v --private-key ~/.ssh/my-key --vault-password-file ~/.password/to_ansible_vault
and I was getting this message
PLAY [localhost] ***************************************************************
TASK [include_vars] ************************************************************
ok: [localhost] => {"ansible_facts": {"ec2_access_key": "decrypted_acces_key_XXXXX", "ec2_secret_key": "decrypted_secret_key_XXXXX"}, "changed": false}
TASK [Creating EC2 Ubuntu instance] ********************************************
fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "msg": "No handler was ready to authenticate. 1 handlers were checked. ['HmacAuthV4Handler'] Check your credentials"}
NO MORE HOSTS LEFT *************************************************************
[WARNING]: Could not create retry file 'create-ec2.retry'. [Errno 2] No such file or directory: ''
PLAY RECAP *********************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=1
when I ran ansible-vault view aws_credentials.yml --vault-password-file ~/.password/to_ansible_vault I got readable content of encrypted aws_credentials.yml,
something like this :
---
ec2_access_key: "XXXXX"
ec2_secret_key: "XXXXX"
Also when I used plain aws_credentials.yml, it doesn't work. Only when I export my credentials, it works without any failure.
Could somebody help me, how can I write playbook for creating ec2 instance with credentials stored in encrypted file?
I think you should supply your keys directly to ec2 module in this case.
Try this:
- name: Creating EC2 Ubuntu instance
ec2:
aws_access_key: "{{ ec2_access_key }}"
aws_secret_key: "{{ ec2_secret_key }}"
instance_type: t1.micro
image: ami-86e0ffe7
region: us-west-2
...
The code suggests that it only checks module's arguments and environment variables, not host variables.
Also you can export your AWS API keys to OS environment variables, like a:
export AWS_ACCESS_KEY=XXXXXXX
In that case in Ansible scenario you need to set:
- name: Creating EC2 Ubuntu instance
ec2:
aws_access_key: "{{ lookup('env', 'AWS_ACCESS_KEY') }}"
aws_secret_key: "{{ lookup('env', 'AWS_SECRET_KEY') }}"
instance_type: t1.micro
image: ami-86e0ffe7
region: us-west-2