├── aws_athena_cloudtrail.model.lkml ├── LICENSE ├── cloudtrail_block.view.lkml ├── ec2_security_group_modifications.dashboard.lookml ├── operational_account_activity.dashboard.lookml ├── README.md ├── cloudtrail_logs.view.lkml ├── general_operations.dashboard.lookml ├── console_login_overview.dashboard.lookml └── error_overview.dashboard.lookml /aws_athena_cloudtrail.model.lkml: -------------------------------------------------------------------------------- 1 | connection: "aws_optimizer" 2 | 3 | # include all the views 4 | include: "*.view" 5 | 6 | # include all the dashboards 7 | include: "*.dashboard" 8 | 9 | explore: cloudtrail_logs { 10 | join: user_login_facts { 11 | type: left_outer 12 | sql_on: ${cloudtrail_logs.user_name} = ${user_login_facts.username} ;; 13 | relationship: many_to_one 14 | } 15 | join: user_ip_facts { 16 | type: left_outer 17 | sql_on: ${cloudtrail_logs.user_name} = ${user_ip_facts.username} ;; 18 | relationship: many_to_one 19 | } 20 | } 21 | 22 | explore: user_login_facts {} 23 | 24 | explore: user_ip_facts {} 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 Looker 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /cloudtrail_block.view.lkml: -------------------------------------------------------------------------------- 1 | view: user_login_facts { 2 | derived_table: { 3 | sql: select useridentity.username, 4 | count(*) as number_of_console_logins, 5 | sum(CASE WHEN errorcode = 'AccessDenied' THEN 1 ELSE 0 END) as failed_logins, 6 | sum(CASE WHEN errorcode = 'AccessDenied' THEN 0 ELSE 1 END) as successful_logins, 7 | min(eventtime) as first_login, 8 | max(eventtime) as latest_login 9 | from aws_optimizer.cloudtrail_logs 10 | where eventname = 'ConsoleLogin' 11 | GROUP BY 1 12 | ;; 13 | } 14 | 15 | measure: count { 16 | type: count 17 | drill_fields: [detail*] 18 | } 19 | 20 | dimension: username { 21 | type: string 22 | primary_key: yes 23 | sql: ${TABLE}.username ;; 24 | } 25 | 26 | dimension: number_of_console_logins { 27 | type: number 28 | hidden: yes 29 | sql: ${TABLE}.number_of_console_logins ;; 30 | } 31 | 32 | dimension: failed_logins { 33 | type: number 34 | hidden: yes 35 | sql: ${TABLE}.failed_logins ;; 36 | } 37 | 38 | dimension: successful_logins { 39 | type: number 40 | hidden: yes 41 | sql: ${TABLE}.successful_logins ;; 42 | } 43 | 44 | dimension: first_login { 45 | type: string 46 | sql: ${TABLE}.first_login ;; 47 | } 48 | 49 | dimension: latest_login { 50 | type: string 51 | sql: ${TABLE}.latest_login ;; 52 | } 53 | 54 | measure: total_console_logins { 55 | type: sum 56 | sql: ${number_of_console_logins} ;; 57 | value_format_name: decimal_0 58 | drill_fields: [detail*] 59 | } 60 | 61 | measure: total_failed_logins { 62 | type: sum 63 | sql: ${failed_logins} ;; 64 | value_format_name: decimal_0 65 | drill_fields: [detail*] 66 | } 67 | 68 | measure: total_successful_logins { 69 | type: sum 70 | sql: ${successful_logins} ;; 71 | value_format_name: decimal_0 72 | drill_fields: [detail*] 73 | } 74 | 75 | set: detail { 76 | fields: [ 77 | username, 78 | total_console_logins, 79 | total_failed_logins, 80 | total_successful_logins, 81 | ] 82 | } 83 | } 84 | 85 | 86 | 87 | view: user_ip_facts { 88 | derived_table: { 89 | sql: SELECT 90 | useridentity.username, 91 | count(distinct sourceipaddress) as ip_addresses 92 | from aws_optimizer.cloudtrail_logs 93 | group by 1 94 | order by 2 desc 95 | limit 50 96 | ;; 97 | } 98 | 99 | suggestions: no 100 | 101 | measure: count { 102 | type: count 103 | drill_fields: [detail*] 104 | } 105 | 106 | dimension: username { 107 | type: string 108 | primary_key: yes 109 | sql: ${TABLE}.username ;; 110 | } 111 | 112 | dimension: ip_addresses { 113 | type: number 114 | sql: ${TABLE}.ip_addresses ;; 115 | hidden: yes 116 | } 117 | 118 | measure: number_ip_addresses { 119 | type: sum 120 | sql: ${ip_addresses} ;; 121 | value_format_name: decimal_0 122 | } 123 | 124 | set: detail { 125 | fields: [username, number_ip_addresses] 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /ec2_security_group_modifications.dashboard.lookml: -------------------------------------------------------------------------------- 1 | - dashboard: ec2_security_group_modifications 2 | title: EC2 Security Group Modifications 3 | layout: newspaper 4 | elements: 5 | - name: Security Group Modifications 6 | title: Security Group Modifications 7 | model: aws_athena_cloudtrail 8 | explore: cloudtrail_logs 9 | type: table 10 | fields: 11 | - cloudtrail_logs.event_name 12 | - cloudtrail_logs.user_name 13 | - cloudtrail_logs.sourceipaddress 14 | # - cloudtrail_logs.event_time 15 | - cloudtrail_logs.requestparameters 16 | sorts: 17 | - cloudtrail_logs.eventname 18 | limit: 500 19 | column_limit: 50 20 | show_view_names: true 21 | show_row_numbers: true 22 | truncate_column_names: false 23 | hide_totals: false 24 | hide_row_totals: false 25 | table_theme: gray 26 | limit_displayed_rows: false 27 | enable_conditional_formatting: false 28 | conditional_formatting_ignored_fields: [] 29 | conditional_formatting_include_totals: false 30 | conditional_formatting_include_nulls: false 31 | listen: 32 | Security Group: cloudtrail_logs.requestparameters 33 | Network ID: cloudtrail_logs.requestparameters 34 | Date: cloudtrail_logs.event_time_date 35 | row: 8 36 | col: 0 37 | width: 24 38 | height: 8 39 | - name: How do I identify Security Modifications? 40 | type: text 41 | title_text: How do I identify Security Modifications? 42 | body_text: |- 43 | If an EC2 instance triggers a CloudWatch metric alarm for high CPU utilization, we can first look to see if there have been any security group changes (the addition of new security groups or the addition of ingress rules to an existing security group) that potentially create more traffic or load on the instance. To start the investigation, we need to look in the EC2 console for the network interface ID and security groups of the impacted EC2 instance. 44 | 45 | The following query can help us dive deep into the security group analysis. 46 | row: 0 47 | col: 0 48 | width: 12 49 | height: 8 50 | - name: What does the below query tell me? 51 | type: text 52 | title_text: What does the below query tell me? 53 | body_text: "We’ll configure the query to filter for our network interface ID,\ 54 | \ security groups, and a time range starting X hours before the alarm occurred\ 55 | \ so we’re aware of recent changes. \n\nSet your security group filter to the\ 56 | \ group that exhibited abnormal activity.\n\nSet your Network Interface ID filter\ 57 | \ to the network ID of the impacted EC2 instance." 58 | row: 0 59 | col: 12 60 | width: 12 61 | height: 8 62 | filters: 63 | - name: Security Group 64 | title: Security Group 65 | type: field_filter 66 | default_value: "%sg%" 67 | model: aws_athena_cloudtrail 68 | explore: cloudtrail_logs 69 | field: cloudtrail_logs.requestparameters 70 | listens_to_filters: [] 71 | allow_multiple_values: true 72 | - name: Network ID 73 | title: Network ID 74 | type: field_filter 75 | default_value: "%eni-%" 76 | model: aws_athena_cloudtrail 77 | explore: cloudtrail_logs 78 | field: cloudtrail_logs.requestparameters 79 | listens_to_filters: [] 80 | allow_multiple_values: true 81 | - name: Date 82 | title: Date 83 | type: date_filter 84 | default_value: 1 years 85 | model: aws_athena_cloudtrail 86 | explore: cloudtrail_logs 87 | field: cloudtrail_logs.event_date 88 | listens_to_filters: [] 89 | allow_multiple_values: true 90 | -------------------------------------------------------------------------------- /operational_account_activity.dashboard.lookml: -------------------------------------------------------------------------------- 1 | - dashboard: operational_account_activity 2 | title: Operational Account Activity 3 | layout: newspaper 4 | elements: 5 | - name: Top AWS Event Errors 6 | title: Top AWS Event Errors 7 | model: aws_athena_cloudtrail 8 | explore: cloudtrail_logs 9 | type: table 10 | fields: 11 | - cloudtrail_logs.count 12 | - cloudtrail_logs.event_name 13 | - cloudtrail_logs.errorcode 14 | - cloudtrail_logs.errormessage 15 | filters: 16 | cloudtrail_logs.errorcode: "-NULL" 17 | sorts: 18 | - cloudtrail_logs.count desc 19 | limit: 15 20 | column_limit: 50 21 | show_view_names: true 22 | show_row_numbers: true 23 | truncate_column_names: false 24 | hide_totals: false 25 | hide_row_totals: false 26 | table_theme: gray 27 | limit_displayed_rows: false 28 | enable_conditional_formatting: false 29 | conditional_formatting_ignored_fields: [] 30 | conditional_formatting_include_totals: false 31 | conditional_formatting_include_nulls: false 32 | listen: 33 | Date: cloudtrail_logs.event_time_date 34 | row: 4 35 | col: 6 36 | width: 18 37 | height: 8 38 | - name: Top IAM Users 39 | title: Top IAM Users 40 | model: aws_athena_cloudtrail 41 | explore: cloudtrail_logs 42 | type: table 43 | fields: 44 | - cloudtrail_logs.user_name 45 | - cloudtrail_logs.event_name 46 | - cloudtrail_logs.total_events 47 | filters: 48 | cloudtrail_logs.user_type: IAMUser 49 | sorts: 50 | - cloudtrail_logs.total_events desc 51 | limit: 15 52 | column_limit: 50 53 | show_view_names: true 54 | show_row_numbers: true 55 | truncate_column_names: false 56 | hide_totals: false 57 | hide_row_totals: false 58 | table_theme: gray 59 | limit_displayed_rows: false 60 | enable_conditional_formatting: false 61 | conditional_formatting_ignored_fields: [] 62 | conditional_formatting_include_totals: false 63 | conditional_formatting_include_nulls: false 64 | listen: 65 | Date: cloudtrail_logs.event_time_date 66 | row: 12 67 | col: 0 68 | width: 18 69 | height: 8 70 | - name: Root Activity 71 | title: Root Activity 72 | model: aws_athena_cloudtrail 73 | explore: cloudtrail_logs 74 | type: table 75 | fields: 76 | - cloudtrail_logs.event_name 77 | - cloudtrail_logs.user_invoked_by 78 | - cloudtrail_logs.total_events 79 | filters: 80 | cloudtrail_logs.user_type: Root 81 | sorts: 82 | - cloudtrail_logs.total_events desc 83 | limit: 15 84 | column_limit: 50 85 | show_view_names: true 86 | show_row_numbers: true 87 | truncate_column_names: false 88 | hide_totals: false 89 | hide_row_totals: false 90 | table_theme: gray 91 | limit_displayed_rows: false 92 | enable_conditional_formatting: false 93 | conditional_formatting_ignored_fields: [] 94 | conditional_formatting_include_totals: false 95 | conditional_formatting_include_nulls: false 96 | listen: 97 | Date: cloudtrail_logs.event_time_date 98 | row: 20 99 | col: 6 100 | width: 18 101 | height: 8 102 | - name: Top AWS Event Errors (Operations) 103 | type: text 104 | title_text: Top AWS Event Errors 105 | subtitle_text: '' 106 | body_text: "Use: Recurring error messages can be a sign of an incorrectly configured\ 107 | \ policy, the wrong permissions applied to an application, or an unknown change\ 108 | \ in your workloads. The following query shows the top errors that have occurred\ 109 | \ during the selected timeframe.\n\nInterpretation: \nThese errors might indicate\ 110 | \ an incorrectly configured CloudWatch alarm or S3 bucket policy." 111 | row: 4 112 | col: 0 113 | width: 6 114 | height: 8 115 | - name: Top IAM Users (Operations) 116 | type: text 117 | title_text: Top IAM Users 118 | body_text: |- 119 | Use: This data table shows the top IAM users and activities by event name. 120 | 121 | Interpretation: The results will show the total activities initiated by each IAM user and the event name for those activities. Drill into this query to filter the activity and view only events that occurred outside of the known network or after hours. 122 | row: 12 123 | col: 18 124 | width: 6 125 | height: 8 126 | - name: Root Activity (Operations) 127 | type: text 128 | title_text: Root Activity 129 | body_text: |- 130 | Use: Another useful query is to understand how the root account and credentials are being used and which activities are being performed by root. The following query will look at the top events initiated by root from the beginning of the year. 131 | 132 | Interpretation: It will show whether these were direct root activities or whether they were invoked by an AWS service (and, if so, which one) to perform an activity. 133 | row: 20 134 | col: 0 135 | width: 6 136 | height: 8 137 | - name: Operational Account Activity 138 | type: text 139 | title_text: Operational Account Activity 140 | body_text: An important part of running workloads in AWS is understanding recurring 141 | errors, how administrators and employees are interacting with your workloads, 142 | and who or what is using root privileges in your account. 143 | row: 0 144 | col: 0 145 | width: 24 146 | height: 4 147 | filters: 148 | - name: Date 149 | title: Date 150 | type: date_filter 151 | default_value: 48 hours 152 | model: aws_athena_cloudtrail 153 | explore: cloudtrail_logs 154 | field: cloudtrail_logs.eventtime 155 | listens_to_filters: [] 156 | allow_multiple_values: true 157 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Set-up Steps 2 | 3 | **Cloudtrail Config** 4 | These instructions assume that you already have CloudTrail configured. If not, please follow the instructions outlined in these [AWS docs](http://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-getting-started.html) to complete the configuration (only takes a few min). 5 | 6 | **Athena Config** 7 | For instructions on how to set up Cloudtrail + Athena, please follow the steps outlined in this [AWS blog post](https://aws.amazon.com/blogs/big-data/aws-cloudtrail-and-amazon-athena-dive-deep-to-analyze-security-compliance-and-operational-activity/) (up to "Popular Use Cases"). At Amazon's suggestion, we have included some of the information, analysis, and interpreations from this blog and repeated throughout this Block. 8 | 9 | **Performance Optimization** 10 | Once you've completed all the initial set-up steps, you can connect Looker to your new Athena datastore and begin analysis. However, if you're working with large data sets or generally want to improve performance, there are two additional steps you should take: Partitioning your S3 buckets, and converting your data to a columnar format. Instructions for how to accomplish both of these steps are included in a seperate [AWS post](https://aws.amazon.com/blogs/big-data/analyzing-data-in-s3-using-amazon-athena/). Beyond these primary levers, there are certain best practices you can follow at query time as well, outlined in this [blog post](https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-tips-for-amazon-athena/). 11 | 12 | 13 | 14 | ### AWS Cloudtrail + Athena 15 | 16 | AWS CloudTrail and Amazon Athena help make it easier by combining the detailed CloudTrail log files with the power of the Athena SQL engine to easily find, analyze, and respond to changes and activities in an AWS account. 17 | 18 | AWS CloudTrail records API calls and account activities and publishes the log files to Amazon S3. Account activity is tracked as an event in the CloudTrail log file. Each event carries information such as who performed the action, when the action was done, which resources were impacted, and many more details. Multiple events are stitched together and structured in a JSON format within the CloudTrail log files. 19 | 20 | ### Configuring the Hive MetaStore (easier than is sounds!) 21 | 22 | Amazon Athena uses Apache Hive’s data definition language (DDL) to create tables and Presto, a distributed SQL engine, to run queries. The DDL statement used to create the table in this Block can be found below, or in this [AWS blog](https://aws.amazon.com/blogs/big-data/aws-cloudtrail-and-amazon-athena-dive-deep-to-analyze-security-compliance-and-operational-activity/). Apache Hive does not natively support files in JSON, so we’ll have to use a SerDe to help Hive understand how the records should be processed. A SerDe interface is a combination of a serializer and deserializer. A deserializer helps take data and convert it into a Java object while the serializer helps convert the Java object into a usable representation. 23 | 24 | ``` 25 | CREATE EXTERNAL TABLE cloudtrail_logs ( 26 | eventversion STRING, 27 | userIdentity STRUCT< 28 | type:STRING, 29 | principalid:STRING, 30 | arn:STRING, 31 | accountid:STRING, 32 | invokedby:STRING, 33 | accesskeyid:STRING, 34 | userName:STRING, 35 | sessioncontext:STRUCT< 36 | attributes:STRUCT< 37 | mfaauthenticated:STRING, 38 | creationdate:STRING>, 39 | sessionIssuer:STRUCT< 40 | type:STRING, 41 | principalId:STRING, 42 | arn:STRING, 43 | accountId:STRING, 44 | userName:STRING>>>, 45 | eventTime STRING, 46 | eventSource STRING, 47 | eventName STRING, 48 | awsRegion STRING, 49 | sourceIpAddress STRING, 50 | userAgent STRING, 51 | errorCode STRING, 52 | errorMessage STRING, 53 | requestParameters STRING, 54 | responseElements STRING, 55 | additionalEventData STRING, 56 | requestId STRING, 57 | eventId STRING, 58 | resources ARRAY>, 61 | eventType STRING, 62 | apiVersion STRING, 63 | readOnly STRING, 64 | recipientAccountId STRING, 65 | serviceEventDetails STRING, 66 | sharedEventID STRING, 67 | vpcEndpointId STRING 68 | ) 69 | ROW FORMAT SERDE 'com.amazon.emr.hive.serde.CloudTrailSerde' 70 | STORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat' 71 | OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat' 72 | LOCATION 's3:///AWSLogs//'; 73 | ``` 74 | 75 | 76 | 77 | 78 | ### Sample Use-Cases 79 | 80 | The sample use-cases below have been highlighted by the AWS team as the primary use-cases that are most applicable and valuable accross their entire customer base. Looker has also added additional use-cases based on our organization's experience using CloudTrail logs operationally. 81 | 82 | * **General Operations** - a holistic view of event activity over time, across users, resources, and regions. Use this dashboard to illicit high-level trends, then drill down into individual resources to identify opportunities for improvement and cost savings 83 | 84 | * **Error Overview** - identifying errors is a crucial component of maintaining an operational AWS environment. This dashboard offers an overview of the most common errors for users and AWS resources, as well as additional detail to help users rectify issues. 85 | 86 | * **Console Login Overview** - provides high-level overview of console login activity, including location, top users, and IP Address analysis. This dashboard can be utilized for several popular use-cases, including identifying suspicious IP logins, finding over-burdensome users, and troubleshooting login issues. 87 | 88 | * **EC2 Security Group Modifications** - when reviewing an operational issue or security incident for an EC2 instance, the ability to see any associated security group change is a vital part of the analysis. The associated dashbopard can help us deep dive into security group analysis. Further detail on how to effectively use the dashboard, along with subsequent areas to explore when abnormailities or opportunities for enhancement arise, can be found on the dashboard. 89 | 90 | * **Operational Account Activity** - a key component of running workloads in AWS is understanding recurring errors, how administrators and employees are interacting with your workloads, and who or what is using root privileges in your account. 91 | 92 | 93 | 94 | ### Necessary Customization 95 | * IP Location must be updated to incorporate Geolocation services, such as those provided by MaxMind 96 | -------------------------------------------------------------------------------- /cloudtrail_logs.view.lkml: -------------------------------------------------------------------------------- 1 | view: cloudtrail_logs { 2 | sql_table_name: aws_optimizer.cloudtrail_logs ;; 3 | suggestions: no 4 | 5 | dimension: additionaleventdata { 6 | type: string 7 | sql: ${TABLE}.additionaleventdata ;; 8 | } 9 | 10 | dimension: apiversion { 11 | type: string 12 | sql: ${TABLE}.apiversion ;; 13 | } 14 | 15 | dimension: awsregion { 16 | type: string 17 | sql: ${TABLE}.awsregion ;; 18 | } 19 | 20 | dimension: errorcode { 21 | type: string 22 | sql: ${TABLE}.errorcode ;; 23 | } 24 | 25 | dimension: errormessage { 26 | type: string 27 | sql: ${TABLE}.errormessage ;; 28 | } 29 | 30 | dimension: eventid { 31 | type: string 32 | sql: ${TABLE}.eventid ;; 33 | } 34 | 35 | dimension: event_name { 36 | type: string 37 | sql: ${TABLE}.eventname ;; 38 | } 39 | 40 | dimension: event_source { 41 | type: string 42 | sql: ${TABLE}.eventsource ;; 43 | } 44 | dimension_group: event_time { 45 | type: time 46 | # hidden: yes 47 | timeframes: [minute15, minute30, hour,date,week,month,year,hour_of_day,day_of_week,month_name] 48 | sql: from_iso8601_timestamp(${TABLE}.eventtime) ;; 49 | } 50 | dimension: eventtype { 51 | type: string 52 | sql: ${TABLE}.eventtype ;; 53 | } 54 | 55 | dimension: eventversion { 56 | type: string 57 | sql: ${TABLE}.eventversion ;; 58 | } 59 | 60 | dimension: readonly { 61 | type: string 62 | sql: ${TABLE}.readonly ;; 63 | } 64 | 65 | dimension: recipientaccountid { 66 | type: string 67 | sql: ${TABLE}.recipientaccountid ;; 68 | } 69 | 70 | dimension: requestid { 71 | type: string 72 | sql: ${TABLE}.requestid ;; 73 | } 74 | 75 | dimension: requestparameters { 76 | type: string 77 | sql: ${TABLE}.requestparameters ;; 78 | } 79 | 80 | dimension: network_interface_id { 81 | type: string 82 | sql: ${TABLE}.requestparameters.networkinterfaceid ;; 83 | } 84 | 85 | dimension: resources { 86 | type: string 87 | sql: ${TABLE}.resources ;; 88 | } 89 | 90 | dimension: responseelements { 91 | type: string 92 | sql: ${TABLE}.responseelements ;; 93 | } 94 | 95 | dimension: serviceeventdetails { 96 | type: string 97 | sql: ${TABLE}.serviceeventdetails ;; 98 | } 99 | 100 | dimension: sharedeventid { 101 | type: string 102 | sql: ${TABLE}.sharedeventid ;; 103 | } 104 | 105 | dimension: mfa_used { 106 | description: "Multi-Factor Authentican Used" 107 | type: string 108 | sql: json_extract_scalar(${additionaleventdata}, '$.MFAUsed') ;; 109 | } 110 | 111 | 112 | dimension: sourceipaddress { 113 | label: "Source IP Address" 114 | type: string 115 | sql: ${TABLE}.sourceipaddress ;; 116 | } 117 | 118 | 119 | ### Location dimension used for demo-purposes only. To determine physical location of each IP Address, utilize a Geotargeting service, such as MaxMind 120 | ### MaxMind at https://www.maxmind.com/en/home?rId=iplocation 121 | 122 | dimension: ip_location { 123 | map_layer_name: countries 124 | sql: CASE 125 | WHEN substr(${sourceipaddress},1,2) = '54' THEN 'China' 126 | WHEN substr(${sourceipaddress},1,2) = '50' THEN 'Japan' 127 | WHEN substr(${sourceipaddress},1,2) = '34' THEN 'London' 128 | ELSE 'United States of America' 129 | END 130 | ;; 131 | } 132 | 133 | 134 | 135 | 136 | ### Parsing of the nested fields (shown as JSON in useridentity column) 137 | 138 | dimension: user_identity { 139 | type: string 140 | group_label: "User Information" 141 | sql: ${TABLE}.useridentity ;; 142 | } 143 | 144 | dimension: user_agent { 145 | type: string 146 | group_label: "User Information" 147 | sql: ${TABLE}.useragent ;; 148 | } 149 | 150 | dimension: user_name { 151 | type: string 152 | group_label: "User Information" 153 | sql: ${TABLE}.useridentity.username ;; 154 | } 155 | 156 | dimension: user_type { 157 | type: string 158 | group_label: "User Information" 159 | sql: ${TABLE}.useridentity.type ;; 160 | } 161 | 162 | dimension: user_invoked_by { 163 | type: string 164 | group_label: "User Information" 165 | sql: ${TABLE}.useridentity.invokedby ;; 166 | } 167 | 168 | dimension: assumed_user_name { 169 | description: "Temporary security credentials obtained by assuming an IAM role" 170 | label: "Assumed User Name" 171 | type: string 172 | group_label: "User Information" 173 | sql: ${TABLE}.useridentity.sessioncontext.sessionissuer.userName ;; 174 | } 175 | 176 | ### End user fields 177 | 178 | dimension: vpcendpointid { 179 | type: string 180 | sql: ${TABLE}.vpcendpointid ;; 181 | } 182 | 183 | dimension: login_status { 184 | description: "Should only be used to evaluate logins" 185 | type: string 186 | sql: CASE 187 | WHEN ${event_name} = 'ConsoleLogin' AND ${errormessage} IS NULL THEN 'Success' 188 | WHEN ${event_name} = 'ConsoleLogin' AND ${errormessage} IS NOT NULL THEN 'Failure' 189 | ELSE NULL 190 | END 191 | ;; 192 | } 193 | 194 | dimension: errors_dim { 195 | hidden: yes 196 | type: string 197 | sql: CASE 198 | WHEN ${errormessage} IS NOT NULL THEN 'Error' 199 | WHEN ${errormessage} IS NULL THEN 'No Error' 200 | ELSE NULL 201 | END 202 | ;; 203 | } 204 | 205 | 206 | measure: total_events { 207 | type: count 208 | drill_fields: [assumed_user_name, event_name, event_source, count] 209 | } 210 | 211 | measure: count { 212 | label: "Total Events" 213 | type: count 214 | drill_fields: [assumed_user_name, event_name, event_source, count] 215 | } 216 | 217 | measure: total_errors { 218 | type: count 219 | filters: { 220 | field: errors_dim ### filter on errormessage because there is always an error message during a failed login attempt 221 | value: "Error" 222 | } 223 | drill_fields: [assumed_user_name, event_name, errorcode, errormessage, event_source, total_errors] 224 | } 225 | 226 | measure: total_logins { 227 | type: count 228 | drill_fields: [assumed_user_name, event_name, event_source, count] 229 | 230 | filters: { 231 | field: event_name 232 | value: "ConsoleLogin" 233 | } 234 | } 235 | 236 | measure: total_failed_logins { 237 | type: count 238 | drill_fields: [event_name, assumed_user_name, event_source, total_failed_logins] 239 | 240 | filters: { 241 | field: event_name 242 | value: "ConsoleLogin" 243 | } 244 | filters: { 245 | field: errors_dim ### filter on errormessage because there is always an error message during a failed login attempt 246 | value: "Error" 247 | } 248 | } 249 | 250 | measure: total_successful_logins { 251 | type: count 252 | drill_fields: [event_name,total_successful_logins] 253 | 254 | filters: { 255 | field: event_name 256 | value: "ConsoleLogin" 257 | } 258 | filters: { 259 | field: errors_dim ### filter on errormessage because there is always an error message during a failed login attempt 260 | value: "No Error" 261 | } 262 | } 263 | 264 | 265 | measure: count_access_denied_events { 266 | type: count 267 | drill_fields: [event_name, assumed_user_name, -user_name, user_invoked_by, count_access_denied_events] 268 | 269 | filters: { 270 | field: errorcode 271 | value: "AccessDenied" 272 | } 273 | } 274 | 275 | measure: count_of_distinct_call_users { 276 | type: count_distinct 277 | sql: ${user_name} ;; 278 | drill_fields: [user_name, user_type] 279 | value_format_name: decimal_0 280 | } 281 | 282 | measure: count_of_distinct_users { 283 | type: count_distinct 284 | drill_fields: [assumed_user_name, user_type] 285 | sql: ${assumed_user_name} ;; 286 | value_format_name: decimal_0 287 | } 288 | 289 | measure: errors_percent_events { 290 | label: "Errors As A Percent Of Events" 291 | sql: 1.00*${cloudtrail_logs.total_errors}/NULLIF(${cloudtrail_logs.count},0);; 292 | type: number 293 | value_format_name:percent_2} 294 | } 295 | -------------------------------------------------------------------------------- /general_operations.dashboard.lookml: -------------------------------------------------------------------------------- 1 | - dashboard: general_operations 2 | title: General Operations 3 | layout: newspaper 4 | elements: 5 | - name: Top 10 Events 6 | title: Top 10 Events 7 | model: aws_athena_cloudtrail 8 | explore: cloudtrail_logs 9 | type: looker_bar 10 | fields: 11 | - cloudtrail_logs.total_events 12 | - cloudtrail_logs.event_name 13 | sorts: 14 | - cloudtrail_logs.total_events desc 15 | limit: 10 16 | column_limit: 50 17 | stacking: '' 18 | show_value_labels: false 19 | label_density: 25 20 | legend_position: center 21 | x_axis_gridlines: false 22 | y_axis_gridlines: true 23 | show_view_names: true 24 | limit_displayed_rows: false 25 | y_axis_combined: true 26 | show_y_axis_labels: true 27 | show_y_axis_ticks: true 28 | y_axis_tick_density: default 29 | y_axis_tick_density_custom: 5 30 | show_x_axis_label: true 31 | show_x_axis_ticks: true 32 | x_axis_scale: auto 33 | y_axis_scale_mode: linear 34 | ordering: none 35 | show_null_labels: false 36 | show_totals_labels: false 37 | show_silhouette: false 38 | totals_color: "#808080" 39 | value_labels: legend 40 | label_type: labPer 41 | show_row_numbers: true 42 | truncate_column_names: false 43 | hide_totals: false 44 | hide_row_totals: false 45 | table_theme: editable 46 | enable_conditional_formatting: false 47 | conditional_formatting_ignored_fields: [] 48 | conditional_formatting_include_totals: false 49 | conditional_formatting_include_nulls: false 50 | series_types: {} 51 | series_colors: 52 | cloudtrail_logs.total_events: "#1f3e5a" 53 | listen: 54 | Date: cloudtrail_logs.event_time_date 55 | row: 0 56 | col: 0 57 | width: 12 58 | height: 8 59 | - name: Top Events (Full Detail) 60 | title: Top Events (Full Detail) 61 | model: aws_athena_cloudtrail 62 | explore: cloudtrail_logs 63 | type: table 64 | fields: 65 | - cloudtrail_logs.total_events 66 | - cloudtrail_logs.event_name 67 | - cloudtrail_logs.count_of_distinct_users 68 | - cloudtrail_logs.count_access_denied_events 69 | - cloudtrail_logs.errors_percent_events 70 | sorts: 71 | - cloudtrail_logs.total_events desc 72 | limit: 100 73 | column_limit: 50 74 | show_view_names: true 75 | show_row_numbers: true 76 | truncate_column_names: false 77 | hide_totals: false 78 | hide_row_totals: false 79 | table_theme: gray 80 | limit_displayed_rows: false 81 | enable_conditional_formatting: false 82 | conditional_formatting_ignored_fields: [] 83 | conditional_formatting_include_totals: false 84 | conditional_formatting_include_nulls: false 85 | value_labels: legend 86 | label_type: labPer 87 | series_types: {} 88 | listen: 89 | Date: cloudtrail_logs.event_time_date 90 | row: 0 91 | col: 12 92 | width: 12 93 | height: 8 94 | - name: Events by Source 95 | title: Events by Source 96 | model: aws_athena_cloudtrail 97 | explore: cloudtrail_logs 98 | type: looker_column 99 | fields: 100 | - cloudtrail_logs.total_events 101 | - cloudtrail_logs.event_source 102 | sorts: 103 | - cloudtrail_logs.event_source 104 | limit: 500 105 | column_limit: 50 106 | query_timezone: America/Los_Angeles 107 | stacking: normal 108 | show_value_labels: false 109 | label_density: 25 110 | legend_position: center 111 | x_axis_gridlines: false 112 | y_axis_gridlines: true 113 | show_view_names: true 114 | limit_displayed_rows: false 115 | y_axis_combined: true 116 | show_y_axis_labels: true 117 | show_y_axis_ticks: true 118 | y_axis_tick_density: default 119 | y_axis_tick_density_custom: 5 120 | show_x_axis_label: true 121 | show_x_axis_ticks: true 122 | x_axis_scale: auto 123 | y_axis_scale_mode: linear 124 | ordering: none 125 | show_null_labels: false 126 | show_totals_labels: false 127 | show_silhouette: false 128 | totals_color: "#808080" 129 | show_null_points: false 130 | point_style: none 131 | interpolation: linear 132 | show_row_numbers: true 133 | truncate_column_names: false 134 | hide_totals: false 135 | hide_row_totals: false 136 | table_theme: editable 137 | enable_conditional_formatting: false 138 | conditional_formatting_ignored_fields: [] 139 | conditional_formatting_include_totals: false 140 | conditional_formatting_include_nulls: false 141 | series_types: {} 142 | series_colors: 143 | cloudtrail_logs.total_events: "#1f3e5a" 144 | listen: 145 | Date: cloudtrail_logs.event_time_date 146 | row: 8 147 | col: 0 148 | width: 12 149 | height: 8 150 | - name: Events by Region 151 | title: Events by Region 152 | model: aws_athena_cloudtrail 153 | explore: cloudtrail_logs 154 | type: looker_area 155 | fields: 156 | - cloudtrail_logs.total_events 157 | - cloudtrail_logs.awsregion 158 | - cloudtrail_logs.event_time_date 159 | pivots: 160 | - cloudtrail_logs.awsregion 161 | fill_fields: 162 | - cloudtrail_logs.event_time_date 163 | sorts: 164 | - cloudtrail_logs.awsregion 165 | - cloudtrail_logs.event_time_date desc 166 | limit: 500 167 | column_limit: 50 168 | query_timezone: America/Los_Angeles 169 | stacking: normal 170 | show_value_labels: false 171 | label_density: 25 172 | legend_position: center 173 | x_axis_gridlines: false 174 | y_axis_gridlines: true 175 | show_view_names: true 176 | limit_displayed_rows: false 177 | y_axis_combined: true 178 | show_y_axis_labels: true 179 | show_y_axis_ticks: true 180 | y_axis_tick_density: default 181 | y_axis_tick_density_custom: 5 182 | show_x_axis_label: true 183 | show_x_axis_ticks: true 184 | x_axis_scale: auto 185 | y_axis_scale_mode: linear 186 | show_null_points: true 187 | point_style: none 188 | interpolation: linear 189 | show_totals_labels: false 190 | show_silhouette: false 191 | totals_color: "#808080" 192 | show_row_numbers: true 193 | truncate_column_names: false 194 | hide_totals: false 195 | hide_row_totals: false 196 | table_theme: editable 197 | enable_conditional_formatting: false 198 | conditional_formatting_ignored_fields: [] 199 | conditional_formatting_include_totals: false 200 | conditional_formatting_include_nulls: false 201 | series_types: {} 202 | listen: 203 | Date: cloudtrail_logs.event_time_date 204 | row: 16 205 | col: 0 206 | width: 12 207 | height: 8 208 | - name: Events by Hour of Day, Day of Week 209 | title: Events by Hour of Day, Day of Week 210 | model: aws_athena_cloudtrail 211 | explore: cloudtrail_logs 212 | type: looker_line 213 | fields: 214 | - cloudtrail_logs.event_time_hour_of_day 215 | - cloudtrail_logs.event_time_day_of_week 216 | - cloudtrail_logs.total_events 217 | pivots: 218 | - cloudtrail_logs.event_time_day_of_week 219 | fill_fields: 220 | - cloudtrail_logs.event_time_hour_of_day 221 | - cloudtrail_logs.event_time_day_of_week 222 | filters: 223 | cloudtrail_logs.awsregion: '' 224 | sorts: 225 | - cloudtrail_logs.event_time_day_of_week 0 226 | - cloudtrail_logs.event_time_hour_of_day 227 | limit: 500 228 | column_limit: 50 229 | stacking: normal 230 | show_value_labels: false 231 | label_density: 25 232 | legend_position: center 233 | x_axis_gridlines: false 234 | y_axis_gridlines: true 235 | show_view_names: true 236 | limit_displayed_rows: false 237 | y_axis_combined: true 238 | show_y_axis_labels: true 239 | show_y_axis_ticks: true 240 | y_axis_tick_density: default 241 | y_axis_tick_density_custom: 5 242 | show_x_axis_label: true 243 | show_x_axis_ticks: true 244 | x_axis_scale: auto 245 | y_axis_scale_mode: linear 246 | show_null_points: true 247 | point_style: none 248 | interpolation: linear 249 | ordering: none 250 | show_null_labels: false 251 | show_totals_labels: false 252 | show_silhouette: false 253 | totals_color: "#808080" 254 | show_row_numbers: true 255 | truncate_column_names: false 256 | hide_totals: false 257 | hide_row_totals: false 258 | table_theme: editable 259 | enable_conditional_formatting: false 260 | conditional_formatting_ignored_fields: [] 261 | conditional_formatting_include_totals: false 262 | conditional_formatting_include_nulls: false 263 | series_types: {} 264 | row: 8 265 | col: 12 266 | width: 12 267 | height: 8 268 | - name: EC2 Instance Changes 269 | title: EC2 Instance Changes 270 | model: aws_athena_cloudtrail 271 | explore: cloudtrail_logs 272 | type: looker_line 273 | fields: 274 | - cloudtrail_logs.total_events 275 | - cloudtrail_logs.event_time_date 276 | - cloudtrail_logs.event_name 277 | pivots: 278 | - cloudtrail_logs.event_name 279 | fill_fields: 280 | - cloudtrail_logs.event_time_date 281 | filters: 282 | cloudtrail_logs.event_name: "%StopInstance%,%StartInstance%,%RunInstance%,%TerminateInstance%" 283 | sorts: 284 | - cloudtrail_logs.event_time_date desc 285 | - cloudtrail_logs.event_name 286 | limit: 500 287 | column_limit: 50 288 | stacking: '' 289 | show_value_labels: false 290 | label_density: 25 291 | legend_position: center 292 | x_axis_gridlines: false 293 | y_axis_gridlines: true 294 | show_view_names: true 295 | limit_displayed_rows: false 296 | y_axis_combined: true 297 | show_y_axis_labels: true 298 | show_y_axis_ticks: true 299 | y_axis_tick_density: default 300 | y_axis_tick_density_custom: 5 301 | show_x_axis_label: true 302 | show_x_axis_ticks: true 303 | x_axis_scale: auto 304 | y_axis_scale_mode: linear 305 | show_null_points: true 306 | point_style: none 307 | interpolation: linear 308 | show_row_numbers: true 309 | truncate_column_names: false 310 | hide_totals: false 311 | hide_row_totals: false 312 | table_theme: editable 313 | enable_conditional_formatting: false 314 | conditional_formatting_ignored_fields: [] 315 | conditional_formatting_include_totals: false 316 | conditional_formatting_include_nulls: false 317 | series_types: {} 318 | row: 16 319 | col: 12 320 | width: 12 321 | height: 8 322 | filters: 323 | - name: Date 324 | title: Date 325 | type: date_filter 326 | default_value: 1 years 327 | model: 328 | explore: 329 | field: 330 | listens_to_filters: [] 331 | allow_multiple_values: true 332 | -------------------------------------------------------------------------------- /console_login_overview.dashboard.lookml: -------------------------------------------------------------------------------- 1 | - dashboard: console_login_overview 2 | title: Console Login Overview 3 | layout: newspaper 4 | elements: 5 | - name: Top User Logins (Top 10) 6 | title: Top User Logins (Top 10) 7 | model: aws_athena_cloudtrail 8 | explore: cloudtrail_logs 9 | type: looker_bar 10 | fields: 11 | - cloudtrail_logs.total_successful_logins 12 | - cloudtrail_logs.total_failed_logins 13 | - cloudtrail_logs.total_logins 14 | - cloudtrail_logs.user_name 15 | sorts: 16 | - cloudtrail_logs.total_logins desc 17 | limit: 10 18 | column_limit: 50 19 | stacking: normal 20 | show_value_labels: false 21 | label_density: 25 22 | legend_position: center 23 | x_axis_gridlines: false 24 | y_axis_gridlines: true 25 | show_view_names: true 26 | limit_displayed_rows: false 27 | y_axis_combined: true 28 | show_y_axis_labels: true 29 | show_y_axis_ticks: true 30 | y_axis_tick_density: default 31 | y_axis_tick_density_custom: 5 32 | show_x_axis_label: true 33 | show_x_axis_ticks: true 34 | x_axis_scale: auto 35 | y_axis_scale_mode: linear 36 | ordering: none 37 | show_null_labels: false 38 | show_totals_labels: false 39 | show_silhouette: false 40 | totals_color: "#808080" 41 | hidden_fields: 42 | - cloudtrail_logs.total_logins 43 | colors: 44 | - 'palette: Looker Classic' 45 | series_colors: 46 | cloudtrail_logs.total_successful_logins: "#1f3e5a" 47 | series_types: 48 | success_rate: line 49 | listen: 50 | Date: cloudtrail_logs.event_time_date 51 | row: 0 52 | col: 12 53 | width: 12 54 | height: 10 55 | - name: Console Logins Over Time 56 | title: Console Logins Over Time 57 | model: aws_athena_cloudtrail 58 | explore: cloudtrail_logs 59 | type: looker_column 60 | fields: 61 | - cloudtrail_logs.total_successful_logins 62 | - cloudtrail_logs.total_failed_logins 63 | - cloudtrail_logs.total_logins 64 | - cloudtrail_logs.event_time_date 65 | fill_fields: 66 | - cloudtrail_logs.event_time_date 67 | sorts: 68 | - cloudtrail_logs.event_time_date 69 | limit: 500 70 | column_limit: 50 71 | stacking: normal 72 | show_value_labels: false 73 | label_density: 25 74 | legend_position: center 75 | x_axis_gridlines: false 76 | y_axis_gridlines: true 77 | show_view_names: true 78 | limit_displayed_rows: false 79 | y_axis_combined: true 80 | show_y_axis_labels: true 81 | show_y_axis_ticks: true 82 | y_axis_tick_density: default 83 | y_axis_tick_density_custom: 5 84 | show_x_axis_label: true 85 | show_x_axis_ticks: true 86 | x_axis_scale: auto 87 | y_axis_scale_mode: linear 88 | ordering: none 89 | show_null_labels: false 90 | show_totals_labels: false 91 | show_silhouette: false 92 | totals_color: "#808080" 93 | hidden_fields: 94 | - cloudtrail_logs.total_logins 95 | series_colors: 96 | cloudtrail_logs.total_successful_logins: "#1f3e5a" 97 | listen: 98 | Date: cloudtrail_logs.event_time_date 99 | row: 10 100 | col: 0 101 | width: 12 102 | height: 7 103 | - name: Logins from Multiple IP Addresses 104 | title: Logins from Multiple IP Addresses 105 | model: aws_athena_cloudtrail 106 | explore: user_ip_facts 107 | type: table 108 | fields: 109 | - user_ip_facts.username 110 | - user_ip_facts.number_ip_addresses 111 | sorts: 112 | - user_ip_facts.number_ip_addresses desc 113 | limit: 500 114 | column_limit: 50 115 | show_view_names: true 116 | show_row_numbers: true 117 | truncate_column_names: false 118 | hide_totals: false 119 | hide_row_totals: false 120 | table_theme: gray 121 | limit_displayed_rows: false 122 | enable_conditional_formatting: false 123 | conditional_formatting_ignored_fields: [] 124 | conditional_formatting_include_totals: false 125 | conditional_formatting_include_nulls: false 126 | row: 17 127 | col: 0 128 | width: 6 129 | height: 7 130 | - name: Most Common IP Addresses 131 | title: Most Common IP Addresses 132 | model: aws_athena_cloudtrail 133 | explore: cloudtrail_logs 134 | type: table 135 | fields: 136 | - cloudtrail_logs.sourceipaddress 137 | - cloudtrail_logs.total_events 138 | sorts: 139 | - cloudtrail_logs.count desc 140 | limit: 500 141 | column_limit: 50 142 | show_view_names: true 143 | show_row_numbers: true 144 | truncate_column_names: false 145 | hide_totals: false 146 | hide_row_totals: false 147 | table_theme: gray 148 | limit_displayed_rows: false 149 | enable_conditional_formatting: false 150 | conditional_formatting_ignored_fields: [] 151 | conditional_formatting_include_totals: false 152 | conditional_formatting_include_nulls: false 153 | listen: 154 | Date: cloudtrail_logs.event_time_date 155 | row: 17 156 | col: 6 157 | width: 6 158 | height: 7 159 | - name: User Login Geolocation 160 | title: User Login Geolocation 161 | model: aws_athena_cloudtrail 162 | explore: cloudtrail_logs 163 | type: looker_geo_choropleth 164 | fields: 165 | - cloudtrail_logs.ip_location 166 | - cloudtrail_logs.total_events 167 | filters: 168 | cloudtrail_logs.ip_location: "-NULL" 169 | sorts: 170 | - cloudtrail_logs.ip_location 171 | limit: 500 172 | column_limit: 50 173 | map: auto 174 | map_projection: '' 175 | show_view_names: true 176 | quantize_colors: false 177 | map_plot_mode: points 178 | heatmap_gridlines: false 179 | heatmap_opacity: 0.5 180 | show_region_field: true 181 | draw_map_labels_above_data: true 182 | map_tile_provider: positron 183 | map_position: custom 184 | map_scale_indicator: 'off' 185 | map_pannable: true 186 | map_zoomable: true 187 | map_marker_type: circle 188 | map_marker_icon_name: default 189 | map_marker_radius_mode: proportional_value 190 | map_marker_units: meters 191 | map_marker_proportional_scale_type: linear 192 | map_marker_color_mode: fixed 193 | show_legend: true 194 | quantize_map_value_colors: false 195 | map_latitude: 32.02670629333614 196 | map_longitude: 4.833984375000001 197 | map_zoom: 3 198 | series_types: {} 199 | listen: 200 | Date: cloudtrail_logs.event_time_date 201 | row: 0 202 | col: 0 203 | width: 12 204 | height: 10 205 | - name: Most Common Login Errors 206 | title: Most Common Login Errors 207 | model: aws_athena_cloudtrail 208 | explore: cloudtrail_logs 209 | type: table 210 | fields: 211 | - cloudtrail_logs.errormessage 212 | - cloudtrail_logs.count 213 | - cloudtrail_logs.count_of_distinct_users 214 | filters: 215 | cloudtrail_logs.errorcode: "-NULL" 216 | cloudtrail_logs.event_name: ConsoleLogin 217 | sorts: 218 | - cloudtrail_logs.count desc 219 | limit: 500 220 | column_limit: 50 221 | dynamic_fields: 222 | - table_calculation: count_of_error_messages 223 | label: Count of Error Messages 224 | expression: "${cloudtrail_logs.count}" 225 | value_format: 226 | value_format_name: decimal_0 227 | - table_calculation: users_impacted_by_error 228 | label: Users Impacted by Error 229 | expression: "${cloudtrail_logs.count_of_users}" 230 | value_format: 231 | value_format_name: decimal_0 232 | show_view_names: true 233 | show_row_numbers: true 234 | truncate_column_names: false 235 | hide_totals: false 236 | hide_row_totals: false 237 | table_theme: gray 238 | limit_displayed_rows: false 239 | enable_conditional_formatting: false 240 | conditional_formatting_ignored_fields: [] 241 | conditional_formatting_include_totals: false 242 | conditional_formatting_include_nulls: false 243 | stacking: '' 244 | show_value_labels: false 245 | label_density: 25 246 | legend_position: center 247 | x_axis_gridlines: false 248 | y_axis_gridlines: true 249 | y_axis_combined: true 250 | show_y_axis_labels: true 251 | show_y_axis_ticks: true 252 | y_axis_tick_density: default 253 | y_axis_tick_density_custom: 5 254 | show_x_axis_label: true 255 | show_x_axis_ticks: true 256 | x_axis_scale: auto 257 | y_axis_scale_mode: linear 258 | ordering: none 259 | show_null_labels: false 260 | show_totals_labels: false 261 | show_silhouette: false 262 | totals_color: "#808080" 263 | series_types: {} 264 | hidden_fields: 265 | - cloudtrail_logs.count 266 | - cloudtrail_logs.count_of_users 267 | listen: 268 | Date: cloudtrail_logs.event_time_date 269 | row: 17 270 | col: 18 271 | width: 6 272 | height: 7 273 | - name: Login User Count Over Time 274 | title: Login User Count Over Time 275 | model: aws_athena_cloudtrail 276 | explore: cloudtrail_logs 277 | type: looker_column 278 | fields: 279 | - cloudtrail_logs.count_of_distinct_users 280 | - cloudtrail_logs.event_time_date 281 | fill_fields: 282 | - cloudtrail_logs.event_time_date 283 | sorts: 284 | - cloudtrail_logs.event_time_date desc 285 | limit: 500 286 | column_limit: 50 287 | stacking: '' 288 | show_value_labels: false 289 | label_density: 25 290 | legend_position: center 291 | x_axis_gridlines: false 292 | y_axis_gridlines: true 293 | show_view_names: true 294 | limit_displayed_rows: false 295 | y_axis_combined: true 296 | show_y_axis_labels: true 297 | show_y_axis_ticks: true 298 | y_axis_tick_density: default 299 | y_axis_tick_density_custom: 5 300 | show_x_axis_label: true 301 | show_x_axis_ticks: true 302 | x_axis_scale: auto 303 | y_axis_scale_mode: linear 304 | ordering: none 305 | show_null_labels: false 306 | show_totals_labels: false 307 | show_silhouette: false 308 | totals_color: "#808080" 309 | series_colors: 310 | cloudtrail_logs.count_of_users: "#1f3e5a" 311 | cloudtrail_logs.count_of_distinct_users: "#1f3e5a" 312 | listen: 313 | Date: cloudtrail_logs.event_time_date 314 | row: 10 315 | col: 12 316 | width: 12 317 | height: 7 318 | - name: Logins without Multi-Factor Auth 319 | title: Logins without Multi-Factor Auth 320 | model: aws_athena_cloudtrail 321 | explore: cloudtrail_logs 322 | type: table 323 | fields: 324 | - cloudtrail_logs.user_name 325 | - cloudtrail_logs.login_status 326 | - cloudtrail_logs.total_logins 327 | filters: 328 | cloudtrail_logs.mfa_used: 'No' 329 | sorts: 330 | - cloudtrail_logs.total_logins desc 331 | limit: 500 332 | column_limit: 50 333 | query_timezone: America/Los_Angeles 334 | show_view_names: true 335 | show_row_numbers: true 336 | truncate_column_names: false 337 | hide_totals: false 338 | hide_row_totals: false 339 | table_theme: gray 340 | limit_displayed_rows: false 341 | enable_conditional_formatting: false 342 | conditional_formatting_ignored_fields: [] 343 | conditional_formatting_include_totals: false 344 | conditional_formatting_include_nulls: false 345 | listen: 346 | Date: cloudtrail_logs.event_time_date 347 | row: 17 348 | col: 12 349 | width: 6 350 | height: 7 351 | filters: 352 | - name: Date 353 | title: Date 354 | type: date_filter 355 | default_value: 1 years 356 | model: 357 | explore: 358 | field: 359 | listens_to_filters: [] 360 | allow_multiple_values: true 361 | -------------------------------------------------------------------------------- /error_overview.dashboard.lookml: -------------------------------------------------------------------------------- 1 | - dashboard: error_overivew 2 | title: Error Overivew 3 | layout: newspaper 4 | elements: 5 | - name: Top Assumed User Types 6 | title: Top Assumed User Types 7 | model: aws_athena_cloudtrail 8 | explore: cloudtrail_logs 9 | type: looker_column 10 | fields: 11 | - cloudtrail_logs.total_errors 12 | - cloudtrail_logs.assumed_user_name 13 | filters: 14 | sorts: 15 | - cloudtrail_logs.total_errors desc 16 | limit: 10 17 | column_limit: 50 18 | stacking: '' 19 | show_value_labels: false 20 | label_density: 25 21 | legend_position: center 22 | x_axis_gridlines: false 23 | y_axis_gridlines: true 24 | show_view_names: false 25 | limit_displayed_rows: false 26 | y_axis_combined: true 27 | show_y_axis_labels: true 28 | show_y_axis_ticks: true 29 | y_axis_tick_density: default 30 | y_axis_tick_density_custom: 5 31 | show_x_axis_label: true 32 | show_x_axis_ticks: true 33 | x_axis_scale: auto 34 | y_axis_scale_mode: linear 35 | ordering: none 36 | show_null_labels: false 37 | show_totals_labels: false 38 | show_silhouette: false 39 | totals_color: "#808080" 40 | series_colors: 41 | cloudtrail_logs.total_errors: "#1f3e5a" 42 | x_axis_label_rotation: -30 43 | colors: 44 | - 'palette: Looker Classic' 45 | series_types: 46 | errors_as_a_percent_of_events: line 47 | hidden_series: [] 48 | y_axes: 49 | - label: '' 50 | maxValue: 51 | minValue: 52 | orientation: left 53 | showLabels: true 54 | showValues: true 55 | tickDensity: default 56 | tickDensityCustom: 5 57 | type: linear 58 | unpinAxis: false 59 | valueFormat: 60 | series: 61 | - id: errors_as_a_percent_of_events 62 | name: Errors as a Percent of Events 63 | __FILE: aws_athena_cloudtrail/error_overview.dashboard.lookml 64 | __LINE_NUM: 180 65 | __FILE: aws_athena_cloudtrail/error_overview.dashboard.lookml 66 | __LINE_NUM: 168 67 | - label: 68 | maxValue: 69 | minValue: 70 | orientation: right 71 | showLabels: true 72 | showValues: true 73 | tickDensity: default 74 | tickDensityCustom: 5 75 | type: linear 76 | unpinAxis: false 77 | valueFormat: 78 | series: 79 | - id: total_errors 80 | name: Total Errors 81 | __FILE: aws_athena_cloudtrail/error_overview.dashboard.lookml 82 | __LINE_NUM: 194 83 | __FILE: aws_athena_cloudtrail/error_overview.dashboard.lookml 84 | __LINE_NUM: 182 85 | listen: 86 | Date: cloudtrail_logs.event_time_date 87 | row: 8 88 | col: 15 89 | width: 9 90 | height: 7 91 | - name: Errors by User Type 92 | title: Errors by User Type 93 | model: aws_athena_cloudtrail 94 | explore: cloudtrail_logs 95 | type: looker_pie 96 | fields: 97 | - cloudtrail_logs.total_errors 98 | - cloudtrail_logs.user_type 99 | filters: 100 | sorts: 101 | - cloudtrail_logs.total_errors desc 102 | limit: 10 103 | column_limit: 50 104 | value_labels: legend 105 | label_type: labPer 106 | stacking: '' 107 | show_value_labels: false 108 | label_density: 25 109 | legend_position: center 110 | x_axis_gridlines: false 111 | y_axis_gridlines: true 112 | show_view_names: true 113 | limit_displayed_rows: false 114 | y_axis_combined: true 115 | show_y_axis_labels: true 116 | show_y_axis_ticks: true 117 | y_axis_tick_density: default 118 | y_axis_tick_density_custom: 5 119 | show_x_axis_label: true 120 | show_x_axis_ticks: true 121 | x_axis_scale: auto 122 | y_axis_scale_mode: linear 123 | ordering: none 124 | show_null_labels: false 125 | show_totals_labels: false 126 | show_silhouette: false 127 | totals_color: "#808080" 128 | show_row_numbers: true 129 | truncate_column_names: false 130 | hide_totals: false 131 | hide_row_totals: false 132 | table_theme: gray 133 | enable_conditional_formatting: false 134 | conditional_formatting_ignored_fields: [] 135 | conditional_formatting_include_totals: false 136 | conditional_formatting_include_nulls: false 137 | series_types: {} 138 | series_colors: 139 | cloudtrail_logs.total_errors: "#1f3e5a" 140 | AssumedRole: "#1f3e5a" 141 | x_axis_label_rotation: -30 142 | inner_radius: 45 143 | listen: 144 | Date: cloudtrail_logs.event_time_date 145 | row: 8 146 | col: 0 147 | width: 9 148 | height: 7 149 | - name: Errors by Source 150 | title: Errors by Source 151 | model: aws_athena_cloudtrail 152 | explore: cloudtrail_logs 153 | type: table 154 | fields: 155 | - cloudtrail_logs.total_errors 156 | - cloudtrail_logs.event_source 157 | filters: 158 | cloudtrail_logs.total_errors: ">0" 159 | sorts: 160 | - cloudtrail_logs.total_errors desc 161 | limit: 500 162 | column_limit: 50 163 | show_view_names: true 164 | show_row_numbers: true 165 | truncate_column_names: false 166 | hide_totals: false 167 | hide_row_totals: false 168 | table_theme: gray 169 | limit_displayed_rows: false 170 | enable_conditional_formatting: false 171 | conditional_formatting_ignored_fields: [] 172 | conditional_formatting_include_totals: false 173 | conditional_formatting_include_nulls: false 174 | stacking: '' 175 | show_value_labels: false 176 | label_density: 25 177 | legend_position: center 178 | x_axis_gridlines: false 179 | y_axis_gridlines: true 180 | y_axis_combined: true 181 | show_y_axis_labels: true 182 | show_y_axis_ticks: true 183 | y_axis_tick_density: default 184 | y_axis_tick_density_custom: 5 185 | show_x_axis_label: true 186 | show_x_axis_ticks: true 187 | x_axis_scale: auto 188 | y_axis_scale_mode: linear 189 | ordering: none 190 | show_null_labels: false 191 | show_totals_labels: false 192 | show_silhouette: false 193 | totals_color: "#808080" 194 | series_types: {} 195 | listen: 196 | Date: cloudtrail_logs.event_time_date 197 | row: 8 198 | col: 9 199 | width: 6 200 | height: 7 201 | - name: Errors and Events Over Time 202 | title: Errors and Events Over Time 203 | model: aws_athena_cloudtrail 204 | explore: cloudtrail_logs 205 | type: looker_column 206 | fields: 207 | - cloudtrail_logs.errors_percent_events 208 | - cloudtrail_logs.total_errors 209 | - cloudtrail_logs.count 210 | - cloudtrail_logs.event_time_minute30 211 | fill_fields: 212 | - cloudtrail_logs.event_time_minute30 213 | sorts: 214 | - cloudtrail_logs.event_time_minute30 215 | limit: 500 216 | column_limit: 50 217 | query_timezone: America/Los_Angeles 218 | stacking: '' 219 | show_value_labels: false 220 | label_density: 25 221 | legend_position: center 222 | x_axis_gridlines: false 223 | y_axis_gridlines: true 224 | show_view_names: false 225 | limit_displayed_rows: false 226 | y_axis_combined: true 227 | show_y_axis_labels: true 228 | show_y_axis_ticks: true 229 | y_axis_tick_density: default 230 | y_axis_tick_density_custom: 5 231 | show_x_axis_label: true 232 | show_x_axis_ticks: true 233 | x_axis_scale: auto 234 | y_axis_scale_mode: linear 235 | ordering: none 236 | show_null_labels: false 237 | show_totals_labels: false 238 | show_silhouette: false 239 | totals_color: "#808080" 240 | show_row_numbers: true 241 | truncate_column_names: false 242 | hide_totals: false 243 | hide_row_totals: false 244 | table_theme: editable 245 | enable_conditional_formatting: false 246 | conditional_formatting_ignored_fields: [] 247 | conditional_formatting_include_totals: false 248 | conditional_formatting_include_nulls: false 249 | show_null_points: true 250 | point_style: none 251 | interpolation: linear 252 | series_types: 253 | errors_as_a_percent_of_events: line 254 | cloudtrail_logs.errors_percent_events: line 255 | series_colors: 256 | errors_as_a_percent_of_events: "#a9c574" 257 | total_errors: "#1f3e5a" 258 | cloudtrail_logs.total_errors: "#1f3e5a" 259 | cloudtrail_logs.errors_percent_events: "#a9c574" 260 | cloudtrail_logs.count: "#1f3e5a" 261 | hidden_fields: 262 | - cloudtrail_logs.total_errors 263 | y_axes: 264 | - label: 265 | maxValue: 266 | minValue: 267 | orientation: left 268 | showLabels: true 269 | showValues: true 270 | tickDensity: default 271 | tickDensityCustom: 272 | type: linear 273 | unpinAxis: false 274 | valueFormat: 275 | series: 276 | - id: cloudtrail_logs.errors_percent_events 277 | name: Errors As A Percent Of Events 278 | __FILE: aws_athena_cloudtrail/error_overview.dashboard.lookml 279 | __LINE_NUM: 280 280 | __FILE: aws_athena_cloudtrail/error_overview.dashboard.lookml 281 | __LINE_NUM: 268 282 | - label: 283 | maxValue: 284 | minValue: 285 | orientation: right 286 | showLabels: true 287 | showValues: true 288 | tickDensity: default 289 | tickDensityCustom: 290 | type: linear 291 | unpinAxis: false 292 | valueFormat: 293 | series: 294 | - id: cloudtrail_logs.count 295 | name: Total Events 296 | __FILE: aws_athena_cloudtrail/error_overview.dashboard.lookml 297 | __LINE_NUM: 294 298 | __FILE: aws_athena_cloudtrail/error_overview.dashboard.lookml 299 | __LINE_NUM: 282 300 | hidden_series: [] 301 | colors: 302 | - 'palette: Looker Classic' 303 | listen: 304 | Date: cloudtrail_logs.event_time_date 305 | row: 0 306 | col: 0 307 | width: 24 308 | height: 8 309 | - name: Top Events with Errors 310 | title: Top Events with Errors 311 | model: aws_athena_cloudtrail 312 | explore: cloudtrail_logs 313 | type: looker_bar 314 | fields: 315 | - cloudtrail_logs.count 316 | - cloudtrail_logs.event_name 317 | filters: 318 | cloudtrail_logs.errorcode: "-NULL" 319 | cloudtrail_logs.errormessage: "-NULL" 320 | sorts: 321 | - cloudtrail_logs.count desc 322 | limit: 10 323 | column_limit: 50 324 | stacking: '' 325 | show_value_labels: false 326 | label_density: 25 327 | legend_position: center 328 | x_axis_gridlines: false 329 | y_axis_gridlines: true 330 | show_view_names: false 331 | limit_displayed_rows: false 332 | y_axis_combined: true 333 | show_y_axis_labels: true 334 | show_y_axis_ticks: true 335 | y_axis_tick_density: default 336 | y_axis_tick_density_custom: 5 337 | show_x_axis_label: true 338 | show_x_axis_ticks: true 339 | x_axis_scale: auto 340 | y_axis_scale_mode: linear 341 | ordering: none 342 | show_null_labels: false 343 | show_totals_labels: false 344 | show_silhouette: false 345 | totals_color: "#808080" 346 | label: Top AWS Event Errors 347 | show_row_numbers: true 348 | truncate_column_names: false 349 | hide_totals: false 350 | hide_row_totals: false 351 | table_theme: gray 352 | enable_conditional_formatting: false 353 | conditional_formatting_ignored_fields: [] 354 | conditional_formatting_include_totals: false 355 | conditional_formatting_include_nulls: false 356 | series_types: {} 357 | series_colors: 358 | cloudtrail_logs.count: "#1f3e5a" 359 | x_axis_label_rotation: -45 360 | listen: 361 | Date: cloudtrail_logs.event_time_date 362 | row: 15 363 | col: 0 364 | width: 12 365 | height: 10 366 | - name: Top Error Codes 367 | title: Top Error Codes 368 | model: aws_athena_cloudtrail 369 | explore: cloudtrail_logs 370 | type: looker_bar 371 | fields: 372 | - cloudtrail_logs.count 373 | - cloudtrail_logs.errorcode 374 | filters: 375 | cloudtrail_logs.errorcode: "-NULL" 376 | cloudtrail_logs.errormessage: "-NULL" 377 | sorts: 378 | - cloudtrail_logs.count desc 379 | limit: 10 380 | column_limit: 50 381 | stacking: '' 382 | show_value_labels: false 383 | label_density: 25 384 | legend_position: center 385 | x_axis_gridlines: false 386 | y_axis_gridlines: true 387 | show_view_names: false 388 | limit_displayed_rows: false 389 | y_axis_combined: true 390 | show_y_axis_labels: true 391 | show_y_axis_ticks: true 392 | y_axis_tick_density: default 393 | y_axis_tick_density_custom: 5 394 | show_x_axis_label: true 395 | show_x_axis_ticks: true 396 | x_axis_scale: auto 397 | y_axis_scale_mode: linear 398 | ordering: none 399 | show_null_labels: false 400 | show_totals_labels: false 401 | show_silhouette: false 402 | totals_color: "#808080" 403 | label: Top AWS Event Errors 404 | show_row_numbers: true 405 | truncate_column_names: false 406 | hide_totals: false 407 | hide_row_totals: false 408 | table_theme: gray 409 | enable_conditional_formatting: false 410 | conditional_formatting_ignored_fields: [] 411 | conditional_formatting_include_totals: false 412 | conditional_formatting_include_nulls: false 413 | series_types: {} 414 | series_colors: 415 | cloudtrail_logs.count: "#1f3e5a" 416 | x_axis_label_rotation: -45 417 | listen: 418 | Date: cloudtrail_logs.event_time_date 419 | row: 15 420 | col: 12 421 | width: 12 422 | height: 10 423 | - name: Assumed IAM User Errors (Full Detail) 424 | title: Assumed IAM User Errors (Full Detail) 425 | model: aws_athena_cloudtrail 426 | explore: cloudtrail_logs 427 | type: table 428 | fields: 429 | - cloudtrail_logs.assumed_user_name 430 | - cloudtrail_logs.event_name 431 | - cloudtrail_logs.errorcode 432 | - cloudtrail_logs.errormessage 433 | - cloudtrail_logs.count 434 | - cloudtrail_logs.event_source 435 | filters: 436 | cloudtrail_logs.errorcode: "-NULL" 437 | cloudtrail_logs.count: ">1" 438 | sorts: 439 | - cloudtrail_logs.count desc 440 | limit: 500 441 | column_limit: 50 442 | label: Top AWS Event Errors 443 | show_view_names: false 444 | show_row_numbers: true 445 | truncate_column_names: false 446 | hide_totals: false 447 | hide_row_totals: false 448 | table_theme: gray 449 | limit_displayed_rows: false 450 | enable_conditional_formatting: false 451 | conditional_formatting_ignored_fields: [] 452 | conditional_formatting_include_totals: false 453 | conditional_formatting_include_nulls: false 454 | listen: 455 | Date: cloudtrail_logs.event_time_date 456 | row: 25 457 | col: 0 458 | width: 24 459 | height: 8 460 | filters: 461 | - name: Date 462 | title: Date 463 | type: date_filter 464 | default_value: 48 hours 465 | model: 466 | explore: 467 | field: 468 | listens_to_filters: [] 469 | allow_multiple_values: true 470 | --------------------------------------------------------------------------------