ansible/test/integration/targets/cloudtrail/tasks/main.yml

1424 lines
39 KiB
YAML
Raw Normal View History

---
# General Tests:
# - s3_bucket_name required when state is 'present'
# - Creation / Deletion
# - Enable/Disable logging
# - Enable/Disable log file validation option
# - Manipulation of Global Event logging option
# - Manipulation of Multi-Region logging option
# - Manipulation of S3 bucket option
# - Manipulation of Encryption option
# - Manipulation of SNS options
# - Manipulation of CloudWatch Log group options
# - Manipulation of Tags
#
# Notes:
# - results include the updates, even when check_mode is true
# - Poor handling of disable global + enable multi-region
# botocore.errorfactory.InvalidParameterCombinationException: An error
# occurred (InvalidParameterCombinationException) when calling the
# UpdateTrail operation: Multi-Region trail must include global service
# events.
# - Using blank string for KMS ID doesn't remove encryption
# - Using blank string for SNS Topic doesn't remove it
# - Using blank string for CloudWatch Log Group / Role doesn't remove them
#
# Possible Bugs:
# - output.exists == false when creating
# - Changed reports true when using a KMS alias
# - Tags Keys are being lower-cased
- module_defaults:
group/aws:
aws_access_key: '{{ aws_access_key }}'
aws_secret_key: '{{ aws_secret_key }}'
security_token: '{{ security_token | default(omit) }}'
region: '{{ aws_region }}'
# Add this as a default because we (almost) always need it
cloudtrail:
s3_bucket_name: '{{ s3_bucket_name }}'
block:
# ============================================================
# Argument Tests
# ============================================================
- name: 'S3 Bucket required when state is "present"'
module_defaults: { cloudtrail: {} }
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
register: output
ignore_errors: yes
- assert:
that:
- output is failed
- '"s3_bucket_name" in output.msg'
- name: 'CloudWatch cloudwatch_logs_log_group_arn required when cloudwatch_logs_role_arn passed'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
cloudwatch_logs_role_arn: 'SomeValue'
register: output
ignore_errors: yes
- assert:
that:
- output is failed
- '"parameters are required together" in output.msg'
- '"cloudwatch_logs_log_group_arn" in output.msg'
- name: 'CloudWatch cloudwatch_logs_role_arn required when cloudwatch_logs_log_group_arn passed'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
cloudwatch_logs_log_group_arn: 'SomeValue'
register: output
ignore_errors: yes
- assert:
that:
- output is failed
- '"parameters are required together" in output.msg'
- '"cloudwatch_logs_role_arn" in output.msg'
#- name: 'Global Logging must be enabled when enabling Multi-region'
# cloudtrail:
# state: present
# name: '{{ cloudtrail_name }}'
# include_global_events: no
# is_multi_region_trail: yes
# register: output
# ignore_errors: yes
#- assert:
# that:
# - output is failed
# ============================================================
# Preparation
# ============================================================
- name: 'Retrieve caller facts'
aws_caller_info: {}
register: aws_caller_info
- name: 'Create S3 bucket'
vars:
bucket_name: '{{ s3_bucket_name }}'
s3_bucket:
state: present
name: '{{ bucket_name }}'
policy: '{{ lookup("template", "s3-policy.j2") }}'
- name: 'Create second S3 bucket'
vars:
bucket_name: '{{ s3_bucket_name }}-2'
s3_bucket:
state: present
name: '{{ bucket_name }}'
policy: '{{ lookup("template", "s3-policy.j2") }}'
- name: 'Create SNS Topic'
vars:
sns_topic_name: '{{ sns_topic }}'
sns_topic:
state: present
name: '{{ sns_topic_name }}'
display_name: 'Used for testing SNS/CloudWatch integration'
policy: "{{ lookup('template', 'sns-policy.j2') | to_json }}"
register: output_sns_topic
- name: 'Create second SNS Topic'
vars:
sns_topic_name: '{{ sns_topic }}-2'
sns_topic:
state: present
name: '{{ sns_topic_name }}'
display_name: 'Used for testing SNS/CloudWatch integration'
policy: "{{ lookup('template', 'sns-policy.j2') | to_json }}"
- name: 'Create KMS Key'
aws_kms:
state: present
alias: '{{ kms_alias }}'
enabled: yes
policy: "{{ lookup('template', 'kms-policy.j2') | to_json }}"
register: kms_key
- name: 'Create second KMS Key'
aws_kms:
state: present
alias: '{{ kms_alias }}-2'
enabled: yes
policy: "{{ lookup('template', 'kms-policy.j2') | to_json }}"
register: kms_key2
- name: 'Create CloudWatch IAM Role'
iam_role:
state: present
name: '{{ cloudwatch_role }}'
assume_role_policy_document: "{{ lookup('template', 'cloudwatch-assume-policy.j2') }}"
register: output_cloudwatch_role
- name: 'Create CloudWatch Log Group'
cloudwatchlogs_log_group:
state: present
log_group_name: '{{ cloudwatch_log_group }}'
retention: 1
register: output_cloudwatch_log_group
- name: 'Create second CloudWatch Log Group'
cloudwatchlogs_log_group:
state: present
log_group_name: '{{ cloudwatch_log_group }}-2'
retention: 1
register: output_cloudwatch_log_group2
- name: 'Add inline policy to CloudWatch Role'
iam_policy:
state: present
iam_type: role
iam_name: '{{ cloudwatch_role }}'
policy_name: 'CloudWatch'
policy_json: "{{ lookup('template', 'cloudwatch-policy.j2') | to_json }}"
# ============================================================
# Tests
# ============================================================
- name: 'Create a trail (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Create a trail'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
register: output
- assert:
that:
- output is changed
# XXX This appears to be a bug...
#- output.exists == True
- output.trail.name == cloudtrail_name
- name: 'No-op update to trail'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
register: output
- assert:
that:
- output is not changed
- output.exists == True
# Check everything is what we expect before we start making changes
- output.trail.name == cloudtrail_name
- output.trail.home_region == aws_region
- output.trail.include_global_service_events == True
- output.trail.is_multi_region_trail == False
- output.trail.is_logging == True
- output.trail.log_file_validation_enabled == False
- output.trail.s3_bucket_name == s3_bucket_name
- output.trail.s3_key_prefix is none
- output.trail.kms_key_id is none
- output.trail.sns_topic_arn is none
- output.trail.sns_topic_name is none
- output.trail.tags | length == 0
# ============================================================
- name: 'Set S3 prefix (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
s3_key_prefix: '{{ cloudtrail_prefix }}'
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Set S3 prefix'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
s3_key_prefix: '{{ cloudtrail_prefix }}'
register: output
- assert:
that:
- output is changed
- output.trail.name == cloudtrail_name
- output.trail.s3_key_prefix == cloudtrail_prefix
- name: 'Set S3 prefix (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
s3_key_prefix: '{{ cloudtrail_prefix }}'
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.s3_key_prefix == cloudtrail_prefix
- name: 'No-op update to trail'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.s3_key_prefix == cloudtrail_prefix
- name: 'Update S3 prefix (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
s3_key_prefix: '{{ cloudtrail_prefix }}-2'
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Update S3 prefix'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
s3_key_prefix: '{{ cloudtrail_prefix }}-2'
register: output
- assert:
that:
- output is changed
- output.trail.name == cloudtrail_name
- 'output.trail.s3_key_prefix == "{{ cloudtrail_prefix }}-2"'
- name: 'Update S3 prefix (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
s3_key_prefix: '{{ cloudtrail_prefix }}-2'
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- 'output.trail.s3_key_prefix == "{{ cloudtrail_prefix }}-2"'
- name: 'Remove S3 prefix (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
s3_key_prefix: '/'
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Remove S3 prefix'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
s3_key_prefix: '/'
register: output
- assert:
that:
- output is changed
- output.trail.name == cloudtrail_name
- output.trail.s3_key_prefix is none
- name: 'Remove S3 prefix (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
s3_key_prefix: '/'
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.s3_key_prefix is none
# ============================================================
- name: 'Add Tag (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
tags:
tag1: Value1
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Add Tag'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
tags:
tag1: Value1
register: output
- assert:
that:
- output is changed
- output.trail.name == cloudtrail_name
- output.trail.tags | length == 1
- '("tag1" in output.trail.tags) and (output.trail.tags["tag1"] == "Value1")'
- name: 'Add Tag (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
tags:
tag1: Value1
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.tags | length == 1
- '("tag1" in output.trail.tags) and (output.trail.tags["tag1"] == "Value1")'
- name: 'Change tags (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
tags:
tag2: Value2
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Change tags'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
tags:
tag2: Value2
register: output
- assert:
that:
- output is changed
- output.trail.name == cloudtrail_name
- output.trail.tags | length == 1
- '("tag2" in output.trail.tags) and (output.trail.tags["tag2"] == "Value2")'
- name: 'Change tags (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
tags:
tag2: Value2
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.tags | length == 1
- '("tag2" in output.trail.tags) and (output.trail.tags["tag2"] == "Value2")'
- name: 'Change tags (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
tags:
tag2: Value2
Tag3: Value3
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Change tags'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
tags:
tag2: Value2
Tag3: Value3
register: output
- assert:
that:
- output is changed
- output.trail.name == cloudtrail_name
- output.trail.tags | length == 2
- '("tag2" in output.trail.tags) and (output.trail.tags["tag2"] == "Value2")'
#- '("Tag3" in output.trail.tags) and (output.trail.tags["Tag3"] == "Value3")'
- name: 'Change tags (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
tags:
tag2: Value2
Tag3: Value3
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.tags | length == 2
- '("tag2" in output.trail.tags) and (output.trail.tags["tag2"] == "Value2")'
#- '("Tag3" in output.trail.tags) and (output.trail.tags["Tag3"] == "Value3")'
- name: 'Remove tags (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Remove tags'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
register: output
- assert:
that:
- output is changed
- output.trail.name == cloudtrail_name
- output.trail.tags | length == 0
- name: 'Remove tags (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.tags | length == 0
# ============================================================
- name: 'Set SNS Topic (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
sns_topic_name: '{{ sns_topic }}'
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Set SNS Topic'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
sns_topic_name: '{{ sns_topic }}'
register: output
- assert:
that:
- output is changed
- output.trail.name == cloudtrail_name
- output.trail.sns_topic_name == sns_topic
- name: 'Set SNS Topic (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
sns_topic_name: '{{ sns_topic }}'
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.sns_topic_name == sns_topic
- name: 'No-op update to trail'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.sns_topic_name == sns_topic
- name: 'Update SNS Topic (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
sns_topic_name: '{{ sns_topic }}-2'
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Update SNS Topic'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
sns_topic_name: '{{ sns_topic }}-2'
register: output
- assert:
that:
- output is changed
- output.trail.name == cloudtrail_name
- 'output.trail.sns_topic_name == "{{ sns_topic }}-2"'
- name: 'Update SNS Topic (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
sns_topic_name: '{{ sns_topic }}-2'
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- 'output.trail.sns_topic_name == "{{ sns_topic }}-2"'
#- name: 'Remove SNS Topic (CHECK MODE)'
# cloudtrail:
# state: present
# name: '{{ cloudtrail_name }}'
# sns_topic_name: ''
# register: output
# check_mode: yes
#- assert:
# that:
# - output is changed
#- name: 'Remove SNS Topic'
# cloudtrail:
# state: present
# name: '{{ cloudtrail_name }}'
# sns_topic_name: ''
# register: output
#- assert:
# that:
# - output is changed
# - output.trail.name == cloudtrail_name
# - output.trail.sns_topic_name is none
#- name: 'Remove SNS Topic (no change)'
# cloudtrail:
# state: present
# name: '{{ cloudtrail_name }}'
# sns_topic_name: ''
# register: output
#- assert:
# that:
# - output is not changed
# - output.trail.name == cloudtrail_name
# - output.trail.sns_topic_name is none
# ============================================================
- name: 'Set CloudWatch Log Group (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
cloudwatch_logs_log_group_arn: '{{ output_cloudwatch_log_group.arn }}'
cloudwatch_logs_role_arn: '{{ output_cloudwatch_role.arn }}'
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Set CloudWatch Log Group'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
cloudwatch_logs_log_group_arn: '{{ output_cloudwatch_log_group.arn }}'
cloudwatch_logs_role_arn: '{{ output_cloudwatch_role.arn }}'
register: output
- assert:
that:
- output is changed
- output.trail.name == cloudtrail_name
- output.trail.cloud_watch_logs_log_group_arn == output_cloudwatch_log_group.arn
- output.trail.cloud_watch_logs_role_arn == output_cloudwatch_role.arn
- name: 'Set CloudWatch Log Group (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
cloudwatch_logs_log_group_arn: '{{ output_cloudwatch_log_group.arn }}'
cloudwatch_logs_role_arn: '{{ output_cloudwatch_role.arn }}'
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.cloud_watch_logs_log_group_arn == output_cloudwatch_log_group.arn
- output.trail.cloud_watch_logs_role_arn == output_cloudwatch_role.arn
- name: 'No-op update to trail'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.cloud_watch_logs_log_group_arn == output_cloudwatch_log_group.arn
- output.trail.cloud_watch_logs_role_arn == output_cloudwatch_role.arn
- name: 'Update CloudWatch Log Group (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
cloudwatch_logs_log_group_arn: '{{ output_cloudwatch_log_group2.arn }}'
cloudwatch_logs_role_arn: '{{ output_cloudwatch_role.arn }}'
register: output
check_mode: yes
- assert:
that:
- output is changed
- output.trail.cloud_watch_logs_log_group_arn == output_cloudwatch_log_group2.arn
- output.trail.cloud_watch_logs_role_arn == output_cloudwatch_role.arn
- name: 'Update CloudWatch Log Group'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
cloudwatch_logs_log_group_arn: '{{ output_cloudwatch_log_group2.arn }}'
cloudwatch_logs_role_arn: '{{ output_cloudwatch_role.arn }}'
register: output
- assert:
that:
- output is changed
- output.trail.name == cloudtrail_name
- output.trail.cloud_watch_logs_log_group_arn == output_cloudwatch_log_group2.arn
- output.trail.cloud_watch_logs_role_arn == output_cloudwatch_role.arn
- name: 'Update CloudWatch Log Group (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
cloudwatch_logs_log_group_arn: '{{ output_cloudwatch_log_group2.arn }}'
cloudwatch_logs_role_arn: '{{ output_cloudwatch_role.arn }}'
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.cloud_watch_logs_log_group_arn == output_cloudwatch_log_group2.arn
- output.trail.cloud_watch_logs_role_arn == output_cloudwatch_role.arn
#- name: 'Remove CloudWatch Log Group (CHECK MODE)'
# cloudtrail:
# state: present
# name: '{{ cloudtrail_name }}'
# cloudwatch_logs_log_group_arn: ''
# cloudwatch_logs_role_arn: ''
# register: output
# check_mode: yes
#- assert:
# that:
# - output is changed
# - output.trail.name == cloudtrail_name
# - output.trail.cloud_watch_logs_log_group_arn is none
# - output.trail.cloud_watch_logs_role_arn is none
#- name: 'Remove CloudWatch Log Group'
# cloudtrail:
# state: present
# name: '{{ cloudtrail_name }}'
# cloudwatch_logs_log_group_arn: ''
# cloudwatch_logs_role_arn: ''
# register: output
#- assert:
# that:
# - output is changed
# - output.trail.name == cloudtrail_name
# - output.trail.cloud_watch_logs_log_group_arn is none
# - output.trail.cloud_watch_logs_role_arn is none
#- name: 'Remove CloudWatch Log Group (no change)'
# cloudtrail:
# state: present
# name: '{{ cloudtrail_name }}'
# cloudwatch_logs_log_group_arn: ''
# cloudwatch_logs_role_arn: ''
# register: output
#- assert:
# that:
# - output is not changed
# - output.trail.name == cloudtrail_name
# - output.trail.cloud_watch_logs_log_group_arn is none
# - output.trail.cloud_watch_logs_role_arn is none
# ============================================================
- name: 'Update S3 bucket (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
s3_bucket_name: '{{ s3_bucket_name }}-2'
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Update S3 bucket'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
s3_bucket_name: '{{ s3_bucket_name }}-2'
register: output
- assert:
that:
- output is changed
- output.trail.name == cloudtrail_name
- 'output.trail.s3_bucket_name == "{{ s3_bucket_name }}-2"'
- name: 'Update S3 bucket (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
s3_bucket_name: '{{ s3_bucket_name }}-2'
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- 'output.trail.s3_bucket_name == "{{ s3_bucket_name }}-2"'
- name: 'Reset S3 bucket'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
register: output
- assert:
that:
- output.trail.name == cloudtrail_name
- output.trail.s3_bucket_name == s3_bucket_name
# ============================================================
- name: 'Disable logging (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
enable_logging: no
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Disable logging'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
enable_logging: no
register: output
- assert:
that:
- output is changed
- output.trail.name == cloudtrail_name
- output.trail.is_logging == False
- name: 'Disable logging (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
enable_logging: no
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.is_logging == False
# Ansible Documentation lists logging as explicitly defaulting to enabled
- name: 'Enable logging (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
enable_logging: yes
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Enable logging'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
enable_logging: yes
register: output
- assert:
that:
- output is changed
- output.trail.name == cloudtrail_name
- output.trail.is_logging == True
- name: 'Enable logging (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
enable_logging: yes
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.is_logging == True
# ============================================================
- name: 'Disable global logging (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
include_global_events: no
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Disable global logging'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
include_global_events: no
register: output
- assert:
that:
- output is changed
- output.trail.name == cloudtrail_name
- output.trail.include_global_service_events == False
- name: 'Disable global logging (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
include_global_events: no
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.include_global_service_events == False
# Ansible Documentation lists Global-logging as explicitly defaulting to enabled
- name: 'Enable global logging (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
include_global_events: yes
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Enable global logging'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
include_global_events: yes
register: output
- assert:
that:
- output is changed
- output.trail.name == cloudtrail_name
- output.trail.include_global_service_events == True
- name: 'Enable global logging (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
include_global_events: yes
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.include_global_service_events == True
# ============================================================
- name: 'Enable multi-region logging (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
is_multi_region_trail: yes
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Enable multi-region logging'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
is_multi_region_trail: yes
register: output
- assert:
that:
- output is changed
- output.trail.name == cloudtrail_name
- output.trail.is_multi_region_trail == True
- name: 'Enable multi-region logging (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
is_multi_region_trail: yes
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.is_multi_region_trail == True
# Ansible Documentation lists Multi-Region-logging as explicitly defaulting to disabled
- name: 'Disable multi-region logging (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
is_multi_region_trail: no
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Disable multi-region logging'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
is_multi_region_trail: no
register: output
- assert:
that:
- output is changed
- output.trail.name == cloudtrail_name
- output.trail.is_multi_region_trail == False
- name: 'Disable multi-region logging (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
is_multi_region_trail: no
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.is_multi_region_trail == False
# ============================================================
- name: 'Enable logfile validation (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
enable_log_file_validation: yes
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Enable logfile validation'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
enable_log_file_validation: yes
register: output
- assert:
that:
- output is changed
- output.trail.name == cloudtrail_name
- output.trail.log_file_validation_enabled == True
- name: 'Enable logfile validation (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
enable_log_file_validation: yes
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.log_file_validation_enabled == True
- name: 'No-op update to trail'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.log_file_validation_enabled == True
- name: 'Disable logfile validation (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
enable_log_file_validation: no
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Disable logfile validation'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
enable_log_file_validation: no
register: output
- assert:
that:
- output is changed
- output.trail.name == cloudtrail_name
- output.trail.log_file_validation_enabled == False
- name: 'Disable logfile validation (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
enable_log_file_validation: no
register: output
- assert:
that:
- output is not changed
- output.trail.name == cloudtrail_name
- output.trail.log_file_validation_enabled == False
# ============================================================
- name: 'Enable logging encryption (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
kms_key_id: '{{ kms_key.key_arn }}'
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Enable logging encryption'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
kms_key_id: '{{ kms_key.key_arn }}'
register: output
- assert:
that:
- output is changed
- output.trail.kms_key_id == kms_key.key_arn
- name: 'Enable logging encryption (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
kms_key_id: '{{ kms_key.key_arn }}'
register: output
- assert:
that:
- output is not changed
- output.trail.kms_key_id == kms_key.key_arn
- name: 'No-op update to trail'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
register: output
- assert:
that:
- output is not changed
- output.trail.kms_key_id == kms_key.key_arn
- name: 'Update logging encryption key (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
kms_key_id: '{{ kms_key2.key_arn }}'
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Update logging encryption key'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
kms_key_id: '{{ kms_key2.key_arn }}'
register: output
- assert:
that:
- output is changed
- output.trail.kms_key_id == kms_key2.key_arn
- name: 'Update logging encryption key (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
kms_key_id: '{{ kms_key2.key_arn }}'
register: output
- assert:
that:
- output is not changed
- output.trail.kms_key_id == kms_key2.key_arn
- name: 'Update logging encryption to alias (CHECK MODE)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
kms_key_id: 'alias/{{ kms_alias }}'
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Update logging encryption to alias'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
kms_key_id: 'alias/{{ kms_alias }}'
register: output
- assert:
that:
- output is changed
- output.trail.kms_key_id == kms_key.key_arn
- name: 'Update logging encryption to alias (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
kms_key_id: 'alias/{{ kms_alias }}'
register: output
- assert:
that:
# - output is not changed
- output.trail.kms_key_id == kms_key.key_arn
#- name: 'Disable logging encryption (CHECK MODE)'
# cloudtrail:
# state: present
# name: '{{ cloudtrail_name }}'
# kms_key_id: ''
# register: output
# check_mode: yes
#- assert:
# that:
# - output is changed
#- name: 'Disable logging encryption'
# cloudtrail:
# state: present
# name: '{{ cloudtrail_name }}'
# kms_key_id: ''
# register: output
#- assert:
# that:
# - output.trail.kms_key_id == None
# - output is changed
#- name: 'Disable logging encryption (no change)'
# cloudtrail:
# state: present
# name: '{{ cloudtrail_name }}'
# kms_key_id: ''
# register: output
#- assert:
# that:
# - output.kms_key_id == None
# - output is not changed
# ============================================================
- name: 'Delete a trail without providing bucket_name (CHECK MODE)'
module_defaults: { cloudtrail: {} }
cloudtrail:
state: absent
name: '{{ cloudtrail_name }}'
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Delete a trail while providing bucket_name (CHECK MODE)'
cloudtrail:
state: absent
name: '{{ cloudtrail_name }}'
register: output
check_mode: yes
- assert:
that:
- output is changed
- name: 'Delete a trail'
cloudtrail:
state: absent
name: '{{ cloudtrail_name }}'
register: output
- assert:
that:
- output is changed
- output.exists == False
- name: 'Delete a non-existent trail'
cloudtrail:
state: absent
name: '{{ cloudtrail_name }}'
register: output
- assert:
that:
- output is not changed
- output.exists == False
# ============================================================
- name: 'Test creation of a complex Trail (all features)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
s3_key_prefix: '{{ cloudtrail_prefix }}'
sns_topic_name: '{{ sns_topic }}'
cloudwatch_logs_log_group_arn: '{{ output_cloudwatch_log_group.arn }}'
cloudwatch_logs_role_arn: '{{ output_cloudwatch_role.arn }}'
is_multi_region_trail: yes
include_global_events: yes
enable_log_file_validation: yes
kms_key_id: '{{ kms_key.key_arn }}'
register: output
- assert:
that:
- output is changed
#- output.exists == True
- output.trail.name == cloudtrail_name
- output.trail.home_region == aws_region
- output.trail.include_global_service_events == True
- output.trail.is_multi_region_trail == True
- output.trail.is_logging == True
- output.trail.log_file_validation_enabled == True
- output.trail.s3_bucket_name == s3_bucket_name
- output.trail.s3_key_prefix == cloudtrail_prefix
- output.trail.kms_key_id == kms_key.key_arn
- output.trail.sns_topic_arn == output_sns_topic.sns_arn
- output.trail.sns_topic_name == sns_topic
- output.trail.tags | length == 0
- name: 'Test creation of a complex Trail (no change)'
cloudtrail:
state: present
name: '{{ cloudtrail_name }}'
s3_key_prefix: '{{ cloudtrail_prefix }}'
sns_topic_name: '{{ sns_topic }}'
cloudwatch_logs_log_group_arn: '{{ output_cloudwatch_log_group.arn }}'
cloudwatch_logs_role_arn: '{{ output_cloudwatch_role.arn }}'
is_multi_region_trail: yes
include_global_events: yes
enable_log_file_validation: yes
kms_key_id: '{{ kms_key.key_arn }}'
register: output
- assert:
that:
- output is not changed
- output.exists == True
- output.trail.name == cloudtrail_name
- output.trail.home_region == aws_region
- output.trail.include_global_service_events == True
- output.trail.is_multi_region_trail == True
- output.trail.is_logging == True
- output.trail.log_file_validation_enabled == True
- output.trail.s3_bucket_name == s3_bucket_name
- output.trail.s3_key_prefix == cloudtrail_prefix
- output.trail.kms_key_id == kms_key.key_arn
- output.trail.sns_topic_arn == output_sns_topic.sns_arn
- output.trail.sns_topic_name == sns_topic
- output.trail.tags | length == 0
always:
# ============================================================
# Cleanup
# ============================================================
- name: 'Delete test trail'
cloudtrail:
state: absent
name: '{{ cloudtrail_name }}'
ignore_errors: yes
- name: 'Delete S3 bucket'
s3_bucket:
state: absent
name: '{{ s3_bucket_name }}'
force: yes
ignore_errors: yes
- name: 'Delete second S3 bucket'
s3_bucket:
state: absent
name: '{{ s3_bucket_name }}-2'
force: yes
ignore_errors: yes
- name: 'Delete KMS Key'
aws_kms:
state: absent
alias: '{{ kms_alias }}'
ignore_errors: yes
- name: 'Delete second KMS Key'
aws_kms:
state: absent
alias: '{{ kms_alias }}-2'
ignore_errors: yes
- name: 'Delete SNS Topic'
sns_topic:
state: absent
name: '{{ sns_topic }}'
ignore_errors: yes
- name: 'Delete second SNS Topic'
sns_topic:
state: absent
name: '{{ sns_topic }}-2'
ignore_errors: yes
- name: 'Delete CloudWatch Log Group'
cloudwatchlogs_log_group:
state: absent
log_group_name: '{{ cloudwatch_log_group }}'
ignore_errors: yes
- name: 'Delete second CloudWatch Log Group'
cloudwatchlogs_log_group:
state: absent
log_group_name: '{{ cloudwatch_log_group }}-2'
ignore_errors: yes
- name: 'Remove inline policy to CloudWatch Role'
iam_policy:
state: absent
iam_type: role
iam_name: '{{ cloudwatch_role }}'
policy_name: 'CloudWatch'
ignore_errors: yes
- name: 'Delete CloudWatch IAM Role'
iam_role:
state: absent
name: '{{ cloudwatch_role }}'
ignore_errors: yes