Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JohnTheodore/abb669a7eb7a41a8a89244b851fa1e7b to your computer and use it in GitHub Desktop.
Save JohnTheodore/abb669a7eb7a41a8a89244b851fa1e7b to your computer and use it in GitHub Desktop.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">
<html lang="en">
<head>
<style></style>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>.</title>
</head>
<body>
<table cellspacing="0" cellpadding="0" border="0"><tr><td><table style="width: 100%;" cellspacing="0" cellpadding="0" border="0"><tr><td style="line-height:0;" height="20" width="20">&nbsp;</td><td style="line-height:0;" height="20">&nbsp;</td><td style="line-height:0;" height="20" width="20">&nbsp;</td></tr><tr><td style="line-height:0;" width="20">&nbsp;</td><td>
<p class="redalert" style="color: #f00; font-weight: bold; font-size: 28px;">
<span class="underline" style="text-decoration: underline;">PLEASE NOTE:</span> FAILURE TO TAKE IMMEDIATE ACTION WILL RESULT IN PERMANENT LOSS OF RESOURCES &amp; DATA IN AWS. PLEASE DO NOT DELAY. REPLIES TO THIS EMAIL ARE NOT MONITORED.
</p>
</td><td style="line-height:0;" width="20">&nbsp;</td></tr><tr><td style="line-height:0;" height="20" width="20">&nbsp;</td><td style="line-height:0;" height="20">&nbsp;</td><td style="line-height:0;" height="20" width="20">&nbsp;</td></tr></table></td></tr><tr><td><table style="width: 100%; background-color: #e7e8ea;" class="grey-bg" cellspacing="0" cellpadding="0" border="0"><tr><td style="line-height:0;" height="20" width="20">&nbsp;</td><td style="line-height:0;" height="20">&nbsp;</td><td style="line-height:0;" height="20" width="20">&nbsp;</td></tr><tr><td style="line-height:0;" width="20">&nbsp;</td><td>
<strong>What is this email about?</strong><br>
This email is sent by Cloud Custodian - a EPC platform service used for scanning and listing AWS resources that are unused, incorrectly tagged or underutilized. Cloud Custodian also terminates the resources if no corrective action is taken. The objective is to optimize Acmecorp use of AWS resources and enforce proper tagging for cost allocations across different business units or groups at Acmecorp This email lists all AWS resources, and states the necessary actions for the owners of those resources. For more information, refer to the <a href="https://confluence.ges.Acmecorp.com/display/EPCSKYLINEKB/AWS+Resource+Tagging+Policy">AWS Tagging Policy</a>.
</td><td style="line-height:0;" width="20">&nbsp;</td></tr><tr><td style="line-height:0;" height="20" width="20">&nbsp;</td><td style="line-height:0;" height="20">&nbsp;</td><td style="line-height:0;" height="20" width="20">&nbsp;</td></tr></table></td></tr><tr><td><table style="width: 100%;" cellspacing="0" cellpadding="0" border="0"><tr><td style="line-height:0;" height="20" width="20">&nbsp;</td><td style="line-height:0;" height="20">&nbsp;</td><td style="line-height:0;" height="20" width="20">&nbsp;</td></tr><tr><td style="line-height:0;" width="20">&nbsp;</td><td>
<br>
<table cellspacing="0" cellpadding="0" border="0">
<tr>
<td class="nowrap cellpadding" style="white-space: nowrap; overflow: hidden; padding-bottom: 10px; padding-right: 10px;"><strong>AWS ACCOUNT NAME</strong></td>
<td class="cellpadding" style="padding-bottom: 10px; padding-right: 10px;"><a href="https://{{ account }}.signin.aws.amazon.com/console">{{ account }}</a></td>
</tr>
<tr>
<td class="nowrap cellpadding" style="white-space: nowrap; overflow: hidden; padding-bottom: 10px; padding-right: 10px;"><strong>AWS REGION NAME</strong></td>
<td class="cellpadding" style="padding-bottom: 10px; padding-right: 10px;">{{ region }}</td>
</tr>
<tr>
<td class="nowrap cellpadding" style="white-space: nowrap; overflow: hidden; padding-bottom: 10px; padding-right: 10px;"><strong>POLICY NAME</strong></td>
<td class="cellpadding" style="padding-bottom: 10px; padding-right: 10px;">{{ policy['name'] }}</td>
</tr>
<tr>
<td class="nowrap cellpadding" style="white-space: nowrap; overflow: hidden; padding-bottom: 10px; padding-right: 10px;"><strong>POLICY ACTION</strong></td>
<td class="cellpadding" style="padding-bottom: 10px; padding-right: 10px;">{{ policy['comments'] }}</td>
</tr>
</table>
<br>
<table cellspacing="0" cellpadding="0" border="0" style="border:none; border-collapse:collapse; border-spacing:0">
{% macro get_header_display_name(table_header, custodian_tables_resource_metadata) -%}
{% if 'display_name' in custodian_tables_resource_metadata['headers'][header] %}
{{ custodian_tables_resource_metadata['headers'][table_header]['display_name'] }}
{% else %}
{{ table_header }}
{% endif %}
{%- endmacro %}
{% macro pretty_print_tags(tags, resource, action, policy, region) -%}
{% if tags|length > 0 %}
<table>
{% for tag in tags %}
{% if tag['Key'] != 'maid_status' %}
<tr>
<td style="border-right:1px solid grey; border-bottom:1px solid grey;">{{ tag['Key'] }}</td>
<td style="border-bottom:1px solid grey;">{{ tag['Value'] }}</td>
</tr>
{% endif %}
{% endfor %}
</table>
{% endif %}
{%- endmacro %}
{% macro get_ebs_search_hyperlink(volume_id, resource, action, policy, region) -%}
<a href="https://console.aws.amazon.com/ec2/v2/home?region={{ region }}#Volumes:search={{ volume_id }}">{{ volume_id }}</a>
{%- endmacro %}
{% macro pretty_print_datetime(datetime_string, resource, action, policy, region) -%}
{{ datetime_string|date_time_format(tz_str='US/Pacific', format='%Y %b %d %H:%M %Z') }}
{%- endmacro %}
{% macro create_table_header(table_headers, resource, custodian_tables_resource_metadata) -%}
{% for table_header in table_headers %}
<th style="border:2px solid grey; text-align: center; padding: 5px;">{{ get_header_display_name(table_header, custodian_tables_resource_metadata) }}</th>
{% endfor %}
{%- endmacro %}
{% macro get_maid_future_action(column_name, resource, action, policy, region) -%}
{% for tag in resource['Tags'] %}
{% if tag['Key'] == 'maid_status' %}
{% set future_action_str = tag['Value'].split('Resource does not meet policy: ')[1] %}
{% set future_action = future_action_str.split('@')[0] %}
{% set future_action_date = future_action_str.split('@')[1] + 'T00:00:01Z' %}
{{ future_action }}@{{ pretty_print_datetime(future_action_date) }}
{% endif %}
{% endfor %}
{%- endmacro %}
{% macro create_table_rows(resources, table_headers, custodian_tables_resource_metadata) -%}
{% for resource in resources %}
<tr style="border:none; border-collapse:collapse">
{% for columnName in table_headers %}
{% if 'macros' in custodian_tables_resource_metadata['headers'][columnName] %}
{% for macro in custodian_tables_resource_metadata['headers'][columnName]['macros'] %}
<td style="border:2px solid grey; padding:4px">{{ macro(resource[columnName], resource, action, policy, region) }}</td>
{% endfor %}
{% else %}
<td style="border:2px solid grey; padding:4px">{{ resource[columnName] }}</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
{%- endmacro %}
{% set custodian_tables = { 'ebs': { 'headers': { 'VolumeId': { 'macros': [get_ebs_search_hyperlink] }, 'Future action': { 'display_name': 'Future Action', 'macros': [get_maid_future_action] }, 'CreateTime': { 'display_name': 'CreationTime', 'macros': [pretty_print_datetime] }, 'State': '', 'Tags': { 'macros': [pretty_print_tags] } } } } %}
{% set aws_resource_type = policy['resource'] %}
{% set table_headers = custodian_tables[aws_resource_type]['headers'].keys()|sort() %}
{% set custodian_tables_resource_metadata = custodian_tables[aws_resource_type] %}
{{ create_table_header(table_headers, aws_resource_type, custodian_tables_resource_metadata) }}
{{ create_table_rows(resources, table_headers, custodian_tables_resource_metadata) }}
</table>
</td><td style="line-height:0;" width="20">&nbsp;</td></tr><tr><td style="line-height:0;" height="20" width="20">&nbsp;</td><td style="line-height:0;" height="20">&nbsp;</td><td style="line-height:0;" height="20" width="20">&nbsp;</td></tr></table></td></tr><tr><td><table style="width: 100%; background-color: #e7e8ea;" class="grey-bg" cellspacing="0" cellpadding="0" border="0"><tr><td style="line-height:0;" height="30" width="9999">&nbsp;</td><td style="line-height:0;" height="30">&nbsp;</td><td style="line-height:0;" height="30" width="9999">&nbsp;</td></tr><tr><td style="line-height:0;" width="9999">&nbsp;</td><td>
<img src="https://www.Acmecorp.com/content/dam/Acmecorp/images/common/Acmecorp-logo-top.png" alt="company logo">
<p>&#xA9; 2017 Acmecorp</p>
</td><td style="line-height:0;" width="9999">&nbsp;</td></tr><tr><td style="line-height:0;" height="25" width="9999">&nbsp;</td><td style="line-height:0;" height="25">&nbsp;</td><td style="line-height:0;" height="25" width="9999">&nbsp;</td></tr></table></td></tr></table>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment