diff --git a/hacking/aws_config/testing_policies/compute-policy.json b/hacking/aws_config/testing_policies/compute-policy.json index a17850a4d08..e6713898293 100644 --- a/hacking/aws_config/testing_policies/compute-policy.json +++ b/hacking/aws_config/testing_policies/compute-policy.json @@ -132,10 +132,12 @@ "elasticloadbalancing:CreateListener", "elasticloadbalancing:CreateLoadBalancer", "elasticloadbalancing:CreateLoadBalancerListeners", + "elasticloadbalancing:CreateRule", "elasticloadbalancing:CreateTargetGroup", "elasticloadbalancing:DeleteListener", "elasticloadbalancing:DeleteLoadBalancer", "elasticloadbalancing:DeleteLoadBalancerListeners", + "elasticloadbalancing:DeleteRule", "elasticloadbalancing:DeleteTargetGroup", "elasticloadbalancing:DeregisterInstancesFromLoadBalancer", "elasticloadbalancing:DescribeInstanceHealth", @@ -143,7 +145,9 @@ "elasticloadbalancing:DescribeTags", "elasticloadbalancing:DisableAvailabilityZonesForLoadBalancer", "elasticloadbalancing:EnableAvailabilityZonesForLoadBalancer", + "elasticloadbalancing:ModifyListener", "elasticloadbalancing:ModifyLoadBalancerAttributes", + "elasticloadbalancing:ModifyRule", "elasticloadbalancing:RegisterInstancesWithLoadBalancer", "elasticloadbalancing:RemoveTags" ], diff --git a/hacking/aws_config/testing_policies/security-policy.json b/hacking/aws_config/testing_policies/security-policy.json index 4b1f53e3628..a1086aadcb0 100644 --- a/hacking/aws_config/testing_policies/security-policy.json +++ b/hacking/aws_config/testing_policies/security-policy.json @@ -122,7 +122,10 @@ "Effect": "Allow", "Action": [ "iam:ListServerCertificates", - "iam:UploadServerCertificate" + "iam:UploadServerCertificate", + "iam:UpdateServerCertificate", + "iam:DeleteServerCertificate", + "iam:GetServerCertificate" ], "Resource": "*" } diff --git a/lib/ansible/module_utils/aws/elbv2.py b/lib/ansible/module_utils/aws/elbv2.py index 47d0e87a51c..34a428dfd96 100644 --- a/lib/ansible/module_utils/aws/elbv2.py +++ b/lib/ansible/module_utils/aws/elbv2.py @@ -466,13 +466,20 @@ class ELBListeners(object): if not listeners: listeners = [] + fixed_listeners = [] for listener in listeners: - if 'TargetGroupName' in listener['DefaultActions'][0]: - listener['DefaultActions'][0]['TargetGroupArn'] = convert_tg_name_to_arn(self.connection, self.module, - listener['DefaultActions'][0]['TargetGroupName']) - del listener['DefaultActions'][0]['TargetGroupName'] - - return listeners + fixed_actions = [] + for action in listener['DefaultActions']: + if 'TargetGroupName' in action: + action['TargetGroupArn'] = convert_tg_name_to_arn(self.connection, + self.module, + action['TargetGroupName']) + del action['TargetGroupName'] + fixed_actions.append(action) + listener['DefaultActions'] = fixed_actions + fixed_listeners.append(listener) + + return fixed_listeners def compare_listeners(self): """ @@ -540,12 +547,47 @@ class ELBListeners(object): modified_listener['Certificates'][0]['CertificateArn'] = new_listener['Certificates'][0]['CertificateArn'] # Default action - # We wont worry about the Action Type because it is always 'forward' - if current_listener['DefaultActions'][0]['TargetGroupArn'] != new_listener['DefaultActions'][0]['TargetGroupArn']: - modified_listener['DefaultActions'] = [] - modified_listener['DefaultActions'].append({}) - modified_listener['DefaultActions'][0]['TargetGroupArn'] = new_listener['DefaultActions'][0]['TargetGroupArn'] - modified_listener['DefaultActions'][0]['Type'] = 'forward' + + # Check proper rule format on current listener + if len(current_listener['DefaultActions']) > 1: + for action in current_listener['DefaultActions']: + if 'Order' not in action: + self.module.fail_json(msg="'Order' key not found in actions. " + "installed version of botocore does not support " + "multiple actions, please upgrade botocore to version " + "1.10.30 or higher") + + # If the lengths of the actions are the same, we'll have to verify that the + # contents of those actions are the same + if len(current_listener['DefaultActions']) == len(new_listener['DefaultActions']): + # if actions have just one element, compare the contents and then update if + # they're different + if len(current_listener['DefaultActions']) == 1 and len(new_listener['DefaultActions']) == 1: + if current_listener['DefaultActions'] != new_listener['DefaultActions']: + modified_listener['DefaultActions'] = new_listener['DefaultActions'] + # if actions have multiple elements, we'll have to order them first before comparing. + # multiple actions will have an 'Order' key for this purpose + else: + current_actions_sorted = sorted(current_listener['DefaultActions'], key=lambda x: x['Order']) + new_actions_sorted = sorted(new_listener['DefaultActions'], key=lambda x: x['Order']) + + # the AWS api won't return the client secret, so we'll have to remove it + # or the module will always see the new and current actions as different + # and try to apply the same config + new_actions_sorted_no_secret = [] + for action in new_actions_sorted: + # the secret is currently only defined in the oidc config + if action['Type'] == 'authenticate-oidc': + action['AuthenticateOidcConfig'].pop('ClientSecret') + new_actions_sorted_no_secret.append(action) + else: + new_actions_sorted_no_secret.append(action) + + if current_actions_sorted != new_actions_sorted_no_secret: + modified_listener['DefaultActions'] = new_listener['DefaultActions'] + # If the action lengths are different, then replace with the new actions + else: + modified_listener['DefaultActions'] = new_listener['DefaultActions'] if modified_listener: return modified_listener @@ -577,7 +619,12 @@ class ELBListener(object): self.listener.pop('Rules') AWSRetry.jittered_backoff()(self.connection.create_listener)(LoadBalancerArn=self.elb_arn, **self.listener) except (BotoCoreError, ClientError) as e: - self.module.fail_json_aws(e) + if '"Order", must be one of: Type, TargetGroupArn' in str(e): + self.module.fail_json(msg="installed version of botocore does not support " + "multiple actions, please upgrade botocore to version " + "1.10.30 or higher") + else: + self.module.fail_json_aws(e) def modify(self): @@ -587,7 +634,12 @@ class ELBListener(object): self.listener.pop('Rules') AWSRetry.jittered_backoff()(self.connection.modify_listener)(**self.listener) except (BotoCoreError, ClientError) as e: - self.module.fail_json_aws(e) + if '"Order", must be one of: Type, TargetGroupArn' in str(e): + self.module.fail_json(msg="installed version of botocore does not support " + "multiple actions, please upgrade botocore to version " + "1.10.30 or higher") + else: + self.module.fail_json_aws(e) def delete(self): @@ -629,12 +681,18 @@ class ELBListenerRules(object): :return: the same list of dicts ensuring that each rule Actions dict has TargetGroupArn key. If a TargetGroupName key exists, it is removed. """ + fixed_rules = [] for rule in rules: - if 'TargetGroupName' in rule['Actions'][0]: - rule['Actions'][0]['TargetGroupArn'] = convert_tg_name_to_arn(self.connection, self.module, rule['Actions'][0]['TargetGroupName']) - del rule['Actions'][0]['TargetGroupName'] + fixed_actions = [] + for action in rule['Actions']: + if 'TargetGroupName' in action: + action['TargetGroupArn'] = convert_tg_name_to_arn(self.connection, self.module, action['TargetGroupName']) + del action['TargetGroupName'] + fixed_actions.append(action) + rule['Actions'] = fixed_actions + fixed_rules.append(rule) - return rules + return fixed_rules def _get_elb_listener_rules(self): @@ -654,7 +712,12 @@ class ELBListenerRules(object): condition_found = False for current_condition in current_conditions: - if current_condition['Field'] == condition['Field'] and current_condition['Values'][0] == condition['Values'][0]: + if current_condition.get('SourceIpConfig'): + if (current_condition['Field'] == condition['Field'] and + current_condition['SourceIpConfig']['Values'][0] == condition['SourceIpConfig']['Values'][0]): + condition_found = True + break + elif current_condition['Field'] == condition['Field'] and current_condition['Values'][0] == condition['Values'][0]: condition_found = True break @@ -669,16 +732,57 @@ class ELBListenerRules(object): modified_rule = {} # Priority - if current_rule['Priority'] != new_rule['Priority']: + if int(current_rule['Priority']) != new_rule['Priority']: modified_rule['Priority'] = new_rule['Priority'] # Actions - # We wont worry about the Action Type because it is always 'forward' - if current_rule['Actions'][0]['TargetGroupArn'] != new_rule['Actions'][0]['TargetGroupArn']: - modified_rule['Actions'] = [] - modified_rule['Actions'].append({}) - modified_rule['Actions'][0]['TargetGroupArn'] = new_rule['Actions'][0]['TargetGroupArn'] - modified_rule['Actions'][0]['Type'] = 'forward' + + # Check proper rule format on current listener + if len(current_rule['Actions']) > 1: + for action in current_rule['Actions']: + if 'Order' not in action: + self.module.fail_json(msg="'Order' key not found in actions. " + "installed version of botocore does not support " + "multiple actions, please upgrade botocore to version " + "1.10.30 or higher") + + # If the lengths of the actions are the same, we'll have to verify that the + # contents of those actions are the same + if len(current_rule['Actions']) == len(new_rule['Actions']): + # if actions have just one element, compare the contents and then update if + # they're different + if len(current_rule['Actions']) == 1 and len(new_rule['Actions']) == 1: + if current_rule['Actions'] != new_rule['Actions']: + modified_rule['Actions'] = new_rule['Actions'] + print("modified_rule:") + print(new_rule['Actions']) + # if actions have multiple elements, we'll have to order them first before comparing. + # multiple actions will have an 'Order' key for this purpose + else: + current_actions_sorted = sorted(current_rule['Actions'], key=lambda x: x['Order']) + new_actions_sorted = sorted(new_rule['Actions'], key=lambda x: x['Order']) + + # the AWS api won't return the client secret, so we'll have to remove it + # or the module will always see the new and current actions as different + # and try to apply the same config + new_actions_sorted_no_secret = [] + for action in new_actions_sorted: + # the secret is currently only defined in the oidc config + if action['Type'] == 'authenticate-oidc': + action['AuthenticateOidcConfig'].pop('ClientSecret') + new_actions_sorted_no_secret.append(action) + else: + new_actions_sorted_no_secret.append(action) + + if current_actions_sorted != new_actions_sorted_no_secret: + modified_rule['Actions'] = new_rule['Actions'] + print("modified_rule:") + print(new_rule['Actions']) + # If the action lengths are different, then replace with the new actions + else: + modified_rule['Actions'] = new_rule['Actions'] + print("modified_rule:") + print(new_rule['Actions']) # Conditions modified_conditions = [] @@ -746,7 +850,12 @@ class ELBListenerRule(object): self.rule['Priority'] = int(self.rule['Priority']) AWSRetry.jittered_backoff()(self.connection.create_rule)(**self.rule) except (BotoCoreError, ClientError) as e: - self.module.fail_json_aws(e) + if '"Order", must be one of: Type, TargetGroupArn' in str(e): + self.module.fail_json(msg="installed version of botocore does not support " + "multiple actions, please upgrade botocore to version " + "1.10.30 or higher") + else: + self.module.fail_json_aws(e) self.changed = True @@ -761,7 +870,12 @@ class ELBListenerRule(object): del self.rule['Priority'] AWSRetry.jittered_backoff()(self.connection.modify_rule)(**self.rule) except (BotoCoreError, ClientError) as e: - self.module.fail_json_aws(e) + if '"Order", must be one of: Type, TargetGroupArn' in str(e): + self.module.fail_json(msg="installed version of botocore does not support " + "multiple actions, please upgrade botocore to version " + "1.10.30 or higher") + else: + self.module.fail_json_aws(e) self.changed = True diff --git a/lib/ansible/modules/cloud/amazon/elb_application_lb.py b/lib/ansible/modules/cloud/amazon/elb_application_lb.py index 70da6637e46..3fa449d11a6 100644 --- a/lib/ansible/modules/cloud/amazon/elb_application_lb.py +++ b/lib/ansible/modules/cloud/amazon/elb_application_lb.py @@ -157,7 +157,7 @@ EXAMPLES = ''' Certificates: # The ARN of the certificate (only one certficate ARN should be provided) - CertificateArn: arn:aws:iam::12345678987:server-certificate/test.domain.com DefaultActions: - - Type: forward # Required. Only 'forward' is accepted at this time + - Type: forward # Required. TargetGroupName: # Required. The name of the target group state: present @@ -181,7 +181,7 @@ EXAMPLES = ''' Certificates: # The ARN of the certificate (only one certficate ARN should be provided) - CertificateArn: arn:aws:iam::12345678987:server-certificate/test.domain.com DefaultActions: - - Type: forward # Required. Only 'forward' is accepted at this time + - Type: forward # Required. TargetGroupName: # Required. The name of the target group state: present @@ -212,6 +212,31 @@ EXAMPLES = ''' Actions: - TargetGroupName: test-target-group Type: forward + - Conditions: + - Field: path-pattern + Values: + - "/redirect-path/*" + Priority: '2' + Actions: + - Type: redirect + RedirectConfig: + Host: "#{host}" + Path: "/example/redir" # or /#{path} + Port: "#{port}" + Protocol: "#{protocol}" + Query: "#{query}" + StatusCode: "HTTP_302" # or HTTP_301 + - Conditions: + - Field: path-pattern + Values: + - "/fixed-response-path/" + Priority: '3' + Actions: + - Type: fixed-response + FixedResponseConfig: + ContentType: "text/plain" + MessageBody: "This is the page you're looking for" + StatusCode: "200" state: present # Remove an ELB diff --git a/test/integration/targets/elb_application_lb/meta/main.yml b/test/integration/targets/elb_application_lb/meta/main.yml index 1f64f1169a9..1810d4bec98 100644 --- a/test/integration/targets/elb_application_lb/meta/main.yml +++ b/test/integration/targets/elb_application_lb/meta/main.yml @@ -1,3 +1,2 @@ dependencies: - - prepare_tests - - setup_ec2 + - setup_remote_tmp_dir diff --git a/test/integration/targets/elb_application_lb/tasks/full_test.yml b/test/integration/targets/elb_application_lb/tasks/full_test.yml new file mode 100644 index 00000000000..ebb2a9ad0e3 --- /dev/null +++ b/test/integration/targets/elb_application_lb/tasks/full_test.yml @@ -0,0 +1,259 @@ +- block: + + - name: set connection information for all tasks + set_fact: + aws_connection_info: &aws_connection_info + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token }}" + region: "{{ aws_region }}" + awscli_connection_info: &awscli_connection_info + AWS_ACCESS_KEY_ID: "{{ aws_access_key }}" + AWS_SECRET_ACCESS_KEY: "{{ aws_secret_key }}" + AWS_SESSION_TOKEN: "{{ security_token }}" + AWS_DEFAULT_REGION: "{{ aws_region }}" + no_log: yes + + - name: create VPC + ec2_vpc_net: + cidr_block: 10.228.228.0/22 + name: "{{ resource_prefix }}_vpc" + state: present + <<: *aws_connection_info + register: vpc + + - name: create internet gateway + ec2_vpc_igw: + vpc_id: "{{ vpc.vpc.id }}" + state: present + tags: + Name: "{{ resource_prefix }}" + <<: *aws_connection_info + register: igw + + - name: create public subnet + ec2_vpc_subnet: + cidr: "{{ item.cidr }}" + az: "{{ aws_region}}{{ item.az }}" + vpc_id: "{{ vpc.vpc.id }}" + state: present + tags: + Public: "{{ item.public|string }}" + Name: "{{ item.public|ternary('public', 'private') }}-{{ item.az }}" + <<: *aws_connection_info + with_items: + - cidr: 10.228.228.0/24 + az: "a" + public: "True" + - cidr: 10.228.229.0/24 + az: "b" + public: "True" + - cidr: 10.228.230.0/24 + az: "a" + public: "False" + - cidr: 10.228.231.0/24 + az: "b" + public: "False" + register: subnets + + - ec2_vpc_subnet_info: + filters: + vpc-id: "{{ vpc.vpc.id }}" + <<: *aws_connection_info + register: vpc_subnets + + - name: create list of subnet ids + set_fact: + alb_subnets: "{{ vpc_subnets|json_query('subnets[?tags.Public == `True`].id') }}" + private_subnets: "{{ vpc_subnets|json_query('subnets[?tags.Public != `True`].id') }}" + + - name: create a route table + ec2_vpc_route_table: + vpc_id: "{{ vpc.vpc.id }}" + <<: *aws_connection_info + tags: + Name: igw-route + Created: "{{ resource_prefix }}" + subnets: "{{ alb_subnets + private_subnets }}" + routes: + - dest: 0.0.0.0/0 + gateway_id: "{{ igw.gateway_id }}" + register: route_table + + - ec2_group: + name: "{{ resource_prefix }}" + description: "security group for Ansible ALB integration tests" + state: present + vpc_id: "{{ vpc.vpc.id }}" + rules: + - proto: tcp + from_port: 1 + to_port: 65535 + cidr_ip: 0.0.0.0/0 + <<: *aws_connection_info + register: sec_group + + - name: create a target group for testing + elb_target_group: + name: "{{ tg_name }}" + protocol: http + port: 80 + vpc_id: "{{ vpc.vpc.id }}" + state: present + <<: *aws_connection_info + register: tg + + - name: create privatekey for testing + openssl_privatekey: + path: ./ansible_alb_test.pem + size: 2048 + + - name: create csr for cert + openssl_csr: + path: ./ansible_alb_test.csr + privatekey_path: ./ansible_alb_test.pem + C: US + ST: AnyPrincipality + L: AnyTown + O: AnsibleIntegrationTest + OU: Test + CN: ansible-alb-test.example.com + + - name: create certificate + openssl_certificate: + path: ./ansible_alb_test.crt + privatekey_path: ./ansible_alb_test.pem + csr_path: ./ansible_alb_test.csr + provider: selfsigned + + # This really should be an ACM Cert, but there is no acm_cert resource module + - name: upload server cert to iam + iam_cert: + name: "{{ alb_name }}" + state: present + cert: ./ansible_alb_test.crt + key: ./ansible_alb_test.pem + <<: *aws_connection_info + register: cert_upload + + - name: register certificate arn to acm_arn fact + set_fact: + cert_arn: "{{ cert_upload.arn }}" + + - include_tasks: test_alb_bad_listener_options.yml + - include_tasks: test_alb_tags.yml + - include_tasks: test_creating_alb.yml + - include_tasks: test_alb_with_asg.yml + - include_tasks: test_modifying_alb_listeners.yml + - include_tasks: test_deleting_alb.yml + - include_tasks: test_multiple_actions.yml + + always: + ############################################################################# + # TEAR DOWN STARTS HERE + ############################################################################# + - name: destroy ALB + elb_application_lb: + name: "{{ alb_name }}" + state: absent + wait: yes + wait_timeout: 600 + <<: *aws_connection_info + ignore_errors: yes + + - name: destroy target group if it was created + elb_target_group: + name: "{{ tg_name }}" + protocol: http + port: 80 + vpc_id: "{{ vpc.vpc.id }}" + state: absent + wait: yes + wait_timeout: 600 + <<: *aws_connection_info + register: remove_tg + retries: 5 + delay: 3 + until: remove_tg is success + when: tg is defined + ignore_errors: yes + + - name: destroy acm certificate + iam_cert: + name: "{{ alb_name }}" + state: absent + <<: *aws_connection_info + register: remove_cert + retries: 5 + delay: 3 + until: remove_cert is success + when: cert_arn is defined + ignore_errors: yes + + - name: destroy sec group + ec2_group: + name: "{{ sec_group.group_name }}" + description: "security group for Ansible ALB integration tests" + state: absent + vpc_id: "{{ vpc.vpc.id }}" + <<: *aws_connection_info + register: remove_sg + retries: 10 + delay: 5 + until: remove_sg is success + ignore_errors: yes + + - name: remove route table + ec2_vpc_route_table: + vpc_id: "{{ vpc.vpc.id }}" + route_table_id: "{{ route_table.route_table.route_table_id }}" + lookup: id + state: absent + <<: *aws_connection_info + register: remove_rt + retries: 10 + delay: 5 + until: remove_rt is success + ignore_errors: yes + + - name: destroy subnets + ec2_vpc_subnet: + cidr: "{{ item.cidr }}" + vpc_id: "{{ vpc.vpc.id }}" + state: absent + <<: *aws_connection_info + register: remove_subnet + retries: 10 + delay: 5 + until: remove_subnet is success + with_items: + - cidr: 10.228.228.0/24 + - cidr: 10.228.229.0/24 + - cidr: 10.228.230.0/24 + - cidr: 10.228.231.0/24 + ignore_errors: yes + + - name: destroy internet gateway + ec2_vpc_igw: + vpc_id: "{{ vpc.vpc.id }}" + tags: + Name: "{{ resource_prefix }}" + state: absent + <<: *aws_connection_info + register: remove_igw + retries: 10 + delay: 5 + until: remove_igw is success + ignore_errors: yes + + - name: destroy VPC + ec2_vpc_net: + cidr_block: 10.228.228.0/22 + name: "{{ resource_prefix }}_vpc" + state: absent + <<: *aws_connection_info + register: remove_vpc + retries: 10 + delay: 5 + until: remove_vpc is success + ignore_errors: yes diff --git a/test/integration/targets/elb_application_lb/tasks/main.yml b/test/integration/targets/elb_application_lb/tasks/main.yml index 866c2aff733..037d7fd4af5 100644 --- a/test/integration/targets/elb_application_lb/tasks/main.yml +++ b/test/integration/targets/elb_application_lb/tasks/main.yml @@ -1,204 +1,44 @@ -- block: - - - name: set connection information for all tasks - set_fact: - aws_connection_info: &aws_connection_info - aws_access_key: "{{ aws_access_key }}" - aws_secret_key: "{{ aws_secret_key }}" - security_token: "{{ security_token }}" - region: "{{ aws_region }}" - no_log: yes - - - name: create VPC - ec2_vpc_net: - cidr_block: 10.228.228.0/22 - name: "{{ resource_prefix }}_vpc" - state: present - <<: *aws_connection_info - register: vpc - - - name: create internet gateway - ec2_vpc_igw: - vpc_id: "{{ vpc.vpc.id }}" - state: present - tags: - Name: "{{ resource_prefix }}" - <<: *aws_connection_info - register: igw - - - name: create public subnet - ec2_vpc_subnet: - cidr: "{{ item.cidr }}" - az: "{{ aws_region}}{{ item.az }}" - vpc_id: "{{ vpc.vpc.id }}" - state: present - tags: - Public: "{{ item.public|string }}" - Name: "{{ item.public|ternary('public', 'private') }}-{{ item.az }}" - <<: *aws_connection_info - with_items: - - cidr: 10.228.228.0/24 - az: "a" - public: "True" - - cidr: 10.228.229.0/24 - az: "b" - public: "True" - - cidr: 10.228.230.0/24 - az: "a" - public: "False" - - cidr: 10.228.231.0/24 - az: "b" - public: "False" - register: subnets - - - ec2_vpc_subnet_info: - filters: - vpc-id: "{{ vpc.vpc.id }}" - <<: *aws_connection_info - register: vpc_subnets - - - name: create list of subnet ids - set_fact: - alb_subnets: "{{ vpc_subnets|json_query('subnets[?tags.Public == `True`].id') }}" - private_subnets: "{{ vpc_subnets|json_query('subnets[?tags.Public != `True`].id') }}" - - - name: create a route table - ec2_vpc_route_table: - vpc_id: "{{ vpc.vpc.id }}" - <<: *aws_connection_info - tags: - Name: igw-route - Created: "{{ resource_prefix }}" - subnets: "{{ alb_subnets + private_subnets }}" - routes: - - dest: 0.0.0.0/0 - gateway_id: "{{ igw.gateway_id }}" - register: route_table - - - ec2_group: - name: "{{ resource_prefix }}" - description: "security group for Ansible ALB integration tests" - state: present - vpc_id: "{{ vpc.vpc.id }}" - rules: - - proto: tcp - from_port: 1 - to_port: 65535 - cidr_ip: 0.0.0.0/0 - <<: *aws_connection_info - register: sec_group - - - name: create a target group for testing - elb_target_group: - name: "{{ tg_name }}" - protocol: http - port: 80 - vpc_id: "{{ vpc.vpc.id }}" - state: present - <<: *aws_connection_info - register: tg - - - include_tasks: test_alb_bad_listener_options.yml - - include_tasks: test_alb_tags.yml - - include_tasks: test_creating_alb.yml - - include_tasks: test_alb_with_asg.yml - - include_tasks: test_modifying_alb_listeners.yml - - include_tasks: test_deleting_alb.yml - - always: - ############################################################################# - # TEAR DOWN STARTS HERE - ############################################################################# - - name: destroy ALB - elb_application_lb: - name: "{{ alb_name }}" - state: absent - wait: yes - wait_timeout: 600 - <<: *aws_connection_info - ignore_errors: yes - - - name: destroy target group if it was created - elb_target_group: - name: "{{ tg_name }}" - protocol: http - port: 80 - vpc_id: "{{ vpc.vpc.id }}" - state: absent - wait: yes - wait_timeout: 600 - <<: *aws_connection_info - register: remove_tg - retries: 5 - delay: 3 - until: remove_tg is success - when: tg is defined - ignore_errors: yes - - - name: destroy sec group - ec2_group: - name: "{{ sec_group.group_name }}" - description: "security group for Ansible ALB integration tests" - state: absent - vpc_id: "{{ vpc.vpc.id }}" - <<: *aws_connection_info - register: remove_sg - retries: 10 - delay: 5 - until: remove_sg is success - ignore_errors: yes - - - name: remove route table - ec2_vpc_route_table: - vpc_id: "{{ vpc.vpc.id }}" - route_table_id: "{{ route_table.route_table.route_table_id }}" - lookup: id - state: absent - <<: *aws_connection_info - register: remove_rt - retries: 10 - delay: 5 - until: remove_rt is success - ignore_errors: yes - - - name: destroy subnets - ec2_vpc_subnet: - cidr: "{{ item.cidr }}" - vpc_id: "{{ vpc.vpc.id }}" - state: absent - <<: *aws_connection_info - register: remove_subnet - retries: 10 - delay: 5 - until: remove_subnet is success - with_items: - - cidr: 10.228.228.0/24 - - cidr: 10.228.229.0/24 - - cidr: 10.228.230.0/24 - - cidr: 10.228.231.0/24 - ignore_errors: yes - - - name: destroy internet gateway - ec2_vpc_igw: - vpc_id: "{{ vpc.vpc.id }}" - tags: - Name: "{{ resource_prefix }}" - state: absent - <<: *aws_connection_info - register: remove_igw - retries: 10 - delay: 5 - until: remove_igw is success - ignore_errors: yes - - - name: destroy VPC - ec2_vpc_net: - cidr_block: 10.228.228.0/22 - name: "{{ resource_prefix }}_vpc" - state: absent - <<: *aws_connection_info - register: remove_vpc - retries: 10 - delay: 5 - until: remove_vpc is success - ignore_errors: yes +- set_fact: + virtualenv: "{{ remote_tmp_dir }}/virtualenv" + virtualenv_command: "{{ ansible_python_interpreter }} -m virtualenv" + +- set_fact: + virtualenv_interpreter: "{{ virtualenv }}/bin/python" + +- pip: + name: virtualenv + +- pip: + name: + - 'botocore<1.10.30' + - boto3 + - boto + - coverage + - cryptography + virtualenv: "{{ virtualenv }}" + virtualenv_command: "{{ virtualenv_command }}" + virtualenv_site_packages: no + +- include_tasks: multiple_actions_fail.yml + vars: + ansible_python_interpreter: "{{ virtualenv_interpreter }}" + + +- pip: + name: + - 'botocore>=1.10.30' + - boto3 + - boto + - coverage + - cryptography + virtualenv: "{{ virtualenv }}" + virtualenv_command: "{{ virtualenv_command }}" + virtualenv_site_packages: no + +- include_tasks: full_test.yml + vars: + ansible_python_interpreter: "{{ virtualenv_interpreter }}" + +- file: + path: "{{ virtualenv }}" + state: absent diff --git a/test/integration/targets/elb_application_lb/tasks/multiple_actions_fail.yml b/test/integration/targets/elb_application_lb/tasks/multiple_actions_fail.yml new file mode 100644 index 00000000000..9c66ba2c68b --- /dev/null +++ b/test/integration/targets/elb_application_lb/tasks/multiple_actions_fail.yml @@ -0,0 +1,253 @@ +- block: + + - name: set connection information for all tasks + set_fact: + aws_connection_info: &aws_connection_info + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token }}" + region: "{{ aws_region }}" + awscli_connection_info: &awscli_connection_info + AWS_ACCESS_KEY_ID: "{{ aws_access_key }}" + AWS_SECRET_ACCESS_KEY: "{{ aws_secret_key }}" + AWS_SESSION_TOKEN: "{{ security_token }}" + AWS_DEFAULT_REGION: "{{ aws_region }}" + no_log: yes + + - name: create VPC + ec2_vpc_net: + cidr_block: 10.228.228.0/22 + name: "{{ resource_prefix }}_vpc" + state: present + <<: *aws_connection_info + register: vpc + + - name: create internet gateway + ec2_vpc_igw: + vpc_id: "{{ vpc.vpc.id }}" + state: present + tags: + Name: "{{ resource_prefix }}" + <<: *aws_connection_info + register: igw + + - name: create public subnet + ec2_vpc_subnet: + cidr: "{{ item.cidr }}" + az: "{{ aws_region}}{{ item.az }}" + vpc_id: "{{ vpc.vpc.id }}" + state: present + tags: + Public: "{{ item.public|string }}" + Name: "{{ item.public|ternary('public', 'private') }}-{{ item.az }}" + <<: *aws_connection_info + with_items: + - cidr: 10.228.228.0/24 + az: "a" + public: "True" + - cidr: 10.228.229.0/24 + az: "b" + public: "True" + - cidr: 10.228.230.0/24 + az: "a" + public: "False" + - cidr: 10.228.231.0/24 + az: "b" + public: "False" + register: subnets + + - ec2_vpc_subnet_facts: + filters: + vpc-id: "{{ vpc.vpc.id }}" + <<: *aws_connection_info + register: vpc_subnets + + - name: create list of subnet ids + set_fact: + alb_subnets: "{{ vpc_subnets|json_query('subnets[?tags.Public == `True`].id') }}" + private_subnets: "{{ vpc_subnets|json_query('subnets[?tags.Public != `True`].id') }}" + + - name: create a route table + ec2_vpc_route_table: + vpc_id: "{{ vpc.vpc.id }}" + <<: *aws_connection_info + tags: + Name: igw-route + Created: "{{ resource_prefix }}" + subnets: "{{ alb_subnets + private_subnets }}" + routes: + - dest: 0.0.0.0/0 + gateway_id: "{{ igw.gateway_id }}" + register: route_table + + - ec2_group: + name: "{{ resource_prefix }}" + description: "security group for Ansible ALB integration tests" + state: present + vpc_id: "{{ vpc.vpc.id }}" + rules: + - proto: tcp + from_port: 1 + to_port: 65535 + cidr_ip: 0.0.0.0/0 + <<: *aws_connection_info + register: sec_group + + - name: create a target group for testing + elb_target_group: + name: "{{ tg_name }}" + protocol: http + port: 80 + vpc_id: "{{ vpc.vpc.id }}" + state: present + <<: *aws_connection_info + register: tg + + - name: create privatekey for testing + openssl_privatekey: + path: ./ansible_alb_test.pem + size: 2048 + + - name: create csr for cert + openssl_csr: + path: ./ansible_alb_test.csr + privatekey_path: ./ansible_alb_test.pem + C: US + ST: AnyPrincipality + L: AnyTown + O: AnsibleIntegrationTest + OU: Test + CN: ansible-alb-test.example.com + + - name: create certificate + openssl_certificate: + path: ./ansible_alb_test.crt + privatekey_path: ./ansible_alb_test.pem + csr_path: ./ansible_alb_test.csr + provider: selfsigned + + # This really should be an ACM Cert, but there is no acm_cert resource module + - name: upload server cert to iam + iam_cert: + name: "{{ alb_name }}" + state: present + cert: ./ansible_alb_test.crt + key: ./ansible_alb_test.pem + <<: *aws_connection_info + register: cert_upload + + - name: register certificate arn to acm_arn fact + set_fact: + cert_arn: "{{ cert_upload.arn }}" + + - include_tasks: test_multiple_actions_fail.yml + + always: + ############################################################################# + # TEAR DOWN STARTS HERE + ############################################################################# + - name: destroy ALB + elb_application_lb: + name: "{{ alb_name }}" + state: absent + wait: yes + wait_timeout: 600 + <<: *aws_connection_info + ignore_errors: yes + + - name: destroy target group if it was created + elb_target_group: + name: "{{ tg_name }}" + protocol: http + port: 80 + vpc_id: "{{ vpc.vpc.id }}" + state: absent + wait: yes + wait_timeout: 600 + <<: *aws_connection_info + register: remove_tg + retries: 10 + delay: 5 + until: remove_tg is success + when: tg is defined + ignore_errors: yes + + - name: destroy acm certificate + iam_cert: + name: "{{ alb_name }}" + state: absent + <<: *aws_connection_info + register: remove_cert + retries: 10 + delay: 5 + until: remove_cert is success + when: cert_arn is defined + ignore_errors: yes + + - name: destroy sec group + ec2_group: + name: "{{ sec_group.group_name }}" + description: "security group for Ansible ALB integration tests" + state: absent + vpc_id: "{{ vpc.vpc.id }}" + <<: *aws_connection_info + register: remove_sg + retries: 10 + delay: 5 + until: remove_sg is success + ignore_errors: yes + + - name: remove route table + ec2_vpc_route_table: + vpc_id: "{{ vpc.vpc.id }}" + route_table_id: "{{ route_table.route_table.route_table_id }}" + lookup: id + state: absent + <<: *aws_connection_info + register: remove_rt + retries: 10 + delay: 5 + until: remove_rt is success + ignore_errors: yes + + - name: destroy subnets + ec2_vpc_subnet: + cidr: "{{ item.cidr }}" + vpc_id: "{{ vpc.vpc.id }}" + state: absent + <<: *aws_connection_info + register: remove_subnet + retries: 10 + delay: 5 + until: remove_subnet is success + with_items: + - cidr: 10.228.228.0/24 + - cidr: 10.228.229.0/24 + - cidr: 10.228.230.0/24 + - cidr: 10.228.231.0/24 + ignore_errors: yes + + - name: destroy internet gateway + ec2_vpc_igw: + vpc_id: "{{ vpc.vpc.id }}" + tags: + Name: "{{ resource_prefix }}" + state: absent + <<: *aws_connection_info + register: remove_igw + retries: 10 + delay: 5 + until: remove_igw is success + ignore_errors: yes + + - name: destroy VPC + ec2_vpc_net: + cidr_block: 10.228.228.0/22 + name: "{{ resource_prefix }}_vpc" + state: absent + <<: *aws_connection_info + register: remove_vpc + retries: 10 + delay: 5 + until: remove_vpc is success + ignore_errors: yes diff --git a/test/integration/targets/elb_application_lb/tasks/test_multiple_actions.yml b/test/integration/targets/elb_application_lb/tasks/test_multiple_actions.yml new file mode 100644 index 00000000000..6223270c3d0 --- /dev/null +++ b/test/integration/targets/elb_application_lb/tasks/test_multiple_actions.yml @@ -0,0 +1,467 @@ +- block: + + - name: set connection information for all tasks + set_fact: + aws_connection_info: &aws_connection_info + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token }}" + region: "{{ aws_region }}" + no_log: yes + + - name: register dummy OIDC config + set_fact: + AuthenticateOidcActionConfig: + AuthorizationEndpoint: "https://www.example.com/auth" + ClientId: "eeeeeeeeeeeeeeeeeeeeeeeeee" + ClientSecret: "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + Issuer: "https://www.example.com/issuer" + OnUnauthenticatedRequest: "authenticate" + Scope: "openid" + SessionCookieName: "AWSELBAuthSessionCookie" + SessionTimeout: 604800 + TokenEndpoint: "https://www.example.com/token" + UserInfoEndpoint: "https://www.example.com/userinfo" + UseExistingClientSecret: true + + - name: register fixed response action + set_fact: + FixedResponseActionConfig: + ContentType: "text/plain" + MessageBody: "This is the page you're looking for" + StatusCode: "200" + + - name: register redirect action + set_fact: + RedirectActionConfig: + Host: "#{host}" + Path: "/example/redir" # or /#{path} + Port: "#{port}" + Protocol: "#{protocol}" + Query: "#{query}" + StatusCode: "HTTP_302" # or HTTP_301 + + - name: delete existing ALB to avoid target group association issues + elb_application_lb: + name: "{{ alb_name }}" + state: absent + <<: *aws_connection_info + wait: yes + wait_timeout: 600 + + - name: cleanup tg to avoid target group association issues + elb_target_group: + name: "{{ tg_name }}" + protocol: http + port: 80 + vpc_id: "{{ vpc.vpc.id }}" + state: absent + wait: yes + wait_timeout: 600 + <<: *aws_connection_info + register: cleanup_tg + retries: 5 + delay: 3 + until: cleanup_tg is success + + - name: recreate a target group + elb_target_group: + name: "{{ tg_name }}" + protocol: http + port: 80 + vpc_id: "{{ vpc.vpc.id }}" + state: present + <<: *aws_connection_info + register: tg + + - name: create ALB with redirect DefaultAction + elb_application_lb: + name: "{{ alb_name }}" + subnets: "{{ alb_subnets }}" + security_groups: "{{ sec_group.group_id }}" + state: present + listeners: + - Protocol: HTTPS + Port: 443 + DefaultActions: + - Type: redirect + RedirectConfig: "{{ RedirectActionConfig }}" + Certificates: + - CertificateArn: "{{ cert_arn }}" + SslPolicy: ELBSecurityPolicy-2016-08 + <<: *aws_connection_info + register: alb + + - assert: + that: + - alb.changed + - alb.listeners|length == 1 + - alb.listeners[0].rules[0].actions|length == 1 + - alb.listeners[0].rules[0].actions[0].type == "redirect" + + - name: test idempotence with redirect DefaultAction + elb_application_lb: + name: "{{ alb_name }}" + subnets: "{{ alb_subnets }}" + security_groups: "{{ sec_group.group_id }}" + state: present + listeners: + - Protocol: HTTPS + Port: 443 + DefaultActions: + - Type: redirect + RedirectConfig: "{{ RedirectActionConfig }}" + Certificates: + - CertificateArn: "{{ cert_arn }}" + SslPolicy: ELBSecurityPolicy-2016-08 + <<: *aws_connection_info + register: alb + + - assert: + that: + - not alb.changed + - alb.listeners|length == 1 + - alb.listeners[0].rules[0].actions|length == 1 + - alb.listeners[0].rules[0].actions[0].type == "redirect" + + - name: update ALB with fixed-response DefaultAction + elb_application_lb: + name: "{{ alb_name }}" + subnets: "{{ alb_subnets }}" + security_groups: "{{ sec_group.group_id }}" + state: present + listeners: + - Protocol: HTTPS + Port: 443 + DefaultActions: + - Type: fixed-response + FixedResponseConfig: "{{ FixedResponseActionConfig }}" + Certificates: + - CertificateArn: "{{ cert_arn }}" + SslPolicy: ELBSecurityPolicy-2016-08 + <<: *aws_connection_info + register: alb + + - assert: + that: + - alb.changed + - alb.listeners|length == 1 + - alb.listeners[0].rules[0].actions|length == 1 + - alb.listeners[0].rules[0].actions[0].type == "fixed-response" + + - name: test idempotence with fixed-response DefaultAction + elb_application_lb: + name: "{{ alb_name }}" + subnets: "{{ alb_subnets }}" + security_groups: "{{ sec_group.group_id }}" + state: present + listeners: + - Protocol: HTTPS + Port: 443 + DefaultActions: + - Type: fixed-response + FixedResponseConfig: "{{ FixedResponseActionConfig }}" + Certificates: + - CertificateArn: "{{ cert_arn }}" + SslPolicy: ELBSecurityPolicy-2016-08 + <<: *aws_connection_info + register: alb + + - assert: + that: + - not alb.changed + - alb.listeners|length == 1 + - alb.listeners[0].rules[0].actions|length == 1 + - alb.listeners[0].rules[0].actions[0].type == "fixed-response" + + - name: test multiple non-default rules + elb_application_lb: + name: "{{ alb_name }}" + subnets: "{{ alb_subnets }}" + security_groups: "{{ sec_group.group_id }}" + state: present + listeners: + - Protocol: HTTPS + Port: 443 + DefaultActions: + - Type: fixed-response + FixedResponseConfig: "{{ FixedResponseActionConfig }}" + Certificates: + - CertificateArn: "{{ cert_arn }}" + SslPolicy: ELBSecurityPolicy-2016-08 + Rules: + - Conditions: + - Field: path-pattern + Values: + - "/forward-path/*" + Priority: 1 + Actions: + - Type: forward + TargetGroupName: "{{ tg_name }}" + - Conditions: + - Field: path-pattern + Values: + - "/redirect-path/*" + Priority: 2 + Actions: + - Type: redirect + RedirectConfig: "{{ RedirectActionConfig }}" + - Conditions: + - Field: path-pattern + Values: + - "/fixed-response-path/" + Priority: 3 + Actions: + - Type: fixed-response + FixedResponseConfig: "{{ FixedResponseActionConfig }}" + <<: *aws_connection_info + register: alb + + - assert: + that: + - alb.changed + - alb.listeners|length == 1 + - alb.listeners[0].rules|length == 4 ## defaultactions is included as a rule + - alb.listeners[0].rules[0].actions|length == 1 + - alb.listeners[0].rules[0].actions[0].type == "forward" + - alb.listeners[0].rules[1].actions|length == 1 + - alb.listeners[0].rules[1].actions[0].type == "redirect" + - alb.listeners[0].rules[2].actions|length == 1 + - alb.listeners[0].rules[2].actions[0].type == "fixed-response" + + - name: test idempotence multiple non-default rules + elb_application_lb: + name: "{{ alb_name }}" + subnets: "{{ alb_subnets }}" + security_groups: "{{ sec_group.group_id }}" + state: present + listeners: + - Protocol: HTTPS + Port: 443 + DefaultActions: + - Type: fixed-response + FixedResponseConfig: "{{ FixedResponseActionConfig }}" + Certificates: + - CertificateArn: "{{ cert_arn }}" + SslPolicy: ELBSecurityPolicy-2016-08 + Rules: + - Conditions: + - Field: path-pattern + Values: + - "/forward-path/*" + Priority: 1 + Actions: + - Type: forward + TargetGroupName: "{{ tg_name }}" + - Conditions: + - Field: path-pattern + Values: + - "/redirect-path/*" + Priority: 2 + Actions: + - Type: redirect + RedirectConfig: "{{ RedirectActionConfig }}" + - Conditions: + - Field: path-pattern + Values: + - "/fixed-response-path/" + Priority: 3 + Actions: + - Type: fixed-response + FixedResponseConfig: "{{ FixedResponseActionConfig }}" + <<: *aws_connection_info + register: alb + + - assert: + that: + - not alb.changed + - alb.listeners|length == 1 + - alb.listeners[0].rules|length == 4 ## defaultactions is included as a rule + - alb.listeners[0].rules[0].actions|length == 1 + - alb.listeners[0].rules[0].actions[0].type == "forward" + - alb.listeners[0].rules[1].actions|length == 1 + - alb.listeners[0].rules[1].actions[0].type == "redirect" + - alb.listeners[0].rules[2].actions|length == 1 + - alb.listeners[0].rules[2].actions[0].type == "fixed-response" + + +# - name: test creating ALB with a default listener with multiple actions +# elb_application_lb: +# name: "{{ alb_name }}" +# subnets: "{{ alb_subnets }}" +# security_groups: "{{ sec_group.group_id }}" +# state: present +# listeners: +# - Protocol: HTTPS +# Port: 443 +# DefaultActions: +# - Type: forward +# TargetGroupName: "{{ tg_name }}" +# Order: 2 +# - Type: authenticate-oidc +# AuthenticateOidcConfig: "{{ AuthenticateOidcActionConfig }}" +# Order: 1 +# Certificates: +# - CertificateArn: "{{ cert_arn }}" +# SslPolicy: ELBSecurityPolicy-2016-08 +# <<: *aws_connection_info +# register: alb +# +# - assert: +# that: +# - alb.listeners|length == 1 +# - alb.listeners[0].rules[0].actions|length == 2 +# +# - name: test changing order of actions +# elb_application_lb: +# name: "{{ alb_name }}" +# subnets: "{{ alb_subnets }}" +# security_groups: "{{ sec_group.group_id }}" +# state: present +# listeners: +# - Protocol: HTTPS +# Port: 443 +# DefaultActions: +# - Type: authenticate-oidc +# AuthenticateOidcConfig: "{{ AuthenticateOidcActionConfig }}" +# Order: 1 +# - Type: forward +# TargetGroupName: "{{ tg_name }}" +# Order: 2 +# Certificates: +# - CertificateArn: "{{ cert_arn }}" +# SslPolicy: ELBSecurityPolicy-2016-08 +# <<: *aws_connection_info +# register: alb +# +# - assert: +# that: +# - not alb.changed +# - alb.listeners|length == 1 +# - alb.listeners[0].rules[0].actions|length == 2 +# +# - name: test non-default rule with multiple actions +# elb_application_lb: +# name: "{{ alb_name }}" +# subnets: "{{ alb_subnets }}" +# security_groups: "{{ sec_group.group_id }}" +# state: present +# listeners: +# - Protocol: HTTPS +# Port: 443 +# DefaultActions: +# - Type: authenticate-oidc +# AuthenticateOidcConfig: "{{ AuthenticateOidcActionConfig }}" +# Order: 1 +# - Type: forward +# TargetGroupName: "{{ tg_name }}" +# Order: 2 +# Certificates: +# - CertificateArn: "{{ cert_arn }}" +# SslPolicy: ELBSecurityPolicy-2016-08 +# Rules: +# - Conditions: +# - Field: path-pattern +# Values: +# - "*" +# Priority: 1 +# Actions: +# - Type: forward +# TargetGroupName: "{{ tg_name }}" +# Order: 2 +# - Type: authenticate-oidc +# AuthenticateOidcConfig: "{{ AuthenticateOidcActionConfig }}" +# Order: 1 +# <<: *aws_connection_info +# register: alb +# +# - assert: +# that: +# - alb.changed +# - alb.listeners|length == 1 +# - alb.listeners[0].rules[0].actions|length == 2 +# - alb.listeners[0].rules[1].actions|length == 2 +# +# - name: test idempotency non-default rule with multiple actions +# elb_application_lb: +# name: "{{ alb_name }}" +# subnets: "{{ alb_subnets }}" +# security_groups: "{{ sec_group.group_id }}" +# state: present +# listeners: +# - Protocol: HTTPS +# Port: 443 +# DefaultActions: +# - Type: authenticate-oidc +# AuthenticateOidcConfig: "{{ AuthenticateOidcActionConfig }}" +# Order: 1 +# - Type: forward +# TargetGroupName: "{{ tg_name }}" +# Order: 2 +# Certificates: +# - CertificateArn: "{{ cert_arn }}" +# SslPolicy: ELBSecurityPolicy-2016-08 +# Rules: +# - Conditions: +# - Field: path-pattern +# Values: +# - "*" +# Priority: 1 +# Actions: +# - Type: forward +# TargetGroupName: "{{ tg_name }}" +# Order: 2 +# - Type: authenticate-oidc +# AuthenticateOidcConfig: "{{ AuthenticateOidcActionConfig }}" +# Order: 1 +# <<: *aws_connection_info +# register: alb +# +# - assert: +# that: +# - not alb.changed +# - alb.listeners|length == 1 +# - alb.listeners[0].rules[0].actions|length == 2 +# - alb.listeners[0].rules[1].actions|length == 2 +# +# - name: test non-default rule action order change +# elb_application_lb: +# name: "{{ alb_name }}" +# subnets: "{{ alb_subnets }}" +# security_groups: "{{ sec_group.group_id }}" +# state: present +# listeners: +# - Protocol: HTTPS +# Port: 443 +# DefaultActions: +# - Type: authenticate-oidc +# AuthenticateOidcConfig: "{{ AuthenticateOidcActionConfig }}" +# Order: 1 +# - Type: forward +# TargetGroupName: "{{ tg_name }}" +# Order: 2 +# Certificates: +# - CertificateArn: "{{ cert_arn }}" +# SslPolicy: ELBSecurityPolicy-2016-08 +# Rules: +# - Conditions: +# - Field: path-pattern +# Values: +# - "*" +# Priority: 1 +# Actions: +# - Type: authenticate-oidc +# AuthenticateOidcConfig: "{{ AuthenticateOidcActionConfig }}" +# Order: 1 +# - Type: forward +# TargetGroupName: "{{ tg_name }}" +# Order: 2 +# <<: *aws_connection_info +# register: alb +# +# - assert: +# that: +# - not alb.changed +# - alb.listeners|length == 1 +# - alb.listeners[0].rules[0].actions|length == 2 +# - alb.listeners[0].rules[1].actions|length == 2 diff --git a/test/integration/targets/elb_application_lb/tasks/test_multiple_actions_fail.yml b/test/integration/targets/elb_application_lb/tasks/test_multiple_actions_fail.yml new file mode 100644 index 00000000000..722002f2591 --- /dev/null +++ b/test/integration/targets/elb_application_lb/tasks/test_multiple_actions_fail.yml @@ -0,0 +1,53 @@ +- block: + + - name: set connection information for all tasks + set_fact: + aws_connection_info: &aws_connection_info + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token }}" + region: "{{ aws_region }}" + no_log: yes + + - name: register dummy OIDC config + set_fact: + AuthenticateOidcActionConfig: + AuthorizationEndpoint: "https://www.example.com/auth" + ClientId: "eeeeeeeeeeeeeeeeeeeeeeeeee" + ClientSecret: "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + Issuer: "https://www.example.com/issuer" + OnUnauthenticatedRequest: "authenticate" + Scope: "openid" + SessionCookieName: "AWSELBAuthSessionCookie" + SessionTimeout: 604800 + TokenEndpoint: "https://www.example.com/token" + UserInfoEndpoint: "https://www.example.com/userinfo" + + - name: create ALB with multiple DefaultActions + elb_application_lb: + name: "{{ alb_name }}" + subnets: "{{ alb_subnets }}" + security_groups: "{{ sec_group.group_id }}" + state: present + listeners: + - Protocol: HTTPS + Port: 443 + DefaultActions: + - Type: forward + TargetGroupName: "{{ tg_name }}" + Order: 2 + - Type: authenticate-oidc + AuthenticateOidcConfig: "{{ AuthenticateOidcActionConfig }}" + Order: 1 + Certificates: + - CertificateArn: "{{ cert_arn }}" + SslPolicy: ELBSecurityPolicy-2016-08 + <<: *aws_connection_info + register: alb + ignore_errors: yes + + - name: check for a graceful failure message + assert: + that: + - alb.failed + - 'alb.msg == "installed version of botocore does not support multiple actions, please upgrade botocore to version 1.10.30 or higher"' diff --git a/test/integration/targets/setup_remote_tmp_dir/handlers/main.yml b/test/integration/targets/setup_remote_tmp_dir/handlers/main.yml index 0e84a785e4f..82c9e5ed485 100644 --- a/test/integration/targets/setup_remote_tmp_dir/handlers/main.yml +++ b/test/integration/targets/setup_remote_tmp_dir/handlers/main.yml @@ -2,6 +2,7 @@ file: path: "{{ remote_tmp_dir }}" state: absent + no_log: yes - name: delete temporary directory (windows) win_file: