Ansible version: 2.9.16
I have several application load balancers in the AWS account and I'm trying to add a new rule to certain listeners from these load balancers. I'm using the community.aws.elb_application_lb_info
plugin to gather information about the load balancers and locate the target listeners where to add the new rule.
In the json returned by community.aws.elb_application_lb_info
the default actions of some listeners look like this:
"default_actions":[
{
"target_group_arn":"some-arn",
"type":"forward",
"order":1,
"forward_config":{
"target_group_stickiness_config":{
"enabled":false
},
"target_groups":[
{
"target_group_arn":"some-arn",
"weight":1
}
]
}
}
]
while others look like this:
"default_actions":[
{
"redirect_config":{
"host":"some-host",
"protocol":"HTTPS",
"path":"/",
"status_code":"HTTP_302",
"query":"",
"port":"443"
},
"type":"redirect",
"order":1
}
]
Then I'm using community.aws.elb_application_lb
plugin to add the rule to the listener.
Now the problem: the parameter listeners: - DefaultActions
is mandatory in community.aws.elb_application_lb
. I'm trying to specify it by extracting it from the json generated by community.aws.elb_application_lb_info
, so my code looks like this:
# load_balancer_name var is defined somewhere else
- name: "Gather information about the following ALB: {{ load_balancer_name }}"
community.aws.elb_application_lb_info:
...
names: "{{ load_balancer_name }}"
register: elb_application_lb_info_ret
...
- name: Get the HTTPS:443 listener from ALB
vars:
listener_port: 443
listener_protocol: "HTTPS"
set_fact:
listener: "{{ elb_application_lb_info_ret.load_balancers[0].listeners | selectattr('protocol', 'equalto', listener_protocol) | selectattr('port', 'equalto', listener_port) | list | first }}"
...
- name: Create the listener rule in the load balancer
community.aws.elb_application_lb:
name: "{{ load_balancer_name }}"
.....
listeners:
- Protocol: "{{ listener.protocol }}"
Port: "{{ listener.port }}"
....
DefaultActions: "{{ listener.default_actions[0] }}"
Rules:
- Conditions:
....
but I get the following error:
TASK [xxx : Create the listener rule in the load balancer] *******************************************************************************************************************************************
fatal: [xxx]: FAILED! => {
"changed": false
}
MSG:
argument DefaultActions is of type <class 'dict'> found in 'listeners'. and we were unable to convert to list: <class 'dict'> cannot be converted to a list
If in the playbook above I change DefaultActions: "{{ listener.default_actions[0] }}"
to DefaultActions: "{{ listener.default_actions }}"
I get the following error:
TASK [xxx : Create the listener rule in the load balancer] *******************************************************************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: KeyError: 'Type'
fatal: [xxx]: FAILED! => {
"changed": false,
"rc": 1
}
MSG:
MODULE FAILURE
See stdout/stderr for the exact error
MODULE_STDERR:
Traceback (most recent call last):
...
KeyError: 'Type'
So, looks like my approach is not good.
Is there any possibility to just tell community.aws.elb_application_lb
to use the already defined DefaultActions for a listener to which I want to add a rule? All my load balancers already exist and have default actions defined. So I just want my script to add a rule and keep the default actions exactly as they are defined.
I guess it is possible to extract the data for each default action from json and recreate the default action each time, but the code would get pretty complicated.
So, I ended up re-creating DefaultActions. Not a nice solution but I couldn't come up with something better so far. But at least it works.
# code to get the target 'listener' via the community.aws.elb_application_lb_info plugin
...
# there are two types of default actions: redirect or forward
- name: Check if default action of listener is "redirect"
vars:
default_action: "{{ listener.default_actions[0] }}"
when: default_action.type == 'redirect'
set_fact:
default_actions:
- Type: "redirect"
RedirectConfig:
Protocol: "{{ default_action.redirect_config.protocol }}"
Port: "{{ default_action.redirect_config.port }}"
Host: "{{ default_action.redirect_config.host }}"
Path: "{{ default_action.redirect_config.path }}"
Query: "{{ default_action.redirect_config.query }}"
StatusCode: "{{ default_action.redirect_config.status_code }}"
- name: Check if default action of listener is "forward"
vars:
default_action: "{{ listener.default_actions[0] }}"
when: default_action.type == 'forward'
set_fact:
default_actions:
- Type: "forward"
TargetGroupArn: "{{ default_action.target_group_arn }}"
- name: Create/modify the listener rule in the load balancer
community.aws.elb_application_lb:
...
listeners:
- Protocol: "{{ listener.protocol }}"
...
DefaultActions: "{{ default_actions }}"
Rules:
...