I have a play-book that created VPC security groups.
It works well, but many times, and update to an existing security group (mostly adding or removing ports) is not applied (not detected by Ansible).
Original code:
- name: create sg_riemann_elb rules
local_action:
module: ec2_group
region: "{{ region }}"
vpc_id: "{{ vpc.vpc.id }}"
name: "sg_riemann_elb"
description: security group for Riemann elb
rules:
- proto: tcp
from_port: 5555
to_port: 5556
group_name: "{{ realm }}_sg_base_server"
group_desc: security group for all servers
rules_egress:
- proto: tcp
from_port: 5555
to_port: 5556
group_name: "{{ realm }}_sg_riemann_server"
group_desc: security group for Riemann servers
New code: (added port 4567)
- name: create sg_riemann_elb rules
local_action:
module: ec2_group
region: "{{ region }}"
vpc_id: "{{ vpc.vpc.id }}"
name: "sg_riemann_elb"
description: security group for Riemann elb
rules:
- proto: tcp
from_port: 4567
to_port: 4567
group_name: "{{ realm }}_sg_base_server"
group_desc: security group for all servers
rules:
- proto: tcp
from_port: 5555
to_port: 5556
group_name: "{{ realm }}_sg_base_server"
group_desc: security group for all servers
rules_egress:
- proto: tcp
from_port: 5555
to_port: 5556
group_name: "{{ realm }}_sg_riemann_server"
group_desc: security group for Riemann servers
The output from the Ansible run is:
TASK [vpc : create sg_riemann_server rules] ************************************
ok: [localhost -> localhost] => {"changed": false, "group_id": "sg-ce89bcaa"}
Any idea why it's not updated with new port (4567)?
There are two items with a key rules in the task create sg_riemann_elb rules and one is overwriting the other. The fix is to define only one rules key with a list of security group rules, like this:
...
description: security group for Riemann elb
rules:
- proto: tcp
from_port: 4567
to_port: 4567
group_name: "{{ realm }}_sg_base_server"
group_desc: security group for all servers
- proto: tcp
from_port: 5555
to_port: 5556
group_name: "{{ realm }}_sg_base_server"
group_desc: security group for all servers
rules_egress:
...
Related
I have installed ansible on one ec2 server and created one role with "AmazonEC2FullAccess" and attached it to the instance. I use this instance as ansible controller node and trying to create ec2 instance with below playbook.
name: provisioning EC2 instance using Ansible
hosts: localhost
connection: local
gather_facts: false
tags: provisioning
vars:
keypair: test
instance_type: t2.micro
image: ami-0c9978668f8d55984
wait: yes
group: webserver
count: 2
region: us-east-1
security_group: my-ansible-security-group
tasks:
name: Task#1 - Create my security group
local_action:
module: ec2_group
name: "{{ security_group }}"
description: security group for webserver
region: "{{ region }}"
rules:
proto: tcp
from_port: 22
to_port: 22
cidr_ip: 0.0.0.0/0
proto: tcp
from_port: 8080
to_port: 8080
cidr_ip: 0.0.0.0/0
proto: tcp
from_port: 80
to_port: 80
cidr_ip: 0.0.0.0/0
proto: tcp
from_port: 443
to_port: 443
cidr_ip: 0.0.0.0/0
rules_egress:
proto: all
cidr_ip: 0.0.0.0/0
register: basic_firewall
name: Task#2 - Launch the new EC2 instance
local_action:
module: ec2
group: "{{ security_group }}"
instance_type: "{{ instance_type }}"
image: "{{ image }}"
wait: true
region: "{{ region }}"
keypair: "{{ keypair }}"
count: "{{ count }}"
register: ec2
name: Task#3 - Add Tagging to EC2 instance
local_action: ec2_tag resource={{ item.id }} region={{ region }} state=present
with_items: "{{ ec2.instances }}"
args:
tags:
Name: MyTargetEc2Instance
But I am getting below error:
ubuntu#ip-172-31-60-239:~/playbooks$ sudo ansible-playbook create_ec2.yml
PLAY [provisioning EC2 instance using Ansible] **********************************************************************************************************************************************
TASK [Task#1 - Create my security group] ****************************************************************************************************************************************************
ok: [local -> localhost]
TASK [Task#2 - Launch the new EC2 instance] *************************************************************************************************************************************************
fatal: [local -> localhost]: FAILED! => {"msg": "The module ec2 was redirected to amazon.aws.ec2, which could not be loaded."}
PLAY RECAP **********************************************************************************************************************************************************************************
local : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
Please help me to resolve it.
I want to run these mikrotik commands using ansible
interface bridge port add bridge=bridge1 ingress-filtering=no interface=ether3
interface bridge port add bridge=bridge1 ingress-filtering=no interface=ether4
BUT NOT
interface bridge port add bridge=bridge1 ingress-filtering=no interface=ether3,ether4
my playbook run wrong command
How to fix that
tq
`# cat main.yml
- hosts: mikrotiks
gather_facts: no
connection: network_cli
vars:
ansible_network_os: routeros
vlans:
- 10:
interfaces:
- ether3
- ether4
untagged_interfaces: ether2
tagged_interfaces: bridge1,ether3,ether4
network: 10.0.10.0
netmask: 24
ip_address1: 10.0.10.1
ip_address2: 10.0.10.2
dns: 192.168.88.1
dhcp_pool1: 10.0.10.101-10.0.10.150
dhcp_pool2: 10.0.10.151-10.0.10.200
leasetime: 1d
- 20:
interfaces:
- ether3
- ether4
untagged_interfaces: ether2
tagged_interfaces: bridge1,ether3,ether4
network: 10.0.20.0
netmask: 24
ip_address1: 10.0.20.1
ip_address2: 10.0.20.2
dns: 192.168.88.1
dhcp_pool1: 10.0.20.101-10.0.20.150
dhcp_pool2: 10.0.20.151-10.0.20.200
leasetime: 1d
tasks:
- import_tasks: vlan.yml
cat vlan.yml
- name: create vlans on R1
routeros_command:
commands:
- "interface bridge port add bridge=bridge1 ingress-filtering=no interface={{ item.value.interfaces }}"
- "interface bridge port add bridge=bridge1 frame-types=admit-only-untagged-and-priority-tagged pvid=10 interface={{ item.value.interfaces }}"
with_dict: "{{ vlans }}"\`
EDIT: my mikrotik commands should be like this
R1 /interface bridge port add bridge=bridge1 ingress-filtering=no interface=ether3 add bridge=bridge1 ingress-filtering=no interface=ether4 add bridge=bridge1 frame-types=admit-only-untagged-and-priority-tagged interface=ether2 pvid=10 /interface bridge vlan add bridge=bridge1 tagged=bridge1,ether3,ether4 untagged=ether2 vlan-ids=10 add bridge=bridge1 tagged=bridge1,ether3,ether4 vlan-ids=20
when I use these
\`routeros_command:
commands:
- "/interface bridge port add bridge=bridge1 ingress-filtering=no interface={{ item.1 }}"
- "/interface bridge port add bridge=bridge1 frame-types=admit-only-untagged-and-priority-tagged pvid=10 interface={{ item.1 }}"
with_subelements:
- "{{ vlans }}"
- interfaces`
I got this error
`fatal: [R1]: FAILED! => {
"msg": "could not find 'interfaces' key in iterated item '{10: {'interfaces': ['ether3', 'ether4'], 'untagged_interfaces': 'ether2', 'tagged_interfaces': 'bridge1,ether3,ether4', 'network': '10.0.10.0', 'netmask': 24, 'ip_address1': '10.0.10.1', 'ip_address2': '10.0.10.2', 'dns': '192.168.88.1', 'dhcp_pool1': '10.0.10.101-10.0.10.150', 'dhcp_pool2': '10.0.10.151-10.0.10.200', 'leasetime': '1d'}}'"`
Iterate with_subelements, e.g.
- debug:
msg: "{{ item.0.keys()|first }} ... interface={{ item.1 }}"
with_subelements:
- "{{ vlans }}"
- interfaces
gives
msg: 10 ... interface=ether3
msg: 10 ... interface=ether4
msg: 20 ... interface=ether3
msg: 20 ... interface=ether4
I'm currently trying to find a way to dynamically create some firewall rules (with the ufw ansible module) on some hosts. In the current context, we're talking about a docker swarm.
What I want to do is to create a set of rules (different protocols, ports) per source ip, but to have that dynamically expand with the number (and IP) of host, so that whatever is the amount or IP of the nodes, it always ends up creating one set of rule PER node on each node. Ideally, I would be able to exclude the current host it's running on as well.
I'm not very familiar with ansible and I'm not sure it's possible, as it would probably require to loop within a loop when creating the rules.
I've tried to join the address within the group with ip_swarm: "{{groups['all']|join(',') }}" but ufw doesn't allow you to create rules that way and require one line per port/ip/proto it would seem (or ansible does, but looking at the code for the module, it seems to be ufw).
I'm assuming if there is a way, this is with some jinja loop in defining variables ? Or maybe with_subelements ?
Here's my current code, though that won't help as this was made for the case of a variable holding a string with comma separated values for IPs :
- name: Regles pare feu pour docker swarm
ufw:
rule: allow
direction: "{{ item.direction }}"
proto: "{{ item.proto }}"
port: "{{ item.port }}"
from_ip: "{{ item.from_ip }}"
state: reloaded
loop:
- direction: "in"
proto: "tcp"
port: "2377"
from_ip: " {{ ip_swarm }}"
- direction: "in"
proto: "tcp"
port: "7946"
from_ip: " {{ ip_swarm }}"
- direction: "in"
proto: "udp"
port: "7946"
from_ip: " {{ ip_swarm }}"
- direction: "in"
proto: "udp"
port: "4789"
from_ip: " {{ ip_swarm }}"
Here you go :) If you have some kind of idea, I'll gladly take it. Have a good day !
Well, turns out it was much simpler than what I intended. Ansible does have nested loop, with either with_nested, or by using non depreceated options, loop with the product filter (the first option being easier to read). See https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html
My vars file that contains the FW parameters (for indication) :
---
liste_regle_pare_feu:
- direction: "in"
proto: "tcp"
port: "2377"
- direction: "in"
proto: "tcp"
port: "7946"
- direction: "in"
proto: "udp"
port: "7946"
- direction: "in"
proto: "udp"
port: "4789"
and the task itself :
- name: Regles pare feu pour docker swarm
ufw:
rule: allow
direction: "{{ item.1.direction }}"
proto: "{{ item.1.proto }}"
port: "{{ item.1.port }}"
from_ip: "{{ item.0 }}"
loop: "{{ groups['all']|product(liste_regle_pare_feu)|list }}"
the loop will, for each item in the first object (here groups['all'], the list of all IPs), iterate over my rule list (of hashtables). See documentation for details on product filter
I have following playbook to modify ASA object-group:
---
- hosts: us_asa
connection: local
gather_facts: false
tasks:
- name: change config
asa_config:
auth_pass: "{{ ansible_ssh_password }}"
username: "{{ ansible_ssh_user }}"
password: "{{ ansible_ssh_password }}"
authorize: yes
timeout: 45
lines:
- network-object host 1.2.3.4
- network-object host 2.3.2.3
parents: ['object-group network BAD_IPs']
This works fine for single group.
Any suggestion how to modify multiple groups with same connection? If I add another object-group after parents: ['object-group network BAD_IPs'] example:
---
- hosts: us_asa
connection: local
gather_facts: false
tasks:
- name: change config
asa_config:
auth_pass: "{{ ansible_ssh_password }}"
username: "{{ ansible_ssh_user }}"
password: "{{ ansible_ssh_password }}"
authorize: yes
timeout: 45
lines:
- network-object host 1.2.3.4
- network-object host 2.3.2.3
parents: ['object-group network BAD_IPs']
- network-object host 4.4.4.4
parents: ['object-group network Good_IPs']
This fails
The offending line appears to be:
parents: ['object-group network BAD_IPs']
- network-object host 4.4.4.4
^ here
Any recommendation on syntax I should use?
Thank you in advance!
You just have a basic YAML syntax error there. A YAML dictionary key with a list value looks either like this:
key: [item1, item2, item3]
Or like this:
key:
- item1
- item2
- item3
You have some weird combination of the two:
parents: ['object-group network BAD_IPs']
- network-object host 4.4.4.4
I don't know exactly what structure you want, but what you have there is simply invalid.
I have been working for a while registering EC2 instances to ELB's using Ansible. But now I'm starting to use ALB's and I need to connect my instances to Target Groups which in turn are connected to the ALB. Is there an Ansible plugin that allows me to register an instance to a AWS Target Group?
Since Ansible does not support registration of instances to target groups I had to use the AWS-CLI tool. With the following command you can register an instance to a target group:
aws elbv2 register-targets --target-group-arn arn:aws:elasticloadbalancing:us-east-1:your-target-group --targets Id=i-your-instance
So I just call this command from Ansible and it's done.
Use elb_target:
name: Gather facts for all new proxy instances
ec2_instance_facts:
filters:
"tag:Name": "{{ ec2_tag_proxy }}"
register: ec2_proxy
elb_target_group:
name: uat-target-proxy
protocol: http
port: 80
vpc_id: vpc-4e6e8112
deregistration_delay_timeout: 60
stickiness_enabled: True
stickiness_lb_cookie_duration: 86400
health_check_path: /
successful_response_codes: "200"
health_check_interval: "20"
state: present
elb_target:
target_group_name: uat-target-proxy
target_id: "{{ item.instance_id }}"
target_port: 80
state: present
with_items: "{{ ec2_proxy.instances }}"
when: ec2_proxy.instances|length > 0
Try the following configurations:
- name: creating target group
local_action:
module: elb_target_group
region: us-east-2
vpc_id: yourvpcid
name: create-targetgrp-delete
protocol: https
port: 443
health_check_path: /
successful_response_codes: "200,250-260"
state: present
targets:
- Id: ec2isntanceid
Port: 443
wait_timeout: 200
register: tgp