douglaslps
douglaslps

Reputation: 8168

Using ec2 tag to create a Metric alarm on ansible

I'm trying to define an alarm for every new instance I bring up using ansible scripts. It is easy to achieve using:

- name: Create CPU utilization metric alarm ec2_metric_alarm: state: present name: "cpu-low" metric: "CPUUtilization" statistic: Average comparison: ">=" threshold: 80.0 unit: "Percent" period: 300 evaluation_periods: 1 description: "It will be triggered when CPU utilization is more than 80% for 5 minutes"

Notice that I'm using cpu-low as the alarm name. That is not what I want since I can have more than one instance triggering that alarm. Therefore, I would like to use the ec2 tag 'Name' which I don't know how to access.

I was trying to use:

- name: List resource tags local_action: ec2_tag resource=XYZ state=list tags: [metric-alarms]

But that requires the resourceID which I also don't have. Is it possible to get the ec2 tags on ansible scripts?

Upvotes: 4

Views: 3119

Answers (2)

douglaslps
douglaslps

Reputation: 8168

This is the task I came up with to use the instance Name on the alarm Name:

- name: Get instance ec2 facts
  action: ec2_facts
  register: ec2_facts

- name: Get resource tags from ec2 facts
  sudo: false
  local_action: ec2_tag
                resource={{ec2_facts.ansible_facts.ansible_ec2_instance_id}}
                region=us-east-1 state=list
  register: result

- name: Create CPU utilization metric alarm
  sudo: false
  local_action: ec2_metric_alarm
                state=present
                region=us-east-1
                name="{{result.Name}}-cpu-utilization"
                metric="CPUUtilization"
                statistic=Average comparison=">="
                threshold=80.0
                unit="Percent"
                period=300
                evaluation_periods=1
                description="It will be triggered when CPU utilization is more than 80% for 5 minutes"
                dimensions="InstanceId"="{{ec2_facts.ansible_facts.ansible_ec2_instance_id}}"
                alarm_actions=arn:aws:sns:us-east-1:123412341234:My_SNS_Notification
                ok_actions=arn:aws:sns:us-east-1:123412341234:My_SNS_Notification

Upvotes: 5

ches
ches

Reputation: 6632

Tags are much more convenient with the EC2 inventory plugin than all the register juggling, but it has some caveats as well. Using the plugin, tags are assigned as host variables with an ec2_tag namespace. Your alert definitions might look something like this:

- name: Set up metric alerts
  hosts: 127.0.0.1
  connection: local

  tasks:
    - name: Create CPU utilization metric alarm
      ec2_metric_alarm:
      args:
        state: present
        name: '{{ hostvars[item].ec_tag_Name }}'
        metric: CPUUtilization
        statistic: Average
        comparison: ">="
        threshold: 80.0
        unit: Percent
        period: 300
        evaluation_periods: 1
        description: >
          Triggered when CPU utilization is more than
          80% for 5 minutes
      with_items: groups['your_targets']

It's even easier when you're executing normal remote plays (not local_action), since you usually don't need hostvars[item] in a loop, you simply refer to ec2_tag_Name for the host currently being configured.

Now the downside: as an inventory plugin, AFAIK there is no way to refresh the data in-memory during a single Ansible run. That means when using Ansible for provisioning, if you launch new EC2 instances with a play, the ec2_tag_Foo variables won't be available in subsequent plays, until you run ansible-playbook a second time, and possibly do ec2.py --refresh-cache to update locally cached data. This is unfortunate. I wish that the inventory plugin and the ec2_facts module were more cohesively integrated.

Upvotes: 1

Related Questions