├── LICENSE
├── README.md
├── cheatsheet.txt
├── cleancache.sh
├── cron
├── crontab.txt
└── mfa-audit.sh
├── custom-site-packages
├── README.md
└── iam.py
├── examples
├── cheatsheet.txt
├── cleancache.sh
├── event-pattern-for-aws-health-event-issue
└── example-output-from-health-event-issues
├── images
├── custom_offhours.png
├── maid_hours.png
└── singlenodedeploy.png
├── msg-templates
├── acm-certificate-audit.html.j2
├── cfn-garbage-collection-audit.html.j2
├── cheatsheet
├── ebs-garbage-collection.html.j2
├── ec2-garbage-collection-audit.html.j2
├── ec2-public-whitelist.html.j2
├── elasticsearch-security-audit.html.j2
├── iam-policy-account-audit-summary.html.j2
├── iam-policy-account-audit.html.j2
├── iam-user-UpdateAccessKey-audit.html.j2
├── iam-user-audit.html.j2
├── mfa-audit-disable-access.html.j2
├── mfa-audit-reminder.html.j2
├── phd-issue.html.j2
├── public-instance-audit.html.j2
├── s3-prevent-bucket-creation.html.j2
├── s3-public-audit.html.j2
├── s3-service-limit-audit.html.j2
├── s3-service-limit-audit.j2
├── s3-target-bucket-audit.html.j2
├── sgroup-delete-marked.html.j2
├── slack-acm-certificate-audit.j2
├── slack-cfn-garbage-collection-audit.j2
├── slack-ebs-garbage-collection.j2
├── slack-ec2-garbage-collection-audit.j2
├── slack-elasticsearch-security-audit.j2
├── slack-iam-policy-account-audit-summary.j2
├── slack-iam-policy-account-audit.j2
├── slack-iam-user-DeleteAccessKey-audit.j2
├── slack-iam-user-DeleteLoginProfile-offboarding-audit
├── slack-iam-user-UpdateAccessKey-audit.j2
├── slack-iam-user-UpdateAccessKey-offboarding-audit.j2
├── slack-iam-user-audit.j2
├── slack-jinja2-filter-template.j2
├── slack-mfa-audit-disable-access.j2
├── slack-mfa-audit-reminder.j2
├── slack-mfa-audit.yml
├── slack-mfa-unused-audit.j2
├── slack-phd-issue.j2
├── slack-phd-notifications.j2
├── slack-public-instance-audit.j2
├── slack-s3-prevent-bucket-creation.j2
├── slack-s3-public-audit.j2
├── slack-s3-service-limit-audit.j2
├── slack-s3-target-bucket-audit.j2
├── slack-subnet-ip-address-usage-audit.j2
├── slack-team-tag-ec2-audit.j2
├── slack-team-tag-s3-audit.j2
├── slack-termination-protection-audit.j2
├── slack-unused-sgroup-audit.j2
├── slack_delete-marked.html.j2
├── slack_ec2-public-whitelist.j2
├── subnet-ip-address-usage-audit.html.j2
├── team-tag-ec2-audit.html.j2
├── team-tag-s3-audit.html.j2
├── termination-protection-audit.html.j2
└── unused-sgroup-audit.html.j2
├── policies
├── acm-certificate-audit.yml
├── admin-group.yml
├── auto-team-tag.yml
├── autotag-owner.yml
├── c7n-org
│ ├── CustomAccount
│ │ ├── README.md
│ │ ├── iam-user-CreateLoginProfile.yml
│ │ └── iam-user-UpdateAccessKey-audit.yml
│ ├── acm-certificate-cross-account-audit.yml
│ ├── all-accounts.yml
│ ├── app-elb.yml
│ ├── cfn-garbage-collection-audit.yml
│ ├── cheatsheet.txt
│ ├── copy-instance-tags.yml
│ ├── dynamodb-table.yml
│ ├── ebs.yml
│ ├── ecr.yml
│ ├── ecs.yml
│ ├── efs.yml
│ ├── elasticip-address-audit.yml
│ ├── elb.yml
│ ├── es.yml
│ ├── iam-group.yml
│ ├── iam-mfa-audit.yml
│ ├── iam-role.yml
│ ├── iam.yml
│ ├── iot.yml
│ ├── lambda-get-function-list.yml
│ ├── lambda.yml
│ ├── public-instance-audit.yml
│ ├── rest-api.yml
│ ├── s3-global-grants-audit.yml
│ ├── s3-prevent-bucket-creation.yml
│ ├── s3-public-audit-scheduled-job.yml
│ ├── s3-public-audit-test.yml
│ ├── s3-public-audit.yml
│ ├── secrets-manager.yml
│ ├── sns.yml
│ └── termination-protection-audit.yml
├── copy-instance-tags.yml
├── delete-marked-sgroups.yml
├── ebs-autocleanup-tag.yml
├── ebs-garbage-collection-lambda.yml
├── ebs-garbage-collection-with-tags.yml
├── ec2-garbage-collection-audit.yml
├── ec2-health-event.yml
├── ec2-publicipaddress-audit.yml
├── ec2.yml
├── elasticsearch-find-all-domains.yml
├── elasticsearch-security-audit.yml
├── emailer.yml
├── get-resources.yml
├── get_lambda_runtime_audit.yml
├── health-event-issues.yml
├── iam-ec2-policy-check.yml
├── iam-policy-CreatePolicy-audit.yml
├── iam-policy-CreatePolicyVersion-audit.yml
├── iam-policy-account-Summary-audit.yml
├── iam-policy-account-audit.yml
├── iam-role-with-managed-policy-audit.yml
├── iam-user-DeleteAccessKey.yml
├── iam-user-DeleteLoginProfile-offboarding.yml
├── iam-user-UpdateAccessKey-offboarding.yml
├── iam-user-administrator-access-audit.yml
├── iam-user-audit.yml
├── iam-user-set-groups.yml
├── iam-user-tagged-resources-audit.yml
├── iam.py
├── iam.yml
├── mailer.yml
├── mark-unused-sgroups.yml
├── mfa-audit-broken.yml
├── mfa-audit.yml
├── mfa-unused.yml
├── mfa.yml
├── new-user-audit.yml
├── offhours.yml
├── owner-tag-audit.yml
├── phd-notifications.yml
├── public-instance-audit.yml
├── public-subnet-instance-audit-lambda.yml
├── public-subnet-instance-audit-notify.yml
├── public-subnet-instance-audit-whitelist.yml
├── roles.yml
├── s3-prevent-bucket-creation.yml
├── s3-public-audit.yml
├── s3-server-access-logging.yml
├── s3-service-limit-audit.yml
├── s3-target-bucket-audit.yml
├── security-groups-unused-notify.yml
├── security-groups-unused.yml
├── sgroup-audit.yml
├── slack-notify.yml
├── ssm-managed-instance.yaml
├── stopped-instances.yml
├── subnet-ip-address-usage-audit.yml
├── tag-audit.yml
├── team-tag-ec2-audit.yml
├── team-tag-s3-audit.yml
├── termination-protection-audit.yml
├── termination-protection-list.yml
├── unused-sgroup-audit.yml
└── vpn.yml
├── scripts
├── custodian-iam-user-cross-account-audit.sh
├── get-iam-roleids.sh
├── get-iam-userids.sh
├── list-custodian-schema-health-event-support.sh
├── report-with-user-input.sh
├── report.sh
└── report_with_user_inputs_and_auto_commit.sh
└── update-mailer-lambda.sh
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 David Lin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/cheatsheet.txt:
--------------------------------------------------------------------------------
1 | ============================
2 | c7n-mailer Developer Install
3 | ============================
4 | $ git clone https://github.com/capitalone/cloud-custodian
5 | $ cd cloud-custodian
6 | $ virtualenv c7n_mailer
7 | $ source c7n_mailer/bin/activate
8 | $ cd tools/c7n_mailer
9 | $ pip install -r requirements.txt
10 | $ python setup.py develop
11 |
12 |
13 | ===================
14 | Invoking c7n Mailer
15 | ===================
16 | c7n-mailer --config mailer.yml --update-lambda && custodian run -c test.yml -s .
17 | c7n-mailer --config mailer_iesandbox.yml --update-lambda && custodian run -c test.yml -s .
18 |
19 |
20 | ===============================
21 | Finding Default Email Templates
22 | ===============================
23 | find ~/ -type f -name "default.html.j2"
24 | find ~/ -type f -name "slack_default.j2"
25 |
26 |
27 | ==============================
28 | Clearing Cloud Custodian Cache
29 | ==============================
30 | $ custodian run --help
31 | $ rm ~/.cache/cloud-custodian.cache
32 |
33 | ==============================
34 | Getting Jenkins Version Number
35 | ==============================
36 | java -jar jenkins-cli.jar -s http://localhost:8080/ version
37 |
38 | =====================================================
39 | Extracting Email Message Variable Names in Mailer SQS
40 | =====================================================
41 | Copy the encoded SQS message into a file (e.g. result)
42 | Decode the text using:
43 | $ cat result | base64 -d > result.zlib
44 | $ printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" | cat - result.zlib | gzip -dc
45 |
46 | The printf is just to pad a proper header for gzip. Otherwise gzip will not be able to uncompress it.
47 |
48 | ========================================
49 | Cloning a Development Branch for Testing
50 | ========================================
51 | git clone -b mailer-test https://github.com/LykinsN/cloud-custodian.git
52 |
53 |
54 | ===================
55 | Useful Git Commands
56 | ===================
57 | git clone -b mailer-test https://github.com/LykinsN/cloud-custodian.git
58 | git pull (from directory branch was cloned)
59 | git branch -a (to view branch info)
60 |
61 |
62 | =======================================
63 | AWS CLI to Create Dummy Security Groups
64 | =======================================
65 | Create security groups in David's VPC Sandbox
66 | export AWS_PROFILE=sandbox
67 | aws ec2 create-security-group --group-name launch-wizard-10 --description "david.lin security group" --vpc-id vpc-2ea22555
68 | aws ec2 create-security-group --group-name launch-wizard-11 --description "david.lin security group" --vpc-id vpc-2ea22555
69 | aws ec2 create-security-group --group-name launch-wizard-12 --description "david.lin security group" --vpc-id vpc-2ea22555
70 | aws ec2 create-security-group --group-name launch-wizard-13 --description "david.lin security group" --vpc-id vpc-2ea22555
71 | aws ec2 create-security-group --group-name launch-wizard-14 --description "david.lin security group" --vpc-id vpc-2ea22555
72 | aws ec2 create-security-group --group-name launch-wizard-15 --description "david.lin security group" --vpc-id vpc-2ea22555
73 |
74 | ================
75 | Custom Reporting
76 | ================
77 | $ custodian report --format grid -s output public-instance-whitelist.yml --field KeyName=KeyName --field PublicIpAddress=PublicIpAddress --no-default-fields --field InstanceId=InstanceI d --field VpcId=VpcId --field tag:SubnetId=SubnetId
78 |
79 | $ custodian report -s output --no-default-fields --format grid --field InstanceId=InstanceId --field tag:Name=tag:Name --field InstanceType=InstanceType --field VpcId=VpcId --field tag: State=State.Name stopped.yml
80 |
81 |
--------------------------------------------------------------------------------
/cleancache.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # to find path of cache issue `sudo find / cloud-custodian.cache
4 |
5 | # for ubuntu
6 | rm ~/.cache/cloud-custodian.cache
7 |
8 | # for centos
9 | # rm /home/ec2-user/.cache/cloud-custodian.cache
10 |
11 | echo 'Cloud Custodian cache deleted'
12 |
--------------------------------------------------------------------------------
/cron/crontab.txt:
--------------------------------------------------------------------------------
1 | 0 17 * * * /home/ubuntu/cloudcustodian/cron/mfa-audit.sh > /home/ubuntu/cloudcustodian/cron/mfa-audit.log 2>&1
2 |
3 |
--------------------------------------------------------------------------------
/cron/mfa-audit.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | PATH=/home/ubuntu/bin:/home/ubuntu/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
3 | export PATH
4 | source c7n_mailer/bin/activate
5 | echo "Running MFA audit policies..."
6 | custodian run -c /home/ubuntu/cloudcustodian/policies/mfa-audit.yml -s output --region us-east-1
7 | echo "MFA audit policies completed"
8 |
9 |
10 |
--------------------------------------------------------------------------------
/custom-site-packages/README.md:
--------------------------------------------------------------------------------
1 | The custom iam.py site-package should live in c7n_mailer site-package directory:
2 |
3 | /home/ubuntu/c7n_mailer/lib/python2.7/site-packages/c7n/resources/iam.py
4 |
5 |
6 | The following block of code was modified to support filtering
7 | on specific IAM Policy actions:
8 |
9 |
10 | for s in statements:
11 | if ('Condition' not in s and
12 | 'Action' in s and
13 | ('account:*' in s['Action'] or
14 | 'account:EnableRegion' in s['Action']) and
15 | 'Resource' in s and
16 | isinstance(s['Resource'], six.string_types) and
17 | s['Resource'] == "*" and
18 | s['Effect'] == "Allow"):
19 | return True
20 | return False
21 |
22 |
--------------------------------------------------------------------------------
/examples/cheatsheet.txt:
--------------------------------------------------------------------------------
1 | ============================
2 | c7n-mailer Developer Install
3 | ============================
4 | $ git clone https://github.com/capitalone/cloud-custodian
5 | $ cd cloud-custodian
6 | $ virtualenv c7n_mailer
7 | $ source c7n_mailer/bin/activate
8 | $ cd tools/c7n_mailer
9 | $ pip install -r requirements.txt
10 | $ python setup.py develop
11 |
12 |
13 | ===================
14 | Invoking c7n Mailer
15 | ===================
16 | c7n-mailer --config mailer.yml --update-lambda && custodian run -c test.yml -s .
17 | c7n-mailer --config mailer_iesandbox.yml --update-lambda && custodian run -c test.yml -s .
18 |
19 |
20 | ===============================
21 | Finding Default Email Templates
22 | ===============================
23 | find ~/ -type f -name "default.html.j2"
24 | find ~/ -type f -name "slack_default.j2"
25 |
26 |
27 | ==============================
28 | Clearing Cloud Custodian Cache
29 | ==============================
30 | $ custodian run --help
31 | $ rm ~/.cache/cloud-custodian.cache
32 |
33 |
34 | ========================================
35 | Cloning a Development Branch for Testing
36 | ========================================
37 | git clone -b mailer-test https://github.com/LykinsN/cloud-custodian.git
38 |
39 |
40 | ===================
41 | Useful Git Commands
42 | ===================
43 | git clone -b mailer-test https://github.com/LykinsN/cloud-custodian.git
44 | git pull (from directory branch was cloned)
45 | git branch -a (to view branch info)
46 |
47 |
48 | =======================================
49 | AWS CLI to Create Dummy Security Groups
50 | =======================================
51 | Create security groups in David's VPC Sandbox
52 | export AWS_PROFILE=sandbox
53 | aws ec2 create-security-group --group-name launch-wizard-10 --description "david.lin security group" --vpc-id vpc-2ea22555
54 | aws ec2 create-security-group --group-name launch-wizard-11 --description "david.lin security group" --vpc-id vpc-2ea22555
55 | aws ec2 create-security-group --group-name launch-wizard-12 --description "david.lin security group" --vpc-id vpc-2ea22555
56 | aws ec2 create-security-group --group-name launch-wizard-13 --description "david.lin security group" --vpc-id vpc-2ea22555
57 | aws ec2 create-security-group --group-name launch-wizard-14 --description "david.lin security group" --vpc-id vpc-2ea22555
58 | aws ec2 create-security-group --group-name launch-wizard-15 --description "david.lin security group" --vpc-id vpc-2ea22555
59 |
60 | ================
61 | Custom Reporting
62 | ================
63 | $ custodian report --format grid -s output public-instance-whitelist.yml --field KeyName=KeyName --field PublicIpAddress=PublicIpAddress --no-default-fields --field InstanceId=InstanceI d --field VpcId=VpcId --field tag:SubnetId=SubnetId
64 |
65 | $ custodian report -s output --no-default-fields --format grid --field InstanceId=InstanceId --field tag:Name=tag:Name --field InstanceType=InstanceType --field VpcId=VpcId --field tag: State=State.Name stopped.yml
66 |
67 |
--------------------------------------------------------------------------------
/examples/cleancache.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | rm ~/.cache/cloud-custodian.cache
3 |
4 |
--------------------------------------------------------------------------------
/examples/event-pattern-for-aws-health-event-issue:
--------------------------------------------------------------------------------
1 | If you want this rule to get triggered for all AWS services,
2 | you will not be able to use "detail" such as "eventTypeCategory" [1].
3 | Therefore, the pattern to monitor all AWS Health events is:
4 |
5 |
6 | {
7 | "source": [
8 | "aws.health"
9 | ],
10 | "detail-type": [
11 | "AWS Health Event"
12 | ]
13 | }
14 |
15 | If you want this to get triggered for a specific service (e.g. ELB), you can change it to the following:
16 |
17 |
18 | {
19 | "source": [
20 | "aws.health"
21 | ],
22 | "detail-type": [
23 | "AWS Health Event"
24 | ],
25 | "detail": {
26 | "service": [
27 | "ELASTICLOADBALANCING"
28 | ],
29 | "eventTypeCategory": [
30 | "issue"
31 | ]
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/examples/example-output-from-health-event-issues:
--------------------------------------------------------------------------------
1 | {
2 | "arn": "arn:aws:health:us-east-1::event/INTERNETCONNECTIVITY/AWS_INTERNETCONNECTIVITY_OPERATIONAL_ISSUE/AWS_INTERNETCONNECTIVITY_OPERATIONAL_ISSUE_XOIUP_161168
3 | 1635",
4 | "service": "INTERNETCONNECTIVITY",
5 | "eventTypeCode": "AWS_INTERNETCONNECTIVITY_OPERATIONAL_ISSUE",
6 | "eventTypeCategory": "issue",
7 | "region": "us-east-1",
8 | "startTime": "2021-01-26T17:20:35.521000+00:00",
9 | "lastUpdatedTime": "2021-01-26T17:23:08.321000+00:00",
10 | "statusCode": "open",
11 | "eventScopeCode": "PUBLIC",
12 | "Description": "External Network Connectivity Issues\n\n[09:20 AM PST] We are investigating connectivity issues with an internet provider, mainly affecting the
13 | East Coast of the United States, outside of the AWS Network. We are investigating the issue with the external provider.",
14 | "AffectedEntities": [
15 | {
16 | "entityValue": "UNKNOWN",
17 | "lastUpdatedTime": "2021-01-26T17:23:08.321000+00:00"
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/images/custom_offhours.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidclin/cloudcustodian-policies/1cbfbb798ac43dce806aa4c0ddcc6848ba788144/images/custom_offhours.png
--------------------------------------------------------------------------------
/images/maid_hours.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidclin/cloudcustodian-policies/1cbfbb798ac43dce806aa4c0ddcc6848ba788144/images/maid_hours.png
--------------------------------------------------------------------------------
/images/singlenodedeploy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidclin/cloudcustodian-policies/1cbfbb798ac43dce806aa4c0ddcc6848ba788144/images/singlenodedeploy.png
--------------------------------------------------------------------------------
/msg-templates/cheatsheet:
--------------------------------------------------------------------------------
1 | ============================================
2 | Finding Path to c7n-mailer Default Templates
3 | ============================================
4 | find ~/ -type f -name "default.html.j2" (for email)
5 | find ~/ -type f -name "slack_default.j2" (for Slack)
6 |
7 | ===============================
8 | All possible msg template paths
9 | ===============================
10 | /home/ubuntu/cloud-custodian/tools/c7n_mailer/tests/test-templates/slack_default.j2
11 | /home/ubuntu/cloud-custodian/tools/c7n_mailer/c7n_mailer/msg-templates/slack_default.j2
12 | /home/ubuntu/junk/lib/python3.6/site-packages/c7n_mailer/msg-templates/slack_default.j2
13 | /home/ubuntu/custodian/lib/python3.6/site-packages/c7n_mailer/msg-templates/slack_default.j2
14 |
15 | ========================================================
16 | Copy templates to all possible msg templates directories
17 | ========================================================
18 | export slack_template="slack_template_filename_goes_here"
19 | export email_template="email_template_filename_goes_here"
20 |
21 | cp $email_template /home/ubuntu/cloud-custodian/tools/c7n_mailer/tests/test-templates/
22 | cp $email_template /home/ubuntu/cloud-custodian/tools/c7n_mailer/c7n_mailer/msg-templates/
23 | cp $email_template /home/ubuntu/junk/lib/python3.6/site-packages/c7n_mailer/msg-templates/
24 | cp $email_template /home/ubuntu/custodian/lib/python3.6/site-packages/c7n_mailer/msg-templates/
25 |
26 | cp $slack_template /home/ubuntu/cloud-custodian/tools/c7n_mailer/tests/test-templates/
27 | cp $slack_template /home/ubuntu/cloud-custodian/tools/c7n_mailer/c7n_mailer/msg-templates/
28 | cp $slack_template /home/ubuntu/junk/lib/python3.6/site-packages/c7n_mailer/msg-templates/
29 | cp $slack_template /home/ubuntu/custodian/lib/python3.6/site-packages/c7n_mailer/msg-templates/
30 |
31 | ============================================
32 | Update msg templates using c7n-mailer Lambda
33 | ============================================
34 | export policy="policy_filename_goes_here"
35 |
36 | from ~/cloudcustodian/policies directory run:
37 | c7n-mailer --config /home/ubuntu/cloudcustodian/mailer/mailer.yml --update-lambda && custodian run -c $policy -s .
38 |
--------------------------------------------------------------------------------
/msg-templates/s3-prevent-bucket-creation.html.j2:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {#
5 | Sample Policy that can be used with this template:
6 |
7 | Additional parameters can be passed in from the policy - i.e. action_desc, violation_desc
8 |
9 | - name: delete-unencrypted-ec2
10 | resource: ec2
11 | filters:
12 | - type: ebs
13 | key: Encrypted
14 | value: false
15 | actions:
16 | - terminate
17 | - type: notify
18 | template: default.html
19 | subject: "[custodian {{ account }}] Delete Unencrypted EC2 - {{ region }}"
20 | violation_desc: "The following EC2(s) are not encrypted:"
21 | action_desc: "The EC2(s) have been terminated"
22 | from: custodian@domain.com
23 | to:
24 | - owner@domain.com
25 | transport:
26 | type: sqs
27 | queue: https://sqs.us-east-1.amazonaws.com/12345678910/custodian-sqs-queue
28 | #}
29 |
30 |
31 | {# You can set any mandatory tags here, and they will be formatted/outputted in the message #}
32 | {% set requiredTags = ['Application','Owner'] %}
33 |
34 | {# The macros below format some resource attributes for better presentation #}
35 | {% macro getTag(resource, tagKey) -%}
36 | {% if resource.get('Tags') %}
37 | {% for t in resource.get('Tags') %}
38 | {% if t.get('Key') == tagKey %}
39 | {{ t.get('Value') }}
40 | {% endif %}
41 | {% endfor %}
42 | {% endif %}
43 | {%- endmacro %}
44 |
45 | {% macro extractList(resource, column) -%}
46 | {% for p in resource.get(column) %}
47 | {{ p }},
48 | {% endfor %}
49 | {%- endmacro %}
50 |
51 | {% macro columnHeading(columnNames, tableWidth) -%}
52 |
53 | {% for columnName in columnNames %}
54 | {{ columnName }} |
55 | {% endfor %}
56 | {%- endmacro %}
57 |
58 | {# The macro below creates the table:
59 | Formatting can be dependent on the column names that are passed in
60 | #}
61 | {% macro columnData(resources, columnNames) -%}
62 | {% for resource in resources %}
63 |
64 | {% for columnName in columnNames %}
65 | {% if columnName in requiredTags %}
66 | {{ getTag(resource,columnName) }} |
67 | {% elif columnName == 'tag.Name' %}
68 | {{ getTag(resource,'Name') }} |
69 | {% elif columnName == 'InstanceCount' %}
70 | {{ resource['Instances'] | length }} |
71 | {% elif columnName == 'VolumeConsumedReadWriteOps' %}
72 | {{ resource['c7n.metrics']['AWS/EBS.VolumeConsumedReadWriteOps.Maximum'][0]['Maximum'] }} |
73 | {% elif columnName == 'PublicIp' %}
74 | {{ resource['NetworkInterfaces'][0].get('Association')['PublicIp'] }} |
75 | {% else %}
76 | {{ resource[columnName] }} |
77 | {% endif %}
78 | {% endfor %}
79 |
80 | {% endfor %}
81 |
82 | {%- endmacro %}
83 |
84 | {# Main #}
85 | {% macro createTable(columnNames, resources, tableWidth) %}
86 | {{ columnHeading(columnNames, tableWidth) }}
87 | {{ columnData(resources, columnNames) }}
88 | {%- endmacro %}
89 |
90 |
91 | Custodian Notification - {{ account }}
92 |
93 |
94 |
131 |
132 |
133 |
134 | {{ "%s - %s" | format(account,region) }}
135 |
136 |
137 | -------------------------------------------------------------------------------
138 |
139 | __ __ __ _ _ ____ _____ _____ ___ ___ __ ___ ________ ___ __
140 | /' _/__`. | \ || |/ _/ |/ / __|_ _| | _ \ __|_ \| __/ _/_ _| __| _\
141 | `._`.|_ | | -< \/ | \_| <| _| | | | v / _| _\ | _| \__ | | | _|| v |
142 | |___/__.' |__/\__/ \__/_|\_\___| |_| |_|_\___/___|___\__/ |_| |___|__/
143 |
144 |
145 | -------------------------------------------------------------------------------
146 |
147 | The following request to create a new S3 bucket was rejected.
148 |
149 | -------------------------------------------------------------------------------
150 |
151 |
152 |
153 | {{ action['violation_desc'] }}
154 |
155 | {# Below, notifications for any resource-type can be formatted with specific columns #}
156 | {% if policy['resource'] == "ami" %}
157 | {% set columnNames = ['Name','ImageId','CreationDate'] %}
158 | {{ createTable(columnNames, resources, '60') }}
159 |
160 | {% elif policy['resource'] == "app-elb" %}
161 | {% set columnNames = ['LoadBalancerName','CreatedTime','Application','Owner'] %}
162 | {{ createTable(columnNames, resources, '80') }}
163 |
164 | {% elif policy['resource'] == "asg" %}
165 | {% if resources[0]['Invalid'] is defined %}
166 | {% set columnNames = ['AutoScalingGroupName','InstanceCount','Invalid'] %}
167 | {% else %}
168 | {% set columnNames = ['AutoScalingGroupName','InstanceCount','Application','Owner'] %}
169 | {% endif %}
170 | {{ createTable(columnNames, resources, '60') }}
171 |
172 | {% elif policy['resource'] == "cache-cluster" %}
173 | {% set columnNames = ['CacheClusterId','CacheClusterCreateTime','CacheClusterStatus','Application','Owner'] %}
174 | {{ createTable(columnNames, resources, '80') }}
175 |
176 | {% elif policy['resource'] == "cache-snapshot" %}
177 | {% set columnNames = ['SnapshotName','CacheClusterId','SnapshotSource','Application','Owner'] %}
178 | {{ createTable(columnNames, resources, '80') }}
179 |
180 | {% elif policy['resource'] == "cfn" %}
181 | {% set columnNames = ['StackName'] %}
182 | {{ createTable(columnNames, resources, '50') }}
183 |
184 | {% elif policy['resource'] == "cloudsearch" %}
185 | {% set columnNames = ['DomainName'] %}
186 | {{ createTable(columnNames, resources, '50') }}
187 |
188 | {% elif policy['resource'] == "ebs" %}
189 | {% set columnNames = ['VolumeId','CreateTime','State','Application','Owner'] %}
190 | {{ createTable(columnNames, resources, '50') }}
191 |
192 | {% elif policy['resource'] == "ebs-snapshot" %}
193 | {% set columnNames = ['SnapshotId','StartTime','Application','Owner'] %}
194 | {{ createTable(columnNames, resources, '80') }}
195 |
196 | {% elif policy['resource'] == "ec2" %}
197 | {% if resources[0]['MatchedFilters'] == ['PublicIpAddress'] %}
198 | {% set columnNames = ['tag.Name','PublicIp','InstanceId'] %}
199 | {% else %}
200 | {% set columnNames = ['tag.Name','PrivateIpAddress','InstanceId','ImageId','Application','Owner'] %}
201 | {% endif %}
202 | {{ createTable(columnNames, resources, '80') }}
203 |
204 | {% elif policy['resource'] == "efs" %}
205 | {% set columnNames = ['CreationToken','CreationTime','FileSystemId','OwnerId'] %}
206 | {{ createTable(columnNames, resources, '50') }}
207 |
208 | {% elif policy['resource'] == "elasticsearch" %}
209 | {% set columnNames = ['DomainName','Endpoint'] %}
210 | {{ createTable(columnNames, resources, '50') }}
211 |
212 | {% elif policy['resource'] == "elb" %}
213 | {% set columnNames = ['LoadBalancerName','InstanceCount','AvailabilityZones','Application','Owner'] %}
214 | {{ createTable(columnNames, resources, '80') }}
215 |
216 | {% elif policy['resource'] == "emr" %}
217 | {% set columnNames = ['Id','EmrState'] %}
218 | {{ createTable(columnNames, resources, '50') }}
219 |
220 | {% elif policy['resource'] == "kinesis" %}
221 | {% set columnNames = ['StreamName'] %}
222 | {{ createTable(columnNames, resources, '50') }}
223 |
224 | {% elif policy['resource'] == "launch-config" %}
225 | {% set columnNames = ['LaunchConfigurationName'] %}
226 | {{ createTable(columnNames, resources, '30') }}
227 |
228 | {% elif policy['resource'] == "log-group" %}
229 | {% set columnNames = ['logGroupName'] %}
230 | {{ createTable(columnNames, resources, '30') }}
231 |
232 | {% elif policy['resource'] == "rds" %}
233 | {% if resources[0]['PubliclyAccessible'] == true or resources[0]['StorageEncrypted'] == false %}
234 | {% set columnNames = ['DBInstanceIdentifier','PubliclyAccessible','StorageEncrypted','DBSubnetGroup'] %}
235 | {% else %}
236 | {% set columnNames = ['DBInstanceIdentifier','Application','Owner'] %}
237 | {% endif %}
238 | {{ createTable(columnNames, resources, '80') }}
239 |
240 | {% elif policy['resource'] == "rds-snapshot" %}
241 | {% set columnNames = ['DBSnapshotIdentifier','SnapshotCreateTime','DBInstanceIdentifier','SnapshotType','Application','Owner'] %}
242 | {{ createTable(columnNames, resources, '80') }}
243 |
244 | {% elif policy['resource'] == "redshift" %}
245 | {% if resources[0]['PubliclyAccessible'] == true or resources[0]['Encrypted'] == false %}
246 | {% set columnNames = ['ClusterIdentifier','NodeCount','PubliclyAccessible','Encrypted'] %}
247 | {% else %}
248 | {% set columnNames = ['ClusterIdentifier','NodeCount','Application','Owner'] %}
249 | {% endif %}
250 | {{ createTable(columnNames, resources, '80') }}
251 |
252 | {% elif policy['resource'] == "redshift-snapshot" %}
253 | {% set columnNames = ['SnapshotIdentifier','DBName','Application','Owner'] %}
254 | {{ createTable(columnNames, resources, '80') }}
255 |
256 | {% elif policy['resource'] == "s3" %}
257 | {% if resources[0]['GlobalPermissions'] is defined %}
258 | {% set columnNames = ['Name','GlobalPermissions'] %}
259 | {% else %}
260 | {% set columnNames = ['Name'] %}
261 | {% endif %}
262 | {{ createTable(columnNames, resources, '80') }}
263 |
264 | {% elif policy['resource'] == "security-group" %}
265 | {% set columnNames = ['GroupName','tag.Name','GroupId','VpcId'] %}
266 | {{ createTable(columnNames, resources, '80') }}
267 |
268 | {% elif policy['resource'] == "simpledb" %}
269 | {% set columnNames = ['DomainName'] %}
270 | {{ createTable(columnNames, resources, '60') }}
271 |
272 | {# If no special formatting is defined for a resource type, all attributes will be formatted in the email #}
273 | {% else %}
274 |
275 |
276 | {% for column in resources[0] %}
277 | {{ column }} |
278 | {% endfor %}
279 |
280 | {% set columnlen = resources[0]|length|int %}
281 | {% for resource in resources %}
282 |
283 | {% for column in resource %}
284 | {{ resource[column] }} |
285 | {% endfor %}
286 |
287 | {% endfor %}
288 |
289 | {% endif %}
290 |
291 | {{ action['action_desc'] }}
292 |
293 |
294 |
295 |
296 |
--------------------------------------------------------------------------------
/msg-templates/s3-public-audit.html.j2:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {#
5 | Sample Policy that can be used with this template:
6 |
7 | Additional parameters can be passed in from the policy - i.e. action_desc, violation_desc
8 |
9 | - name: delete-unencrypted-ec2
10 | resource: ec2
11 | filters:
12 | - type: ebs
13 | key: Encrypted
14 | value: false
15 | actions:
16 | - terminate
17 | - type: notify
18 | template: default.html
19 | subject: "[custodian {{ account }}] Delete Unencrypted EC2 - {{ region }}"
20 | violation_desc: "The following EC2(s) are not encrypted:"
21 | action_desc: "The EC2(s) have been terminated"
22 | from: custodian@domain.com
23 | to:
24 | - owner@domain.com
25 | transport:
26 | type: sqs
27 | queue: https://sqs.us-east-1.amazonaws.com/12345678910/custodian-sqs-queue
28 | #}
29 |
30 |
31 | {# You can set any mandatory tags here, and they will be formatted/outputted in the message #}
32 | {% set requiredTags = ['Application','Owner'] %}
33 |
34 | {# The macros below format some resource attributes for better presentation #}
35 | {% macro getTag(resource, tagKey) -%}
36 | {% if resource.get('Tags') %}
37 | {% for t in resource.get('Tags') %}
38 | {% if t.get('Key') == tagKey %}
39 | {{ t.get('Value') }}
40 | {% endif %}
41 | {% endfor %}
42 | {% endif %}
43 | {%- endmacro %}
44 |
45 | {% macro extractList(resource, column) -%}
46 | {% for p in resource.get(column) %}
47 | {{ p }},
48 | {% endfor %}
49 | {%- endmacro %}
50 |
51 | {% macro columnHeading(columnNames, tableWidth) -%}
52 |
53 | {% for columnName in columnNames %}
54 | {{ columnName }} |
55 | {% endfor %}
56 | {%- endmacro %}
57 |
58 | {# The macro below creates the table:
59 | Formatting can be dependent on the column names that are passed in
60 | #}
61 | {% macro columnData(resources, columnNames) -%}
62 | {% for resource in resources %}
63 |
64 | {% for columnName in columnNames %}
65 | {% if columnName in requiredTags %}
66 | {{ getTag(resource,columnName) }} |
67 | {% elif columnName == 'tag.Name' %}
68 | {{ getTag(resource,'Name') }} |
69 | {% elif columnName == 'InstanceCount' %}
70 | {{ resource['Instances'] | length }} |
71 | {% elif columnName == 'VolumeConsumedReadWriteOps' %}
72 | {{ resource['c7n.metrics']['AWS/EBS.VolumeConsumedReadWriteOps.Maximum'][0]['Maximum'] }} |
73 | {% elif columnName == 'PublicIp' %}
74 | {{ resource['NetworkInterfaces'][0].get('Association')['PublicIp'] }} |
75 | {% else %}
76 | {{ resource[columnName] }} |
77 | {% endif %}
78 | {% endfor %}
79 |
80 | {% endfor %}
81 |
82 | {%- endmacro %}
83 |
84 | {# Main #}
85 | {% macro createTable(columnNames, resources, tableWidth) %}
86 | {{ columnHeading(columnNames, tableWidth) }}
87 | {{ columnData(resources, columnNames) }}
88 | {%- endmacro %}
89 |
90 |
91 | Custodian Notification - {{ account }}
92 |
93 |
94 |
131 |
132 |
133 |
134 | {{ "%s - %s" | format(account,region) }}
135 |
136 |
137 | -------------------------------------------------------------------------------
138 | _ ___ ___ __ _ __ _ __ _ ___ ___ ___ _ __ _ __
139 | | | __| | __| \| |/ _] | \| | __| __| _ \ | \| |/ _]
140 | | | _| | _|| | ' | [/\ | | ' | _|| _|| v / | | ' | [/\
141 | |_|___| |___|_|\__|\__/_|_|\__|___|___|_|_\_|_|\__|\__/
142 |
143 | -------------------------------------------------------------------------------
144 |
145 | The following S3 bucket was created with Public access.
146 |
147 | -------------------------------------------------------------------------------
148 |
149 |
150 |
151 | {{ action['violation_desc'] }}
152 |
153 | {# Below, notifications for any resource-type can be formatted with specific columns #}
154 | {% if policy['resource'] == "ami" %}
155 | {% set columnNames = ['Name','ImageId','CreationDate'] %}
156 | {{ createTable(columnNames, resources, '60') }}
157 |
158 | {% elif policy['resource'] == "app-elb" %}
159 | {% set columnNames = ['LoadBalancerName','CreatedTime','Application','Owner'] %}
160 | {{ createTable(columnNames, resources, '80') }}
161 |
162 | {% elif policy['resource'] == "asg" %}
163 | {% if resources[0]['Invalid'] is defined %}
164 | {% set columnNames = ['AutoScalingGroupName','InstanceCount','Invalid'] %}
165 | {% else %}
166 | {% set columnNames = ['AutoScalingGroupName','InstanceCount','Application','Owner'] %}
167 | {% endif %}
168 | {{ createTable(columnNames, resources, '60') }}
169 |
170 | {% elif policy['resource'] == "cache-cluster" %}
171 | {% set columnNames = ['CacheClusterId','CacheClusterCreateTime','CacheClusterStatus','Application','Owner'] %}
172 | {{ createTable(columnNames, resources, '80') }}
173 |
174 | {% elif policy['resource'] == "cache-snapshot" %}
175 | {% set columnNames = ['SnapshotName','CacheClusterId','SnapshotSource','Application','Owner'] %}
176 | {{ createTable(columnNames, resources, '80') }}
177 |
178 | {% elif policy['resource'] == "cfn" %}
179 | {% set columnNames = ['StackName'] %}
180 | {{ createTable(columnNames, resources, '50') }}
181 |
182 | {% elif policy['resource'] == "cloudsearch" %}
183 | {% set columnNames = ['DomainName'] %}
184 | {{ createTable(columnNames, resources, '50') }}
185 |
186 | {% elif policy['resource'] == "ebs" %}
187 | {% set columnNames = ['VolumeId','CreateTime','State','Application','Owner'] %}
188 | {{ createTable(columnNames, resources, '50') }}
189 |
190 | {% elif policy['resource'] == "ebs-snapshot" %}
191 | {% set columnNames = ['SnapshotId','StartTime','Application','Owner'] %}
192 | {{ createTable(columnNames, resources, '80') }}
193 |
194 | {% elif policy['resource'] == "ec2" %}
195 | {% if resources[0]['MatchedFilters'] == ['PublicIpAddress'] %}
196 | {% set columnNames = ['tag.Name','PublicIp','InstanceId'] %}
197 | {% else %}
198 | {% set columnNames = ['tag.Name','PrivateIpAddress','InstanceId','ImageId','Application','Owner'] %}
199 | {% endif %}
200 | {{ createTable(columnNames, resources, '80') }}
201 |
202 | {% elif policy['resource'] == "efs" %}
203 | {% set columnNames = ['CreationToken','CreationTime','FileSystemId','OwnerId'] %}
204 | {{ createTable(columnNames, resources, '50') }}
205 |
206 | {% elif policy['resource'] == "elasticsearch" %}
207 | {% set columnNames = ['DomainName','Endpoint'] %}
208 | {{ createTable(columnNames, resources, '50') }}
209 |
210 | {% elif policy['resource'] == "elb" %}
211 | {% set columnNames = ['LoadBalancerName','InstanceCount','AvailabilityZones','Application','Owner'] %}
212 | {{ createTable(columnNames, resources, '80') }}
213 |
214 | {% elif policy['resource'] == "emr" %}
215 | {% set columnNames = ['Id','EmrState'] %}
216 | {{ createTable(columnNames, resources, '50') }}
217 |
218 | {% elif policy['resource'] == "kinesis" %}
219 | {% set columnNames = ['StreamName'] %}
220 | {{ createTable(columnNames, resources, '50') }}
221 |
222 | {% elif policy['resource'] == "launch-config" %}
223 | {% set columnNames = ['LaunchConfigurationName'] %}
224 | {{ createTable(columnNames, resources, '30') }}
225 |
226 | {% elif policy['resource'] == "log-group" %}
227 | {% set columnNames = ['logGroupName'] %}
228 | {{ createTable(columnNames, resources, '30') }}
229 |
230 | {% elif policy['resource'] == "rds" %}
231 | {% if resources[0]['PubliclyAccessible'] == true or resources[0]['StorageEncrypted'] == false %}
232 | {% set columnNames = ['DBInstanceIdentifier','PubliclyAccessible','StorageEncrypted','DBSubnetGroup'] %}
233 | {% else %}
234 | {% set columnNames = ['DBInstanceIdentifier','Application','Owner'] %}
235 | {% endif %}
236 | {{ createTable(columnNames, resources, '80') }}
237 |
238 | {% elif policy['resource'] == "rds-snapshot" %}
239 | {% set columnNames = ['DBSnapshotIdentifier','SnapshotCreateTime','DBInstanceIdentifier','SnapshotType','Application','Owner'] %}
240 | {{ createTable(columnNames, resources, '80') }}
241 |
242 | {% elif policy['resource'] == "redshift" %}
243 | {% if resources[0]['PubliclyAccessible'] == true or resources[0]['Encrypted'] == false %}
244 | {% set columnNames = ['ClusterIdentifier','NodeCount','PubliclyAccessible','Encrypted'] %}
245 | {% else %}
246 | {% set columnNames = ['ClusterIdentifier','NodeCount','Application','Owner'] %}
247 | {% endif %}
248 | {{ createTable(columnNames, resources, '80') }}
249 |
250 | {% elif policy['resource'] == "redshift-snapshot" %}
251 | {% set columnNames = ['SnapshotIdentifier','DBName','Application','Owner'] %}
252 | {{ createTable(columnNames, resources, '80') }}
253 |
254 | {% elif policy['resource'] == "s3" %}
255 | {% if resources[0]['GlobalPermissions'] is defined %}
256 | {% set columnNames = ['Name','GlobalPermissions'] %}
257 | {% else %}
258 | {% set columnNames = ['Name','Application','Owner'] %}
259 | {% endif %}
260 | {{ createTable(columnNames, resources, '80') }}
261 |
262 | {% elif policy['resource'] == "security-group" %}
263 | {% set columnNames = ['GroupName','tag.Name','GroupId','VpcId'] %}
264 | {{ createTable(columnNames, resources, '80') }}
265 |
266 | {% elif policy['resource'] == "simpledb" %}
267 | {% set columnNames = ['DomainName'] %}
268 | {{ createTable(columnNames, resources, '60') }}
269 |
270 | {# If no special formatting is defined for a resource type, all attributes will be formatted in the email #}
271 | {% else %}
272 |
273 |
274 | {% for column in resources[0] %}
275 | {{ column }} |
276 | {% endfor %}
277 |
278 | {% set columnlen = resources[0]|length|int %}
279 | {% for resource in resources %}
280 |
281 | {% for column in resource %}
282 | {{ resource[column] }} |
283 | {% endfor %}
284 |
285 | {% endfor %}
286 |
287 | {% endif %}
288 |
289 | {{ action['action_desc'] }}
290 |
291 |
292 |
293 |
294 |
--------------------------------------------------------------------------------
/msg-templates/slack-acm-certificate-audit.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian ACM Certificate Audit",
5 | "title":"ACM Certificate Audit",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"Description",
10 | "value":"ACM certificate(s) found nearing their expiration date <60 days"
11 | },
12 | {
13 | "title":"Domain Name(s)",
14 | "value":"{{ resources | selectattr('DomainName') | map(attribute='DomainName') | list }}"
15 | },
16 | {
17 | "title":"Expiration Date(s)",
18 | "value":"{{ resources | selectattr('NotAfter') | map(attribute='NotAfter') | list }}"
19 | },
20 | {
21 | "title":"Certificate Arn(s)",
22 | "value":"{{ resources | selectattr('CertificateArn') | map(attribute='CertificateArn') | list }}"
23 | },
24 | {
25 | "title":"Account ID",
26 | "value":"{{ account_id }}"
27 | },
28 | {
29 | "title":"Region",
30 | "value":"{{ region }}"
31 | },
32 | {
33 | "title":"Action Description",
34 | "value":"See email notification for details."
35 | }
36 | ]
37 | }
38 | ],
39 | "channel":"{{ recipient }}",
40 | "username":"Custodian"
41 | }
42 |
--------------------------------------------------------------------------------
/msg-templates/slack-cfn-garbage-collection-audit.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Garbage Collection",
5 | "title":"CloudFormation Stack Audit",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"CloudFormation stack found older than 3 days",
10 | "value":"{%- for resource in resources -%}
11 | {{ format_resource(resource, policy['resource']) }}
12 | {%- endfor -%}"
13 | },
14 | {
15 | "title":"Account ID",
16 | "value":"{{ account_id }}"
17 | },
18 | {
19 | "title":"Region",
20 | "value":"{{ region }}"
21 | },
22 | {
23 | "title":"Action Description",
24 | "value":"Delete IAM Pipeline Training CloudFormation stacks that have 'iam-challenge' in the name and older than 3 days. No further action necessary."
25 | }
26 | ]
27 | }
28 | ],
29 | "channel":"{{ recipient }}",
30 | "username":"Custodian"
31 | }
32 |
--------------------------------------------------------------------------------
/msg-templates/slack-ebs-garbage-collection.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"EBS Garbage Collection",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"Available EBS Volumes Older than 1 Day :",
10 | "value":"{%- for resource in resources -%}
11 | {{ format_resource(resource, policy['resource']) }}
12 | {%- endfor -%}"
13 | },
14 | {
15 | "title":"Account",
16 | "value":"{{ account }}"
17 | },
18 | {
19 | "title":"Region",
20 | "value":"{{ region }}"
21 | },
22 | {
23 | "title":"Action Description",
24 | "value":"Unused EBS volumes deleted. No further action is required on your part."
25 | },
26 | {
27 | "title":"Note:",
28 | "value":"This is informational only. Check email for more details."
29 | }
30 | ]
31 | }
32 | ],
33 | "channel":"{{ recipient }}",
34 | "username":"Custodian"
35 | }
36 |
--------------------------------------------------------------------------------
/msg-templates/slack-ec2-garbage-collection-audit.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"EC2 Packer Builder Reaper Audit",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"Packer Builder Instance(s) found with age greater than 1 hour",
10 | "value":"{{ resources | selectattr('InstanceId') | map(attribute='InstanceId') | list }}"
11 | },
12 | {
13 | "title":"Account ID",
14 | "value":"{{ account_id }}"
15 | },
16 | {
17 | "title":"Region",
18 | "value":"{{ region }}"
19 | },
20 | {
21 | "title":"Action Description",
22 | "value":"All Packer Builder instances older than 1 hr have been deleted. This notification is informational only. No action is required on your part."
23 | }
24 | ]
25 | }
26 | ],
27 | "channel":"{{ recipient }}",
28 | "username":"Custodian"
29 | }
30 |
--------------------------------------------------------------------------------
/msg-templates/slack-elasticsearch-security-audit.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"ElasticSearch Security Audit",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"Info",
10 | "value":"An ES domain was found with access policy that is too permissive."
11 | },
12 | {
13 | "title":"Account",
14 | "value":"{{ account }}"
15 | },
16 | {
17 | "title":"Region",
18 | "value":"{{ region }}"
19 | },
20 | {
21 | "title":"Action Description",
22 | "value":"Email notification sent. See email for details."
23 | }
24 | ]
25 | }
26 | ],
27 | "channel":"{{ recipient }}",
28 | "username":"Custodian"
29 | }
30 |
--------------------------------------------------------------------------------
/msg-templates/slack-iam-policy-account-audit-summary.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"IAM Policy Audit - Summary",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"IAM policies found containing the account:* or account:EnableRegion action",
10 | "value":"{%- for resource in resources -%}
11 | {{ format_resource(resource, policy['resource']) }}
12 | {%- endfor -%}"
13 | },
14 | {
15 | "title":"Account ID",
16 | "value":"{{ account_id }}"
17 | },
18 | {
19 | "title":"Region",
20 | "value":"{{ region }}"
21 | },
22 | {
23 | "title":"Action Description",
24 | "value":"Email notification sent. "
25 | }
26 | ]
27 | }
28 | ],
29 | "channel":"{{ recipient }}",
30 | "username":"Custodian"
31 | }
32 |
--------------------------------------------------------------------------------
/msg-templates/slack-iam-policy-account-audit.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"IAM Policy Audit",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"IAM policy created or modified containing the account:* action or account:EnableRegion",
10 | "value":"{%- for resource in resources -%}
11 | {{ format_resource(resource, policy['resource']) }}
12 | {%- endfor -%}"
13 | },
14 | {
15 | "title":"Account ID",
16 | "value":"{{ account_id }}"
17 | },
18 | {
19 | "title":"Region",
20 | "value":"{{ region }}"
21 | },
22 | {
23 | "title":"Action Description",
24 | "value":"Email notification sent. "
25 | }
26 | ]
27 | }
28 | ],
29 | "channel":"{{ recipient }}",
30 | "username":"Custodian"
31 | }
32 |
--------------------------------------------------------------------------------
/msg-templates/slack-iam-user-DeleteAccessKey-audit.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"IAM User Access Key Audit",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"Access key Deleted for IAM User",
10 | "value":"{%- for resource in resources -%}
11 | {{ format_resource(resource, policy['resource']) }}
12 | {%- endfor -%}"
13 | },
14 | {
15 | "title":"AccessKeyId",
16 | "value":"{{ resources | selectattr('UserId') | map(attribute='UserId') | list }}"
17 | },
18 | {
19 | "title":"Changed by",
20 | "value":"{{ event.detail.userIdentity.userName }}"
21 | },
22 | {
23 | "title":"Account ID",
24 | "value":"{{ account_id }}"
25 | },
26 | {
27 | "title":"Region",
28 | "value":"{{ region }}"
29 | },
30 | {
31 | "title":"Action Description",
32 | "value":"This is informational only. No action required. "
33 | }
34 | ]
35 | }
36 | ],
37 | "channel":"{{ recipient }}",
38 | "username":"Custodian"
39 | }
40 |
--------------------------------------------------------------------------------
/msg-templates/slack-iam-user-DeleteLoginProfile-offboarding-audit:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"IAM User Management Console Audit",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"Management console disabled for IAM User",
10 | "value":"{%- for resource in resources -%}
11 | {{ format_resource(resource, policy['resource']) }}
12 | {%- endfor -%}"
13 | },
14 | {
15 | "title":"Management console disabled by",
16 | "value":"{{ event.detail.userIdentity.userName }}"
17 | },
18 | {
19 | "title":"Account ID",
20 | "value":"{{ account_id }}"
21 | },
22 | {
23 | "title":"Region",
24 | "value":"{{ region }}"
25 | },
26 | {
27 | "title":"Action Description",
28 | "value":"This is informational only. No action required."
29 | }
30 | ]
31 | }
32 | ],
33 | "channel":"{{ recipient }}",
34 | "username":"Custodian"
35 | }
36 |
--------------------------------------------------------------------------------
/msg-templates/slack-iam-user-UpdateAccessKey-audit.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"IAM User Access Key Audit",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"Disabled IAM User Found with Re-activated Access Key",
10 | "value":"{%- for resource in resources -%}
11 | {{ format_resource(resource, policy['resource']) }}
12 | {%- endfor -%}"
13 | },
14 | {
15 | "title":"Account ID",
16 | "value":"{{ account_id }}"
17 | },
18 | {
19 | "title":"Region",
20 | "value":"{{ region }}"
21 | },
22 | {
23 | "title":"Action Description",
24 | "value":"Email notification sent. "
25 | }
26 | ]
27 | }
28 | ],
29 | "channel":"{{ recipient }}",
30 | "username":"Custodian"
31 | }
32 |
--------------------------------------------------------------------------------
/msg-templates/slack-iam-user-UpdateAccessKey-offboarding-audit.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"IAM User Access Key Audit",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"Access key disabled for IAM User",
10 | "value":"{%- for resource in resources -%}
11 | {{ format_resource(resource, policy['resource']) }}
12 | {%- endfor -%}"
13 | },
14 | {
15 | "title":"Changed by",
16 | "value":"{{ event.detail.userIdentity.userName }}"
17 | },
18 | {
19 | "title":"Account ID",
20 | "value":"{{ account_id }}"
21 | },
22 | {
23 | "title":"Region",
24 | "value":"{{ region }}"
25 | },
26 | {
27 | "title":"Action Description",
28 | "value":"This is informational only. No action required. "
29 | }
30 | ]
31 | }
32 | ],
33 | "channel":"{{ recipient }}",
34 | "username":"Custodian"
35 | }
36 |
--------------------------------------------------------------------------------
/msg-templates/slack-iam-user-audit.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"IAM User(s) Audit",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"IAM Users not in the Ec2Instance Launchers Group but have AmazonEC2FullAccess",
10 | "value":"{%- for resource in resources -%}
11 | {{ format_resource(resource, policy['resource']) }}
12 | {%- endfor -%}"
13 | },
14 | {
15 | "title":"Account",
16 | "value":"{{ account }}"
17 | },
18 | {
19 | "title":"Region",
20 | "value":"{{ region }}"
21 | },
22 | {
23 | "title":"Action Description",
24 | "value":"Email notification sent."
25 | }
26 | ]
27 | }
28 | ],
29 | "channel":"{{ recipient }}",
30 | "username":"Custodian"
31 | }
32 |
--------------------------------------------------------------------------------
/msg-templates/slack-jinja2-filter-template.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian ACM Certificate Audit",
5 | "title":"ACM Certificate Audit",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"Description",
10 | "value":"ACM certificate(s) found nearing their expiration date <60 days"
11 | },
12 | {
13 | "title":"Domain Name(s)",
14 | "value":"{{ resources | selectattr('DomainName') | map(attribute='DomainName') | list }}"
15 | },
16 | {
17 | "title":"Expiration Date(s)",
18 | "value":"{{ resources | selectattr('NotAfter') | map(attribute='NotAfter') | list }}"
19 | },
20 | {
21 | "title":"Certificate Arn(s)",
22 | "value":"{{ resources | selectattr('CertificateArn') | map(attribute='CertificateArn') | list }}"
23 | },
24 | {
25 | "title":"Account ID",
26 | "value":"{{ account_id }}"
27 | },
28 | {
29 | "title":"Region",
30 | "value":"{{ region }}"
31 | },
32 | {
33 | "title":"Action Description",
34 | "value":"See email notification for details."
35 | }
36 | ]
37 | }
38 | ],
39 | "channel":"{{ recipient }}",
40 | "username":"Custodian"
41 | }
42 |
--------------------------------------------------------------------------------
/msg-templates/slack-mfa-audit-disable-access.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"IAM Users in Administrators Group with MFA Disabled",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"IAM User Name(s)",
10 | "value":"{{ resources | selectattr('UserName') | map(attribute='UserName') | list }}"
11 | },
12 | {
13 | "title":"Create Date",
14 | "value":"{{ resources | selectattr('CreateDate') | map(attribute='CreateDate') | list }}"
15 | },
16 | {
17 | "title":"Account",
18 | "value":"{{ account }}"
19 | },
20 | {
21 | "title":"Region",
22 | "value":"{{ region }}"
23 | },
24 | {
25 | "title":"Action Description",
26 | "value":"Console access disabled. Access keys deleted. Please work with user if access is still required and make sure MFA gets enabled.
27 | }
28 | ]
29 | }
30 | ],
31 | "channel":"{{ recipient }}",
32 | "username":"Custodian"
33 | }
34 |
--------------------------------------------------------------------------------
/msg-templates/slack-mfa-audit-reminder.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"Reminder to enable MFA",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"User Name(s)",
10 | "value":"{{ resources | selectattr('UserName') | map(attribute='UserName') | list }}"
11 | },
12 | {
13 | "title":"Create Date",
14 | "value":"{{ resources | selectattr('CreateDate') | map(attribute='CreateDate') | list }}"
15 | },
16 | {
17 | "title":"Account",
18 | "value":"{{ account }}"
19 | },
20 | {
21 | "title":"Region",
22 | "value":"{{ region }}"
23 | },
24 | {
25 | "title":"Action Description",
26 | "value":"If your user name is on this list, please enable MFA before access is disabled."
27 | },
28 | ]
29 | }
30 | ],
31 | "channel":"{{ recipient }}",
32 | "username":"Custodian"
33 | }
34 |
--------------------------------------------------------------------------------
/msg-templates/slack-mfa-audit.yml:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"Security Audit: Detected Admins with MFA Disabled",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"IAM User(s)",
10 | "value":"{%- for resource in resources -%}
11 | {{ format_resource(resource, policy['resource']) }}
12 | {%- endfor -%}"
13 | },
14 | {
15 | "title":"Account ID",
16 | "value":"{{ account_id }}"
17 | },
18 | {
19 | "title":"Action",
20 | "value":"Please work with user(s) to enable MFA."
21 | }
22 | ]
23 | }
24 | ],
25 | "channel":"{{ recipient }}",
26 | "username":"Custodian"
27 | }
28 |
--------------------------------------------------------------------------------
/msg-templates/slack-mfa-unused-audit.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"IAM Users in Administrators Group with MFA Disabled",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"Resources",
10 | "value":"{%- for resource in resources -%}
11 | {{ format_resource(resource, policy['resource']) }}
12 | {%- endfor -%}"
13 | },
14 | {
15 | "title":"Region",
16 | "value":"{{ region }}"
17 | },
18 | {
19 | "title":"Action Description",
20 | "value":"Console access disabled. Access keys deleted."
21 | },
22 | {
23 | "title":"Note",
24 | "value":"Users will need to contact IE Team to regain access."
25 | }
26 | ]
27 | }
28 | ],
29 | "channel":"{{ recipient }}",
30 | "username":"Custodian"
31 | }
32 |
--------------------------------------------------------------------------------
/msg-templates/slack-phd-issue.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Personal Health Dashboard (PHD) Operational Issue",
5 | "title":"Personal Health Dashboard (PHD) Operational Notification",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"Account ID",
10 | "value":"{{ account_id }}"
11 | },
12 | {
13 | "title":"Region",
14 | "value":"{{ region }}"
15 | },
16 | {
17 | "title":"Service(s)",
18 | "value":"{{ resources | selectattr('service') | map(attribute='service') | list }}"
19 | },
20 | {
21 | "title":"Action",
22 | "value":"See Personal Health Dashboard 'Open issues' tab @ phd.aws.amazon.com for more info. Note, you may need to click the View event log to see details."
23 | }
24 | ]
25 | }
26 | ],
27 | "channel":"{{ recipient }}",
28 | "username":"Custodian"
29 | }
30 |
--------------------------------------------------------------------------------
/msg-templates/slack-phd-notifications.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Personal Health Dashboard (PHD)",
5 | "title":"Personal Health Dashboard (PHD) Notification",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"Account ID",
10 | "value":"{{ account_id }}"
11 | },
12 | {
13 | "title":"Region",
14 | "value":"{{ region }}"
15 | },
16 | {
17 | "title":"Service(s)",
18 | "value":"{{ resources | selectattr('service') | map(attribute='service') | list }}"
19 | },
20 | {
21 | "title":"Action",
22 | "value":"See Personal Health Dashboard 'Other notifications' tab @ phd.aws.amazon.com for more info."
23 | }
24 | ]
25 | }
26 | ],
27 | "channel":"{{ recipient }}",
28 | "username":"Custodian"
29 | }
30 |
--------------------------------------------------------------------------------
/msg-templates/slack-public-instance-audit.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"EC2 Instance Public Audit",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"EC2 Instance was launched with Public IP and Public subnet",
10 | "value":"{%- for resource in resources -%}
11 | {{ format_resource(resource, policy['resource']) }}
12 | {%- endfor -%}"
13 | },
14 | {
15 | "title":"Account",
16 | "value":"{{ account }}"
17 | },
18 | {
19 | "title":"Region",
20 | "value":"{{ region }}"
21 | },
22 | {
23 | "title":"Action Description",
24 | "value":"Email notification sent containing KeyName."
25 | }
26 | ]
27 | }
28 | ],
29 | "channel":"{{ recipient }}",
30 | "username":"Custodian"
31 | }
32 |
--------------------------------------------------------------------------------
/msg-templates/slack-s3-prevent-bucket-creation.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"Request to Create New S3 Bucket Rejected",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"S3 Bucket Name",
10 | "value":"{%- for resource in resources -%}
11 | {{ format_resource(resource, policy['resource']) }}
12 | {%- endfor -%}"
13 | },
14 | {
15 | "title":"Account",
16 | "value":"{{ account }}"
17 | },
18 | {
19 | "title":"Region",
20 | "value":"{{ region }}"
21 | },
22 | {
23 | "title":"Action Description",
24 | "value":"Email notification sent."
25 | }
26 | ]
27 | }
28 | ],
29 | "channel":"{{ recipient }}",
30 | "username":"Custodian"
31 | }
32 |
--------------------------------------------------------------------------------
/msg-templates/slack-s3-public-audit.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"Public S3 Bucket Audit",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"S3 Bucket Name",
10 | "value":"{%- for resource in resources -%}
11 | {{ format_resource(resource, policy['resource']) }}
12 | {%- endfor -%}"
13 | },
14 | {
15 | "title":"Account",
16 | "value":"{{ account }}"
17 | },
18 | {
19 | "title":"Region",
20 | "value":"{{ region }}"
21 | },
22 | {
23 | "title":"Action Description",
24 | "value":"Email notification sent."
25 | }
26 | ]
27 | }
28 | ],
29 | "channel":"{{ recipient }}",
30 | "username":"Custodian"
31 | }
32 |
--------------------------------------------------------------------------------
/msg-templates/slack-s3-service-limit-audit.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"S3 Service Limit Audit",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"S3 Service Limit Threshold Exceeded:",
10 | "value":"It may be time to increase the S3 service limit or do some housekeeping."
11 | },
12 | {
13 | "title":"Account",
14 | "value":"{{ account }}"
15 | },
16 | {
17 | "title":"Region",
18 | "value":"{{ region }}"
19 | },
20 | {
21 | "title":"Action Description",
22 | "value":"Email notification sent."
23 | }
24 | ]
25 | }
26 | ],
27 | "channel":"{{ recipient }}",
28 | "username":"Custodian"
29 | }
30 |
--------------------------------------------------------------------------------
/msg-templates/slack-s3-target-bucket-audit.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"S3 Target Bucket Audit",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"Notifcation:",
10 | "value":"S3 buckets were found with non-compliant target bucket names."
11 | },
12 | {
13 | "title":"Account",
14 | "value":"{{ account }}"
15 | },
16 | {
17 | "title":"Region",
18 | "value":"{{ region }}"
19 | },
20 | {
21 | "title":"Action Description",
22 | "value":"Email notification sent."
23 | }
24 | ]
25 | }
26 | ],
27 | "channel":"{{ recipient }}",
28 | "username":"Custodian"
29 | }
30 |
--------------------------------------------------------------------------------
/msg-templates/slack-subnet-ip-address-usage-audit.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Subnet IP Address Usage Audit",
5 | "title":"Subnet IP Address Usage Audit",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"Account ID",
10 | "value":"{{ account_id }}"
11 | },
12 | {
13 | "title":"Region",
14 | "value":"{{ region }}"
15 | },
16 | {
17 | "title":"SubnetId(s)",
18 | "value":"{{ resources | selectattr('SubnetId') | map(attribute='SubnetId') | list }}"
19 | },
20 | {
21 | "title":"AvailableIpAddressCount(s)",
22 | "value":"{{ resources | selectattr('AvailableIpAddressCount') | map(attribute='AvailableIpAddressCount') | list }}"
23 | },
24 | {
25 | "title":"CidrBlock(s)",
26 | "value":"{{ resources | selectattr('CidrBlock') | map(attribute='CidrBlock') | list }}"
27 | },
28 | {
29 | "title":"AvailabilityZone(s)",
30 | "value":"{{ resources | selectattr('AvailabilityZone') | map(attribute='AvailabilityZone') | list }}"
31 | },
32 | {
33 | "title":"Action Description",
34 | "value":"See email notification for more details."
35 | }
36 | ]
37 | }
38 | ],
39 | "channel":"{{ recipient }}",
40 | "username":"Custodian"
41 | }
42 |
--------------------------------------------------------------------------------
/msg-templates/slack-team-tag-ec2-audit.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"EC2 Team Tag Audit",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"Instance(s) found with absent or empty Team tag",
10 | "value":"{%- for resource in resources -%}
11 | {{ format_resource(resource, policy['resource']) }}
12 | {%- endfor -%}"
13 | },
14 | {
15 | "title":"Account ID",
16 | "value":"{{ account_id }}"
17 | },
18 | {
19 | "title":"Region",
20 | "value":"{{ region }}"
21 | },
22 | {
23 | "title":"Action Description",
24 | "value":"Email notification sent containing KeyName(s)."
25 | }
26 | ]
27 | }
28 | ],
29 | "channel":"{{ recipient }}",
30 | "username":"Custodian"
31 | }
32 |
--------------------------------------------------------------------------------
/msg-templates/slack-team-tag-s3-audit.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"S3 Team Tag Audit",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"Buckets(s) found with absent or empty Team tag",
10 | "value":"{%- for resource in resources -%}
11 | {{ format_resource(resource, policy['resource']) }}
12 | {%- endfor -%}"
13 | },
14 | {
15 | "title":"Account ID",
16 | "value":"{{ account_id }}"
17 | },
18 | {
19 | "title":"Region",
20 | "value":"{{ region }}"
21 | },
22 | {
23 | "title":"Action Description",
24 | "value":"Email notification sent."
25 | }
26 | ]
27 | }
28 | ],
29 | "channel":"{{ recipient }}",
30 | "username":"Custodian"
31 | }
32 |
--------------------------------------------------------------------------------
/msg-templates/slack-termination-protection-audit.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"EC2 Termination Protection Audit",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"White Listed EC2 Instances Found with Termination Protection Disabled:",
10 | "value":"{%- for resource in resources -%}
11 | {{ format_resource(resource, policy['resource']) }}
12 | {%- endfor -%}"
13 | },
14 | {
15 | "title":"Account",
16 | "value":"{{ account }}"
17 | },
18 | {
19 | "title":"Region",
20 | "value":"{{ region }}"
21 | },
22 | {
23 | "title":"Action Description",
24 | "value":"Email notification sent."
25 | }
26 | ]
27 | }
28 | ],
29 | "channel":"{{ recipient }}",
30 | "username":"Custodian"
31 | }
32 |
--------------------------------------------------------------------------------
/msg-templates/slack-unused-sgroup-audit.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"Security Group Audit",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"Unused Security Groups that match '*wizard':",
10 | "value":"{%- for resource in resources -%}
11 | {{ format_resource(resource, policy['resource']) }}
12 | {%- endfor -%}"
13 | },
14 | {
15 | "title":"Account",
16 | "value":"{{ account }}"
17 | },
18 | {
19 | "title":"Region",
20 | "value":"{{ region }}"
21 | },
22 | {
23 | "title":"Action Description",
24 | "value":"Unused security groups deleted."
25 | },
26 | {
27 | "title":"Note:",
28 | "value":"Check email for more details."
29 | }
30 | ]
31 | }
32 | ],
33 | "channel":"{{ recipient }}",
34 | "username":"Custodian"
35 | }
36 |
--------------------------------------------------------------------------------
/msg-templates/slack_delete-marked.html.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Garbage Collection",
5 | "title":"Unused Security Groups",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"Resources",
10 | "value":"{%- for resource in resources -%}
11 | {{ format_resource(resource, policy['resource']) }}
12 | {%- endfor -%}"
13 | },
14 | {
15 | "title":"Region",
16 | "value":"{{ region }}"
17 | },
18 | {
19 | "title":"Status",
20 | "value":"Unused security groups marked for deletion successfully deleted."
21 | }
22 | ]
23 | }
24 | ],
25 | "channel":"{{ recipient }}",
26 | "username":"Custodian"
27 | }
28 |
--------------------------------------------------------------------------------
/msg-templates/slack_ec2-public-whitelist.j2:
--------------------------------------------------------------------------------
1 | {
2 | "attachments":[
3 | {
4 | "fallback":"Cloud Custodian Policy Violation",
5 | "title":"Detected EC2 instance launched in public subnet",
6 | "color":"danger",
7 | "fields":[
8 | {
9 | "title":"Resources",
10 | "value":"{%- for resource in resources -%}
11 | {{ format_resource(resource, policy['resource']) }}
12 | {%- endfor -%}"
13 | },
14 | {
15 | "title":"Region",
16 | "value":"{{ region }}"
17 | },
18 | {
19 | "title":"Action Description",
20 | "value":"EC2 instance was immediately terminated"
21 | },
22 | {
23 | "title":"Note",
24 | "value":"Check CloudTrail to correlate who launched instance"
25 | }
26 | ]
27 | }
28 | ],
29 | "channel":"{{ recipient }}",
30 | "username":"Custodian"
31 | }
32 |
--------------------------------------------------------------------------------
/policies/acm-certificate-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: acm-certificate-audit
3 | resource: acm-certificate
4 | description: |
5 | Retrieve list of ACM certificates and
6 | send notifications if expiration reaches
7 | given threshold
8 | filters:
9 | - or:
10 | - "tag:Audit": absent
11 | - "tag:Audit": empty
12 | - type: value
13 | key: Name
14 | op: regex
15 | value: ".*"
16 | - type: value
17 | key: NotAfter
18 | op: less-than
19 | value_type: expiration
20 | value: 60
21 | mode:
22 | type: periodic
23 | role: arn:aws:iam::XXXXXXXXXXXX:role/CloudCustodian
24 | schedule: "rate(12 days)"
25 | packages: [boto3, botocore, urllib3]
26 | actions:
27 | - type: post-finding
28 | severity_normalized: 10
29 | types:
30 | - "Software and Configuration Checks/AWS Security Best Practices"
31 | - type: notify
32 | template: acm-certificate-audit.html
33 | slack_template: slack-acm-certificate-audit
34 | template_format: 'html'
35 | priority_header: '5'
36 | subject: 'ACM Certificate about to expire'
37 | to:
38 | - cloudcustodianadmins@company.com
39 | - slack://#my-slack-channel
40 | owner_absent_contact:
41 | - cloudcustodianadmin@company.com
42 | transport:
43 | type: sqs
44 | queue: https://sqs.us-east-1.amazonaws.com/XXXXXXXXXXXX/cloud-cloudcustodian
45 |
--------------------------------------------------------------------------------
/policies/admin-group.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: iam-users-in-admin-group
3 | resource: iam-user
4 | description: |
5 | Retrieve list of IAM users in the group named 'Administrators'.
6 | filters:
7 | - type: group
8 | key: GroupName
9 | value: Administrators
10 |
--------------------------------------------------------------------------------
/policies/auto-team-tag.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: tag-team-infra
3 | resource: ec2
4 | comment: |
5 | Cloud Custodian EC2 Team tag based on the owner
6 | filters:
7 | - "tag:Team": absent
8 | - type: value
9 | key: "tag:Owner"
10 | value: (.*david\.lin|.*john\.doe)
11 | op: regex
12 | actions:
13 | - type: tag
14 | key: "Team"
15 | value: "InfrastuctureTeam"
16 | - name: tag-team-it
17 | resource: ec2
18 | comment: |
19 | Cloud Custodian EC2 Team tag based on the owner
20 | filters:
21 | - "tag:Team": absent
22 | - type: value
23 | key: "tag:Owner"
24 | value: (.*harry\.potter)
25 | op: regex
26 | actions:
27 | - type: tag
28 | key: "Team"
29 | value: "WizardsTeam"
30 |
--------------------------------------------------------------------------------
/policies/autotag-owner.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: autotag-copy
3 | resource: ec2
4 | comment: |
5 | Copy autotag to test-owner if absent
6 | filters:
7 | - "tag:AutoTag_Creator": not-null
8 | - or:
9 | - "tag:Owner": empty
10 | - "tag:Owner": absent
11 | actions:
12 | - type: copy-tag
13 | current_key: AutoTag_Creator
14 | new_key: Owner
15 |
16 | - name: strip-tag
17 | resource: ec2
18 | comment: |
19 | Strip Copy autotag to owner if absent
20 | filters:
21 | - "tag:Owner": not-null
22 | actions:
23 | - type: normalize-tag
24 | key: Owner
25 | action: remove
26 | value: "arn:aws:iam::123456789012:"
27 |
--------------------------------------------------------------------------------
/policies/c7n-org/CustomAccount/README.md:
--------------------------------------------------------------------------------
1 | # Notes
2 | These policies send Slack and email notifications when an IAM user's console management gets enabled or access keys re-activated.
3 | Please remember to update c7n_mailer so the associated msg templates get updated.
4 |
--------------------------------------------------------------------------------
/policies/c7n-org/CustomAccount/iam-user-CreateLoginProfile.yml:
--------------------------------------------------------------------------------
1 | policies:
2 |
3 | - name: iam-user-CreateLoginProfile-audit
4 | resource: iam-user
5 | description: |
6 | Cloud Custodian IAM User Management Console Event Audit
7 | comment: |
8 | Monitor re-activation of IAM user management console
9 | email/Slack notification if contains account:* action
10 | mode:
11 | type: cloudtrail
12 | events:
13 | - source: iam.amazonaws.com
14 | event: CreateLoginProfile
15 | ids: 'requestParameters.userName'
16 | filters:
17 | - or:
18 | - type: value
19 | key: UserName
20 | value: 'iam-username-1'
21 | - type: value
22 | key: UserName
23 | value: 'iam-username-2'
24 |
25 | actions:
26 | - type: notify
27 | template: iam-user-CreateLoginProfile-audit.html
28 | slack_template: slack-iam-user-CreateLoginProfile-audit
29 | template_format: 'html'
30 | priority_header: '5'
31 | subject: 'Security Audit: IAM User Console Access Found Reenabled in Account'
32 | to:
33 | - name@company.com
34 | - slack://#slack-channel-goes-here
35 | owner_absent_contact:
36 | - name@company.com
37 | transport:
38 | type: sqs
39 | queue: https://sqs.us-east-1.amazonaws.com/XXXXXXXXXXXX/cloud-cloudcustodian
40 |
--------------------------------------------------------------------------------
/policies/c7n-org/CustomAccount/iam-user-UpdateAccessKey-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 |
3 | - name: iam-user-UpdateAccessKey-audit
4 | resource: iam-user
5 | description: |
6 | Cloud Custodian IAM User UpdateAccessKey Event Audit
7 | comment: |
8 | Monitor re-activation of IAM user access keys
9 | email/Slack notification if contains account:* action
10 | mode:
11 | type: cloudtrail
12 | events:
13 | - source: iam.amazonaws.com
14 | event: UpdateAccessKey
15 | ids: 'requestParameters.userName'
16 | filters:
17 | - type: event
18 | key: 'detail.requestParameters.status'
19 | value: 'Active'
20 | - or:
21 | - type: value
22 | key: UserName
23 | value: 'neo'
24 | - type: value
25 | key: UserName
26 | value: 'trinity'
27 | actions:
28 | - type: notify
29 | template: iam-user-UpdateAccessKey-audit.html
30 | slack_template: slack-iam-user-UpdateAccessKey-audit
31 | template_format: 'html'
32 | priority_header: '5'
33 | subject: 'Security Audit: IAM User Access Key Found Re-activated in Production Account'
34 | to:
35 | - username@company.com
36 | - slack://#my-slack-channel-name
37 | owner_absent_contact:
38 | - username@company.com
39 | transport:
40 | type: sqs
41 | queue: https://sqs.us-east-1.amazonaws.com/XXXXXXXXXXXX/cloud-cloudcustodian
42 |
--------------------------------------------------------------------------------
/policies/c7n-org/acm-certificate-cross-account-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: acm-certificate-cross-account-audit
3 | resource: acm-certificate
4 | description: |
5 | Retrieve list of ACM certificates and
6 | send notifications if expiration reaches
7 | given threshold
8 | filters:
9 | - or:
10 | - "tag:Audit": absent
11 | - "tag:Audit": empty
12 | - type: value
13 | key: Name
14 | op: regex
15 | value: ".*"
16 | - type: value
17 | key: NotAfter
18 | op: less-than
19 | value_type: expiration
20 | value: 60
21 | mode:
22 | type: periodic
23 | schedule: "rate(12 days)"
24 | actions:
25 | # - type: post-finding
26 | # severity_normalized: 10
27 | # types:
28 | # - "Software and Configuration Checks/AWS Security Best Practices"
29 | - type: notify
30 | template: acm-certificate-audit.html
31 | slack_template: slack-acm-certificate-audit
32 | template_format: 'html'
33 | priority_header: '5'
34 | subject: 'ACM Certificate Audit'
35 | to:
36 | - cloudcustodianadmins@company.com
37 | - slack://
38 | owner_absent_contact:
39 | - cloudcustodianadmins@company.com
40 | transport:
41 | type: sqs
42 | queue: https://sqs.us-east-1.amazonaws.com/123456789012/cloud-cloudcustodian
43 |
--------------------------------------------------------------------------------
/policies/c7n-org/all-accounts.yml:
--------------------------------------------------------------------------------
1 | accounts:
2 | - account_id: '1234567890'
3 | email: email@address.com
4 | name: Sandbox
5 | role: arn:aws:iam::1234567890:role/OrganizationAccountAccessRole
6 | tags:
7 | - team:sandbox
8 |
--------------------------------------------------------------------------------
/policies/c7n-org/app-elb.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: app-elb-filter-policy
3 | resource: app-elb
4 | description: |
5 | Retrieve list of Network and Application Load Balancers
6 | filters:
7 | - or:
8 | - "tag:Audit": absent
9 | - "tag:Audit": empty
10 | - type: value
11 | key: Name
12 | op: regex
13 | value: ".*"
14 |
--------------------------------------------------------------------------------
/policies/c7n-org/cfn-garbage-collection-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: cfn-garbage-collection-audit
3 | resource: aws.cfn
4 | description: |
5 | Cloud Custodian CloudFormation Stack Garbage Collection
6 | comments: |
7 | Retrieve Delete old CloudFormation stacks matching given string
8 | mode:
9 | type: periodic
10 | schedule: "rate(1 day)"
11 | role: arn:aws:iam::111111111111:role/cloud_custodian_role_in_cross_account
12 | filters:
13 | - type: value
14 | key: StackName
15 | op: regex
16 | value: ".*your_string_goes_here.*"
17 | - type: value
18 | key: CreationTime
19 | op: greater-than
20 | value_type: age
21 | value: 3
22 | actions:
23 | - type: delete
24 | force: true
25 | - type: post-finding
26 | severity_normalized: 10
27 | types:
28 | - "Software and Configuration Checks/AWS Security Best Practices"
29 | - type: notify
30 | template: cfn-garbage-collection-audit.html
31 | slack_template: slack-cfn-garbage-collection-audit
32 | template_format: 'html'
33 | priority_header: '5'
34 | subject: 'CloudFormation Garbage Collection Audit'
35 | to:
36 | - custodianadmins@email.com
37 | - slack://#channel_name
38 | owner_absent_contact:
39 | - custodianadmins@email.com
40 | transport:
41 | type: sqs
42 | queue: https://sqs.us-east-1.amazonaws.com/111111111111/cloud-cloudcustodian
43 |
--------------------------------------------------------------------------------
/policies/c7n-org/cheatsheet.txt:
--------------------------------------------------------------------------------
1 | ===========================
2 | Path to orgaccounts.py file
3 | ===========================
4 | /home/ubuntu/cloud-custodian/tools/c7n_org/scripts/orgaccounts.py
5 | How: sudo find / -name orgaccounts.py
6 |
7 | python orgaccounts.py -f accounts.yml
8 |
9 | ======================================
10 | Security Audit for Public IP Addresses
11 | ======================================
12 | custodian run -s output test-elastic-ip-all.yml --region all
13 | custodian report -s output test-elastic-ip-all.yml --region all --format grid > elastic-ip-all.log
14 |
15 | custodian run -s output test-ec2-publicipaddress-all.yml --region all
16 | custodian report -s output test-ec2-publicipaddress-all.yml --region all --format grid --field PublicIp=PublicIp > ec2-public-ip.log
17 |
18 | Tip: Copy to clipboard and reduce font size
19 |
20 |
21 |
22 | =======================================
23 | Launch c7n-org based on tags and region
24 | =======================================
25 | c7n-org run -s output -c all-accounts.yml -u iam-group.yml -t team:tarsadmin --region us-east-1
26 | c7n-org run -s output -c all-accounts.yml -u iam-role.yml -t team:tarsadmin --region us-east-1
27 | c7n-org run -s output -c all-accounts.yml -u rest-api.yml -t team:tarsadmin --region all
28 | c7n-org run -s output -c all-accounts.yml -u app-elb.yml -t team:tarsadmin --region all
29 | c7n-org run -s output -c all-accounts.yml -u elb.yml -t team:tarsadmin --region all
30 | c7n-org run -s output -c all-accounts.yml -u iot.yml -t team:tarsadmin --region all
31 | c7n-org run -s output -c all-accounts.yml -u secrets-manager.yml -t team:tarsadmin --region all
32 | c7n-org run -s output -c all-accounts.yml -u efs.yml -t team:tarsadmin --region all
33 | c7n-org run -s output -c all-accounts.yml -u ecs.yml -t team:tarsadmin --region all
34 | c7n-org run -s output -c all-accounts.yml -u ebs.yml -t team:tarsadmin --region all
35 | c7n-org run -s output -c all-accounts.yml -u sns.yml -t team:tarsadmin --region all
36 | c7n-org run -s output -c all-accounts.yml -u ecr.yml -t team:tarsadmin --region all
37 | c7n-org run -s output -c all-accounts.yml -u dynamodb-table.yml -t team:tarsadmin --region all
38 | c7n-org run -s output -c all-accounts.yml -u lambda.yml -t team:tarsadmin --region all
39 | c7n-org run -s output -c all-accounts.yml -u iam.yml -t team:tarsadmin
40 | c7n-org run -s output -c accounts.yml -u public-instance-audit.yml -t team:sandbox --region us-west-2
41 | c7n-org run -s output -c accounts.yml -u s3-prevent-bucket-creation.yml -t team:sandbox
42 |
43 |
44 | ===================
45 | c7n Report Examples
46 | ===================
47 |
48 | custodian report -s output test.yml --field NetworkInterfaces.VpcId=VpcId --field SubnetId=SubnetId --field KeyName=KeyName --field tag:AutoTag_Creator=tag:AutoTag_Creator
49 |
50 | =======================
51 | c7n-org Report Examples
52 | =======================
53 | c7n-org report -c all-accounts.yml -u iam-group.yml -s output --field GroupName=GroupName --field GroupId=GroupId --field Arn=Arn --field CreateDate=CreateDate --region us-east-1
54 | c7n-org report -c all-accounts.yml -u iam-role.yml -s output --field RoleName=RoleName --field Description=Description --field Arn=Arn --field CreateDate=CreateDate --region us-east-1
55 | c7n-org report -c all-accounts.yml -u rest-api.yml -s output --field name=name --field id=id --field description=description --field endpointConfiguration[0].types=endpointConfiguration[0].types --field createdDate=createdDate --no-default-fields --region all
56 | c7n-org report -c all-accounts.yml -u app-elb.yml -s output --field LoadBalancerName=LoadBalancerName --field State.Code=State.Code --field DNSName=DNSName --field Type=Type --field Scheme=Scheme --field LoadBalancerName=LoadBalancerName --field CreatedTime=CreatedTime --no-default-fields
57 | c7n-org report -c all-accounts.yml -u iot.yml -s output --field thingName=thingName --field thingTypeName=thingTypeName --field thingArn=thingArn --no-default-fields --region all
58 | c7n-org report -c all-accounts.yml -u secrets-manager.yml -s output --field Name=Name --field Tags.Key=Tags[0].Key --field Tags.Value=Tags[0].Value --field LastChangedDate=LastChangedDate --no-default-fields --region all
59 | c7n-org report -c all-accounts.yml -u efs.yml -s output --field FileSystemId=FileSystemId --field NumberOfMountTargets=NumberOfMountTargets --field PerformanceMode=PerformanceMode --field SizeInBytes=SizeInBytes.Value --field Tag:Key=Tags[0].Key --field Tag:Value=Tags[0].Value --field CreationTime=CreationTime --no-default-fields --region all
60 | c7n-org report -c all-accounts.yml -u ecs.yml -s output --field serviceName=serviceName --field status=status --field launchType=launchType --field createdAt=createdAt --field deployments.taskDefinition=deployments[0].taskDefinition --field deployments.updatedAt=deployments[0].updatedAt --no-default-fields --region all
61 | c7n-org report -c all-accounts.yml -u ebs.yml -s output -field VolumeId=VolumeId --field State=State --field Size=Size --field Attachments.InstanceId=Attachments[0].InstanceId --field Attachments.State=Attachments[0].State --field Attachments.DeleteOnTermination=Attachments[0].DeleteOnTermination --field Attachments.Device=Attachments[0].Device --field VolumeType=VolumeType --field CreateTime=CreateTime --no-default-fields --region all
62 | c7n-org report -c all-accounts.yml -u sns.yml -s output --no-default-fields --region all
63 | c7n-org report -c all-accounts.yml -u ecr.yml -s output --no-default-fields --field repositoryName=repositoryName --field createdAt=createdAt --region all
64 | c7n-org report -c all-accounts.yml -u dynamodb-table.yml -s output --no-default-fields --field TableName=TableName --field region=region --field ItemCount=ItemCount --field TableSizeBytes=TableSizeBytes --field TableStatus=TableStatus --field LatestStreamArn=LatestStreamArn --region all
65 | c7n-org report -c all-accounts.yml -u lambda.yml -s output --no-default-fields --field FunctionName=FunctionName --field region=region --field LastModified=LastModified --region all
66 |
67 |
68 | ========================
69 | Launch c7n-mailer Lambda
70 | ========================
71 | c7n-mailer --config /home/ubuntu/cloudcustodian/mailer/mailer.yml --update-lambda && custodian run -c test.yml -s .
72 |
73 |
74 | ============================================
75 | Finding Path to c7n-mailer Default Templates
76 | ============================================
77 | find ~/ -type f -name "default.html.j2" (for email)
78 | find ~/ -type f -name "slack_default.j2" (for Slack)
79 |
80 | /home/ubuntu/cloud-custodian/tools/c7n_mailer/msg-templates/
81 |
82 | ===============================
83 | Example Custodian Custom Report
84 | ===============================
85 | custodian report -s output owner-tag-audit.yml --field State=State --field Name=tag:Name --field InstanceId=InstanceId --field Team=tag:Team --field Owner=tag:Owner --no-default-fields
86 |
87 | Note: Sometimes a field will have a value preceded with 'tag:' and other times without. Trial and error. :)
88 |
89 |
90 | Another example using JMESpath query (i.e. JSON filtering)
91 | custodian report -s output vpn.yml --no-default --field Name=tag:Name --field VpnId=VpnConnectionId --format grid --field CustomerGwId=CustomerGatewayId --field OutsideIp="VgwTelemetry[0].OutsideIpAddress" --field Status="VgwTelemetry[0].Status" --field LastStatusChange="VgwTelemetry[0].LastStatusChange"
92 |
93 |
94 | ==========================
95 | Get Jenkins Version Number
96 | ==========================
97 | java -jar jenkins-cli.jar -s http://localhost:8080/ version
98 |
99 |
100 | ===================
101 | Useful Git Commands
102 | ===================
103 | git clone -b mailer-test https://github.com/LykinsN/cloud-custodian.git
104 | git pull (from directory branch was cloned)
105 | git branch -a (to view branch info)
106 |
107 | ============================
108 | c7n-mailer Developer Install
109 | ============================
110 | $ git clone https://github.com/capitalone/cloud-custodian
111 | $ cd cloud-custodian
112 | $ virtualenv c7n_mailer
113 | $ source c7n_mailer/bin/activate
114 | $ cd tools/c7n_mailer
115 | $ pip install -r requirements.txt
116 | $ python setup.py develop
117 |
118 | ==============================
119 | Deleting Cloud Custodian Cache
120 | ==============================
121 | rm ~/.cache/cloud-custodian.cache
122 |
123 |
124 | ====================================================
125 | AWS CLI to Create Dummy Security Groups (IE Sandbox)
126 | ====================================================
127 | Create security groups in David's VPC IE Sandbox
128 | export AWS_PROFILE=iesandbox
129 | aws ec2 create-security-group --group-name launch-wizard-10 --description "david.lin.ctr security group" --vpc-id vpc-2ea22555
130 | aws ec2 create-security-group --group-name launch-wizard-11 --description "david.lin.ctr security group" --vpc-id vpc-2ea22555
131 | aws ec2 create-security-group --group-name launch-wizard-12 --description "david.lin.ctr security group" --vpc-id vpc-2ea22555
132 | aws ec2 create-security-group --group-name launch-wizard-13 --description "david.lin.ctr security group" --vpc-id vpc-2ea22555
133 | aws ec2 create-security-group --group-name launch-wizard-14 --description "david.lin.ctr security group" --vpc-id vpc-2ea22555
134 | aws ec2 create-security-group --group-name launch-wizard-15 --description "david.lin.ctr security group" --vpc-id vpc-2ea22555
135 |
136 | ================================================
137 | AWS CLI to Create Dummy Security Groups (TRI-NA)
138 | ================================================
139 | Create security groups in TRI-NA
140 | export AWS_PROFILE=default
141 | aws ec2 create-security-group --group-name launch-wizard-abc --description "david.lin.ctr security group" --vpc-id vpc-b7407ed3
142 | aws ec2 create-security-group --group-name launch-wizard-def --description "david.lin.ctr security group" --vpc-id vpc-b7407ed3
143 | aws ec2 create-security-group --group-name launch-wizard-fhi --description "david.lin.ctr security group" --vpc-id vpc-b7407ed3
144 | aws ec2 create-security-group --group-name launch-wizard-jkl --description "david.lin.ctr security group" --vpc-id vpc-b7407ed3
145 | aws ec2 create-security-group --group-name launch-wizard-mno --description "david.lin.ctr security group" --vpc-id vpc-b7407ed3
146 | aws ec2 create-security-group --group-name launch-wizard-pqr --description "david.lin.ctr security group" --vpc-id vpc-b7407ed3
147 |
148 | =============
149 | Custom Report
150 | =============
151 | custodian report --format grid -s output public-instance-whitelist.yml --field KeyName=KeyName --field PublicIpAddress=PublicIpAddress --no-default-fields --field InstanceId=InstanceId --field VpcId=VpcId --field tag:SubnetId=SubnetId
152 |
--------------------------------------------------------------------------------
/policies/c7n-org/copy-instance-tags.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: copy-instance-tags
3 | resource: ebs
4 | description: |
5 | Cloud Custodian Copy Instance Tag to Volume
6 | comment: |
7 | Copy instance tags to respective instance's ebs volume.
8 | mode:
9 | type: periodic
10 | role: arn:aws:iam::1234567890:role/CloudCustodian
11 | schedule: "rate(15 minutes)"
12 | filters:
13 | - type: value
14 | key: "Attachments[0].Device"
15 | value: not-null
16 | actions:
17 | - type: copy-instance-tags
18 | tags:
19 | - Name
20 | - type: copy-instance-tags
21 | tags:
22 | - Owner
23 | - type: copy-instance-tags
24 | tags:
25 | - Team
26 | - type: copy-instance-tags
27 | tags:
28 | - Backup
29 |
30 |
--------------------------------------------------------------------------------
/policies/c7n-org/dynamodb-table.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: dynamodb-table-filter-policy
3 | resource: dynamodb-table
4 | description: |
5 | Retrieve list of DynamoDB tables that match regex.
6 | filters:
7 | - or:
8 | - "tag:Audit": absent
9 | - "tag:Audit": empty
10 | - type: value
11 | key: Name
12 | op: regex
13 | value: ".*"
14 |
--------------------------------------------------------------------------------
/policies/c7n-org/ebs.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: ebs-filter-policy
3 | resource: ebs
4 | description: |
5 | Retrieve list of EBS that match regex.
6 | filters:
7 | - or:
8 | - "tag:Audit": absent
9 | - "tag:Audit": empty
10 | - type: value
11 | key: Name
12 | op: regex
13 | value: ".*"
14 |
--------------------------------------------------------------------------------
/policies/c7n-org/ecr.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: ecr-filter-policy
3 | resource: ecr
4 | description: |
5 | Retrieve list of ECR functions that match regex.
6 | filters:
7 | - or:
8 | - "tag:Audit": absent
9 | - "tag:Audit": empty
10 | - type: value
11 | key: Name
12 | op: regex
13 | value: ".*"
14 |
--------------------------------------------------------------------------------
/policies/c7n-org/ecs.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: ecs-filter-policy
3 | resource: ecs-service
4 | description: |
5 | Retrieve list of ECS clusters
6 | filters:
7 | - or:
8 | - "tag:Audit": absent
9 | - "tag:Audit": empty
10 |
--------------------------------------------------------------------------------
/policies/c7n-org/efs.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: efs-filter-policy
3 | resource: efs
4 | description: |
5 | Retrieve list of EFS that match regex.
6 | filters:
7 | - or:
8 | - "tag:Audit": absent
9 | - "tag:Audit": empty
10 | - type: value
11 | key: Name
12 | op: regex
13 | value: ".*"
14 |
--------------------------------------------------------------------------------
/policies/c7n-org/elasticip-address-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: elastic-ip
3 | resource: elastic-ip
4 | description: |
5 | Cloud Custodian Elastic IP Audit
6 | comments: |
7 | Retrieve info
8 | filters:
9 | - type: value
10 | key: PublicIp
11 | value: "x.x.x.x"
12 |
--------------------------------------------------------------------------------
/policies/c7n-org/elb.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: elb-filter-policy
3 | resource: elb
4 | description: |
5 | Retrieve list of Classic ELBs
6 | filters:
7 | - or:
8 | - "tag:Audit": absent
9 | - "tag:Audit": empty
10 | - type: value
11 | key: Name
12 | op: regex
13 | value: ".*"
14 |
--------------------------------------------------------------------------------
/policies/c7n-org/es.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: es
3 | resource: elasticsearch
4 | description: |
5 | Cloud Custodian Elasticsearch
6 | comments: |
7 | Retrieve Elasticsearch Attributes
8 | filters:
9 | - or:
10 | - "tag:Name": empty
11 | - not:
12 | - "tag:Name": empty
13 |
--------------------------------------------------------------------------------
/policies/c7n-org/iam-group.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: iam-group-filter-policy
3 | resource: iam-group
4 | description: |
5 | Retrieve list of IAM groups
6 | filters:
7 | - or:
8 | - "tag:Audit": absent
9 | - "tag:Audit": empty
10 | - type: value
11 | key: Name
12 | op: regex
13 | value: ".*"
14 |
--------------------------------------------------------------------------------
/policies/c7n-org/iam-mfa-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: iam-mfa-audit
3 | description: |
4 | Cloud Custodian IAM User MFA Audit
5 | comments: |
6 | Retrieve list of all IAM users in the group 'Administrators'
7 | who have not enabled MFA and send notifications.
8 | resource: iam-user
9 | mode:
10 | type: periodic
11 | schedule: "rate(1 day)"
12 | filters:
13 | - not:
14 | - type: credential
15 | key: mfa_active
16 | value: true
17 | - type: group
18 | key: GroupName
19 | value: Administrators
20 | actions:
21 | - type: notify
22 | template: mfa-audit.html
23 | template_format: 'html'
24 | slack_template: slack-mfa-audit
25 | priority_header: '5'
26 | subject: 'Cloud Custodian: IAM User Admins Audit'
27 | to:
28 | - custodianadmins@email.com
29 | - slack://#test-alerts
30 | transport:
31 | type: sqs
32 | queue: https://sqs.us-east-1.amazonaws.com/111111111111/cloud-cloudcustodian
33 |
--------------------------------------------------------------------------------
/policies/c7n-org/iam-role.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: iam-role-filter-policy
3 | resource: iam-role
4 | description: |
5 | Retrieve list of IAM roles
6 | filters:
7 | - or:
8 | - "tag:Audit": absent
9 | - "tag:Audit": empty
10 | - type: value
11 | key: Name
12 | op: regex
13 | value: ".*"
14 |
--------------------------------------------------------------------------------
/policies/c7n-org/iam.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: iam-user-filter-policy
3 | resource: iam-user
4 | description: |
5 | Retrieve list of IAM users that match regex.
6 | filters:
7 | - type: value
8 | key: UserName
9 | op: regex
10 | value: ".*"
11 |
--------------------------------------------------------------------------------
/policies/c7n-org/iot.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: iot-filter-policy
3 | resource: iot
4 | description: |
5 | Retrieve list of Secrets
6 | filters:
7 | - or:
8 | - "tag:Audit": absent
9 | - "tag:Audit": empty
10 | - type: value
11 | key: Name
12 | op: regex
13 | value: ".*"
14 |
--------------------------------------------------------------------------------
/policies/c7n-org/lambda-get-function-list.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: lambda-filter-policy
3 | resource: lambda
4 | description: |
5 | Retrieve list of Lambda functions that match regex.
6 | filters:
7 | - type: value
8 | key: FunctionName
9 | op: regex
10 | value: .*acm.*
11 |
--------------------------------------------------------------------------------
/policies/c7n-org/lambda.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: lambda-filter-policy
3 | resource: lambda
4 | description: |
5 | Retrieve list of Lambda functions that match regex.
6 | filters:
7 | - or:
8 | - "tag:Audit": absent
9 | - "tag:Audit": empty
10 | - type: value
11 | key: Name
12 | op: regex
13 | value: ".*"
14 |
--------------------------------------------------------------------------------
/policies/c7n-org/public-instance-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: public-instance-audit
3 | resource: ec2
4 | description: |
5 | Cloud Custodian Public Instance Audit
6 | comments: |
7 | Retrieve list of all instances that
8 | - are not in whitelist
9 | - attached to a public subnet
10 | - have public IP address
11 | mode:
12 | type: ec2-instance-state
13 | events:
14 | - pending
15 | filters:
16 | - not:
17 | - type: value
18 | key: "tag:Name"
19 | value: (VPN|Bastion|OpenVPN-Test)
20 | op: regex
21 | - or:
22 | - type: subnet
23 | key: "tag:Name"
24 | op: regex
25 | value: ".*pub"
26 | - type: value
27 | key: "PublicIpAddress"
28 | value: not-null
29 | actions:
30 | - type: notify
31 | template: public-instance-audit.html
32 | slack_template: slack-public-instance-audit
33 | template_format: 'html'
34 | priority_header: '5'
35 | subject: 'Security Audit: Public EC2 Instance Launched'
36 | to:
37 | - email@address.com
38 | - slack://#
39 | owner_absent_contact:
40 | - email@address.com
41 | transport:
42 | type: sqs
43 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/cloud-cloudcustodian
44 |
--------------------------------------------------------------------------------
/policies/c7n-org/rest-api.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: rest-api-filter-policy
3 | resource: rest-api
4 | description: |
5 | Retrieve list of REST APIs
6 | filters:
7 | - or:
8 | - "tag:Audit": absent
9 | - "tag:Audit": empty
10 | - type: value
11 | key: Name
12 | op: regex
13 | value: ".*"
14 |
--------------------------------------------------------------------------------
/policies/c7n-org/s3-global-grants-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: s3-retrieve-global-grants
3 | resource: s3
4 | filters:
5 | - type: global-grants
6 |
7 |
--------------------------------------------------------------------------------
/policies/c7n-org/s3-prevent-bucket-creation.yml:
--------------------------------------------------------------------------------
1 | policies:
2 |
3 |
4 | - name: s3-prevent-bucket-creation
5 | resource: s3
6 | description: |
7 | Cloud Custodian S3 Bucket Creation Prevention
8 | comments: |
9 | Prevents creation of S3 buckets in us-east-1
10 | and sends email notification to user
11 | mode:
12 | type: cloudtrail
13 | events:
14 | - CreateBucket
15 | timeout: 200
16 | filters:
17 | - and:
18 | - not:
19 | - type: value
20 | key: "Name"
21 | value: "david-lin-sandbox-1|david-lin--sandbox-2"
22 | op: regex
23 | - type: event
24 | key: "region"
25 | op: in
26 | value:
27 | - us-east-1
28 | actions:
29 | - type: delete
30 | remove-contents: true
31 | - type: notify
32 | template: s3-prevent-bucket-creation.html
33 | template_format: 'html'
34 | slack_template: slack-s3-prevent-bucket-creation
35 | priority_header: '5'
36 | subject: "S3 Audit: S3 Bucket Deleted"
37 | to:
38 | - email@address.com
39 | - slack://#
40 | - event-owner
41 | owner_absent_contact:
42 | - email@address.com
43 | transport:
44 | type: sqs
45 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/cloud-cloudcustodian
46 |
--------------------------------------------------------------------------------
/policies/c7n-org/s3-public-audit-scheduled-job.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: s3-public-audit
3 | description: |
4 | Cloud Custodian Public S3 Audit
5 | comments: |
6 | Send notification when public S3 bucket is found
7 | resource: s3
8 | mode:
9 | type: periodic
10 | schedule: "rate(6 hours)"
11 | timeout: 300
12 | filters:
13 | - not:
14 | - type: value
15 | key: Name
16 | value: white-listed-public-bucket
17 | - or:
18 | - type: has-statement
19 | statements:
20 | - Effect: Allow
21 | Action: 's3:*'
22 | Principal: '*'
23 | - type: has-statement
24 | statements:
25 | - Effect: Allow
26 | Action: 's3:GetObject'
27 | Principal: '*'
28 | actions:
29 | - type: notify
30 | template: s3-public-audit.html
31 | template_format: 'html'
32 | slack_template: slack-s3-public-audit
33 | priority_header: '5'
34 | subject: 'Security Audit: Public S3 Bucket Found'
35 | to:
36 | - email@domain.com
37 | - slack://#my-slack-channel-name
38 | owner_absent_contact:
39 | - email@domain.com
40 | transport:
41 | type: sqs
42 | queue: https://sqs.us-east-1.amazonaws.com/XXXXXXXXXXXX/cloud-cloudcustodian
43 |
--------------------------------------------------------------------------------
/policies/c7n-org/s3-public-audit-test.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: s3-public-audit
3 | description: |
4 | Cloud Custodian Public S3 Audit
5 | comments: |
6 | Retrieve list of public S3 buckets
7 | resource: s3
8 | filters:
9 | - type: global-grants
10 |
--------------------------------------------------------------------------------
/policies/c7n-org/s3-public-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: s3-public-audit
3 | description: |
4 | Cloud Custodian Public S3 Audit
5 | comments: |
6 | Send notification when public S3 bucket gets created
7 | resource: s3
8 | mode:
9 | type: cloudtrail
10 | events:
11 | - CreateBucket
12 | filters:
13 | - type: global-grants
14 | actions:
15 | - type: notify
16 | template: s3-public-audit.html
17 | template_format: 'html'
18 | slack_template: slack-s3-public-audit
19 | priority_header: '5'
20 | subject: 'Security Audit: Public S3 Bucket Created'
21 | to:
22 | - email@address.com
23 | - slack://#
24 | owner_absent_contact:
25 | - email@address.com
26 | transport:
27 | type: sqs
28 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/cloud-cloudcustodian
29 |
--------------------------------------------------------------------------------
/policies/c7n-org/secrets-manager.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: secrets-manager-filter-policy
3 | resource: secrets-manager
4 | description: |
5 | Retrieve list of Secrets
6 | filters:
7 | - or:
8 | - "tag:Audit": absent
9 | - "tag:Audit": empty
10 | - type: value
11 | key: Name
12 | op: regex
13 | value: ".*"
14 |
--------------------------------------------------------------------------------
/policies/c7n-org/sns.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: sns-filter-policy
3 | resource: sns
4 | description: |
5 | Retrieve list of SNS that match regex.
6 | filters:
7 | - or:
8 | - "tag:Audit": absent
9 | - "tag:Audit": empty
10 | - type: value
11 | key: Name
12 | op: regex
13 | value: ".*"
14 |
--------------------------------------------------------------------------------
/policies/c7n-org/termination-protection-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: termination-protection-audit
3 | resource: ec2
4 | description: |
5 | Cloud Custodian EC2 Termination Protection Audit
6 | comment: |
7 | Periodically check for white listed EC2 instances that
8 | do not have termination protection enabled.
9 | Send email/Slack notification.
10 | mode:
11 | type: periodic
12 | schedule: "rate(5 minutes)"
13 | query:
14 | - instance-state-name: running
15 | filters:
16 | - not:
17 | - type: termination-protected
18 | - or:
19 | - "tag:Name": Cloud Custodian Production
20 | - "tag:Name": GHE
21 | - "tag:Name": david.lin.Bastion
22 | actions:
23 | - type: notify
24 | template: termination-protection-audit.html
25 | slack_template: slack-termination-protection-audit
26 | template_format: 'html'
27 | priority_header: '5'
28 | subject: 'Security Audit: White Listed Instance(s) found with Termination Protection Disabled'
29 | to:
30 | - email@address.com
31 | - slack://#
32 | owner_absent_contact:
33 | - email@address.com
34 | transport:
35 | type: sqs
36 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/cloud-cloudcustodian
37 |
--------------------------------------------------------------------------------
/policies/copy-instance-tags.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: copy-instance-tags
3 | resource: ebs
4 | description: |
5 | Cloud Custodian Copy Instance Tag to Volume
6 | comment: |
7 | Copy instance tags to respective instance's ebs volume.
8 | mode:
9 | type: periodic
10 | role: arn:aws:iam::1234567890:role/CloudCustodian
11 | schedule: "rate(15 minutes)"
12 | filters:
13 | - type: value
14 | key: "Attachments[0].Device"
15 | value: not-null
16 | actions:
17 | - type: copy-instance-tags
18 | tags:
19 | - Name
20 | - type: copy-instance-tags
21 | tags:
22 | - Owner
23 | - type: copy-instance-tags
24 | tags:
25 | - Team
26 |
--------------------------------------------------------------------------------
/policies/delete-marked-sgroups.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: unmark-attached-security-groups
3 | resource: security-group
4 | description: |
5 | Unmark attached security groups that were previously tagged for deletion.
6 | filters:
7 | - used
8 | - type: value
9 | key: GroupName
10 | value: not-null
11 | - "tag:maid_status": not-null
12 | actions:
13 | - unmark
14 |
15 | - name: delete-marked-security-groups
16 | resource: security-group
17 | description: |
18 | Delete security groups marked for deletion
19 | filters:
20 | - type: marked-for-op
21 | op: delete
22 | actions:
23 | - delete
24 | - type: notify
25 | template: sgroup-delete-marked.html
26 | template_format: 'html'
27 | priority_header: '5'
28 | subject: 'CloudCustodian: Unused Security Groups'
29 | to:
30 | - email@address.com
31 | owner_absent_contact:
32 | - email@address.com
33 | transport:
34 | type: sqs
35 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/sandbox
36 |
--------------------------------------------------------------------------------
/policies/ebs-autocleanup-tag.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: ebs-autocleanup-tag
3 | resource: ebs
4 | description: |
5 | Cloud Custodian EBS AutoCleanup Tag
6 | comments: |
7 | Tags ebs volume with name "AutoCleanup" and sets value to "true".
8 | This policy is used with the ebs-garbage-collection policy
9 | which periodically checks ebs volumes with the "AutoClenaup"
10 | tag set to "true" to mark ebs volumes for deletion after 24 hours
11 | of being in the state "available".
12 | mode:
13 | type: periodic
14 | role: arn:aws:iam::929292782238:role/CloudCustodian
15 | schedule: "rate(5 minutes)"
16 | filters:
17 | - or:
18 | - not:
19 | - or:
20 | - "tag:AutoCleanup": "false"
21 | - "tag:AutoCleanup": "False"
22 | - "tag:AutoCleanup": "FALSE"
23 | - "tag:AutoCleanup": absent
24 | actions:
25 | - type: tag
26 | key: "AutoCleanup"
27 | value: "true"
28 |
--------------------------------------------------------------------------------
/policies/ebs-garbage-collection-lambda.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: ebs-mark-unattached-deletion
3 | resource: ebs
4 | comments: |
5 | Delete any unattached EBS volumes.
6 | Volumes set to not delete on instance termination do have
7 | valid use cases as data drives, but 99% of the time they
8 | appear to be just garbage creation.
9 | To run across all regions -> custodian run --dryrun -s out --region all ebs-garbage-collection.yml
10 | Use this policy at your discretion.
11 | mode:
12 | type: periodic
13 | role: arn:aws:iam::{account_id}:role/CloudCustodianRole
14 | schedule: "rate(1 day)"
15 | filters:
16 | - Attachments: []
17 | - "tag:maid_status": absent
18 | actions:
19 | - delete
20 |
--------------------------------------------------------------------------------
/policies/ebs-garbage-collection-with-tags.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: ebs-garbage-collection-with-tags
3 | resource: ebs
4 | description: |
5 | Cloud Custodian EBS Garbage Collection
6 | comments: |
7 | Delete unattached EBS volumes older than 1 day (24hrs) that
8 | have the tag AutoCleanup set to true.
9 | Volumes set to not delete on instance termination do have
10 | valid use cases as data drives, but 99% of the time they
11 | appear to be just garbage creation.
12 | Use this policy at your discretion.
13 | mode:
14 | type: periodic
15 | role: arn:aws:iam::1234567890:role/CloudCustodian
16 | schedule: "rate(1 hour)"
17 | filters:
18 | - Attachments: []
19 | - type: value
20 | key: CreateTime
21 | op: greater-than
22 | value_type: age
23 | value: 1
24 | - "tag:AutoCleanup": "true"
25 | actions:
26 | - delete
27 | - type: notify
28 | template: ebs-garbage-collection.html
29 | slack_template: slack-ebs-garbage-collection
30 | template_format: 'html'
31 | priority_header: '5'
32 | subject: 'EBS Garbage Collection'
33 | to:
34 | - email@address.com
35 | - slack://#slackchannel
36 | owner_absent_contact:
37 | - email@address.com
38 | transport:
39 | type: sqs
40 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/cloud-cloudcustodian
41 |
--------------------------------------------------------------------------------
/policies/ec2-garbage-collection-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: ec2-garbage-collection-audit
3 | resource: ec2
4 | description: |
5 | Cloud Custodian EC2 Garbage Collection
6 | comments: |
7 | Terminate EC2 instances that have been running longer than specified age
8 | filters:
9 | - type: value
10 | key: tag:Name
11 | op: regex
12 | value: ^InstanceNameGoesHere$
13 | - type: instance-age
14 | op: gt
15 | hours: 1
16 | mode:
17 | type: periodic
18 | role: arn:aws:iam::XXXXXXXXXXXX:role/CloudCustodian
19 | schedule: "rate(30 minutes)"
20 | packages: [boto3, botocore, urllib3]
21 | actions:
22 | - terminate
23 | - type: post-finding
24 | severity_normalized: 10
25 | types:
26 | - "Software and Configuration Checks/AWS Security Best Practices"
27 | - type: notify
28 | template: ec2-garbage-collection-audit.html
29 | slack_template: slack-ec2-garbage-collection-audit
30 | template_format: 'html'
31 | priority_header: '5'
32 | subject: 'EC2 Packer Builder Reaper Audit'
33 | to:
34 | - cloudcustodianadmins@company.com
35 | - slack://#
36 | owner_absent_contact:
37 | - cloudcustodianadmins@company.com
38 | transport:
39 | type: sqs
40 | queue: https://sqs.us-east-1.amazonaws.com/XXXXXXXXXXXX/cloud-cloudcustodian
41 |
--------------------------------------------------------------------------------
/policies/ec2-health-event.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: ec2-health-event
3 | resource: ec2
4 | description: |
5 | Cloud Custodian EC2 Health Event
6 | comments: |
7 | Retrieve EC2 instances with scheduled event
8 | filters:
9 | - type: health-event
10 | statuses: [upcoming,open,closed]
11 | mode:
12 | type: periodic
13 | role: arn:aws:iam::123456789:role/CloudCustodian
14 | schedule: "cron(0 20 * * ? *)"
15 | packages: [boto3, botocore, urllib3]
16 | actions:
17 | - type: post-finding
18 | severity_normalized: 10
19 | types:
20 | - "Software and Configuration Checks/AWS Security Best Practices"
21 | - type: notify
22 | template: ec2-health-event.html
23 | slack_template: slack-ec2-health-event
24 | template_format: 'html'
25 | priority_header: '5'
26 | subject: 'Upcoming EC2 Scheduled Events'
27 | to:
28 | - email@example.com
29 | - slack://#
30 | owner_absent_contact:
31 | - email@example.com
32 | transport:
33 | type: sqs
34 | queue: https://sqs.us-east-1.amazonaws.com/123456789/cloud-cloudcustodian
35 |
--------------------------------------------------------------------------------
/policies/ec2-publicipaddress-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: ec2-publicipaddress-audit
3 | resource: ec2
4 | description: |
5 | Cloud Custodian Public Ipaddress Audit
6 | comments: |
7 | Retrieve list of all instances that
8 | - have public IP address matching value
9 | filters:
10 | - type: value
11 | key: "PublicIpAddress"
12 | value: "x.x.x.x"
13 |
--------------------------------------------------------------------------------
/policies/ec2.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: ec2-attributes
3 | resource: ec2
4 | description: |
5 | Cloud Custodian EC2 Attributes
6 | comments: |
7 | Retrieve EC2 Attributes
8 | filters:
9 | - and:
10 | - type: instance-attribute
11 | attribute: instanceType
12 | key: "Value"
13 | value: p3.8xlarge
14 | - type: value
15 | key: tag:Name
16 | op: regex
17 | value: ".*Jenkins2-Driving.*"
18 |
--------------------------------------------------------------------------------
/policies/elasticsearch-find-all-domains.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: elastic-search-find-all-domains
3 | resource: elasticsearch
4 | description: |
5 | Cloud Custodian Elasticsearch
6 | comments: |
7 | Find Elasticsearch Domains and Retrieve Attributes
8 | filters:
9 | - or:
10 | - "tag:Name": empty
11 | - not:
12 | - "tag:Name": empty
13 |
--------------------------------------------------------------------------------
/policies/elasticsearch-security-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: elasticsearch_security_audit
3 | resource: elasticsearch
4 | description: |
5 | Cloud Custodian Elasticsearch Security Audit
6 | comments: |
7 | Periodically check PUBLIC ES domains that have
8 | access policies that are too permissive.
9 | Ignore PRIVATE ES domains.
10 | PRIVATE domains will have VPCOptions configured.
11 | PUBLIC domains will have a Condition with AccessApolicies configured.
12 | Send email/Slack notification.
13 | mode:
14 | type: periodic
15 | role: arn:aws:iam:::role/CloudCustodian
16 | schedule: "rate(5 minutes)"
17 | filters:
18 | - type: value
19 | key: VPCOptions
20 | value: null
21 | - or:
22 | - not:
23 | - type: value
24 | key: AccessPolicies
25 | op: regex
26 | value: .*Condition.*
27 | - type: value
28 | key: AccessPolicies
29 | op: regex
30 | value: .*0.0.0.0/0.*
31 | actions:
32 | - type: notify
33 | template: elasticsearch-security-audit.html
34 | slack_template: slack-elasticsearch-security-audit
35 | template_format: 'html'
36 | priority_header: '5'
37 | subject: 'ElasticSearch Security Audit: ES Domain found out of compliance'
38 | to:
39 | -
40 | - slack://#
41 | owner_absent_contact:
42 | -
43 | transport:
44 | type: sqs
45 | queue: https://sqs.us-east-1.amazonaws.com//cloud-cloudcustodian
46 |
--------------------------------------------------------------------------------
/policies/emailer.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: mfa-unused
3 | resource: iam-user
4 | description: |
5 | Retrieve list of all IAM users in the group 'Administrators'
6 | who have not enabled MFA and generate email report.
7 | filters:
8 | - type: credential
9 | key: mfa_active
10 | value: false
11 | - type: group
12 | key: GroupName
13 | value: Administrators
14 | actions:
15 | - type: notify
16 | template: default.html
17 | template_format: 'html'
18 | priority_header: '5'
19 | subject: 'CloudCustodian: Admins with MFA Disabled'
20 | to:
21 | - david.lin.ctr@tri.global
22 | owner_absent_contact:
23 | - david.lin.ctr@tri.global
24 | transport:
25 | type: sqs
26 | queue: https://sqs.us-east-1.amazonaws.com/929292782238/david-lin-ctr-cloudcustodian
27 |
--------------------------------------------------------------------------------
/policies/get-resources.yml:
--------------------------------------------------------------------------------
1 | policies:
2 |
3 | - name: report-all-ec2s
4 | resource: ec2
5 |
--------------------------------------------------------------------------------
/policies/get_lambda_runtime_audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: lambda_runtime_audit
3 | resource: lambda
4 | description: |
5 | Cloud Custodian Lambda Runtime Audit
6 | comments: |
7 | Retrieve list of all Lambdas
8 | filters:
9 | - or:
10 | - "tag:Team": absent
11 | - "tag:Team": empty
12 | - type: value
13 | key: Runtime
14 | op: regex
15 | value: .*nodejs.*
16 |
--------------------------------------------------------------------------------
/policies/health-event-issues.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: health-event-issues
3 | resource: health-event
4 | mode:
5 | type: periodic
6 | role: arn:aws:iam::123456789123:role/CloudCustodian
7 | schedule: "cron(0 5 * * ? *)"
8 | filters:
9 | - type: value
10 | key: eventTypeCategory
11 | value: issue
12 | - type: value
13 | key: statusCode
14 | value: open
15 | actions:
16 | - type: post-finding
17 | severity_normalized: 10
18 | types:
19 | - "Software and Configuration Checks/AWS Security Best Practices"
20 | - type: notify
21 | template: phd-issue.html
22 | slack_template: slack-phd-issue
23 | template_format: 'html'
24 | priority_header: '5'
25 | subject: 'Personal Health Dashboard - Operational Issue Notification'
26 | to:
27 | - cloudcustodianadmins@email.com
28 | - slack://#alerts
29 | owner_absent_contact:
30 | - cloudcustodianadmins@email.com
31 | transport:
32 | type: sqs
33 | queue: https://sqs.us-east-1.amazonaws.com/123456789123/cloud-cloudcustodian
34 |
--------------------------------------------------------------------------------
/policies/iam-ec2-policy-check.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: iam-no-used-ec2-all-policy
3 | resource: iam-policy
4 | filters:
5 | - type: has-allow-all
6 |
7 | ##############################################################################################
8 | Note: By default, `has-allow-all` matches IAM policies that have the following JSON code block
9 | ##############################################################################################
10 | {
11 | 'Version': '2012-10-17',
12 | 'Statement': [{
13 | 'Action': '*',
14 | 'Resource': '*',
15 | 'Effect': 'Allow'
16 | }]
17 | }
18 |
19 |
20 | ##############################################################################################
21 | Since I needed to have the Action match on specific values, the following lines were manually
22 | added to the /cloud-custodian/c7n/resources/iam.py module:
23 | ##############################################################################################
24 | def has_allow_all_policy(self, client, resource):
25 | statements = client.get_policy_version(
26 | PolicyArn=resource['Arn'],
27 | VersionId=resource['DefaultVersionId']
28 | )['PolicyVersion']['Document']['Statement']
29 | if isinstance(statements, dict):
30 | statements = [statements]
31 |
32 | # has ec2:*
33 | for s in statements:
34 | if ('Condition' not in s and
35 | 'Action' in s and
36 | isinstance(s['Action'], six.string_types) and
37 | s['Action'] == "ec2:*" and
38 | 'Resource' in s and
39 | isinstance(s['Resource'], six.string_types) and
40 | s['Resource'] == "*" and
41 | s['Effect'] == "Allow"):
42 | return True
43 |
44 | # has elasticloadbalancing:*
45 | for s in statements:
46 | if ('Condition' not in s and
47 | 'Action' in s and
48 | isinstance(s['Action'], six.string_types) and
49 | s['Action'] == "elasticloadbalancing:*" and
50 | 'Resource' in s and
51 | isinstance(s['Resource'], six.string_types) and
52 | s['Resource'] == "*" and
53 | s['Effect'] == "Allow"):
54 | return True
55 |
56 | # has cloudwatch:*
57 | for s in statements:
58 | if ('Condition' not in s and
59 | 'Action' in s and
60 | isinstance(s['Action'], six.string_types) and
61 | s['Action'] == "cloudwatch:*" and
62 | 'Resource' in s and
63 | isinstance(s['Resource'], six.string_types) and
64 | s['Resource'] == "*" and
65 | s['Effect'] == "Allow"):
66 | return True
67 |
68 | # has autoscaling:*
69 | for s in statements:
70 | if ('Condition' not in s and
71 | 'Action' in s and
72 | isinstance(s['Action'], six.string_types) and
73 | s['Action'] == "autoscaling:*" and
74 | 'Resource' in s and
75 | isinstance(s['Resource'], six.string_types) and
76 | s['Resource'] == "*" and
77 | s['Effect'] == "Allow"):
78 | return True
79 |
80 | # has iam:CreateServiceLinkedRole
81 | for s in statements:
82 | if ('Condition' not in s and
83 | 'Action' in s and
84 | isinstance(s['Action'], six.string_types) and
85 | s['Action'] == "iam:CreateServiceLinkedRole" and
86 | 'Resource' in s and
87 | isinstance(s['Resource'], six.string_types) and
88 | s['Resource'] == "*" and
89 | s['Effect'] == "Allow"):
90 | return True
91 |
92 | # has ec2:RunInstances
93 | for s in statements:
94 | if ('Condition' not in s and
95 | 'Action' in s and
96 | isinstance(s['Action'], six.string_types) and
97 | s['Action'] == "ec2:RunInstances" and
98 | 'Resource' in s and
99 | isinstance(s['Resource'], six.string_types) and
100 | s['Resource'] == "*" and
101 | s['Effect'] == "Allow"):
102 | return True
103 | return False
104 |
105 | def process(self, resources, event=None):
106 | c = local_session(self.manager.session_factory).client('iam')
107 | results = [r for r in resources if self.has_allow_all_policy(c, r)]
108 | self.log.info(
109 | "%d of %d iam policies have allow all.",
110 | len(results), len(resources))
111 | return results
112 |
113 | ##############################################################################################
114 | Note: For the changes to the iam.py module to take effect, remember to issue:
115 | ##############################################################################################
116 |
117 | $ cd ~/cloud-custodian
118 | $ python install setup.up install
119 |
--------------------------------------------------------------------------------
/policies/iam-policy-CreatePolicy-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 |
3 | - name: iam-policy-CreatePolicy-account-audit
4 | resource: iam-policy
5 | description: |
6 | Cloud Custodian IAM Policy account:* and account:EnableRegion Audit
7 | comment: |
8 | Send email/Slack notification if IAM policy contains account:* or account:EnableRegion action.
9 | Note, this policy will NOT work out of the box and requires the iam.py site-package be modified
10 | to match on specific actions.
11 | mode:
12 | type: cloudtrail
13 | role: arn:aws:iam::1234567890:role/CloudCustodian
14 | events:
15 | - source: iam.amazonaws.com
16 | event: CreatePolicy
17 | ids: 'responseElements.policy.arn'
18 | packages: [boto3, botocore, urllib3]
19 | filters:
20 | - type: has-allow-all
21 | actions:
22 | - type: post-finding
23 | severity_normalized: 10
24 | types:
25 | - "Software and Configuration Checks/AWS Security Best Practices"
26 | - type: notify
27 | template: iam-policy-account-audit.html
28 | slack_template: slack-iam-policy-account-audit
29 | template_format: 'html'
30 | priority_header: '5'
31 | subject: 'Security Audit: IAM policies found with account:* action'
32 | to:
33 | - foo@company.com
34 | - slack://#
35 | owner_absent_contact:
36 | - foo@company.com
37 | transport:
38 | type: sqs
39 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/cloud-cloudcustodian
40 |
--------------------------------------------------------------------------------
/policies/iam-policy-CreatePolicyVersion-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 |
3 | - name: iam-policy-CreatePolicyVersion-account-audit
4 | resource: iam-policy
5 | description: |
6 | Cloud Custodian IAM Policy account:* and account:EnableRegion Audit
7 | comment: |
8 | Send email/Slack notification if IAM policy contains account:* or account:EnableRegion action.
9 | Note, this policy will NOT work out of the box and requires the iam.py site-package be modified
10 | to match on specific actions.
11 | mode:
12 | type: cloudtrail
13 | role: arn:aws:iam::1234567890:role/CloudCustodian
14 | events:
15 | - source: iam.amazonaws.com
16 | event: CreatePolicyVersion
17 | ids: 'requestParameters.policyArn'
18 | packages: [boto3, botocore, urllib3]
19 | filters:
20 | - type: has-allow-all
21 | actions:
22 | - type: post-finding
23 | severity_normalized: 10
24 | types:
25 | - "Software and Configuration Checks/AWS Security Best Practices"
26 | - type: notify
27 | template: iam-policy-account-audit.html
28 | slack_template: slack-iam-policy-account-audit
29 | template_format: 'html'
30 | priority_header: '5'
31 | subject: 'Security Audit: IAM policies found with account:* action'
32 | to:
33 | - foo@company.com
34 | - slack://#
35 | owner_absent_contact:
36 | - foo@company.com
37 | transport:
38 | type: sqs
39 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/cloud-cloudcustodian
40 |
--------------------------------------------------------------------------------
/policies/iam-policy-account-Summary-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 |
3 | - name: iam-policy-Summary-account-audit
4 | resource: iam-policy
5 | description: |
6 | Cloud Custodian IAM Policy account:* Audit
7 | comment: |
8 | Periodically check IAM policies and send
9 | email/Slack notification if contains account:* action
10 | This policy does NOT work out of the box and requires
11 | a modification to the iam.py site-package for the has-allow-all filter
12 | if you want to match on policies with actions that are NOT "*".
13 | mode:
14 | type: periodic
15 | role: arn:aws:iam::1234567890:role/CloudCustodian
16 | schedule: "rate(1 day)"
17 | packages: [boto3, botocore, urllib3]
18 | filters:
19 | - type: has-allow-all
20 | actions:
21 | - type: post-finding
22 | severity_normalized: 10
23 | types:
24 | - "Software and Configuration Checks/AWS Security Best Practices"
25 | - type: notify
26 | template: iam-policy-account-audit-summary.html
27 | slack_template: slack-iam-policy-account-audit-summary
28 | template_format: 'html'
29 | priority_header: '5'
30 | subject: 'Security Audit: IAM policies found with account:* action'
31 | to:
32 | - foo@company.com
33 | - slack://#
34 | owner_absent_contact:
35 | - foo@company.com
36 | transport:
37 | type: sqs
38 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/cloud-cloudcustodian
39 |
--------------------------------------------------------------------------------
/policies/iam-policy-account-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 |
3 | - name: iam-policy-account-audit-policy
4 | resource: iam-policy
5 | description: |
6 | Cloud Custodian IAM Policy account:* Audit
7 | comment: |
8 | Periodically check IAM policies and send
9 | email/Slack notification if contains account:* action
10 | Note: The iam.py module was manually modified to match on
11 | the Action account:*. This policy will NOT work out of the box.
12 | mode:
13 | type: periodic
14 | role: arn:aws:iam::929292782238:role/CloudCustodian
15 | schedule: "rate(1 hour)"
16 | packages: [boto3, botocore, urllib3]
17 | filters:
18 | - type: has-allow-all
19 | actions:
20 | - type: post-finding
21 | severity_normalized: 10
22 | types:
23 | - "Software and Configuration Checks/AWS Security Best Practices"
24 | - type: notify
25 | template: iam-policy-account-audit.html
26 | slack_template: slack-iam-policy-account-audit
27 | template_format: 'html'
28 | priority_header: '5'
29 | subject: 'Security Audit: IAM policies found with account:* action'
30 | to:
31 | - cloudcustodianadmins@tri.global
32 | - slack://#ie-alerts
33 | owner_absent_contact:
34 | - cloudcustodianadmins@tri.global
35 | transport:
36 | type: sqs
37 | queue: https://sqs.us-east-1.amazonaws.com/929292782238/cloud-cloudcustodian
38 |
--------------------------------------------------------------------------------
/policies/iam-role-with-managed-policy-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: iam-role-with-managed-policy-audit
3 | resource: iam-role
4 | description: |
5 | Cloud Custodian IAM Role Audit
6 | comments: |
7 | Send notification when IAM role is found with
8 | AmazonEC2FullAccess, AutoScalingFullAccess,
9 | ElasitcLoadBalancingFullAccess, or AutoScalingConsoleFullAccess.
10 | mode:
11 | type: periodic
12 | role: arn:aws:iam:::role/CloudCustodian
13 | schedule: "rate(1 day)"
14 | filters:
15 | - or:
16 | - type: has-specific-managed-policy
17 | value: AmazonEC2FullAccess
18 | - type: has-specific-managed-policy
19 | value: AutoScalingFullAccess
20 | - type: has-specific-managed-policy
21 | value: ElasticLoadBalancingFullAccess
22 | - type: has-specific-managed-policy
23 | value: AutoScalingConsoleFullAccess
24 | actions:
25 | - type: notify
26 | template: iam-role-audit.html
27 | slack_template: slack-iam-role-audit
28 | template_format: 'html'
29 | priority_header: '5'
30 | subject: 'Security Audit: IAM Role(s) found with AmazonEC2FullAccess Permissions'
31 | to:
32 | - cloudcustodianadmins@company.com
33 | - slack://#
34 | owner_absent_contact:
35 | - cloudcustodianadmins@company.com
36 | transport:
37 | type: sqs
38 | queue: https://sqs.us-east-1.amazonaws.com//cloud-cloudcustodian
39 |
--------------------------------------------------------------------------------
/policies/iam-user-DeleteAccessKey.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: iam-user-DeleteAccessKey-audit
3 | resource: iam-user
4 | description: |
5 | Cloud Custodian IAM User DeleteAccessKey Event Audit
6 | comment: |
7 | Monitor deletion of IAM user access keys
8 | Slack notification if contains account:* action
9 | mode:
10 | type: cloudtrail
11 | role: arn:aws:iam::123456789123:role/CloudCustodian
12 | events:
13 | - source: iam.amazonaws.com
14 | event: DeleteAccessKey
15 | ids: 'requestParameters.userName'
16 | filters:
17 | - type: event
18 | key: 'detail.eventName'
19 | value: 'DeleteAccessKey'
20 | actions:
21 | - type: notify
22 | slack_template: slack-iam-user-DeleteAccessKey-audit
23 | template_format: 'html'
24 | priority_header: '5'
25 | subject: 'IAM User Access Key Deleted'
26 | to:
27 | - slack://#slack-channel-name-goes-here
28 | transport:
29 | type: sqs
30 | queue: https://sqs.us-east-1.amazonaws.com/123456789123/cloud-cloudcustodian
31 |
--------------------------------------------------------------------------------
/policies/iam-user-DeleteLoginProfile-offboarding.yml:
--------------------------------------------------------------------------------
1 | policies:
2 |
3 | - name: iam-user-DeleteLoginProfile-audit
4 | resource: iam-user
5 | description: |
6 | Cloud Custodian IAM User Management Console Event Audit
7 | comment: |
8 | Monitor Disablement of IAM user management console
9 | Slack notification if contains account:* action
10 | mode:
11 | type: cloudtrail
12 | role: arn:aws:iam::XXXXXXXXXXXX:role/CloudCustodian
13 | events:
14 | - source: iam.amazonaws.com
15 | event: DeleteLoginProfile
16 | ids: 'requestParameters.userName'
17 | actions:
18 | - type: notify
19 | template: iam-user-DeleteLoginProfile-offboarding-audit.html
20 | slack_template: slack-iam-user-DeleteLoginProfile-offboarding-audit
21 | template_format: 'html'
22 | priority_header: '5'
23 | subject: 'IAM User Console Access Disabled'
24 | to:
25 | - slack://#it-offboarding
26 | transport:
27 | type: sqs
28 | queue: https://sqs.us-east-1.amazonaws.com/XXXXXXXXXXXX/cloud-cloudcustodian
29 |
--------------------------------------------------------------------------------
/policies/iam-user-UpdateAccessKey-offboarding.yml:
--------------------------------------------------------------------------------
1 | policies:
2 |
3 | - name: iam-user-UpdateAccessKey-offboarding-audit
4 | resource: iam-user
5 | description: |
6 | Cloud Custodian IAM User UpdateAccessKey Event Audit for Offboarding
7 | comment: |
8 | Monitor de-activation of IAM user access keys
9 | Slack notification if contains account:* action
10 | mode:
11 | type: cloudtrail
12 | role: arn:aws:iam::XXXXXXXXXXXX:role/CloudCustodian
13 | events:
14 | - source: iam.amazonaws.com
15 | event: UpdateAccessKey
16 | ids: 'requestParameters.userName'
17 | filters:
18 | - type: event
19 | key: 'detail.requestParameters.status'
20 | value: 'Inactive'
21 | actions:
22 | - type: notify
23 | slack_template: slack-iam-user-UpdateAccessKey-offboarding-audit
24 | template_format: 'html'
25 | priority_header: '5'
26 | subject: 'IAM User Access Key Deactivated'
27 | to:
28 | - slack://#it-offboarding
29 | transport:
30 | type: sqs
31 | queue: https://sqs.us-east-1.amazonaws.com/XXXXXXXXXXXX/cloud-cloudcustodian
32 |
--------------------------------------------------------------------------------
/policies/iam-user-administrator-access-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: iam-user-administrator-access-audit
3 | resource: iam-user
4 | description: |
5 | Cloud Custodian IAM User Audit with AWS Security Hub Integration
6 | comments: |
7 | Send notification when IAM user is found with Administrator access
8 | mode:
9 | type: periodic
10 | role: arn:aws:iam:::role/CloudCustodian
11 | schedule: "rate(1 day)"
12 | packages: [boto3, botocore, urllib3]
13 | filters:
14 | - or:
15 | - type: group
16 | key: GroupName
17 | value: Administrators
18 | op: regex
19 | - type: group
20 | key: GroupName
21 | value: Administrators-HighlyConfidential
22 | op: regex
23 | - type: policy
24 | key: PolicyName
25 | value: AdministratorAccess
26 | op: regex
27 | - not:
28 | - or:
29 | - UserName: david.lin
30 | - UserName: rodney.mullen
31 | actions:
32 | - type: post-finding
33 | severity_normalized: 50
34 | types:
35 | - "Effects/Data Exposure"
36 | - type: notify
37 | template: iam-user-administrator-access-audit.html
38 | template_format: 'html'
39 | slack_template: slack-iam-user-administrator-access-audit
40 | priority_header: '5'
41 | subject: 'IAM User Audit: Non-whitelisted IAM User(s) found with Administrator Access'
42 | to:
43 | -
44 | - slack://
45 | owner_absent_contact:
46 | -
47 | transport:
48 | type: sqs
49 | queue: https://sqs.us-east-1.amazonaws.com//cloud-cloudcustodian
50 |
--------------------------------------------------------------------------------
/policies/iam-user-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: iam-user-audit
3 | resource: iam-user
4 | description: |
5 | Cloud Custodian IAM User Audit
6 | comments: |
7 | Send notification when IAM user is found with AmazonEC2FullAccess
8 | and not part of the Ec2InstanceLaunchers group.
9 | mode:
10 | type: periodic
11 | role: arn:aws:iam:::role/CloudCustodian
12 | schedule: "rate(1 day)"
13 | filters:
14 | - not:
15 | - type: group
16 | key: GroupName
17 | value: Ec2InstanceLaunchers
18 | - type: policy
19 | key: PolicyName
20 | value: AmazonEC2FullAccess
21 | op: regex
22 | actions:
23 | - type: notify
24 | template: iam-user-audit
25 | template_format: 'html'
26 | slack_template: slack-iam-user-audit
27 | priority_header: '5'
28 | subject: 'IAM User Audit: IAM User(s) found not in Ec2InstanceLaunchers but with AmazonEC2FullAccess'
29 | to:
30 | - cloudcustodianadmins@company.com
31 | - slack://#
32 | owner_absent_contact:
33 | - cloudcustodianadmins@company.com
34 | transport:
35 | type: sqs
36 | queue: https://sqs.us-east-1.amazonaws.com//cloud-cloudcustodian
37 |
--------------------------------------------------------------------------------
/policies/iam-user-set-groups.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: iam-user-set-group
3 | resource: iam-user
4 | filters:
5 | - type: value
6 | key: UserName
7 | value: iam-user-1|iam-user-2|iam-user-3
8 | op: regex
9 | actions:
10 | - type: set-groups
11 | state: add
12 | group: MyIAMGroupName
13 |
--------------------------------------------------------------------------------
/policies/iam-user-tagged-resources-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 |
3 | - name: iam-user-ec2-tagged-resources-report
4 | resource: ec2
5 | filters:
6 | - or:
7 | - type: value
8 | key: tag:Owner
9 | op: regex
10 | value: .*minh.do.*
11 |
12 | - name: iam-user-ebs-tagged-resources-report
13 | resource: ebs
14 | filters:
15 | - or:
16 | - type: value
17 | key: tag:Owner
18 | op: regex
19 | value: .*minh.do.*
20 |
21 | - name: iam-user-ebs-snapshot-tagged-resources-report
22 | resource: ebs-snapshot
23 | filters:
24 | - or:
25 | - type: value
26 | key: tag:Owner
27 | op: regex
28 | value: .*minh.do.*
29 |
30 | - name: iam-user-security-group-tagged-resources-report
31 | resource: security-group
32 | filters:
33 | - or:
34 | - type: value
35 | key: tag:Owner
36 | op: regex
37 | value: .*minh.do.*
38 |
39 | - name: iam-user-ami-tagged-resources-report
40 | resource: ami
41 | filters:
42 | - or:
43 | - type: value
44 | key: tag:Owner
45 | op: regex
46 | value: .*minh.do.*
47 |
48 | - name: iam-user-dynamodb-table-tagged-resources-report
49 | resource: dynamodb-table
50 | filters:
51 | - or:
52 | - type: value
53 | key: tag:Owner
54 | op: regex
55 | value: .*minh.do.*
56 |
57 | - name: iam-user-dynamodb-stream-tagged-resources-report
58 | resource: dynamodb-stream
59 | filters:
60 | - or:
61 | - type: value
62 | key: tag:Owner
63 | op: regex
64 | value: .*minh.do.*
65 |
66 | - name: iam-user-dynamodb-backup-tagged-resources-report
67 | resource: dynamodb-backup
68 | filters:
69 | - or:
70 | - type: value
71 | key: tag:Owner
72 | op: regex
73 | value: .*minh.do.*
74 |
75 | - name: iam-user-elasticsearch-resources-report
76 | resource: elasticsearch
77 | filters:
78 | - or:
79 | - type: value
80 | key: tag:Owner
81 | op: regex
82 | value: .*minh.do.*
83 |
84 | - name: iam-user-elb-tagged-resources-report
85 | resource: elb
86 | filters:
87 | - or:
88 | - type: value
89 | key: tag:Owner
90 | op: regex
91 | value: .*minh.do.*
92 |
93 | - name: iam-user-eni-tagged-resources-report
94 | resource: eni
95 | filters:
96 | - or:
97 | - type: value
98 | key: tag:Owner
99 | op: regex
100 | value: .*minh.do.*
101 |
102 | - name: iam-user-lambda-tagged-resources-report
103 | resource: lambda
104 | filters:
105 | - or:
106 | - type: value
107 | key: tag:Owner
108 | op: regex
109 | value: .*minh.do.*
110 |
111 | - name: iam-user-lambda-layer-tagged-resources-report
112 | resource: lambda-layer
113 | filters:
114 | - or:
115 | - type: value
116 | key: tag:Owner
117 | op: regex
118 | value: .*minh.do.*
119 |
120 | - name: iam-user-rds-tagged-resources-report
121 | resource: rds
122 | filters:
123 | - or:
124 | - type: value
125 | key: tag:Owner
126 | op: regex
127 | value: .*minh.do.*
128 |
129 | - name: iam-user-s3-tagged-resources-report
130 | resource: s3
131 | filters:
132 | - or:
133 | - type: value
134 | key: tag:Owner
135 | op: regex
136 | value: .*minh.do.*
137 |
138 | - name: iam-user-sqs-tagged-resources-report
139 | resource: sqs
140 | filters:
141 | - or:
142 | - type: value
143 | key: tag:Owner
144 | op: regex
145 | value: .*minh.do.*
146 |
147 | - name: iam-user-sns-tagged-resources-report
148 | resource: sns
149 | filters:
150 | - or:
151 | - type: value
152 | key: tag:Owner
153 | op: regex
154 | value: .*minh.do.*
155 |
156 | - name: iam-user-cfn-tagged-resources-report
157 | resource: cfn
158 | filters:
159 | - or:
160 | - type: value
161 | key: tag:Owner
162 | op: regex
163 | value: .*minh.do.*
164 |
165 |
166 |
167 |
--------------------------------------------------------------------------------
/policies/iam.py:
--------------------------------------------------------------------------------
1 | # This section of code should be used to replace the has-allow-all function
2 | # in the /cloud-custodian/c7n/resources/iam.py file
3 | #
4 | # Usage:
5 | #
6 | # 1) Backup original ~/cloud-custodian/c7n/resources/iam.py
7 | # 2) Update iam.py with section below (search for has-allow-all)
8 | # 3) Rebuild site-package
9 | # 4) cd ~/cloud-custodian
10 | # python setup.py install
11 | # 5) Test
12 |
13 | schema = type_schema('has-allow-all')
14 | permissions = ('iam:ListPolicies', 'iam:ListPolicyVersions')
15 |
16 | def has_allow_all_policy(self, client, resource):
17 | statements = client.get_policy_version(
18 | PolicyArn=resource['Arn'],
19 | VersionId=resource['DefaultVersionId']
20 | )['PolicyVersion']['Document']['Statement']
21 | if isinstance(statements, dict):
22 | statements = [statements]
23 |
24 | for s in statements:
25 | if ('Condition' not in s and
26 | 'Action' in s and
27 | ('account:*' in s['Action'] or
28 | 'account:EnableRegion' in s['Action']) and
29 | 'Resource' in s and
30 | isinstance(s['Resource'], six.string_types) and
31 | s['Resource'] == "*" and
32 | s['Effect'] == "Allow"):
33 | return True
34 | return False
35 |
--------------------------------------------------------------------------------
/policies/iam.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: iam-user-filter-policy
3 | resource: iam-user
4 | description: |
5 | Retrieve list of IAM users that match regex.
6 | filters:
7 | - type: value
8 | key: UserName
9 | op: regex
10 | value: "david.lin.ctr"
11 |
--------------------------------------------------------------------------------
/policies/mailer.yml:
--------------------------------------------------------------------------------
1 | # Which queue should we listen to for messages
2 | queue_url: https://sqs.us-east-1.amazonaws.com/1234567890/sandbox
3 |
4 | # Default from address
5 | from_address: email@address.com
6 |
7 | # Tags that we should look at for address infomation
8 | contact_tags:
9 | - OwnerContact
10 | - OwnerEmail
11 | - SNSTopicARN
12 |
13 | # Standard Lambda Function Config
14 | region: us-east-1
15 | role: arn:aws:iam::1234567890:role/CloudCustodianRole
16 | slack_token: xoxb-bot_token_string_goes_here
17 |
18 |
--------------------------------------------------------------------------------
/policies/mark-unused-sgroups.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: mark-unused-security-groups-for-deletion
3 | resource: security-group
4 | description: |
5 | Mark unused security groups for deletion in X days.
6 | A mark is a tag that gets created for each
7 | unused security group.
8 | The key/value pair takes on the following attributes:
9 | key = maid_status
10 | value = 'Resource does not meet policy: delete@year/month/day'
11 | filters:
12 | - unused
13 | - type: value
14 | key: GroupName
15 | op: regex
16 | value: .*launch\-wizard.*
17 | actions:
18 | - type: mark-for-op
19 | op: delete
20 | days: 0
21 |
--------------------------------------------------------------------------------
/policies/mfa-audit-broken.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: mfa-audit-reminder
3 | description: Cloud Custodian MFA Audit Notification
4 | comment: |
5 | Retrieve list of all IAM users with MFA disabled
6 | in the group 'Administrators' and send notification
7 | if MFA is not enabled after 3 days of the create date.
8 | Send notification via SES and Slack.
9 | resource: iam-user
10 | mode:
11 | type: periodic
12 | role: arn:aws:iam::1234567890:role/CloudCustodian
13 | schedule: "rate(5 minutes)"
14 | filters:
15 | - type: credential
16 | key: mfa_active
17 | value: false
18 | - type: group
19 | key: GroupName
20 | value: Administrators
21 | - type: value
22 | key: CreateDate
23 | op: less-than
24 | value_type: age
25 | value: 3
26 | actions:
27 | - type: notify
28 | template: mfa-audit-reminder.html
29 | template_format: 'html'
30 | slack_template: slack-mfa-audit-reminder
31 | priority_header: '5'
32 | subject: 'Security Audit: IAM users in Administrators group with MFA Disabled'
33 | to:
34 | -
35 | - slack://#ie-stratus
36 | owner_absent_contact:
37 | -
38 | transport:
39 | type: sqs
40 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/cloud-cloudcustodian
41 |
42 |
43 | - name: mfa-audit-disable-access
44 | description: Cloud Custodian MFA Audit Disable Access
45 | comment: |
46 | Retrieve list of all IAM users with MFA disabled
47 | in the group 'Administrators' and send notification
48 | if MFA is not enabled after 5 days of inactivity.
49 | Send notification via SES and Slack.
50 | Disable user access to management console.
51 | Delete user access-keys.
52 | resource: iam-user
53 | mode:
54 | type: periodic
55 | role: arn:aws:iam::1234567890:role/CloudCustodian
56 | schedule: "rate(5 minutes)"
57 | filters:
58 | - type: credential
59 | key: mfa_active
60 | value: false
61 | - type: group
62 | key: GroupName
63 | value: Administrators
64 | - type: value
65 | key: CreateDate
66 | op: greater-than
67 | value_type: age
68 | value: 5
69 | actions:
70 | - type: delete
71 | options:
72 | - access-keys
73 | - console-access
74 | - type: notify
75 | template: mfa-audit-disable-access
76 | template_format: 'html'
77 | slack_template: slack-mfa-audit-disable-access
78 | priority_header: '5'
79 | subject: 'Security Audit: AWS Console Access Disabled and Access Keys Deleted'
80 | to:
81 | -
82 | - slack://#
83 | owner_absent_contact:
84 | -
85 | transport:
86 | type: sqs
87 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/cloud-cloudcustodian
88 |
--------------------------------------------------------------------------------
/policies/mfa-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: mfa-audit-reminder
3 | description: Cloud Custodian MFA Audit Notification
4 | comment: |
5 | Retrieve list of all IAM users with MFA disabled
6 | in the group 'Administrators' and send notification
7 | if MFA is not enabled after 3 days of the create date.
8 | Send notification via SES and Slack.
9 | Requires 'iam:ListGroupsForUser' permissions.
10 | resource: iam-user
11 | filters:
12 | - type: credential
13 | key: mfa_active
14 | value: false
15 | - type: group
16 | key: GroupName
17 | value: Administrators
18 | - type: value
19 | key: CreateDate
20 | op: less-than
21 | value_type: age
22 | value: 3
23 | actions:
24 | - type: notify
25 | template: mfa-audit-reminder.html
26 | template_format: 'html'
27 | slack_template: slack-mfa-audit-reminder
28 | priority_header: '5'
29 | subject: 'Security Audit: IAM users in Administrators group with MFA Disabled'
30 | to:
31 | -
32 | - slack://#
33 | owner_absent_contact:
34 | -
35 | transport:
36 | type: sqs
37 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/cloud-cloudcustodian
38 |
39 |
40 | - name: mfa-audit-disable-access
41 | description: Cloud Custodian MFA Audit Disable Access
42 | comment: |
43 | Retrieve list of all IAM users with MFA disabled
44 | in the group 'Administrators' and send notification
45 | if MFA is not enabled after 5 days of inactivity.
46 | Send notification via SES and Slack.
47 | Disable user access to management console.
48 | Delete user access-keys.
49 | resource: iam-user
50 | filters:
51 | - type: credential
52 | key: mfa_active
53 | value: false
54 | - type: group
55 | key: GroupName
56 | value: Administrators
57 | - type: value
58 | key: CreateDate
59 | op: greater-than
60 | value_type: age
61 | value: 5
62 | actions:
63 | - type: delete
64 | options:
65 | - access-keys
66 | - console-access
67 | - type: notify
68 | template: mfa-audit-disable-access.html
69 | template_format: 'html'
70 | slack_template: slack-mfa-audit-disable-access
71 | priority_header: '5'
72 | subject: 'Security Audit: AWS Console Access Disabled and Access Keys Deleted'
73 | to:
74 | -
75 | - slack://#
76 | owner_absent_contact:
77 | -
78 | transport:
79 | type: sqs
80 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/cloud-cloudcustodian
81 |
--------------------------------------------------------------------------------
/policies/mfa-unused.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: mfa-unused
3 | resource: iam-user
4 | description: |
5 | Retrieve list of all IAM users in the group 'Administrators'
6 | who have not enabled MFA.
7 | filters:
8 | - type: credential
9 | key: mfa_active
10 | value: false
11 | - type: group
12 | key: GroupName
13 | value: Administrators
14 |
--------------------------------------------------------------------------------
/policies/mfa.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: mfa-user-filter-policy
3 | resource: iam-user
4 | description: |
5 | Retrieve list of IAM users with MFA enabled.
6 | filters:
7 | - type: credential
8 | key: mfa_active
9 | value: true
10 |
--------------------------------------------------------------------------------
/policies/new-user-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: new-user-audit
3 | resource: iam-user
4 | description: |
5 | Cloud Custodian New User Audit
6 | comment: |
7 | Retrieves list of all IAM users with MFA disabled
8 | in the last 30 days.
9 | filters:
10 | - type: credential
11 | key: mfa_active
12 | value: false
13 | - type: value
14 | key: CreateDate
15 | op: less-than
16 | value_type: age
17 | value: 30
18 | - type: group
19 | key: GroupName
20 | value: CloudCustodianAdmins
21 |
22 |
--------------------------------------------------------------------------------
/policies/offhours.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: maid-offhours
3 | description: |
4 | Cloud Custodian Maid Offhours
5 | comment: |
6 | Stop EC2 instances after offhours that have tag of
7 | key = 'maid_offhours'
8 | value = schedule
9 | example value -> 'on=(M-F,16);off=(M-F,23);tz=est'
10 | use 'pt' for pacific time
11 | See http://capitalone.github.io/cloud-custodian/docs/quickstart/offhours.html#offhours
12 | resource: ec2
13 | mode:
14 | type: periodic
15 | role: arn:aws:iam::1234567890:role/CloudCustodian
16 | schedule: "rate(1 minute)"
17 | filters:
18 | - type: offhour
19 | default_tz: est
20 | offhour: 1
21 | actions:
22 | - stop
23 |
24 | - name: maid-onhours
25 | description: |
26 | Cloud Custodian Maid Onhours
27 | comment: |
28 | Start EC2 instances after onhours that have a tag of
29 | key = 'maid_offhours'
30 | value = schedule
31 | example value -> 'on=(M-F,16);tz=est'
32 | use 'pt' for pacific time
33 | See http://capitalone.github.io/cloud-custodian/docs/quickstart/offhours.html#offhours
34 | resource: ec2
35 | mode:
36 | type: periodic
37 | role: arn:aws:iam::1234567890:role/CloudCustodian
38 | schedule: "rate(1 minute)"
39 | filters:
40 | - type: onhour
41 | default_tz: est
42 | onhour: 1
43 | actions:
44 | - start
45 |
46 | - name: custom-offhours
47 | description: |
48 | Cloud Custodian Custom Offhours
49 | comment: |
50 | Stop EC2 instances after hours that have custom tag of
51 | tag = 'StopAfterHours'
52 | value = schedule
53 | example value -> 'off=(M-F,23);tz=est'
54 | use 'tz=pt' for pacific time
55 | See http://capitalone.github.io/cloud-custodian/docs/quickstart/offhours.html#offhours
56 | resource: ec2
57 | mode:
58 | type: periodic
59 | role: arn:aws:iam::1234567890:role/CloudCustodian
60 | schedule: "rate(1 minute)"
61 | filters:
62 | - type: offhour
63 | tag: StopAfterHours
64 | default_tz: est
65 | offhour: 1
66 | actions:
67 | - stop
68 |
69 | - name: custom-onhours
70 | description: |
71 | Cloud Custodian Custom Onhours
72 | comments: |
73 | Start EC2 instances after onhours that have custom tag of
74 | tag = 'StartAfterHours'
75 | value = schedule
76 | example value -> 'on=(M-F,16);tz=est'
77 | use 'tz=pt' for pacific time
78 | See http://capitalone.github.io/cloud-custodian/docs/quickstart/offhours.html#offhours
79 | resource: ec2
80 | mode:
81 | type: periodic
82 | role: arn:aws:iam::1234567890:role/CloudCustodian
83 | schedule: "rate(1 minute)"
84 | filters:
85 | - type: onhour
86 | tag: StartAfterHours
87 | default_tz: est
88 | onhour: 1
89 | actions:
90 | - start
91 |
--------------------------------------------------------------------------------
/policies/owner-tag-audit.yml:
--------------------------------------------------------------------------------
1 | # custodian report -s output owner-tag-audit.yml --field Name=tag:Name --field tag:Owner=tag:Owner --field KeyName=KeyName --field InstanceId=InstanceId --field Type=InstanceType --field State=State --format grid --no-default
2 | policies:
3 | - name: owner-tag-audit
4 | resource: ec2
5 | description: |
6 | Cloud Custodian Owner Tag Audit
7 | comments: |
8 | Retrieve list of all instances that
9 | match specific "Owner" tag
10 | mode:
11 | type: ec2-instance-state
12 | role: arn:aws:iam::123456789:role/CloudCustodian
13 | events:
14 | - running
15 | filters:
16 | - or:
17 | - type: value
18 | key: "tag:Owner"
19 | value: (.*david.*)
20 | op: regex
21 | - type: value
22 | key: "KeyName"
23 | value: (.*david.*)
24 | op: regex
25 | actions:
26 | - type: notify
27 | template: owner-tag-audit.html
28 | slack_template: slack-ownder-tag-audit
29 | template_format: 'html'
30 | priority_header: '5'
31 | subject: 'Tag Audit: EC Instance(s) with Owner tag set to srikanth.yadav.ctr'
32 | to:
33 | -
34 | - slack://#
35 | owner_absent_contact:
36 | -
37 | transport:
38 | type: sqs
39 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/cloud-cloudcustodian
40 |
--------------------------------------------------------------------------------
/policies/phd-notifications.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: phd-notifications
3 | resource: health-event
4 | description: |
5 | Cloud Custodian Personal Health Dashboard (PHD) Notifications
6 | comments: |
7 | Send alert when PHD notification is found
8 | mode:
9 | type: periodic
10 | role: arn:aws:iam::929292782238:role/CloudCustodian
11 | schedule: "rate(1 day)"
12 | filters:
13 | - type: value
14 | key: "lastUpdatedTime"
15 | op: less-than
16 | value_type: age
17 | value: 1
18 | actions:
19 | - type: notify
20 | slack_template: slack-phd-notifications
21 | priority_header: '5'
22 | subject: 'Personal Health Dashboard Notification(s)'
23 | to:
24 | - slack://#ie-alerts
25 | transport:
26 | type: sqs
27 | queue: https://sqs.us-east-1.amazonaws.com/929292782238/cloud-cloudcustodian
28 |
--------------------------------------------------------------------------------
/policies/public-instance-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: public-instance-audit
3 | resource: ec2
4 | description: |
5 | Cloud Custodian Public Instance Audit
6 | comments: |
7 | Retrieve list of all instances that
8 | - are not in whitelist
9 | - attached to a public subnet
10 | - have public IP address
11 | mode:
12 | type: ec2-instance-state
13 | role: arn:aws:iam::1234567890:role/CloudCustodian
14 | events:
15 | - pending
16 | filters:
17 | - not:
18 | - type: value
19 | key: "tag:Name"
20 | value: (david-VPN|davidi-Bastion)
21 | op: regex
22 | - or:
23 | - type: subnet
24 | key: "tag:Name"
25 | op: regex
26 | value: ".*pub"
27 | - type: value
28 | key: "PublicIpAddress"
29 | value: not-null
30 | - and:
31 | - type: value
32 | key: VpcId
33 | value: vpc-12345678
34 | actions:
35 | - type: notify
36 | template: public-instance-audit.html
37 | slack_template: slack-public-instance-audit
38 | template_format: 'html'
39 | priority_header: '5'
40 | subject: 'Security Audit: Public EC2 Instance Launched'
41 | to:
42 | -
43 | - slack://#
44 | owner_absent_contact:
45 | -
46 | transport:
47 | type: sqs
48 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/cloud-cloudcustodian
49 |
--------------------------------------------------------------------------------
/policies/public-subnet-instance-audit-lambda.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: subnet-audit
3 | resource: ec2
4 | description: |
5 | Filter ec2 resources based on the attributes of the network
6 | they are attached to then take action. For example, subnets with tag 'Location'
7 | and value that matches 'Internet' should be stopped.
8 | mode:
9 | type: ec2-instance-state
10 | role: arn:aws:iam::485020822820:role/CloudCustodianRole
11 | events:
12 | - pending
13 | filters:
14 | - type: subnet
15 | key: "tag:Location"
16 | value: "Internet"
17 | actions:
18 | - stop
19 |
--------------------------------------------------------------------------------
/policies/public-subnet-instance-audit-notify.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: public-subnet-instance-audit-notification
3 | resource: ec2
4 | mode:
5 | type: ec2-instance-state
6 | role: arn:aws:iam::485020822820:role/CloudCustodianRole
7 | events:
8 | - pending
9 | filters:
10 | - type: subnet
11 | key: "tag:Location"
12 | value: "Internet"
13 | actions:
14 | - type: notify
15 | template: default.html
16 | template_format: 'html'
17 | priority_header: '5'
18 | subject: 'Cloud Custodian: EC2 Instance Launched in Public Subnet'
19 | to:
20 | - david.lin.ctr@tri.global, peter.richmond@tri.global, mike.garrison@tri.global
21 | owner_absent_contact:
22 | - david.lin.ctr@tri.global
23 | transport:
24 | type: sqs
25 | queue: https://sqs.us-east-1.amazonaws.com/485020822820/david-lin-ctr-iesandbox-cloudcustodian
26 |
--------------------------------------------------------------------------------
/policies/public-subnet-instance-audit-whitelist.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: whitelist
3 | resource: ec2
4 | mode:
5 | type: ec2-instance-state
6 | role: arn:aws:iam::1234567890:role/CloudCustodianRole
7 | events:
8 | - pending
9 | filters:
10 | - not:
11 | - type: value
12 | key: "tag:Name"
13 | value: (Instance_Name_1|Instance_Name_2)
14 | op: regex
15 | - and:
16 | - type: subnet
17 | key: "tag:Name"
18 | value: "PublicSubnet"
19 | actions:
20 | - terminate
21 | - type: notify
22 | template: ec2-public-whitelist.html
23 | slack_template: slack_ec2-public-whitelist
24 | template_format: 'html'
25 | priority_header: '5'
26 | subject: 'Cloud Custodian: EC2 Instance Launched in Public Subnet'
27 | to:
28 | - email@address.com
29 | - slack://#slack-channel-goes-here
30 | owner_absent_contact:
31 | - email@address.com
32 | transport:
33 | type: sqs
34 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/sandbox
35 |
--------------------------------------------------------------------------------
/policies/roles.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: iam-roles-unused
3 | resource: iam-role
4 | description: |
5 | Retrieve list of unused roles.
6 | filters:
7 | - type: used
8 | state: false
9 |
--------------------------------------------------------------------------------
/policies/s3-prevent-bucket-creation.yml:
--------------------------------------------------------------------------------
1 | policies:
2 |
3 |
4 | - name: s3-prevent-bucket-creation
5 | resource: s3
6 | description: |
7 | Cloud Custodian S3 Bucket Creation Prevention
8 | comments: |
9 | Prevents creation of S3 buckets in us-east-1
10 | and sends email notification to user
11 | mode:
12 | type: cloudtrail
13 | role: arn:aws:iam::account_id:role/CloudCustodian
14 | events:
15 | - CreateBucket
16 | timeout: 200
17 | filters:
18 | - and:
19 | - not:
20 | - type: value
21 | key: "Name"
22 | value: "david-lin-ctr-sandbox-1|david-lin-ctr-sandbox-2"
23 | op: regex
24 | - type: event
25 | key: "region"
26 | op: in
27 | value:
28 | - us-east-1
29 | actions:
30 | - type: delete
31 | remove-contents: true
32 | - type: notify
33 | template: s3-prevent-bucket-creation.html
34 | template_format: 'html'
35 | slack_template: slack-s3-prevent-bucket-creation
36 | priority_header: '5'
37 | subject: "S3 Audit: S3 Bucket Deleted"
38 | to:
39 | - cloudcustodianadmins@company.com
40 | - slack://#channel_name
41 | - event-owner
42 | owner_absent_contact:
43 | - cloudcustodianadmins@company.com
44 | transport:
45 | type: sqs
46 | queue: https://sqs.us-east-1.amazonaws.com/account_id/cloud-cloudcustodian
47 |
--------------------------------------------------------------------------------
/policies/s3-public-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: s3-public-audit
3 | description: |
4 | Cloud Custodian Public S3 Audit
5 | comments: |
6 | Send notification when public S3 bucket gets created
7 | resource: s3
8 | mode:
9 | type: cloudtrail
10 | role: arn:aws:iam::1234567890:role/CloudCustodian
11 | events:
12 | - CreateBucket
13 | filters:
14 | - type: global-grants
15 | actions:
16 | - type: notify
17 | template: s3-public-audit.html
18 | template_format: 'html'
19 | slack_template: slack-s3-public-audit
20 | priority_header: '5'
21 | subject: 'Security Audit: Public S3 Bucket Created'
22 | to:
23 | - your_verified_email@domain.com
24 | - slack://#channel_name_goes_here
25 | owner_absent_contact:
26 | - your_verified_email@domain.com
27 | transport:
28 | type: sqs
29 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/cloud-cloudcustodian
30 |
--------------------------------------------------------------------------------
/policies/s3-server-access-logging.yml:
--------------------------------------------------------------------------------
1 | policies:
2 |
3 | - name: s3-server-access-logging-us-east-1
4 | resource: s3
5 | description: |
6 | Cloud Custodian S3 Server Access Logging
7 | comments: |
8 | Enables S3 server access logging and sets TargetBucket
9 | and TargetPrefix for us-east-1
10 | mode:
11 | type: periodic
12 | role: arn:aws:iam::1234567890:role/CloudCustodian
13 | schedule: "rate(1 day)"
14 | timeout: 300
15 | filters:
16 | - type: value
17 | key: "Location.LocationConstraint"
18 | value: null
19 | actions:
20 | - type: toggle-logging
21 | target_bucket: s3-access-logs-1234567890-us-east-1
22 | target_prefix: access_logs/{source_bucket_name}/{source_bucket_name}
23 |
24 |
25 | - name: s3-server-access-logging-us-east-2
26 | resource: s3
27 | description: |
28 | Cloud Custodian S3 Server Access Logging
29 | comments: |
30 | Enables S3 server access logging and sets TargetBucket
31 | and TargetPrefix for us-east-2
32 | mode:
33 | type: periodic
34 | role: arn:aws:iam::1234567890:role/CloudCustodian
35 | schedule: "rate(1 day)"
36 | timeout: 300
37 | filters:
38 | - type: value
39 | key: "Location.LocationConstraint"
40 | value: "us-east-2"
41 | actions:
42 | - type: toggle-logging
43 | target_bucket: s3-access-logs-1234567890-us-east-2
44 | target_prefix: access_logs/{source_bucket_name}/{source_bucket_name}
45 |
46 |
47 | - name: s3-server-access-logging-us-west-1
48 | resource: s3
49 | description: |
50 | Cloud Custodian S3 Server Access Logging
51 | comments: |
52 | Enables S3 server access logging and sets TargetBucket
53 | and TargetPrefix for us-west-1
54 | mode:
55 | type: periodic
56 | role: arn:aws:iam::1234567890:role/CloudCustodian
57 | schedule: "rate(1 day)"
58 | timeout: 300
59 | filters:
60 | - type: value
61 | key: "Location.LocationConstraint"
62 | value: "us-west-1"
63 | actions:
64 | - type: toggle-logging
65 | target_bucket: s3-access-logs-1234567890-us-west-1
66 | target_prefix: access_logs/{source_bucket_name}/{source_bucket_name}
67 |
68 |
69 | - name: s3-server-access-logging-us-west-2
70 | resource: s3
71 | description: |
72 | Cloud Custodian S3 Server Access Logging
73 | comments: |
74 | Enables S3 server access logging and sets TargetBucket
75 | and TargetPrefix for us-west-2
76 | mode:
77 | type: periodic
78 | role: arn:aws:iam::1234567890:role/CloudCustodian
79 | schedule: "rate(1 day)"
80 | timeout: 300
81 | filters:
82 | - type: value
83 | key: "Location.LocationConstraint"
84 | value: "us-west-2"
85 | actions:
86 | - type: toggle-logging
87 | target_bucket: s3-access-logs-1234567890-us-west-2
88 | target_prefix: access_logs/{source_bucket_name}/{source_bucket_name}
89 |
90 |
91 | - name: s3-server-access-logging-ap-northeast-1
92 | resource: s3
93 | description: |
94 | Cloud Custodian S3 Server Access Logging
95 | comments: |
96 | Enables S3 server access logging and sets TargetBucket
97 | and TargetPrefix for ap-northeast-1
98 | mode:
99 | type: periodic
100 | role: arn:aws:iam::1234567890:role/CloudCustodian
101 | schedule: "rate(1 day)"
102 | timeout: 300
103 | filters:
104 | - type: value
105 | key: "Location.LocationConstraint"
106 | value: "ap-northeast-1"
107 | actions:
108 | - type: toggle-logging
109 | target_bucket: s3-access-logs-1234567890-ap-northeast-1
110 | target_prefix: access_logs/{source_bucket_name}/{source_bucket_name}
111 |
--------------------------------------------------------------------------------
/policies/s3-service-limit-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: s3-service-limit-audit
3 | resource: s3
4 | description: |
5 | Cloud Custodian S3 Service Limit Audit
6 | comment: |
7 | Periodically check S3 service limit
8 | mode:
9 | type: periodic
10 | role: arn:aws:iam:::role/CloudCustodian
11 | schedule: "rate(1 day)"
12 | timeout: 300
13 | filters:
14 | - not:
15 | - "tag:Name": "NoOneWillEverUseThisName"
16 | - type: value
17 | value_type: resource_count
18 | op: gt
19 | value: 200
20 | actions:
21 | - type: notify
22 | template: s3-service-limit-audit.html
23 | slack_template: slack-s3-service-limit-audit
24 | template_format: 'html'
25 | priority_header: '5'
26 | subject: 'S3 Service Limit Audit: S3 Service Limit Exceeded'
27 | to:
28 | -
29 | - slack://#
30 | owner_absent_contact:
31 | -
32 | transport:
33 | type: sqs
34 | queue: https://sqs.us-east-1.amazonaws.com//cloud-cloudcustodian
35 |
--------------------------------------------------------------------------------
/policies/s3-target-bucket-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 |
3 |
4 | - name: s3-target-bucket-audit
5 | resource: s3
6 | description: |
7 | Cloud Custodian S3 Target Bucket Audit
8 | comments: |
9 | Checks S3 server access logging target bucket name is compliant.
10 | Sends notification if name is not compliant.
11 | Supplements s3-server-access-logging.yml policy.
12 | mode:
13 | type: periodic
14 | role: arn:aws:iam::acccount_id:role/CloudCustodian
15 | schedule: "rate(1 day)"
16 | timeout: 300
17 | filters:
18 | - not:
19 | - or:
20 | - type: value
21 | key: "Logging"
22 | value: empty
23 | - type: value
24 | key: "Logging.TargetBucket"
25 | value: "^s3-access-logs-.*"
26 | op: regex
27 | actions:
28 | - type: notify
29 | template: s3-target-bucket-audit.html
30 | template_format: 'html'
31 | slack_template: slack-s3-target-bucket-audit
32 | priority_header: '5'
33 | subject: 'Security Audit: S3 Target Bucket Audit'
34 | to:
35 | - email@address.com
36 | - slack://#channel
37 | owner_absent_contact:
38 | - email@address.com
39 | transport:
40 | type: sqs
41 | queue: https://sqs.us-east-1.amazonaws.com/account_id/cloud-cloudcustodian
42 |
--------------------------------------------------------------------------------
/policies/security-groups-unused-notify.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: security-groups-unused
3 | resource: security-group
4 | description: |
5 | Retrieve unused security groups using regex.
6 | Notify using Simple Email Service (SES).
7 | To get a complete list, use value of .*
8 | To get a subset, use a regex pattern.
9 | filters:
10 | - unused
11 | - type: value
12 | key: GroupName
13 | op: regex
14 | value: .*
15 | actions:
16 | - type: notify
17 | template: default.html
18 | template_format: 'html'
19 | priority_header: '5'
20 | subject: 'CloudCustodian: Unused Security Groups'
21 | to:
22 | - email-address-goes-here
23 | owner_absent_contact:
24 | - email-address-goes-here
25 | transport:
26 | type: sqs
27 | queue: sqs-url-goes-here
28 |
--------------------------------------------------------------------------------
/policies/security-groups-unused.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: security-groups-unused
3 | resource: security-group
4 | description: |
5 | Retrieve unused security groups using regex.
6 | To get a complete list, use value of .*
7 | To get a subset, use a regex pattern.
8 | filters:
9 | - unused
10 | - type: value
11 | key: GroupName
12 | op: regex
13 | value: ".*wiz"
14 |
--------------------------------------------------------------------------------
/policies/sgroup-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: sgroup-audit
3 | resource: aws.security-group
4 | description: |
5 | Cloud Custodian Security Groups Audit
6 | comments: |
7 | Retrieve Security Groups that Match Filter
8 | filters:
9 | - type: ingress
10 | Cidr:
11 | value_type: cidr
12 | op: in
13 | value: 10.120.0.0/16
14 | - not:
15 | - type: ingress
16 | Cidr:
17 | value_type: cidr
18 | op: in
19 | value: 10.121.0.0/16
20 |
--------------------------------------------------------------------------------
/policies/slack-notify.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: slack-notify
3 | resource: security-group
4 | description: |
5 | Retrieve unused security groups using regex.
6 | Notify using Slack.
7 | To get a complete list, use value of .*
8 | To get a subset, use a regex pattern.
9 | filters:
10 | - unused
11 | - type: value
12 | key: GroupName
13 | op: regex
14 | value: .*
15 | actions:
16 | - type: notify
17 | template_slack: slack_default
18 | template_format: 'html'
19 | priority_header: '5'
20 | subject: 'CloudCustodian: Unused Security Groups'
21 | to:
22 | - slack://#cloudcustodianprivate
23 | owner_absent_contact:
24 | - email@address.com
25 | transport:
26 | type: sqs
27 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/sandbox
28 |
--------------------------------------------------------------------------------
/policies/ssm-managed-instance.yaml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: ssm-managed-instance
3 | resource: ssm-managed-instance
4 | description: |
5 | Cloud Custodian SSM Managed Instances
6 | comments: |
7 | Retrieve All SSM Managed Instance Attributes
8 | filters:
9 | - not:
10 | - type: value
11 | key: foo
12 | value: "foo"
13 |
--------------------------------------------------------------------------------
/policies/stopped-instances.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: stopped-instances
3 | resource: ec2
4 | description: |
5 | Cloud Custodian Stopped Instances Audit
6 | comments: |
7 | Retrieve list of all instances that
8 | - are stopped
9 | filters:
10 | - type: value
11 | key: VpcId
12 | value: vpc-b7407ed3
13 | - type: value
14 | key: State.Name
15 | value: stopped
16 |
17 |
--------------------------------------------------------------------------------
/policies/subnet-ip-address-usage-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: subnet-ip-address-usage-audit
3 | resource: subnet
4 | description: |
5 | Cloud Custodian Subnet IP Address Audit
6 | comments: |
7 | Periodically retrieve list of private subnets for specific availability zones.
8 | Generate email and Slack notifications when AvailableIpAddressCount
9 | is less-than 10 for specified regions.
10 | mode:
11 | type: periodic
12 | role: arn:aws:iam::123456789012:role/CloudCustodian
13 | schedule: "rate(1 hour)"
14 | packages: [boto3, botocore, urllib3]
15 | filters:
16 | - type: value
17 | key: State
18 | value: "available"
19 | - type: value
20 | key: AvailableIpAddressCount
21 | value: 10
22 | op: less-than
23 | - or:
24 | - type: value
25 | key: AvailabilityZone
26 | value: "us-east-1a"
27 | - type: value
28 | key: AvailabilityZone
29 | value: "us-east-1c"
30 | - type: value
31 | key: AvailabilityZone
32 | value: "us-east-1d"
33 | - type: value
34 | key: MapPublicIpOnLaunch
35 | value: false
36 | actions:
37 | - type: post-finding
38 | severity_normalized: 10
39 | types:
40 | - "Software and Configuration Checks/AWS Security Best Practices"
41 | - type: notify
42 | template: subnet-ip-address-usage-audit.html
43 | slack_template: slack-subnet-ip-address-usage-audit
44 | template_format: 'html'
45 | priority_header: '5'
46 | subject: 'Subnet Audit: Subnets running low on IP addresses'
47 | to:
48 | - cloudcustodianadmins@domain.com
49 | - slack://#custodian-alerts
50 | owner_absent_contact:
51 | - cloudcustodianadmins@domain.com
52 | transport:
53 | type: sqs
54 | queue: https://sqs.us-east-1.amazonaws.com/123456789012/cloud-cloudcustodian
55 |
--------------------------------------------------------------------------------
/policies/tag-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: tag-audit
3 | resource: ec2
4 | comment: |
5 | Retrieve list of all resources that match tag
6 | Note, ec2 is used as an example, but any resource that supports tags
7 | can be used. Simply replace the resource with the appropriate name.
8 | For example, replace ec2 with security-group if you want to filter
9 | against tagged security groups.
10 | filters:
11 | - "tag:Team": absent
12 | - type: value
13 | key: "tag:Owner"
14 | value: (.*mike\.garrison|.*amir\.kibbar|.*jon\.voigt|.*chris\.varnerin|.*nikos\.michalakis)
15 | op: regex
16 | # actions:
17 | # - type: tag
18 | # key: "Team"
19 | # value: "Cloud"
20 |
--------------------------------------------------------------------------------
/policies/team-tag-ec2-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: team-tag-audit
3 | resource: ec2
4 | description: |
5 | Cloud Custodian EC2 Team Tag Audit
6 | comments: |
7 | Retrieve list of all instances that
8 | - are missing the tag "Team"
9 | mode:
10 | type: periodic
11 | role: arn:aws:iam::123456789012:role/CloudCustodian
12 | schedule: "cron(0 20 * * ? *)"
13 | filters:
14 | - or:
15 | - "tag:Team": absent
16 | - "tag:Team": empty
17 | actions:
18 | - type: notify
19 | template: team-tag-ec2-audit.html
20 | slack_template: slack-team-tag-ec2-audit
21 | template_format: 'html'
22 | priority_header: '5'
23 | subject: 'Tag Audit: EC2 Instance(s) with no tag named Team'
24 | to:
25 | -
26 | - slack://#
27 | owner_absent_contact:
28 | -
29 | transport:
30 | type: sqs
31 | queue: https://sqs.us-east-1.amazonaws.com/123456789012/cloud-cloudcustodian
32 |
--------------------------------------------------------------------------------
/policies/team-tag-s3-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: team-tag-s3-audit
3 | resource: s3
4 | description: |
5 | Cloud Custodian S3 Team Tag Audit
6 | comments: |
7 | Periodically retrieve list of all S3 buckets that
8 | are missing the tag "Team" then send notification.
9 | mode:
10 | type: periodic
11 | role: arn:aws:iam::1234567890:role/CloudCustodian
12 | timeout: 300
13 | schedule: "cron(0 17 ? * MON-FRI *)"
14 | filters:
15 | - "tag:Team": absent
16 | actions:
17 | - type: notify
18 | template: team-tag-s3-audit.html
19 | slack_template: slack-team-tag-s3-audit
20 | template_format: 'html'
21 | priority_header: '5'
22 | subject: 'Tag Audit: S3 Bucket(s) with no tag named Team'
23 | to:
24 | -
25 | - slack://#
26 | owner_absent_contact:
27 | -
28 | transport:
29 | type: sqs
30 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/cloud-cloudcustodian
31 |
--------------------------------------------------------------------------------
/policies/termination-protection-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: termination-protection-audit
3 | resource: ec2
4 | query:
5 | - instance-state-name: running
6 | filters:
7 | - not:
8 | - type: termination-protected
9 | - or:
10 | - "tag:Name": instance-1
11 | - "tag:Name": instance-2
12 | - "tag:Name": etc
13 | actions:
14 | - type: notify
15 | template: termination-protection-audit.html
16 | slack_template: slack-termination-protection-audit
17 | template_format: 'html'
18 | priority_header: '5'
19 | subject: 'Security Audit: White Listed Instance(s) found with Termination Protection Disabled'
20 | to:
21 | -
22 | - slack://#
23 | owner_absent_contact:
24 | -
25 | transport:
26 | type: sqs
27 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/cloud-cloudcustodian
28 |
--------------------------------------------------------------------------------
/policies/termination-protection-list.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: termination-protection-list
3 | resource: ec2
4 | filters:
5 | - type: termination-protected
6 |
7 |
--------------------------------------------------------------------------------
/policies/unused-sgroup-audit.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: unused-sgroups-audit
3 | resource: security-group
4 | description: |
5 | Cloud Custodian Unused Security Group Audit
6 | comments: |
7 | Retrieve unused security groups using regex and delete.
8 | Notify using Simple Email Service (SES).
9 | To get a complete list, use value of .*
10 | To get a subset, use a regex pattern.
11 | mode:
12 | type: periodic
13 | role: arn:aws:iam::1234567890:role/CloudCustodian
14 | schedule: "rate(1 day)"
15 | filters:
16 | - unused
17 | - type: value
18 | key: GroupName
19 | op: regex
20 | value: ".*wizard"
21 | actions:
22 | - delete
23 | - type: notify
24 | template: unused-sgroup-audit.html
25 | slack_template: slack-unused-sgroup-audit
26 | template_format: 'html'
27 | priority_header: '5'
28 | subject: 'Security Audit: Unused Security Groups'
29 | to:
30 | -
31 | - slack://#
32 | owner_absent_contact:
33 | -
34 | transport:
35 | type: sqs
36 | queue: https://sqs.us-east-1.amazonaws.com/1234567890/cloud-cloudcustodian
37 |
--------------------------------------------------------------------------------
/policies/vpn.yml:
--------------------------------------------------------------------------------
1 | policies:
2 | - name: vpn_connections
3 | resource: vpn-connection
4 | description: |
5 | Cloud Custodian VPN Connections
6 | comments: |
7 | Retrieve all VPN Connections
8 | filters:
9 | - not:
10 | - "tag:Name": empty
11 |
--------------------------------------------------------------------------------
/scripts/custodian-iam-user-cross-account-audit.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # ===========
4 | # DESCRIPTION
5 | # ===========
6 | # This script is used as part of the TRI offboarding process to
7 | # retrieve a list of IAM users across all AWS accounts under the TRI org.
8 | #
9 | # This script uses c7n-org's orgaccounts.py script to generate a yml file named
10 | # offboading-orgaccounts.yml which contains the list of all known AWS accounts
11 | # under the TRI org.
12 | #
13 | # The offboarding-orgaccounts.yml file is then used by c7n-org to
14 | # search against all IAM users and write the results to file.
15 | #
16 | # VIM is used to open the file to quickly search for IAM user(s) being offboarded.
17 | #
18 | # Within vim, you can use the `/` command to search against usernames.
19 | # If a match is found, the account name that maps to the aws account number
20 | # can be found in the offboarding-oraccounts.yml file.
21 |
22 | # =========
23 | # VARIABLES
24 | # =========
25 | # ORGACCOUNTSPATH is the path where c7n-org's orgaccounts.py lives
26 | # ORGACCOUNTSFILE is the name of the file generated after orgaccounts.py is invoked
27 | # C7NORGPATH is the path where the output file offboarding-iam-users-audit.yml is stored
28 |
29 | ORGACCOUNTSPATH="/home/ubuntu/cloud-custodian/tools/c7n_org/scripts"
30 | ORGACCOUNTSFILE="offboarding-orgaccounts.yml"
31 | C7NORGPATH="/home/ubuntu/cloudcustodian/policies/c7n-org"
32 |
33 |
34 | echo "Creating $ORGACCOUNTSFILE file. This will take a minute..."
35 | #python $ORGACCOUNTSPATH/orgaccounts.py -f $ORGACCOUNTSPATH/$ORGACCOUNTSFILE
36 | python $ORGACCOUNTSPATH/orgaccounts.py -f /home/ubuntu/$ORGACCOUNTSFILE
37 | echo "offboarding-orgaccounts.yml file successfully created!"
38 |
39 | echo "Retrieving list of all IAM users across org..."
40 | echo "You will be taken into a VIM session upon completion"
41 | echo "Use the forward slash '/' to search file against IAM user(s)"
42 | read -p "Press enter to continue..."
43 |
44 | source "/home/ubuntu/c7n_org/bin/activate"
45 | c7n-org run -s output -c $ORGACCOUNTSPATH/$ORGACCOUNTSFILE -u $C7NORGPATH/offboarding-iam-users-audit.yml
46 | #c7n-org report -c $ORGACCOUNTSPATH/$ORGACCOUNTSFILE -u $C7NORGPATH/offboarding-iam-users-audit.yml -s output --region us-east-1 > /home/ubuntu/cloudcustodian/policies/c7n
47 | -org/offboarding-iam-users-audit.txt
48 | c7n-org report -c /home/ubuntu/$ORGACCOUNTSFILE -u $C7NORGPATH/offboarding-iam-users-audit.yml -s output --region all > /home/ubuntu/offboarding-iam-users-audit.txt
49 | vim /home/ubuntu/offboarding-iam-users-audit.txt
50 | echo "IAM user audit across accounts completed"
51 | echo "If you would like to see the results again, see file /home/ubuntu/offboarding-iam-users-audit.txt"
52 | echo "To get the account name to account ID mapping, see file /home/ubuntu/offboarding-orgaccounts.yml"
53 |
--------------------------------------------------------------------------------
/scripts/get-iam-roleids.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # by David Lin
4 |
5 | # ===========
6 | # DESCRIPTION
7 | # ===========
8 | # This script is used to fetch all IAM RoleIds across all accounts.
9 | #
10 | # This script uses c7n-org's orgaccounts.py script to generate a yml file named
11 | # all-orgaccounts.yml which contains the list of all known AWS accounts
12 | # under the TRI org.
13 | #
14 | # The all-orgaccounts.yml file is then used by c7n-org to
15 | # search against all IAM roles and write the results to file.
16 | #
17 | # VIM is used to open the file to quickly search for IAM RoleIds and RoleNames.
18 | #
19 | # Within vim, you can use the `/` command to search against role names.
20 | # If a match is found, the account name that maps to the aws account number
21 | # can be found in the offboarding-oraccounts.yml file.
22 |
23 | # =========
24 | # VARIABLES
25 | # =========
26 | # |-------------------+--------------------------------------------------------------|
27 | # | Variable Name | Description |
28 | # |-------------------+--------------------------------------------------------------|
29 | # | ORG_ACCOUNTS_FILE | filename generated by c7n-org's orgaccounts.py |
30 | # | | after orgaccounts.py is invoked |
31 | # | | this file is saved in the $HOME directory for easy retrieval |
32 | # |-------------------+--------------------------------------------------------------|
33 | # | ORG_ACCOUNTS_PATH | path where c7n-org's orgaccounts.py lives |
34 | # |-------------------+--------------------------------------------------------------|
35 | # | C7N_ORG_PATH | path where the output file ourput-iam-roleids.yml is stored |
36 | # |-------------------+--------------------------------------------------------------|
37 | # | CUSTODIAN_POLICY | name of cloud custodian policy that retrieves iam roles |
38 | # |-------------------+--------------------------------------------------------------|
39 | # | REGION | AWS region |
40 | # |-------------------+--------------------------------------------------------------|
41 |
42 | ORG_ACCOUNTS_FILE="all-orgaccounts.yml"
43 | ORG_ACCOUNTS_PATH="${HOME}/cloud-custodian/tools/c7n_org/scripts"
44 | C7N_ORG_PATH="${HOME}/cloudcustodian/policies/c7n-org"
45 | CUSTODIAN_POLICY="iam-role.yml"
46 | OUTPUT_IAM_ROLEIDS="${HOME}/output-iam-roleids.txt"
47 | REGION="us-east-1"
48 |
49 | read -p "Use latest list of all accounts? [y|n]:" response
50 |
51 | if [ "${response}" = "y" ]
52 | then
53 | # ============================
54 | # CREATE all-accounts.yml FILE
55 | # ============================
56 | echo "Creating ${HOME}/${ORG_ACCOUNTS_FILE} file. This will take a minute..."
57 | python $ORG_ACCOUNTS_PATH/orgaccounts.py -f $HOME/$ORG_ACCOUNTS_FILE
58 | echo "${HOME}/${ORG_ACCOUNTS_FILE} successfully created!"
59 |
60 | echo "Retrieving list of all IAM roles across org..."
61 | echo "You will be taken into a VIM session upon completion"
62 | echo "Use the forward slash '/' to search file against IAM role(s)"
63 | read -p "Press enter to continue..."
64 | else
65 | echo "Using last known list of accounts..."
66 | fi
67 |
68 |
69 | # Activate c7n-org virtual environment
70 | source $HOME/c7n_org/bin/activate
71 | c7n-org run -s output -c $HOME/$ORG_ACCOUNTS_FILE -u $C7N_ORG_PATH/$CUSTODIAN_POLICY --region $REGION
72 | c7n-org report -c $HOME/$ORG_ACCOUNTS_FILE -u $C7N_ORG_PATH/$CUSTODIAN_POLICY -s output --no-default-fields --field RoleId=RoleId --field RoleName=RoleName --region us-east-
73 | 1 > $OUTPUT_IAM_ROLEIDS
74 | vim $OUTPUT_IAM_ROLEIDS
75 |
76 | echo "==================================================="
77 | echo "IAM role audit across accounts completed"
78 | echo "If you would like to see the results again, see file $OUTPUT_IAM_ROLEIDS
79 | echo "To get the role name to account ID mapping, see file $OUTPUT_IAM_ROLEIDS
80 |
--------------------------------------------------------------------------------
/scripts/get-iam-userids.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # by David Lin
4 |
5 | # ===========
6 | # DESCRIPTION
7 | # ===========
8 | # This script is used to fetch all IAM user IDs across all accounts.
9 | #
10 | # This script uses c7n-org's orgaccounts.py script to generate a yml file named
11 | # all-orgaccounts.yml which contains the list of all known AWS accounts
12 | # under the TRI org.
13 | #
14 | # The all-orgaccounts.yml file is then used by c7n-org to
15 | # search against all IAM users and write the results to file.
16 | #
17 | # VIM is used to open the file to quickly search for IAM UserIds and UserIds.
18 | #
19 | # Within vim, you can use the `/` command to search against usernames.
20 | # If a match is found, the account name that maps to the aws account number
21 | # can be found in the offboarding-oraccounts.yml file.
22 |
23 | # =========
24 | # VARIABLES
25 | # =========
26 | # |-------------------+--------------------------------------------------------------|
27 | # | Variable Name | Description |
28 | # |-------------------+--------------------------------------------------------------|
29 | # | ORG_ACCOUNTS_FILE | filename generated by c7n-org's orgaccounts.py |
30 | # | | after orgaccounts.py is invoked |
31 | # | | this file is saved in the $HOME directory for easy retrieval |
32 | # |-------------------+--------------------------------------------------------------|
33 | # | ORG_ACCOUNTS_PATH | path where c7n-org's orgaccounts.py lives |
34 | # |-------------------+--------------------------------------------------------------|
35 | # | C7N_ORG_PATH | path where the output file iam-userids-audit.yml is stored |
36 | # |-------------------+--------------------------------------------------------------|
37 | # | CUSTODIAN_POLICY | name of cloud custodian policy that retrieves iam users |
38 | # |-------------------+--------------------------------------------------------------|
39 | # | REGION | AWS region |
40 | # |-------------------+--------------------------------------------------------------|
41 |
42 | ORG_ACCOUNTS_FILE="all-orgaccounts.yml"
43 | ORG_ACCOUNTS_PATH="${HOME}/cloud-custodian/tools/c7n_org/scripts"
44 | C7N_ORG_PATH="${HOME}/cloudcustodian/policies/c7n-org"
45 | OUTPUT_IAM_USERIDS="${HOME}/output-iam-userids.txt"
46 | CUSTODIAN_POLICY="iam-user.yml"
47 | REGION="us-east-1"
48 |
49 | read -p "Use latest list of all accounts? [y|n]:" response
50 |
51 | if [ "${response}" = "y"]
52 | then
53 | # ====================================
54 | # CREATE LATEST all-accounts.yml FILE
55 | # ====================================
56 | echo "Creating ${HOME}/${ORG_ACCOUNTS_FILE} file. This will take a minute..."
57 | python $ORG_ACCOUNTS_PATH/orgaccounts.py -f $HOME/$ORG_ACCOUNTS_FILE
58 | echo "${HOME}/${ORG_ACCOUNTS_FILE} successfully created!"
59 |
60 | echo "Retrieving list of all IAM users across org..."
61 | echo "You will be taken into a VIM session upon completion"
62 | echo "Use the forward slash '/' to search file against IAM user(s)"
63 | read -p "Press enter to continue..."
64 | else
65 | echo "Using last known list of accounts..."
66 | fi
67 |
68 |
69 | # Activate c7n-org virtual environment
70 | source $HOME/c7n_org/bin/activate
71 | c7n-org run -s output -c $HOME/$ORG_ACCOUNTS_FILE -u $C7N_ORG_PATH/$CUSTODIAN_POLICY --region $REGION
72 | c7n-org report -c $HOME/$ORG_ACCOUNTS_FILE -u $C7N_ORG_PATH/$CUSTODIAN_POLICY -s output --no-default-fields --field UserId=UserId --field UserName=UserName --region us-east-
73 | 1 > $OUTPUT_IAM_USERIDS
74 | vim $OUTPUT_IAM_USERIDS
75 |
76 | echo "==================================================="
77 | echo "IAM user audit across accounts completed"
78 | echo "If you would like to see the results again, see file $OUTPUT_IAM_USERIDS
79 | echo "To get the account name to account ID mapping, see file $OUTPUT_IAM_USERIDS
80 |
--------------------------------------------------------------------------------
/scripts/list-custodian-schema-health-event-support.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Find aws resources that support the "health-event" filter with "issue" category
4 | #
5 |
6 | # List of services from 'custodian schema'
7 | SERVICE=account,acm-certificate,alarm,ami,app-elb,app-elb-target-group,asg,backup-plan,batch-compute,batch-definition,cache-cluster,cache-snapsho
8 | t,cache-subnet-group,cfn,cloud-directory,cloudhsm-cluster,cloudsearch,cloudtrail,codebuild,codecommit,codepipeline,config-recorder,config-rule,cu
9 | stomer-gateway,datapipeline,dax,directconnect,directory,distribution,dlm-policy,dms-endpoint,dms-instance,dynamodb-backup,dynamodb-stream,dynamod
10 | b-table,ebs,ebs-snapshot,ec2,ec2-reserved,ecr,ecs,ecs-container-instance,ecs-service,ecs-task,ecs-task-definition,efs,efs-mount-target,eks,elasti
11 | cbeanstalk,elasticbeanstalk-environment,elasticsearch,elb,emr,eni,event-rule,event-rule-target,firehose,fsx,fsx-backup,gamelift-build,gamelift-fl
12 | eet,glacier,glue-connection,glue-crawler,glue-database,glue-dev-endpoint,glue-job,glue-table,health-event,healthcheck,hostedzone,hsm,hsm-client,h
13 | sm-hapg,iam-certificate,iam-group,iam-policy,iam-profile,iam-role,iam-user,identity-pool,internet-gateway,iot,kafka,key-pair,kinesis,kinesis-anal
14 | ytics,kms,kms-key,lambda,lambda-layer,launch-config,launch-template-version,lightsail-db,lightsail-elb,lightsail-instance,log-group,message-broke
15 | r,ml-model,nat-gateway,network-acl,network-addr,ops-item,opswork-cm,opswork-stack,peering-connection,r53domain,rds,rds-cluster,rds-cluster-param-
16 | group,rds-cluster-snapshot,rds-param-group,rds-reserved,rds-snapshot,rds-subnet-group,rds-subscription,redshift,redshift-snapshot,redshift-subnet
17 | -group,rest-account,rest-api,rest-resource,rest-stage,rest-vpclink,route-table,rrset,s3,sagemaker-endpoint,sagemaker-endpoint-config,sagemaker-jo
18 | b,sagemaker-model,sagemaker-notebook,sagemaker-transform-job,secrets-manager,security-group,shield-attack,shield-protection,simpledb,snowball,sno
19 | wball-cluster,sns,sqs,ssm-activation,ssm-managed-instance,ssm-parameter,step-machine,storage-gateway,streaming-distribution,subnet,support-case,t
20 | ransit-attachment,transit-gateway,user-pool,vpc,vpc-endpoint,vpn-connection,vpn-gateway,waf,waf-regional,workspaces
21 |
22 | # Delete old result file
23 | rm result
24 |
25 | # Iterate custodian schema
26 | echo '-----------------------------------------------------------------' >> result
27 | echo 'custodian schema service_name.filters.health-event | grep issue' >> result
28 | echo '-----------------------------------------------------------------' >> result
29 |
30 |
31 | for i in $(echo $SERVICE | sed "s/,/ /g")
32 | do
33 | # Loop through the SERVICE list
34 | echo $i >> result
35 | custodian schema $i.filters.health-event | grep issue >> result
36 | echo '-----------------------------------------------------------------' >> result
37 | done
38 |
--------------------------------------------------------------------------------
/scripts/report-with-user-input.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # This script invokes the Cloud Custodian iam-user-tagged-resources-audit.yml
4 | # policy then generates a consolidated report of AWS resources
5 | # that match the given IAM user specified by the Owner tag.
6 | #
7 | # To change the owner, find/replace the IAM user in
8 | # iam-user-tagged-resource.audit.yml.
9 | #
10 | # By default, the policy is invoked in us-east-1.
11 | # The region can be modified by changing the value of variable 'REGION'.
12 | #
13 | # Upon completion, the consolidated report can be found here:
14 | # /home/ubuntu/cloudcustodian/policies/report.xt
15 | #
16 |
17 | # Variables
18 | RESOURCE=ebs,ebs-snapshot,security-group,s3,ami,dynamodb-table,dynamodb-stream,dynamodb-backup,elasticsearch,elb,eni,lambda,lambda-layer,rds,s3,sqs,sns,cfn
19 | REGION="--region us-east-1"
20 | CUSTODIAN_POLICY="/home/ubuntu/cloudcustodian/policies/iam-user-tagged-resources-audit.yml"
21 | CUSTODIAN_OUTPUT_DIRECTORY="/home/ubuntu/cloudcustodian/policies/output"
22 | CUSTODIAN_REPORT="/home/ubuntu/cloudcustodian/policies/report.txt"
23 |
24 | # User input
25 | read -p "Enter AWS username: " aws_username
26 | read -p "Enter GHE username: " ghe_username
27 | read -s -p "Enter GHE password: " ghe_password
28 |
29 | # Activate c7n virtual environment
30 | cd /home/ubuntu
31 | source c7n_mailer/bin/activate
32 |
33 | # Clear c7n cache
34 | echo '------------------'
35 | echo 'Clearing c7n cache '
36 | echo '------------------'
37 | rm /home/ubuntu/.cache/cloud-custodian.cache
38 | echo '~/.cachecloud-custodian.cache cleared'
39 |
40 | # Invoke c7n policy
41 | echo '-------------------'
42 | echo 'Invoking c7n policy'
43 | echo '-------------------'
44 | custodian run -s $CUSTODIAN_OUTPUT_DIRECTORY $CUSTODIAN_POLICY $REGION
45 |
46 | # Generate c7n reports
47 | echo '-------------------------------'
48 | echo 'Generating report for resources'
49 | echo '-------------------------------'
50 |
51 | # Write ec2 report to file
52 | echo 'ec2'
53 | echo 'ec2' > $CUSTODIAN_REPORT
54 | custodian report -s $CUSTODIAN_OUTPUT_DIRECTORY -t ec2 $CUSTODIAN_POLICY --field tag:Owner=tag:Owner --format grid >> $CUSTODIAN_REPORT
55 | echo ' ' >> $CUSTODIAN_REPORT
56 |
57 | # Append more resources to file
58 | for i in $(echo $RESOURCE | sed "s/,/ /g")
59 | do
60 | # Loop through the RESOURCE list
61 | echo $i
62 | echo $i >> $CUSTODIAN_REPORT
63 | custodian report -s $CUSTODIAN_OUTPUT_DIRECTORY -t $i $CUSTODIAN_POLICY --field tag:Owner=tag:Owner --format grid >> $CUSTODIAN_REPORT
64 | echo ' ' >> $CUSTODIAN_REPORT
65 | done
66 |
67 | echo ''
68 | echo '-------------------------------'
69 | echo 'Report'
70 | echo '-------------------------------'
71 | #more $CUSTODIAN_REPORT
72 |
73 | echo 'Copy report.txt to ~/offboarding'
74 | DATE=`date +%Y-%m-%d`
75 | cp /home/ubuntu/cloudcustodian/policies/report.txt /home/ubuntu/offboarding-aws-audit/$DATE-$aws_username-'report'
76 |
77 | echo '------------------------------------------------'
78 | echo 'Push report.txt to IE/offboarding-aws-audit repo'
79 | echo '------------------------------------------------'
80 | cd /home/ubuntu/offboarding-aws-audit/
81 | git pull https://$ghe_username:$ghe_password@github.awsinternal.tri.global/IE/offboarding-aws-audit
82 | git add /home/ubuntu/offboarding-aws-audit/$DATE-$aws_username-'report'
83 | git commit -m 'AWS audit report'
84 | git push https://$ghe_username:$ghe_password@github.awsinternal.tri.global/IE/offboarding-aws-audit
85 |
86 | echo ''
87 | echo 'Report committed to IE/offboarding-aws-audit repo '
88 | echo 'Local copy here /home/ubuntu/cloudcustodian/policies/report.txt'
89 | echo 'Report completed!
90 |
--------------------------------------------------------------------------------
/scripts/report.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # This script invokes the Cloud Custodian iam-user-tagged-resources-audit.yml
4 | # policy then generates a consolidated report of AWS resources
5 | # that match the given IAM user specified by the Owner tag.
6 | #
7 | # To change the owner, find/replace the IAM user in
8 | # iam-user-tagged-resource.audit.yml.
9 | #
10 | # By default, the policy is invoked in us-east-1.
11 | # The region can be modified by changing the value of variable 'REGION'.
12 | #
13 | # Upon completion, the consolidated report can be found here:
14 | # /home/ubuntu/cloudcustodian/policies/report.txt
15 | #
16 |
17 | # Variables
18 | RESOURCE=ebs,ebs-snapshot,security-group,s3,ami,dynamodb-table,dynamodb-stream,dynamodb-backup,elasticsearch,elb,eni,lambda,lambda-layer,rds,s3,sqs,sns,cfn
19 | REGION="--region us-east-1"
20 | CUSTODIAN_POLICY="/home/ubuntu/cloudcustodian/policies/iam-user-tagged-resources-audit.yml"
21 | CUSTODIAN_OUTPUT_DIRECTORY="/home/ubuntu/cloudcustodian/policies/output"
22 | CUSTODIAN_REPORT="/home/ubuntu/cloudcustodian/policies/report.txt"
23 |
24 | # Activate c7n virtual environment
25 | cd /home/ubuntu
26 | source c7n_mailer/bin/activate
27 |
28 | # Clear c7n cache
29 | echo '------------------'
30 | echo 'Clearing c7n cache '
31 | echo '------------------'
32 | rm /home/ubuntu/.cache/cloud-custodian.cache
33 | echo '~/.cachecloud-custodian.cache cleared'
34 |
35 | # Invoke c7n policy
36 | echo '-------------------'
37 | echo 'Invoking c7n policy'
38 | echo '-------------------'
39 | custodian run -s $CUSTODIAN_OUTPUT_DIRECTORY $CUSTODIAN_POLICY $REGION
40 |
41 | # Generate c7n reports
42 | echo '-------------------------------'
43 | echo 'Generating report for resources'
44 | echo '-------------------------------'
45 |
46 | # Write ec2 report to file
47 | echo 'ec2'
48 | echo 'ec2' > $CUSTODIAN_REPORT
49 | custodian report -s $CUSTODIAN_OUTPUT_DIRECTORY -t ec2 $CUSTODIAN_POLICY --field tag:Owner=tag:Owner --format grid >> $CUSTODIAN_REPORT
50 | echo ' ' >> $CUSTODIAN_REPORT
51 |
52 | # Append more resources to file
53 | for i in $(echo $RESOURCE | sed "s/,/ /g")
54 | do
55 | # Loop through the RESOURCE list
56 | echo $i
57 | echo $i >> $CUSTODIAN_REPORT
58 | custodian report -s $CUSTODIAN_OUTPUT_DIRECTORY -t $i $CUSTODIAN_POLICY --field tag:Owner=tag:Owner --format grid >> $CUSTODIAN_REPORT
59 | echo ' ' >> $CUSTODIAN_REPORT
60 | done
61 |
62 | echo ''
63 | echo '-------------------------------'
64 | echo 'Report'
65 | echo '-------------------------------'
66 | more $CUSTODIAN_REPORT
67 |
68 | echo ''
69 | echo 'Report completed! '
70 | echo 'See /home/ubuntu/cloudcustodian/policies/report.txt'
71 |
--------------------------------------------------------------------------------
/scripts/report_with_user_inputs_and_auto_commit.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # This script invokes the Cloud Custodian iam-user-tagged-resources-audit.yml
4 | # policy then generates a consolidated report of AWS resources
5 | # that match the given IAM user specified by the Owner tag.
6 | #
7 | # To change the owner, find/replace the IAM user in
8 | # iam-user-tagged-resource.audit.yml.
9 | #
10 | # By default, the policy is invoked in us-east-1.
11 | # The region can be modified by changing the value of variable 'REGION'.
12 | #
13 | # Upon completion, the consolidated report can be found here:
14 | # /home/ubuntu/cloudcustodian/policies/report.xt
15 | #
16 |
17 | # Variables
18 | RESOURCE=ebs,ebs-snapshot,security-group,s3,ami,dynamodb-table,dynamodb-stream,dynamodb-backup,elasticsearch,elb,eni,lambda,lambda-layer,rds,s3,sqs,sns,cfn
19 | REGION="--region us-east-1"
20 | CUSTODIAN_POLICY="/home/ubuntu/cloudcustodian/policies/iam-user-tagged-resources-audit.yml"
21 | CUSTODIAN_OUTPUT_DIRECTORY="/home/ubuntu/cloudcustodian/policies/output"
22 | CUSTODIAN_REPORT="/home/ubuntu/cloudcustodian/policies/report.txt"
23 |
24 | # User input
25 | read -p "Enter AWS username: " aws_username
26 | read -p "Enter GHE username: " ghe_username
27 | read -s -p "Enter GHE password: " ghe_password
28 |
29 | # Activate c7n virtual environment
30 | cd /home/ubuntu
31 | source c7n_mailer/bin/activate
32 |
33 | # Clear c7n cache
34 | echo '------------------'
35 | echo 'Clearing c7n cache '
36 | echo '------------------'
37 | rm /home/ubuntu/.cache/cloud-custodian.cache
38 | echo '~/.cachecloud-custodian.cache cleared'
39 |
40 | # Invoke c7n policy
41 | echo '-------------------'
42 | echo 'Invoking c7n policy'
43 | echo '-------------------'
44 | custodian run -s $CUSTODIAN_OUTPUT_DIRECTORY $CUSTODIAN_POLICY $REGION
45 |
46 | # Generate c7n reports
47 | echo '-------------------------------'
48 | echo 'Generating report for resources'
49 | echo '-------------------------------'
50 |
51 | # Write ec2 report to file
52 | echo 'ec2'
53 | echo 'ec2' > $CUSTODIAN_REPORT
54 | custodian report -s $CUSTODIAN_OUTPUT_DIRECTORY -t ec2 $CUSTODIAN_POLICY --field tag:Owner=tag:Owner --format grid >> $CUSTODIAN_REPORT
55 | echo ' ' >> $CUSTODIAN_REPORT
56 |
57 | # Append more resources to file
58 | for i in $(echo $RESOURCE | sed "s/,/ /g")
59 | do
60 | # Loop through the RESOURCE list
61 | echo $i
62 | echo $i >> $CUSTODIAN_REPORT
63 | custodian report -s $CUSTODIAN_OUTPUT_DIRECTORY -t $i $CUSTODIAN_POLICY --field tag:Owner=tag:Owner --format grid >> $CUSTODIAN_REPORT
64 | echo ' ' >> $CUSTODIAN_REPORT
65 | done
66 |
67 | echo ''
68 | echo '-------------------------------'
69 | echo 'Report'
70 | echo '-------------------------------'
71 | #more $CUSTODIAN_REPORT
72 |
73 | echo 'Copy report.txt to ~/offboarding'
74 | DATE=`date +%Y-%m-%d`
75 | cp /home/ubuntu/cloudcustodian/policies/report.txt /home/ubuntu/offboarding-aws-audit/$DATE-$aws_username-'report'
76 |
77 | echo '------------------------------------------------'
78 | echo 'Push report.txt to IE/offboarding-aws-audit repo'
79 | echo '------------------------------------------------'
80 | cd /home/ubuntu/offboarding-aws-audit/
81 | git pull https://$ghe_username:$ghe_password@github.awsinternal.tri.global/IE/offboarding-aws-audit
82 | git add /home/ubuntu/offboarding-aws-audit/$DATE-$aws_username-'report'
83 | git commit -m 'AWS audit report'
84 | git push https://$ghe_username:$ghe_password@github.awsinternal.tri.global/IE/offboarding-aws-audit
85 |
86 | echo ''
87 | echo 'Report completed! '
88 | echo 'See /home/ubuntu/cloudcustodian/policies/report.txt'
89 |
--------------------------------------------------------------------------------
/update-mailer-lambda.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | c7n-mailer --config /home/ubuntu/cloudcustodian/mailer.yml --update-lambda
3 |
--------------------------------------------------------------------------------