diff options
author | Tad Merchant <wm284@cornell.edu> | 2019-12-12 22:09:09 +0100 |
---|---|---|
committer | Jill R <4121322+jillr@users.noreply.github.com> | 2019-12-12 22:09:09 +0100 |
commit | 493ec588abcd715211818b5832e6997e75f58c42 (patch) | |
tree | 22e00897242684ea1e5d2b2a436a38c7198be89c /test/integration/targets/ec2_metric_alarm | |
parent | apt target: use 'until' when the cache is updated (#65456) (diff) | |
download | ansible-493ec588abcd715211818b5832e6997e75f58c42.tar.xz ansible-493ec588abcd715211818b5832e6997e75f58c42.zip |
Ec2 metric alarm boto3 and treat missing data (#62669)
* Converted ec2_metric_alarm to boto3. Added treat_missing_data option.
* Handle potentially non-existent alarm keys in ec2_metric_alarm module
* Add treat missing data to ec2_metric_alarms wth some tests
Continues the work of #23407
* Clean up ec2_metric_alarm main test playbook
* fix test suite and sanity checks
* more fixes for sanity tests
* fixes to ec2_metric_alarms requested in code review
* import ClientError from botocore, catch generic ClientError
* more fixes from review
drops extra dict in argument spec and set_facts for aws access
* Fix pep8 blank line issue
* switch to fail_json_aws, add idempotency test
* fix under indented continuation
* remove unsupported alias
* Add group to ec2_metric_alarm aliases
* Put alarm prefix before resource prefix to match aws-terminator pr 63
* Add type for treat_missing_data
Diffstat (limited to 'test/integration/targets/ec2_metric_alarm')
7 files changed, 396 insertions, 0 deletions
diff --git a/test/integration/targets/ec2_metric_alarm/aliases b/test/integration/targets/ec2_metric_alarm/aliases new file mode 100644 index 0000000000..a112c3d1bb --- /dev/null +++ b/test/integration/targets/ec2_metric_alarm/aliases @@ -0,0 +1,2 @@ +cloud/aws +shippable/aws/group1 diff --git a/test/integration/targets/ec2_metric_alarm/defaults/main.yml b/test/integration/targets/ec2_metric_alarm/defaults/main.yml new file mode 100644 index 0000000000..4d80b5d6e0 --- /dev/null +++ b/test/integration/targets/ec2_metric_alarm/defaults/main.yml @@ -0,0 +1,6 @@ +--- +# defaults file for ec2_instance +ec2_instance_name: '{{ resource_prefix }}-node' +ec2_instance_owner: 'integration-run-{{ resource_prefix }}' +ec2_ami_name: "amzn-ami-hvm*" +alarm_prefix: "ansible-test" diff --git a/test/integration/targets/ec2_metric_alarm/meta/main.yml b/test/integration/targets/ec2_metric_alarm/meta/main.yml new file mode 100644 index 0000000000..1f64f1169a --- /dev/null +++ b/test/integration/targets/ec2_metric_alarm/meta/main.yml @@ -0,0 +1,3 @@ +dependencies: + - prepare_tests + - setup_ec2 diff --git a/test/integration/targets/ec2_metric_alarm/tasks/env_cleanup.yml b/test/integration/targets/ec2_metric_alarm/tasks/env_cleanup.yml new file mode 100644 index 0000000000..e90ddc6450 --- /dev/null +++ b/test/integration/targets/ec2_metric_alarm/tasks/env_cleanup.yml @@ -0,0 +1,94 @@ +- name: remove any instances in the test VPC + ec2_instance: + filters: + vpc_id: "{{ testing_vpc.vpc.id }}" + state: absent + register: removed + until: removed is not failed + ignore_errors: yes + retries: 10 + +- name: remove ENIs + ec2_eni_info: + filters: + vpc-id: "{{ testing_vpc.vpc.id }}" + register: enis + +- name: delete all ENIs + ec2_eni: + eni_id: "{{ item.id }}" + state: absent + until: removed is not failed + with_items: "{{ enis.network_interfaces }}" + ignore_errors: yes + retries: 10 + +- name: remove the security group + ec2_group: + name: "{{ resource_prefix }}-sg" + description: a security group for ansible tests + vpc_id: "{{ testing_vpc.vpc.id }}" + state: absent + register: removed + until: removed is not failed + ignore_errors: yes + retries: 10 + +- name: remove routing rules + ec2_vpc_route_table: + state: absent + vpc_id: "{{ testing_vpc.vpc.id }}" + tags: + created: "{{ resource_prefix }}-route" + routes: + - dest: 0.0.0.0/0 + gateway_id: "{{ igw.gateway_id }}" + subnets: + - "{{ testing_subnet_a.subnet.id }}" + - "{{ testing_subnet_b.subnet.id }}" + register: removed + until: removed is not failed + ignore_errors: yes + retries: 10 + +- name: remove internet gateway + ec2_vpc_igw: + vpc_id: "{{ testing_vpc.vpc.id }}" + state: absent + register: removed + until: removed is not failed + ignore_errors: yes + retries: 10 + +- name: remove subnet A + ec2_vpc_subnet: + state: absent + vpc_id: "{{ testing_vpc.vpc.id }}" + cidr: 10.22.32.0/24 + register: removed + until: removed is not failed + ignore_errors: yes + retries: 10 + +- name: remove subnet B + ec2_vpc_subnet: + state: absent + vpc_id: "{{ testing_vpc.vpc.id }}" + cidr: 10.22.33.0/24 + register: removed + until: removed is not failed + ignore_errors: yes + retries: 10 + +- name: remove the VPC + ec2_vpc_net: + name: "{{ resource_prefix }}-vpc" + cidr_block: 10.22.32.0/23 + state: absent + tags: + Name: Ansible Testing VPC + tenancy: default + register: removed + until: removed is not failed + ignore_errors: yes + retries: 10 diff --git a/test/integration/targets/ec2_metric_alarm/tasks/env_setup.yml b/test/integration/targets/ec2_metric_alarm/tasks/env_setup.yml new file mode 100644 index 0000000000..80b49dbcf7 --- /dev/null +++ b/test/integration/targets/ec2_metric_alarm/tasks/env_setup.yml @@ -0,0 +1,62 @@ +- name: Create VPC for use in testing + ec2_vpc_net: + name: "{{ resource_prefix }}-vpc" + cidr_block: 10.22.32.0/23 + tags: + Name: Ansible ec2_instance Testing VPC + tenancy: default + register: testing_vpc + +- name: Create internet gateway for use in testing + ec2_vpc_igw: + vpc_id: "{{ testing_vpc.vpc.id }}" + state: present + register: igw + +- name: Create default subnet in zone A + ec2_vpc_subnet: + state: present + vpc_id: "{{ testing_vpc.vpc.id }}" + cidr: 10.22.32.0/24 + az: "{{ aws_region }}a" + resource_tags: + Name: "{{ resource_prefix }}-subnet-a" + register: testing_subnet_a + +- name: Create secondary subnet in zone B + ec2_vpc_subnet: + state: present + vpc_id: "{{ testing_vpc.vpc.id }}" + cidr: 10.22.33.0/24 + az: "{{ aws_region }}b" + resource_tags: + Name: "{{ resource_prefix }}-subnet-b" + register: testing_subnet_b + +- name: create routing rules + ec2_vpc_route_table: + vpc_id: "{{ testing_vpc.vpc.id }}" + tags: + created: "{{ resource_prefix }}-route" + routes: + - dest: 0.0.0.0/0 + gateway_id: "{{ igw.gateway_id }}" + subnets: + - "{{ testing_subnet_a.subnet.id }}" + - "{{ testing_subnet_b.subnet.id }}" + +- name: create a security group with the vpc + ec2_group: + name: "{{ resource_prefix }}-sg" + description: a security group for ansible tests + vpc_id: "{{ testing_vpc.vpc.id }}" + rules: + - proto: tcp + from_port: 22 + to_port: 22 + cidr_ip: 0.0.0.0/0 + - proto: tcp + from_port: 80 + to_port: 80 + cidr_ip: 0.0.0.0/0 + register: sg diff --git a/test/integration/targets/ec2_metric_alarm/tasks/main.yml b/test/integration/targets/ec2_metric_alarm/tasks/main.yml new file mode 100644 index 0000000000..f3f645cb2a --- /dev/null +++ b/test/integration/targets/ec2_metric_alarm/tasks/main.yml @@ -0,0 +1,228 @@ +- name: run ec2_metric_alarm tests + module_defaults: + group/aws: + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" + block: + - set_fact: + alarm_full_name: "{{ alarm_prefix }}-{{ resource_prefix }}-cpu-low" + + # until there's a module to get info about alarms, awscli is needed + - name: install awscli + pip: + state: present + name: awscli + + - name: set up environment for testing. + include_tasks: env_setup.yml + + - name: get info on alarms + command: aws cloudwatch describe-alarms --alarm-names {{ alarm_full_name }} + environment: + AWS_ACCESS_KEY_ID: "{{ aws_access_key }}" + AWS_SECRET_ACCESS_KEY: "{{ aws_secret_key }}" + AWS_SESSION_TOKEN: "{{ security_token | default('') }}" + AWS_DEFAULT_REGION: "{{ aws_region }}" + register: alarm_info_query + + - name: Find AMI to use + ec2_ami_info: + owners: 'amazon' + filters: + name: '{{ ec2_ami_name }}' + register: ec2_amis + - set_fact: + ec2_ami_image: '{{ ec2_amis.images[0].image_id }}' + + - name: Make instance in a default subnet of the VPC + ec2_instance: + name: "{{ resource_prefix }}-test-default-vpc" + image_id: "{{ec2_ami_image }}" + tags: + TestId: "{{ resource_prefix }}" + security_groups: "{{ sg.group_id }}" + instance_type: t2.micro + wait: true + register: ec2_instance_results + + - name: create ec2 metric alarm on ec2 instance + ec2_metric_alarm: + dimensions: + InstanceId: "{{ ec2_instance_results.instances[0].instance_id }}" + state: present + name: "{{ alarm_full_name }}" + metric: "CPUUtilization" + namespace: "AWS/EC2" + treat_missing_data: missing + statistic: Average + comparison: "<=" + threshold: 5.0 + period: 300 + evaluation_periods: 3 + unit: "Percent" + description: "This will alarm when an instance's cpu usage average is lower than 5% for 15 minutes " + register: ec2_instance_metric_alarm + + - name: get info on alarms + command: aws cloudwatch describe-alarms --alarm-names {{ alarm_full_name }} + environment: + AWS_ACCESS_KEY_ID: "{{ aws_access_key }}" + AWS_SECRET_ACCESS_KEY: "{{ aws_secret_key }}" + AWS_SESSION_TOKEN: "{{ security_token | default('') }}" + AWS_DEFAULT_REGION: "{{ aws_region }}" + register: alarm_info_query + + - name: convert it to an object + set_fact: + alarm_info: "{{ alarm_info_query.stdout |from_json }}" + + - name: "verify that an alarm was created" + assert: + that: + - 'ec2_instance_metric_alarm.changed' + - 'ec2_instance_metric_alarm.alarm_arn' + - 'ec2_instance_metric_alarm.statistic == alarm_info["MetricAlarms"][0].Statistic' + - 'ec2_instance_metric_alarm.name == alarm_info["MetricAlarms"][0].AlarmName' + - 'ec2_instance_metric_alarm.metric== alarm_info["MetricAlarms"][0].MetricName' + - 'ec2_instance_metric_alarm.namespace == alarm_info["MetricAlarms"][0].Namespace' + - 'ec2_instance_metric_alarm.comparison == alarm_info["MetricAlarms"][0].ComparisonOperator' + - 'ec2_instance_metric_alarm.comparison == alarm_info["MetricAlarms"][0].ComparisonOperator' + - 'ec2_instance_metric_alarm.threshold == alarm_info["MetricAlarms"][0].Threshold' + - 'ec2_instance_metric_alarm.period == alarm_info["MetricAlarms"][0].Period' + - 'ec2_instance_metric_alarm.unit == alarm_info["MetricAlarms"][0].Unit' + - 'ec2_instance_metric_alarm.evaluation_periods == alarm_info["MetricAlarms"][0].EvaluationPeriods' + - 'ec2_instance_metric_alarm.description == alarm_info["MetricAlarms"][0].AlarmDescription' + - 'ec2_instance_metric_alarm.treat_missing_data == alarm_info["MetricAlarms"][0].TreatMissingData' + + - name: create ec2 metric alarm on ec2 instance (idempotent) + ec2_metric_alarm: + dimensions: + InstanceId: "{{ ec2_instance_results.instances[0].instance_id }}" + state: present + name: "{{ alarm_full_name }}" + metric: "CPUUtilization" + namespace: "AWS/EC2" + treat_missing_data: missing + statistic: Average + comparison: "<=" + threshold: 5.0 + period: 300 + evaluation_periods: 3 + unit: "Percent" + description: "This will alarm when an instance's cpu usage average is lower than 5% for 15 minutes " + register: ec2_instance_metric_alarm_idempotent + + - name: get info on alarms + command: aws cloudwatch describe-alarms --alarm-names {{ alarm_full_name }} + environment: + AWS_ACCESS_KEY_ID: "{{ aws_access_key }}" + AWS_SECRET_ACCESS_KEY: "{{ aws_secret_key }}" + AWS_SESSION_TOKEN: "{{ security_token | default('') }}" + AWS_DEFAULT_REGION: "{{ aws_region }}" + register: alarm_info_query_idempotent + + - name: convert it to an object + set_fact: + alarm_info_idempotent: "{{ alarm_info_query_idempotent.stdout |from_json }}" + + - name: "Verify alarm does not register as changed after update" + assert: + that: + - not ec2_instance_metric_alarm_idempotent.changed + + - name: "Verify alarm did not change after updating" + assert: + that: + - "alarm_info['MetricAlarms'][0]['{{item}}'] == alarm_info_idempotent['MetricAlarms'][0]['{{ item }}']" + with_items: + - AlarmArn + - Statistic + - AlarmName + - MetricName + - Namespace + - ComparisonOperator + - Threshold + - Period + - Unit + - EvaluationPeriods + - AlarmDescription + - TreatMissingData + + - name: update alarm + ec2_metric_alarm: + dimensions: + InstanceId: "{{ ec2_instance_results.instances[0].instance_id }}" + state: present + name: "{{ alarm_full_name }}" + metric: "CPUUtilization" + namespace: "AWS/EC2" + statistic: Average + comparison: "<=" + threshold: 5.0 + period: 60 + evaluation_periods: 3 + unit: "Percent" + description: "This will alarm when an instance's cpu usage average is lower than 5% for 3 minutes " + register: ec2_instance_metric_alarm_update + + - name: "verify that alarm registers as updated" + assert: + that: + - 'ec2_instance_metric_alarm.changed' + + - name: "verify that properties were changed" + assert: + that: + - 'ec2_instance_metric_alarm_update.changed' + - 'ec2_instance_metric_alarm_update.period == 60' #Period should be 60, not matching old value + - 'ec2_instance_metric_alarm_update.alarm_arn == ec2_instance_metric_alarm.alarm_arn' + - 'ec2_instance_metric_alarm_update.statistic == alarm_info["MetricAlarms"][0].Statistic' + - 'ec2_instance_metric_alarm_update.name == alarm_info["MetricAlarms"][0].AlarmName' + - 'ec2_instance_metric_alarm_update.metric== alarm_info["MetricAlarms"][0].MetricName' + - 'ec2_instance_metric_alarm_update.namespace == alarm_info["MetricAlarms"][0].Namespace' + - 'ec2_instance_metric_alarm_update.statistic == alarm_info["MetricAlarms"][0].Statistic' + - 'ec2_instance_metric_alarm_update.comparison == alarm_info["MetricAlarms"][0].ComparisonOperator' + - 'ec2_instance_metric_alarm_update.threshold == alarm_info["MetricAlarms"][0].Threshold' + - 'ec2_instance_metric_alarm_update.unit == alarm_info["MetricAlarms"][0].Unit' + - 'ec2_instance_metric_alarm_update.evaluation_periods == alarm_info["MetricAlarms"][0].EvaluationPeriods' + - 'ec2_instance_metric_alarm_update.treat_missing_data == alarm_info["MetricAlarms"][0].TreatMissingData' + + - name: try to remove the alarm + ec2_metric_alarm: + state: absent + name: "{{ alarm_full_name }}" + + register: ec2_instance_metric_alarm_deletion + + - name: Verify that the alarm reports deleted/changed + assert: + that: + - 'ec2_instance_metric_alarm_deletion.changed' + + - name: get info on alarms + command: aws cloudwatch describe-alarms --alarm-names {{ alarm_full_name }} + environment: + AWS_ACCESS_KEY_ID: "{{ aws_access_key }}" + AWS_SECRET_ACCESS_KEY: "{{ aws_secret_key }}" + AWS_SESSION_TOKEN: "{{ security_token | default('') }}" + AWS_DEFAULT_REGION: "{{ aws_region }}" + register: alarm_info_query + + - name: convert it to an object + set_fact: + alarm_info: "{{ alarm_info_query.stdout |from_json }}" + + - name: Verify that the alarm was deleted using cli + assert: + that: + - 'alarm_info["MetricAlarms"]|length == 0' + always: + - name: try to stop the ec2 instance + ec2_instance: + instance_ids: "{{ ec2_instance_results.instances[0].instance_id }}" + state: terminated + ignore_errors: yes + + - include_tasks: env_cleanup.yml diff --git a/test/integration/targets/ec2_metric_alarm/vars/main.yml b/test/integration/targets/ec2_metric_alarm/vars/main.yml new file mode 100644 index 0000000000..ed97d539c0 --- /dev/null +++ b/test/integration/targets/ec2_metric_alarm/vars/main.yml @@ -0,0 +1 @@ +--- |