├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── stale.yml │ └── sync-labels.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── dashboards ├── docs │ ├── wellarchitected_workload_detail.md │ └── wellarchitected_workload_risks_report.md ├── wellarchitected.sp ├── wellarchitected_workload_detail.sp └── wellarchitected_workload_risks_report.sp ├── docs ├── aws_well_architected_console.png ├── aws_well_architected_reliability_dashboard.png ├── aws_well_architected_workload_risks_report.png └── index.md ├── mod.pp ├── powerpipe.ppvars.example ├── variables.pp └── well_architected_framework ├── docs └── well_architected_framework_overview.md ├── operational_excellence ├── operational_excellence.pp ├── ops04.pp └── ops05.pp ├── reliability ├── rel01.pp ├── rel02.pp ├── rel06.pp ├── rel07.pp ├── rel08.pp ├── rel09.pp └── reliability.pp ├── security ├── sec01.pp ├── sec02.pp ├── sec03.pp ├── sec04.pp ├── sec05.pp ├── sec06.pp ├── sec08.pp ├── sec09.pp ├── sec10.pp ├── sec11.pp └── security.pp └── well_architected_framework.pp /.gitattributes: -------------------------------------------------------------------------------- 1 | **/*.sp linguist-language=HCL 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **Powerpipe version (`powerpipe -v`)** 14 | Example: v0.3.0 15 | 16 | **Steampipe version (`steampipe -v`)** 17 | Example: v0.3.0 18 | 19 | **Plugin version (`steampipe plugin list`)** 20 | Example: v0.5.0 21 | 22 | **To reproduce** 23 | Steps to reproduce the behavior (please include relevant code and/or commands). 24 | 25 | **Expected behavior** 26 | A clear and concise description of what you expected to happen. 27 | 28 | **Additional context** 29 | Add any other context about the problem here. 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Questions 4 | url: https://turbot.com/community/join 5 | about: GitHub issues in this repository are only intended for bug reports and feature requests. Other issues will be closed. Please ask and answer questions through the Steampipe Slack community. 6 | - name: Powerpipe CLI Bug Reports and Feature Requests 7 | url: https://github.com/turbot/powerpipe/issues/new/choose 8 | about: Powerpipe CLI has its own codebase. Bug reports and feature requests for those pieces of functionality should be directed to that repository. 9 | - name: Steampipe CLI Bug Reports and Feature Requests 10 | url: https://github.com/turbot/steampipe/issues/new/choose 11 | about: Steampipe CLI has its own codebase. Bug reports and feature requests for those pieces of functionality should be directed to that repository. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Checklist 2 | - [ ] Issue(s) linked 3 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: Stale Issues and PRs 2 | on: 3 | schedule: 4 | - cron: "30 23 * * *" 5 | workflow_dispatch: 6 | inputs: 7 | dryRun: 8 | description: Set to true for a dry run 9 | required: false 10 | default: "false" 11 | type: string 12 | 13 | jobs: 14 | stale_workflow: 15 | uses: turbot/steampipe-workflows/.github/workflows/stale.yml@main 16 | with: 17 | dryRun: ${{ github.event.inputs.dryRun }} -------------------------------------------------------------------------------- /.github/workflows/sync-labels.yml: -------------------------------------------------------------------------------- 1 | name: Sync Labels 2 | on: 3 | schedule: 4 | - cron: "30 22 * * 1" 5 | workflow_dispatch: 6 | 7 | jobs: 8 | sync_labels_workflow: 9 | uses: turbot/steampipe-workflows/.github/workflows/sync-labels.yml@main -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Swap files 9 | *.swp 10 | 11 | # Steampipe variable files 12 | *.spvars 13 | *.auto.spvars 14 | 15 | # Powerpipe variable files 16 | *.ppvars 17 | *.auto.ppvars 18 | 19 | # Steampipe mod dependencies 20 | .steampipe 21 | .powerpipe 22 | 23 | # Cache json files 24 | *.cache.json 25 | 26 | # Ignore Desktop Services Store files 27 | .DS_Store 28 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## v1.0.0 [2024-10-22] 2 | 3 | This mod now requires [Powerpipe](https://powerpipe.io). [Steampipe](https://steampipe.io) users should check the [migration guide](https://powerpipe.io/blog/migrating-from-steampipe). 4 | 5 | ## v0.11 [2024-04-06] 6 | 7 | _Powerpipe_ 8 | 9 | [Powerpipe](https://powerpipe.io) is now the preferred way to run this mod! [Migrating from Steampipe →](https://powerpipe.io/blog/migrating-from-steampipe) 10 | 11 | All v0.x versions of this mod will work in both Steampipe and Powerpipe, but v1.0.0 onwards will be in Powerpipe format only. 12 | 13 | _Enhancements_ 14 | 15 | - Focus documentation on Powerpipe commands. 16 | - Show how to combine Powerpipe mods with Steampipe plugins. 17 | 18 | ## v0.10 [2024-01-12] 19 | 20 | _Bug fixes_ 21 | 22 | - Updated the tags to use `risk` instead of `severity` to eliminate duplicate column names in output files. ([#41](https://github.com/turbot/steampipe-mod-aws-well-architected/pull/41)) 23 | 24 | ## v0.9 [2023-11-03] 25 | 26 | _Breaking changes_ 27 | 28 | - Updated the plugin dependency section of the mod to use `min_version` instead of `version`. ([#34](https://github.com/turbot/steampipe-mod-aws-well-architected/pull/34)) 29 | 30 | _Bug fixes_ 31 | 32 | - Fixed the README and index docs to correctly reference the `well_architected_framework_security` benchmark. ([#25](https://github.com/turbot/steampipe-mod-aws-well-architected/pull/25)) 33 | 34 | ## v0.8 [2023-05-26] 35 | 36 | _Breaking changes_ 37 | 38 | - The standalone Well-Architected Framework Reliability and Security benchmarks have been removed, as they are now included in the Well-Architected Framework benchmark. 39 | 40 | _What's new?_ 41 | 42 | - Added Well-Architected Framework benchmark (`steampipe check benchmark.well_architected_framework`). ([#22](https://github.com/turbot/steampipe-mod-aws-well-architected/pull/22)) 43 | - New dashboards added: ([#21](https://github.com/turbot/steampipe-mod-aws-well-architected/pull/21)) 44 | - [AWS Well-Architected Workload Detail](https://hub.steampipe.io/mods/turbot/aws_well_architected/dashboards/dashboard.wellarchitected_workload_detail) 45 | - [AWS Well-Architected Workload Risks Report](https://hub.steampipe.io/mods/turbot/aws_well_architected/dashboards/dashboard.wellarchitected_workload_risks_report) 46 | 47 | _Dependencies_ 48 | 49 | - AWS Compliance mod `v0.66` or higher is now required. ([#22](https://github.com/turbot/steampipe-mod-aws-well-architected/pull/22)) 50 | 51 | ## v0.7 [2023-05-22] 52 | 53 | _Dependencies_ 54 | 55 | - AWS Compliance mod `v0.64` or higher is now required. 56 | 57 | _Bug fixes_ 58 | 59 | - Fixed semver constraint for AWS Compliance mod to require a minimum minor version instead of an exact minor version. 60 | - Removed unused ECS queries that are now in AWS Compliance mod controls. ([#18](https://github.com/turbot/steampipe-mod-aws-well-architected/pull/18)) 61 | 62 | ## v0.6 [2023-05-03] 63 | 64 | _Bug fixes_ 65 | 66 | - Fixed dashboard localhost URLs in README and index doc. ([#15](https://github.com/turbot/steampipe-mod-aws-well-architected/pull/15)) 67 | 68 | ## v0.5 [2023-04-24] 69 | 70 | _Dependencies_ 71 | 72 | - AWS Compliance mod `v0.63` or higher is now required. ([#9](https://github.com/turbot/steampipe-mod-aws-well-architected/pull/9)) 73 | 74 | ## v0.4 [2023-04-19] 75 | 76 | _Bug fixes_ 77 | 78 | - Added variables and locals to this mod to avoid incorrect referenecs to those in the AWS Compliance mod. ([#11](https://github.com/turbot/steampipe-mod-aws-well-architected/pull/11)) 79 | 80 | ## v0.3 [2023-04-19] 81 | 82 | _Dependencies_ 83 | 84 | - AWS Compliance mod `v0.62` or higher is now required. ([#4](https://github.com/turbot/steampipe-mod-aws-well-architected/pull/4)) 85 | 86 | ## v0.2 [2023-04-12] 87 | 88 | _Bug fixes_ 89 | 90 | - Fixed reference to `apigateway_rest_api_stage_use_ssl_certificate` control in `security_9` benchmark to use fully qualified resource name. 91 | 92 | ## v0.1 [2023-04-10] 93 | 94 | _What's new?_ 95 | 96 | - Added: Reliability Pillar benchmark (`steampipe check benchmark.reliability`) 97 | - Added: Security Pillar benchmark (`steampipe check benchmark.security`) 98 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AWS Well-Architected Mod for Powerpipe 2 | 3 | 200+ checks covering AWS Well-Architected Framework defined best practices across all AWS regions. 4 | 5 | Run checks in a dashboard: 6 | ![image](https://raw.githubusercontent.com/turbot/steampipe-mod-aws-well-architected/main/docs/aws_well_architected_reliability_dashboard.png) 7 | 8 | Or in a terminal: 9 | ![image](https://raw.githubusercontent.com/turbot/steampipe-mod-aws-well-architected/main/docs/aws_well_architected_console.png) 10 | 11 | ## Getting Started 12 | 13 | ### Installation 14 | 15 | Install Powerpipe (https://powerpipe.io/downloads), or use Brew: 16 | 17 | ```sh 18 | brew install turbot/tap/powerpipe 19 | ``` 20 | 21 | This mod also requires [Steampipe](https://steampipe.io) with the [AWS plugin](https://hub.steampipe.io/plugins/turbot/aws) as the data source. Install Steampipe (https://steampipe.io/downloads), or use Brew: 22 | 23 | ```sh 24 | brew install turbot/tap/steampipe 25 | steampipe plugin install aws 26 | ``` 27 | 28 | Steampipe will automatically use your default AWS credentials. Optionally, you can [setup multiple accounts](https://hub.steampipe.io/plugins/turbot/aws#multi-account-connections) or [customize AWS credentials](https://hub.steampipe.io/plugins/turbot/aws#configuring-aws-credentials). 29 | 30 | Finally, install the mod: 31 | 32 | ```sh 33 | mkdir dashboards 34 | cd dashboards 35 | powerpipe mod init 36 | powerpipe mod install github.com/turbot/steampipe-mod-aws-well-architected 37 | ``` 38 | 39 | ### Browsing Dashboards 40 | 41 | Start Steampipe as the data source: 42 | 43 | ```sh 44 | steampipe service start 45 | ``` 46 | 47 | Start the dashboard server: 48 | 49 | ```sh 50 | powerpipe server 51 | ``` 52 | 53 | Browse and view your dashboards at **http://localhost:9033**. 54 | 55 | ### Running Checks in Your Terminal 56 | 57 | Instead of running benchmarks in a dashboard, you can also run them within your 58 | terminal with the `powerpipe benchmark` command: 59 | 60 | List available benchmarks: 61 | 62 | ```sh 63 | powerpipe benchmark list 64 | ``` 65 | 66 | Run a benchmark: 67 | 68 | ```sh 69 | powerpipe benchmark run well_architected_framework 70 | ``` 71 | 72 | Run a benchmark for a specific pillar: 73 | 74 | ```sh 75 | powerpipe benchmark run well_architected_framework_security 76 | ``` 77 | 78 | Run a benchmark for a specific question: 79 | 80 | ```sh 81 | powerpipe benchmark run well_architected_framework_sec01 82 | ``` 83 | 84 | Run a benchmark for a specific best practice: 85 | 86 | ```sh 87 | powerpipe benchmark run well_architected_framework_sec01_bp01 88 | ``` 89 | 90 | Different output formats are also available, for more information please see 91 | [Output Formats](https://powerpipe.io/docs/reference/cli/benchmark#output-formats). 92 | 93 | ### Common and Tag Dimensions 94 | 95 | The benchmark queries use common properties (like `account_id`, `connection_name` and `region`) and tags that are defined in the dependent [AWS Compliance mod](https://github.com/turbot/steampipe-mod-aws-compliance) These properties can be executed in the following ways: 96 | 97 | It's easiest to setup your vars file, starting with the sample: 98 | 99 | ```sh 100 | cp powerpipe.ppvars.example powerpipe.ppvars 101 | vi powerpipe.ppvars 102 | ``` 103 | 104 | Alternatively you can pass variables on the command line: 105 | 106 | ```sh 107 | powerpipe benchmark run well_architected_framework_security --var 'common_dimensions=["account_id", "connection_name", "region"]' 108 | ``` 109 | 110 | Or through environment variables: 111 | 112 | ```sh 113 | export PP_VAR_common_dimensions='["account_id", "connection_name", "region"]' 114 | export PP_VAR_tag_dimensions='["Environment", "Owner"]' 115 | powerpipe benchmark run well_architected_framework_security 116 | ``` 117 | 118 | ## Open Source & Contributing 119 | 120 | This repository is published under the [Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0). Please see our [code of conduct](https://github.com/turbot/.github/blob/main/CODE_OF_CONDUCT.md). We look forward to collaborating with you! 121 | 122 | [Steampipe](https://steampipe.io) and [Powerpipe](https://powerpipe.io) are products produced from this open source software, exclusively by [Turbot HQ, Inc](https://turbot.com). They are distributed under our commercial terms. Others are allowed to make their own distribution of the software, but cannot use any of the Turbot trademarks, cloud services, etc. You can learn more in our [Open Source FAQ](https://turbot.com/open-source). 123 | 124 | ## Get Involved 125 | 126 | **[Join #powerpipe on Slack →](https://turbot.com/community/join)** 127 | 128 | Want to help but don't know where to start? Pick up one of the `help wanted` issues: 129 | 130 | - [Powerpipe](https://github.com/turbot/powerpipe/labels/help%20wanted) 131 | - [AWS Well-Architected Mod](https://github.com/turbot/steampipe-mod-aws-well-architected/labels/help%20wanted) 132 | 133 | ## Credits 134 | 135 | - Thanks to [@JPPienaar](https://github.com/JPPienaar) and [@nathanwebsterdotme](https://github.com/nathanwebsterdotme) from [Daemon](https://github.com/Daemon-Solutions) for developing some of the control mappings used in the Well-Architected Framework benchmarks. 136 | -------------------------------------------------------------------------------- /dashboards/docs/wellarchitected_workload_detail.md: -------------------------------------------------------------------------------- 1 | This dashboard answers the following questions for each workload: 2 | 3 | - How many questions are answered? 4 | - How many risks are there for each lens and pillar? 5 | - What are the risk counts for each milestone? 6 | - How many unanswered questions are there for each milestone? 7 | -------------------------------------------------------------------------------- /dashboards/docs/wellarchitected_workload_risks_report.md: -------------------------------------------------------------------------------- 1 | This report answers the following questions: 2 | 3 | - How many workloads have high and medium risks? 4 | - How many high and medium risks are there? 5 | - What are the risk counts for each workload? 6 | -------------------------------------------------------------------------------- /dashboards/wellarchitected.sp: -------------------------------------------------------------------------------- 1 | locals { 2 | wellarchitected_common_tags = { 3 | service = "AWS/WellArchitected" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /dashboards/wellarchitected_workload_detail.sp: -------------------------------------------------------------------------------- 1 | // Risk types from aws_wellarchitected_workload are not returned if their count is 0, so use coalesce(..., 0) 2 | // But from aws_wellarchitected_lens_review, all risk types are returned even when their count is 0 3 | dashboard "wellarchitected_workload_detail" { 4 | 5 | title = "AWS Well-Architected Workload Detail" 6 | documentation = file("./dashboards/docs/wellarchitected_workload_detail.md") 7 | 8 | tags = merge(local.wellarchitected_common_tags, { 9 | type = "Detail" 10 | }) 11 | 12 | input "workload_id" { 13 | title = "Select a workload:" 14 | query = query.wellarchitected_workload_input 15 | width = 4 16 | } 17 | 18 | input "lens_arn" { 19 | title = "Select a lens:" 20 | type = "multicombo" 21 | width = 3 22 | 23 | query = query.wellarchitected_lens_input 24 | args = [self.input.workload_id.value] 25 | } 26 | 27 | container { 28 | 29 | card { 30 | width = 2 31 | query = query.wellarchitected_workload_answered_question_count 32 | args = { 33 | workload_id = self.input.workload_id.value 34 | lens_arn = self.input.lens_arn.value 35 | } 36 | } 37 | 38 | card { 39 | width = 2 40 | query = query.wellarchitected_workload_high_risk_count 41 | args = { 42 | workload_id = self.input.workload_id.value 43 | lens_arn = self.input.lens_arn.value 44 | } 45 | } 46 | 47 | card { 48 | width = 2 49 | query = query.wellarchitected_workload_medium_risk_count 50 | args = { 51 | workload_id = self.input.workload_id.value 52 | lens_arn = self.input.lens_arn.value 53 | } 54 | } 55 | 56 | card { 57 | width = 2 58 | query = query.wellarchitected_workload_no_improvements_risk_count 59 | args = { 60 | workload_id = self.input.workload_id.value 61 | lens_arn = self.input.lens_arn.value 62 | } 63 | } 64 | 65 | card { 66 | width = 2 67 | query = query.wellarchitected_workload_not_applicable_risk_count 68 | args = { 69 | workload_id = self.input.workload_id.value 70 | lens_arn = self.input.lens_arn.value 71 | } 72 | } 73 | 74 | } 75 | 76 | container { 77 | 78 | chart { 79 | title = "Risk Counts by Milestone" 80 | type = "line" 81 | grouping = "compare" 82 | width = 6 83 | 84 | series "high_risks" { 85 | title = "High" 86 | color = "red" 87 | } 88 | 89 | series "medium_risks" { 90 | title = "Medium" 91 | color = "yellow" 92 | } 93 | 94 | series "no_improvements_risks" { 95 | title = "No Improvements" 96 | color = "green" 97 | } 98 | 99 | series "not_applicable_risks" { 100 | title = "N/A" 101 | color = "gray" 102 | } 103 | 104 | series "unanswered_risks" { 105 | title = "Unanswered" 106 | color = "gray" 107 | } 108 | 109 | axes { 110 | x { 111 | labels { 112 | display = "always" 113 | } 114 | } 115 | } 116 | 117 | query = query.wellarchitected_workload_risks_by_milestone 118 | args = { 119 | workload_id = self.input.workload_id.value 120 | lens_arn = self.input.lens_arn.value 121 | } 122 | } 123 | 124 | chart { 125 | title = "Risk Counts by Lens" 126 | type = "column" 127 | grouping = "compare" 128 | width = 6 129 | 130 | series "high_risks" { 131 | title = "High" 132 | color = "red" 133 | } 134 | 135 | series "medium_risks" { 136 | title = "Medium" 137 | color = "yellow" 138 | } 139 | 140 | series "no_improvements_risks" { 141 | title = "No Improvements" 142 | color = "green" 143 | } 144 | 145 | series "not_applicable_risks" { 146 | title = "N/A" 147 | color = "gray" 148 | } 149 | 150 | series "unanswered_risks" { 151 | title = "Unanswered" 152 | color = "gray" 153 | } 154 | 155 | axes { 156 | x { 157 | labels { 158 | display = "always" 159 | } 160 | } 161 | } 162 | 163 | query = query.wellarchitected_workload_risks_by_lens 164 | args = { 165 | workload_id = self.input.workload_id.value 166 | lens_arn = self.input.lens_arn.value 167 | } 168 | } 169 | 170 | chart { 171 | title = "Unanswered Questions by Milestone" 172 | type = "line" 173 | grouping = "compare" 174 | width = 6 175 | 176 | series "unanswered_risks" { 177 | title = "Unanswered" 178 | color = "gray" 179 | } 180 | 181 | axes { 182 | x { 183 | labels { 184 | display = "always" 185 | } 186 | } 187 | } 188 | 189 | query = query.wellarchitected_workload_unanswered_by_milestone 190 | args = { 191 | workload_id = self.input.workload_id.value 192 | lens_arn = self.input.lens_arn.value 193 | } 194 | } 195 | 196 | chart { 197 | title = "Risk Counts by Pillar" 198 | type = "column" 199 | grouping = "compare" 200 | width = 6 201 | 202 | series "high_risks" { 203 | title = "High" 204 | color = "red" 205 | } 206 | 207 | series "medium_risks" { 208 | title = "Medium" 209 | color = "yellow" 210 | } 211 | 212 | series "no_improvements_risks" { 213 | title = "No Improvements" 214 | color = "green" 215 | } 216 | 217 | series "not_applicable_risks" { 218 | title = "N/A" 219 | color = "gray" 220 | } 221 | 222 | series "unanswered_risks" { 223 | title = "Unanswered" 224 | color = "gray" 225 | } 226 | 227 | axes { 228 | x { 229 | labels { 230 | display = "always" 231 | } 232 | } 233 | } 234 | 235 | query = query.wellarchitected_workload_risks_by_pillar 236 | args = { 237 | workload_id = self.input.workload_id.value 238 | lens_arn = self.input.lens_arn.value 239 | } 240 | } 241 | 242 | } 243 | 244 | container { 245 | 246 | table { 247 | title = "Risk Counts by Milestone" 248 | width = 6 249 | query = query.wellarchitected_workload_milestone_risk_table 250 | args = { 251 | workload_id = self.input.workload_id.value 252 | lens_arn = self.input.lens_arn.value 253 | } 254 | } 255 | 256 | table { 257 | title = "Risk Counts by Lens" 258 | width = 6 259 | query = query.wellarchitected_workload_lens_risk_table 260 | args = { 261 | workload_id = self.input.workload_id.value 262 | lens_arn = self.input.lens_arn.value 263 | } 264 | } 265 | 266 | table { 267 | title = "Unanswered Questions by Milestone" 268 | width = 6 269 | query = query.wellarchitected_workload_milestone_unanswered_table 270 | args = { 271 | workload_id = self.input.workload_id.value 272 | lens_arn = self.input.lens_arn.value 273 | } 274 | } 275 | 276 | table { 277 | title = "Risk Counts by Pillar" 278 | width = 6 279 | query = query.wellarchitected_workload_pillar_risk_table 280 | args = { 281 | workload_id = self.input.workload_id.value 282 | lens_arn = self.input.lens_arn.value 283 | } 284 | } 285 | 286 | } 287 | 288 | } 289 | 290 | # Input queries 291 | 292 | query "wellarchitected_workload_input" { 293 | sql = <<-EOQ 294 | select 295 | title as label, 296 | workload_id as value, 297 | json_build_object( 298 | 'account_id', account_id, 299 | 'region', region, 300 | 'workload_name', workload_name 301 | ) as tags 302 | from 303 | aws_wellarchitected_workload 304 | order by 305 | title; 306 | EOQ 307 | } 308 | 309 | query "wellarchitected_lens_input" { 310 | sql = <<-EOQ 311 | select 312 | l.title as label, 313 | l.arn as value, 314 | json_build_object( 315 | 'account_id', l.account_id, 316 | 'region', l.region, 317 | 'lens_alias', l.lens_alias 318 | ) as tags 319 | from 320 | aws_wellarchitected_workload w, 321 | aws_wellarchitected_lens l, 322 | jsonb_array_elements_text(w.lenses) la 323 | where 324 | (la = l.lens_alias or la = l.arn) 325 | and l.account_id = w.account_id 326 | and l.region = w.region 327 | and w.workload_id = $1 328 | order by 329 | l.title; 330 | EOQ 331 | } 332 | 333 | # Card queries 334 | 335 | query "wellarchitected_workload_answered_question_count" { 336 | sql = <<-EOQ 337 | with question_counts as ( 338 | select 339 | sum((risk_counts ->> 'UNANSWERED')::int) as unanswered_questions, 340 | sum((risk_counts ->> 'HIGH')::int) + sum((risk_counts ->> 'MEDIUM')::int) + sum((risk_counts ->> 'NONE')::int) + sum((risk_counts ->> 'NOT_APPLICABLE')::int) as answered_questions 341 | from 342 | aws_wellarchitected_lens_review as r 343 | where 344 | r.workload_id = $1 345 | and r.lens_arn = any(string_to_array($2, ',')) 346 | ) 347 | select 348 | 'Answered Questions' as label, 349 | answered_questions || '/' || unanswered_questions + answered_questions || ' (' || (100 * answered_questions/(unanswered_questions + answered_questions))::numeric || '%)' as value, 350 | case 351 | when unanswered_questions = 0 then 'ok' 352 | else 'alert' 353 | end as type 354 | from 355 | question_counts 356 | EOQ 357 | 358 | param "workload_id" {} 359 | param "lens_arn" {} 360 | } 361 | 362 | query "wellarchitected_workload_high_risk_count" { 363 | sql = <<-EOQ 364 | select 365 | 'High Risks' as label, 366 | sum((risk_counts ->> 'HIGH')::int) as value, 367 | case 368 | sum((risk_counts ->> 'HIGH')::int) when 0 then 'ok' 369 | else 'alert' 370 | end as type 371 | from 372 | aws_wellarchitected_lens_review as r 373 | where 374 | r.workload_id = $1 375 | and r.lens_arn = any(string_to_array($2, ',')) 376 | EOQ 377 | 378 | param "workload_id" {} 379 | param "lens_arn" {} 380 | } 381 | 382 | query "wellarchitected_workload_medium_risk_count" { 383 | sql = <<-EOQ 384 | select 385 | 'Medium Risks' as label, 386 | sum((risk_counts ->> 'MEDIUM')::int) as value, 387 | case 388 | sum((risk_counts ->> 'MEDIUM')::int) when 0 then 'ok' 389 | else 'alert' 390 | end as type 391 | from 392 | aws_wellarchitected_lens_review as r 393 | where 394 | r.workload_id = $1 395 | and r.lens_arn = any(string_to_array($2, ',')) 396 | EOQ 397 | 398 | param "workload_id" {} 399 | param "lens_arn" {} 400 | } 401 | 402 | query "wellarchitected_workload_no_improvements_risk_count" { 403 | sql = <<-EOQ 404 | select 405 | 'No Improvements' as label, 406 | sum((risk_counts ->> 'NONE')::int) as value 407 | from 408 | aws_wellarchitected_lens_review as r 409 | where 410 | r.workload_id = $1 411 | and r.lens_arn = any(string_to_array($2, ',')) 412 | EOQ 413 | 414 | param "workload_id" {} 415 | param "lens_arn" {} 416 | } 417 | 418 | query "wellarchitected_workload_not_applicable_risk_count" { 419 | sql = <<-EOQ 420 | select 421 | 'Not Applicable' as label, 422 | sum((risk_counts ->> 'NOT_APPLICABLE')::int) as value 423 | from 424 | aws_wellarchitected_lens_review as r 425 | where 426 | r.workload_id = $1 427 | and r.lens_arn = any(string_to_array($2, ',')) 428 | EOQ 429 | 430 | param "workload_id" {} 431 | param "lens_arn" {} 432 | } 433 | 434 | # Chart queries 435 | 436 | query "wellarchitected_workload_risks_by_lens" { 437 | sql = <<-EOQ 438 | select 439 | r.lens_name, 440 | (r.risk_counts ->> 'HIGH')::int as high_risks, 441 | (r.risk_counts ->> 'MEDIUM')::int as medium_risks, 442 | (r.risk_counts ->> 'NONE')::int as no_improvements_risks, 443 | (r.risk_counts ->> 'NOT_APPLICABLE')::int as not_applicable_risks 444 | from 445 | aws_wellarchitected_lens_review as r 446 | where 447 | r.workload_id = $1 448 | and r.lens_arn = any(string_to_array($2, ',')) 449 | group by 450 | r.lens_name, 451 | r.risk_counts 452 | order by 453 | r.lens_name 454 | EOQ 455 | 456 | param "workload_id" {} 457 | param "lens_arn" {} 458 | } 459 | 460 | query "wellarchitected_workload_risks_by_pillar" { 461 | sql = <<-EOQ 462 | select 463 | p ->> 'PillarName' as pillar_name, 464 | sum((p -> 'RiskCounts' ->> 'HIGH')::int) as high_risks, 465 | sum((p -> 'RiskCounts' ->> 'MEDIUM')::int) as medium_risks, 466 | sum((p -> 'RiskCounts' ->> 'NONE')::int) as no_improvements_risks, 467 | sum((p -> 'RiskCounts' ->> 'NOT_APPLICABLE')::int) as not_applicable_risks 468 | from 469 | aws_wellarchitected_lens_review as r, 470 | jsonb_array_elements(r.pillar_review_summaries) as p 471 | where 472 | r.workload_id = $1 473 | and r.lens_arn = any(string_to_array($2, ',')) 474 | group by 475 | pillar_name 476 | order by 477 | pillar_name 478 | EOQ 479 | 480 | param "workload_id" {} 481 | param "lens_arn" {} 482 | } 483 | 484 | query "wellarchitected_workload_risks_by_milestone" { 485 | sql = <<-EOQ 486 | with milestone_info as ( 487 | select 488 | workload_id, 489 | milestone_number, 490 | milestone_name, 491 | recorded_at 492 | from 493 | aws_wellarchitected_milestone 494 | where 495 | workload_id = $1 496 | 497 | union 498 | 499 | select 500 | $1 as workload_id, 501 | 0 as milestone_number, -- Lens review API returns latest milestone as 0 502 | 'latest' as milestone_name, 503 | current_timestamp as recorded_at 504 | ), lens_review as ( 505 | select 506 | * 507 | from 508 | aws_wellarchitected_lens_review 509 | where 510 | milestone_number in (select milestone_number from aws_wellarchitected_milestone where workload_id = $1 union select 0 as milestone_number) -- Latest milestone is returned as 0 511 | and workload_id = (select workload_id from aws_wellarchitected_workload where workload_id = $1) 512 | ), risk_data as ( 513 | select 514 | milestone_number, 515 | sum((risk_counts ->> 'HIGH')::int) as high_risks, 516 | sum((risk_counts ->> 'MEDIUM')::int) as medium_risks, 517 | sum((risk_counts ->> 'NONE')::int) as no_improvements_risks, 518 | sum((risk_counts ->> 'NOT_APPLICABLE')::int) as not_applicable_risks 519 | --sum((risk_counts ->> 'UNANSWERED')::int) as unanswered_risks 520 | from 521 | lens_review as r 522 | where 523 | r.lens_arn = any(string_to_array($2, ',')) 524 | group by 525 | r.milestone_number 526 | order by 527 | r.milestone_number 528 | ) select 529 | m.milestone_name, 530 | r.high_risks, 531 | r.medium_risks, 532 | r.no_improvements_risks, 533 | r.not_applicable_risks 534 | from 535 | risk_data r 536 | left join milestone_info m 537 | on r.milestone_number = m.milestone_number 538 | order by 539 | m.recorded_at; 540 | EOQ 541 | 542 | param "workload_id" {} 543 | param "lens_arn" {} 544 | } 545 | 546 | query "wellarchitected_workload_unanswered_by_milestone" { 547 | sql = <<-EOQ 548 | with milestone_info as ( 549 | select 550 | workload_id, 551 | milestone_number, 552 | milestone_name, 553 | recorded_at 554 | from 555 | aws_wellarchitected_milestone 556 | where 557 | workload_id = $1 558 | 559 | union 560 | 561 | select 562 | $1 as workload_id, 563 | 0 as milestone_number, -- Lens review API returns latest milestone as 0 564 | 'latest' as milestone_name, 565 | current_timestamp as recorded_at 566 | ), lens_review as ( 567 | select 568 | * 569 | from 570 | aws_wellarchitected_lens_review 571 | where 572 | milestone_number in (select milestone_number from aws_wellarchitected_milestone where workload_id = $1 union select 0 as milestone_number) -- Latest milestone is returned as 0 573 | and workload_id = (select workload_id from aws_wellarchitected_workload where workload_id = $1) 574 | ), risk_data as ( 575 | select 576 | milestone_number, 577 | sum((risk_counts ->> 'UNANSWERED')::int) as unanswered_risks 578 | from 579 | lens_review as r 580 | where 581 | r.lens_arn = any(string_to_array($2, ',')) 582 | group by 583 | r.milestone_number 584 | order by 585 | r.milestone_number 586 | ) select 587 | m.milestone_name, 588 | r.unanswered_risks 589 | from 590 | risk_data r 591 | left join milestone_info m 592 | on r.milestone_number = m.milestone_number 593 | order by 594 | recorded_at; 595 | EOQ 596 | 597 | param "workload_id" {} 598 | param "lens_arn" {} 599 | } 600 | 601 | # Table queries 602 | 603 | query "wellarchitected_workload_lens_risk_table" { 604 | sql = <<-EOQ 605 | select 606 | r.lens_name as "Lens Name", 607 | (r.risk_counts ->> 'HIGH')::int as "High", 608 | (r.risk_counts ->> 'MEDIUM')::int as "Medium", 609 | (r.risk_counts ->> 'NONE')::int as "No Improvements", 610 | (r.risk_counts ->> 'NOT_APPLICABLE')::int as "Not Applicable" 611 | from 612 | aws_wellarchitected_lens_review as r 613 | where 614 | r.workload_id = $1 615 | and r.lens_arn = any(string_to_array($2, ',')) 616 | group by 617 | r.lens_name, 618 | r.risk_counts 619 | order by 620 | r.lens_name 621 | EOQ 622 | 623 | param "workload_id" {} 624 | param "lens_arn" {} 625 | } 626 | 627 | query "wellarchitected_workload_pillar_risk_table" { 628 | sql = <<-EOQ 629 | select 630 | p ->> 'PillarName' as "Pillar Name", 631 | sum((p -> 'RiskCounts' ->> 'HIGH')::int) as "High", 632 | sum((p -> 'RiskCounts' ->> 'MEDIUM')::int) as "Medium", 633 | sum((p -> 'RiskCounts' ->> 'NONE')::int) as "No Improvements", 634 | sum((p -> 'RiskCounts' ->> 'NOT_APPLICABLE')::int) as "Not Applicable" 635 | from 636 | aws_wellarchitected_lens_review as r, 637 | jsonb_array_elements(r.pillar_review_summaries) as p 638 | where 639 | r.workload_id = $1 640 | and r.lens_arn = any(string_to_array($2, ',')) 641 | group by 642 | "Pillar Name" 643 | order by 644 | "Pillar Name" 645 | EOQ 646 | 647 | param "workload_id" {} 648 | param "lens_arn" {} 649 | } 650 | 651 | query "wellarchitected_workload_milestone_risk_table" { 652 | sql = <<-EOQ 653 | with milestone_info as ( 654 | select 655 | workload_id, 656 | milestone_number, 657 | milestone_name, 658 | recorded_at 659 | from 660 | aws_wellarchitected_milestone 661 | where 662 | workload_id = $1 663 | 664 | union 665 | 666 | select 667 | $1 as workload_id, 668 | 0 as milestone_number, -- Lens review API returns latest milestone as 0 669 | 'latest' as milestone_name, 670 | current_timestamp as recorded_at 671 | ), lens_review as ( 672 | select 673 | * 674 | from 675 | aws_wellarchitected_lens_review 676 | where 677 | milestone_number in (select milestone_number from aws_wellarchitected_milestone where workload_id = $1 union select 0 as milestone_number) -- Latest milestone is returned as 0 678 | and workload_id = (select workload_id from aws_wellarchitected_workload where workload_id = $1) 679 | ), risk_data as ( 680 | select 681 | milestone_number, 682 | sum((risk_counts ->> 'HIGH')::int) as high_risks, 683 | sum((risk_counts ->> 'MEDIUM')::int) as medium_risks, 684 | sum((risk_counts ->> 'NONE')::int) as no_improvements_risks, 685 | sum((risk_counts ->> 'NOT_APPLICABLE')::int) as not_applicable_risks 686 | from 687 | lens_review as r 688 | where 689 | r.lens_arn = any(string_to_array($2, ',')) 690 | group by 691 | r.milestone_number 692 | order by 693 | r.milestone_number 694 | ) select 695 | case 696 | when m.milestone_number = 0 then null -- Instead of showing milestone number as 0 for latest, show null to avoid confusion 697 | else m.milestone_number 698 | end as "Milestone Number", 699 | case 700 | when m.milestone_number = 0 then 'latest' 701 | else m.milestone_name 702 | end as "Milestone Name", 703 | r.high_risks as "High", 704 | r.medium_risks as "Medium", 705 | r.no_improvements_risks as "No Improvements", 706 | r.not_applicable_risks as "Not Applicable", 707 | to_char(m.recorded_at, 'YYYY-MM-DD HH24:MI') as "Date Saved" 708 | from 709 | risk_data r 710 | left join milestone_info m 711 | on r.milestone_number = m.milestone_number 712 | order by 713 | m.recorded_at desc; 714 | EOQ 715 | 716 | param "workload_id" {} 717 | param "lens_arn" {} 718 | } 719 | 720 | query "wellarchitected_workload_milestone_unanswered_table" { 721 | sql = <<-EOQ 722 | with milestone_info as ( 723 | select 724 | workload_id, 725 | milestone_number, 726 | milestone_name, 727 | recorded_at 728 | from 729 | aws_wellarchitected_milestone 730 | where 731 | workload_id = $1 732 | 733 | union 734 | 735 | select 736 | $1 as workload_id, 737 | 0 as milestone_number, -- Lens review API returns latest milestone as 0 738 | 'latest' as milestone_name, 739 | current_timestamp as recorded_at 740 | ), lens_review as ( 741 | select 742 | * 743 | from 744 | aws_wellarchitected_lens_review 745 | where 746 | milestone_number in (select milestone_number from aws_wellarchitected_milestone where workload_id = $1 union select 0 as milestone_number) -- Latest milestone is returned as 0 747 | and workload_id = (select workload_id from aws_wellarchitected_workload where workload_id = $1) 748 | ), risk_data as ( 749 | select 750 | milestone_number, 751 | sum((risk_counts ->> 'UNANSWERED')::int) as unanswered_risks 752 | from 753 | lens_review as r 754 | where 755 | r.lens_arn = any(string_to_array($2, ',')) 756 | group by 757 | r.milestone_number 758 | order by 759 | r.milestone_number 760 | ) select 761 | case 762 | when m.milestone_number = 0 then null -- Instead of showing milestone number as 0 for latest, show null to avoid confusion 763 | else m.milestone_number 764 | end as "Milestone Number", 765 | case 766 | when m.milestone_number = 0 then 'latest' 767 | else m.milestone_name 768 | end as "Milestone Name", 769 | r.unanswered_risks as "Unanswered Questions", 770 | to_char(m.recorded_at, 'YYYY-MM-DD HH24:MI') as "Date Saved" 771 | from 772 | risk_data r 773 | left join milestone_info m 774 | on r.milestone_number = m.milestone_number 775 | order by 776 | recorded_at desc; 777 | EOQ 778 | 779 | param "workload_id" {} 780 | param "lens_arn" {} 781 | } 782 | -------------------------------------------------------------------------------- /dashboards/wellarchitected_workload_risks_report.sp: -------------------------------------------------------------------------------- 1 | // Risk types from aws_wellarchitected_workload are not returned if their count is 0, so use coalesce(..., 0) 2 | // But from aws_wellarchitected_lens_review, all risk types are returned even when their count is 0 3 | dashboard "wellarchitected_workload_risks_report" { 4 | 5 | title = "AWS Well-Architected Workload Risks Report" 6 | documentation = file("./dashboards/docs/wellarchitected_workload_risks_report.md") 7 | 8 | tags = merge(local.wellarchitected_common_tags, { 9 | type = "Report" 10 | }) 11 | 12 | container { 13 | 14 | # Analysis 15 | card { 16 | query = query.wellarchitected_workload_count 17 | width = 2 18 | } 19 | 20 | # Assessments 21 | card { 22 | query = query.wellarchitected_workload_with_high_issue_count 23 | width = 2 24 | } 25 | 26 | card { 27 | query = query.wellarchitected_workload_high_issue_count 28 | width = 2 29 | } 30 | 31 | card { 32 | query = query.wellarchitected_workload_with_medium_issue_count 33 | width = 2 34 | } 35 | 36 | card { 37 | query = query.wellarchitected_workload_medium_issue_count 38 | width = 2 39 | } 40 | 41 | } 42 | 43 | container { 44 | 45 | table { 46 | width = 12 47 | title = "Risk Counts" 48 | query = query.wellarchitected_workload_risk_count_table 49 | } 50 | 51 | } 52 | } 53 | 54 | # Card Queries 55 | 56 | query "wellarchitected_workload_count" { 57 | sql = <<-EOQ 58 | select 59 | count(*) as "Workloads" 60 | from 61 | aws_wellarchitected_workload; 62 | EOQ 63 | } 64 | 65 | query "wellarchitected_workload_with_high_issue_count" { 66 | sql = <<-EOQ 67 | with workloads_with_high_issues as ( 68 | select 69 | workload_id 70 | from 71 | aws_wellarchitected_workload 72 | where 73 | coalesce((risk_counts ->> 'HIGH')::int, 0) > 0 74 | ) 75 | select 76 | count(*) as value, 77 | 'Workloads with High Risks' as label, 78 | case 79 | count(*) when 0 then 'ok' 80 | else 'alert' 81 | end as type 82 | from 83 | workloads_with_high_issues; 84 | EOQ 85 | } 86 | 87 | query "wellarchitected_workload_high_issue_count" { 88 | sql = <<-EOQ 89 | with workloads_high_issue_count as ( 90 | select 91 | coalesce((risk_counts ->> 'HIGH')::int, 0) as risk_count_high 92 | from 93 | aws_wellarchitected_workload 94 | ) 95 | select 96 | sum(risk_count_high) as value, 97 | 'Total High Risks' as label, 98 | case 99 | sum(risk_count_high) when 0 then 'ok' 100 | else 'alert' 101 | end as type 102 | from 103 | workloads_high_issue_count; 104 | EOQ 105 | } 106 | 107 | query "wellarchitected_workload_with_medium_issue_count" { 108 | sql = <<-EOQ 109 | with workloads_with_medium_issues as ( 110 | select 111 | workload_id 112 | from 113 | aws_wellarchitected_workload 114 | where 115 | coalesce((risk_counts ->> 'MEDIUM')::int, 0) > 0 116 | ) 117 | select 118 | count(*) as value, 119 | 'Workloads with Medium Risks' as label, 120 | case 121 | count(*) when 0 then 'ok' 122 | else 'alert' 123 | end as type 124 | from 125 | workloads_with_medium_issues; 126 | EOQ 127 | } 128 | 129 | query "wellarchitected_workload_medium_issue_count" { 130 | sql = <<-EOQ 131 | with workloads_medium_issue_count as ( 132 | select 133 | coalesce((risk_counts ->> 'MEDIUM')::int, 0) as risk_count_medium 134 | from 135 | aws_wellarchitected_workload 136 | ) 137 | select 138 | sum(risk_count_medium) as value, 139 | 'Total Medium Risks' as label, 140 | case 141 | sum(risk_count_medium) when 0 then 'ok' 142 | else 'alert' 143 | end as type 144 | from 145 | workloads_medium_issue_count; 146 | EOQ 147 | } 148 | 149 | query "wellarchitected_workload_high_medium_risk_counts" { 150 | sql = <<-EOQ 151 | -- Get current risk counts 152 | select 153 | workload_id, 154 | workload_name, 155 | coalesce((workload -> 'RiskCounts' ->> 'HIGH')::int, 0) as high_risks, 156 | coalesce((workload -> 'RiskCounts' ->> 'MEDIUM')::int, 0) as medium_risks 157 | from 158 | aws_wellarchitected_workload 159 | group by 160 | workload_name, 161 | 162 | EOQ 163 | } 164 | 165 | query "wellarchitected_workload_milestone_risk_counts" { 166 | sql = <<-EOQ 167 | -- Get current risk counts 168 | select 169 | workload_id, 170 | workload_name, 171 | 'latest' as milestone_name, 172 | 101 as milestone_number, -- 100 milestone max for workloads 173 | updated_at as recorded_at, 174 | risk_counts 175 | from 176 | aws_wellarchitected_workload 177 | union 178 | -- Get past milestone risk counts 179 | select 180 | workload_id, 181 | workload ->> 'WorkloadName' as workload_name, 182 | milestone_name, 183 | milestone_number, 184 | recorded_at, 185 | workload -> 'RiskCounts' as risk_counts 186 | from 187 | aws_wellarchitected_milestone 188 | order by 189 | workload_id, 190 | milestone_number 191 | EOQ 192 | } 193 | 194 | query "wellarchitected_workload_milestone_lens_review_risk_counts" { 195 | sql = <<-EOQ 196 | -- Get current version's lens review 197 | select 198 | r.workload_id, 199 | r.milestone_number, 200 | r.lens_arn, 201 | jsonb_pretty(r.risk_counts) as lens_risk_counts, 202 | p ->> 'PillarId' as pillar_id, 203 | p ->> 'PillarName' as pillar_name, 204 | p -> 'RiskCounts' as pillar_risk_counts 205 | from 206 | aws_wellarchitected_lens_review as r, 207 | jsonb_array_elements(pillar_review_summaries) as p 208 | union 209 | -- Get past milestone lens reviews 210 | select 211 | r.workload_id, 212 | r.milestone_number, 213 | r.lens_arn, 214 | jsonb_pretty(r.risk_counts) as lens_risk_counts, 215 | p ->> 'PillarId' as pillar_id, 216 | p ->> 'PillarName' as pillar_name, 217 | p -> 'RiskCounts' as pillar_risk_counts 218 | from 219 | aws_wellarchitected_milestone as m 220 | left join 221 | aws_wellarchitected_lens_review as r 222 | on m.milestone_number = r.milestone_number, 223 | jsonb_array_elements(pillar_review_summaries) as p 224 | EOQ 225 | } 226 | 227 | query "wellarchitected_workload_risk_count_table" { 228 | sql = <<-EOQ 229 | select 230 | workload_name as "Name", 231 | coalesce((risk_counts ->> 'HIGH')::int, 0) as "High", 232 | coalesce((risk_counts ->> 'MEDIUM')::int, 0) as "Medium", 233 | coalesce((risk_counts ->> 'NONE')::int, 0) as "No Improvements", 234 | coalesce((risk_counts ->> 'NOT_APPLICABLE')::int, 0) as "N/A", 235 | coalesce((risk_counts ->> 'UNANSWERED')::int, 0) as "Unanswered" 236 | from 237 | aws_wellarchitected_workload 238 | order by 239 | "High" desc, 240 | "Medium" desc 241 | EOQ 242 | } 243 | -------------------------------------------------------------------------------- /docs/aws_well_architected_console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/turbot/steampipe-mod-aws-well-architected/7e38fce0e676c8f158e03427213bf01e6e4a9531/docs/aws_well_architected_console.png -------------------------------------------------------------------------------- /docs/aws_well_architected_reliability_dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/turbot/steampipe-mod-aws-well-architected/7e38fce0e676c8f158e03427213bf01e6e4a9531/docs/aws_well_architected_reliability_dashboard.png -------------------------------------------------------------------------------- /docs/aws_well_architected_workload_risks_report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/turbot/steampipe-mod-aws-well-architected/7e38fce0e676c8f158e03427213bf01e6e4a9531/docs/aws_well_architected_workload_risks_report.png -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # AWS Well-Architected Mod 2 | 3 | Run controls across all of your AWS accounts to check if they are following AWS Well-Architected Framework best practices. 4 | 5 | 6 | 7 | 8 | 9 | ## Documentation 10 | 11 | - **[Benchmarks and controls →](https://hub.powerpipe.io/mods/turbot/aws_well_architected/controls)** 12 | - **[Named queries →](https://hub.powerpipe.io/mods/turbot/aws_well_architected/queries)** 13 | 14 | ## Getting Started 15 | 16 | ### Installation 17 | 18 | Install Powerpipe (https://powerpipe.io/downloads), or use Brew: 19 | 20 | ```sh 21 | brew install turbot/tap/powerpipe 22 | ``` 23 | 24 | This mod also requires [Steampipe](https://steampipe.io) with the [AWS plugin](https://hub.steampipe.io/plugins/turbot/aws) as the data source. Install Steampipe (https://steampipe.io/downloads), or use Brew: 25 | 26 | ```sh 27 | brew install turbot/tap/steampipe 28 | steampipe plugin install aws 29 | ``` 30 | 31 | Steampipe will automatically use your default AWS credentials. Optionally, you can [setup multiple accounts](https://hub.steampipe.io/plugins/turbot/aws#multi-account-connections) or [customize AWS credentials](https://hub.steampipe.io/plugins/turbot/aws#configuring-aws-credentials). 32 | 33 | Finally, install the mod: 34 | 35 | ```sh 36 | mkdir dashboards 37 | cd dashboards 38 | powerpipe mod init 39 | powerpipe mod install github.com/turbot/steampipe-mod-aws-well-architected 40 | ``` 41 | 42 | ### Browsing Dashboards 43 | 44 | Start Steampipe as the data source: 45 | 46 | ```sh 47 | steampipe service start 48 | ``` 49 | 50 | Start the dashboard server: 51 | 52 | ```sh 53 | powerpipe server 54 | ``` 55 | 56 | Browse and view your dashboards at **http://localhost:9033**. 57 | 58 | ### Running Checks in Your Terminal 59 | 60 | Instead of running benchmarks in a dashboard, you can also run them within your 61 | terminal with the `powerpipe benchmark` command: 62 | 63 | List available benchmarks: 64 | 65 | ```sh 66 | powerpipe benchmark list 67 | ``` 68 | 69 | Run a benchmark: 70 | 71 | ```sh 72 | powerpipe benchmark run well_architected_framework 73 | ``` 74 | 75 | Run a benchmark for a specific pillar: 76 | 77 | ```sh 78 | powerpipe benchmark run well_architected_framework_security 79 | ``` 80 | 81 | Run a benchmark for a specific question: 82 | 83 | ```sh 84 | powerpipe benchmark run well_architected_framework_sec01 85 | ``` 86 | 87 | Run a benchmark for a specific best practice: 88 | 89 | ```sh 90 | powerpipe benchmark run well_architected_framework_sec01_bp01 91 | ``` 92 | 93 | Different output formats are also available, for more information please see 94 | [Output Formats](https://powerpipe.io/docs/reference/cli/benchmark#output-formats). 95 | 96 | ### Common and Tag Dimensions 97 | 98 | The benchmark queries use common properties (like `account_id`, `connection_name` and `region`) and tags that are defined in the dependent [AWS Compliance mod](https://github.com/turbot/steampipe-mod-aws-compliance) These properties can be executed in the following ways: 99 | 100 | It's easiest to setup your vars file, starting with the sample: 101 | 102 | ```sh 103 | cp powerpipe.ppvars.example powerpipe.ppvars 104 | vi powerpipe.ppvars 105 | ``` 106 | 107 | Alternatively you can pass variables on the command line: 108 | 109 | ```sh 110 | powerpipe benchmark run well_architected_framework_security --var 'common_dimensions=["account_id", "connection_name", "region"]' 111 | ``` 112 | 113 | Or through environment variables: 114 | 115 | ```sh 116 | export PP_VAR_common_dimensions='["account_id", "connection_name", "region"]' 117 | export PP_VAR_tag_dimensions='["Environment", "Owner"]' 118 | powerpipe benchmark run well_architected_framework_security 119 | ``` 120 | 121 | ## Open Source & Contributing 122 | 123 | This repository is published under the [Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0). Please see our [code of conduct](https://github.com/turbot/.github/blob/main/CODE_OF_CONDUCT.md). We look forward to collaborating with you! 124 | 125 | [Steampipe](https://steampipe.io) and [Powerpipe](https://powerpipe.io) are products produced from this open source software, exclusively by [Turbot HQ, Inc](https://turbot.com). They are distributed under our commercial terms. Others are allowed to make their own distribution of the software, but cannot use any of the Turbot trademarks, cloud services, etc. You can learn more in our [Open Source FAQ](https://turbot.com/open-source). 126 | 127 | ## Get Involved 128 | 129 | **[Join #powerpipe on Slack →](https://turbot.com/community/join)** 130 | 131 | Want to help but don't know where to start? Pick up one of the `help wanted` issues: 132 | 133 | - [Powerpipe](https://github.com/turbot/powerpipe/labels/help%20wanted) 134 | - [AWS Well-Architected Mod](https://github.com/turbot/steampipe-mod-aws-well-architected/labels/help%20wanted) 135 | -------------------------------------------------------------------------------- /mod.pp: -------------------------------------------------------------------------------- 1 | mod "aws_well_architected" { 2 | # Hub metadata 3 | title = "AWS Well-Architected" 4 | description = "Run controls across all of your AWS accounts to check if they are following AWS Well-Architected best practices using Powerpipe and Steampipe." 5 | color = "#FF9900" 6 | documentation = file("./docs/index.md") 7 | icon = "/images/mods/turbot/aws-well-architected.svg" 8 | categories = ["aws", "compliance", "public cloud", "security"] 9 | 10 | opengraph { 11 | title = "Powerpipe Mod for AWS Well-Architected" 12 | description = "Run controls across all of your AWS accounts to check if they are following AWS Well-Architected best practices using Powerpipe and Steampipe." 13 | image = "/images/mods/turbot/aws-well-architected-social-graphic.png" 14 | } 15 | 16 | require { 17 | plugin "aws" { 18 | min_version = "0.101.0" 19 | } 20 | mod "github.com/turbot/steampipe-mod-aws-compliance" { 21 | version = ">=0.66.0" 22 | args = { 23 | common_dimensions = var.common_dimensions, 24 | tag_dimensions = var.tag_dimensions 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /powerpipe.ppvars.example: -------------------------------------------------------------------------------- 1 | # Dimensions 2 | common_dimensions = ["account_id", "region"] 3 | tag_dimensions = [] 4 | -------------------------------------------------------------------------------- /variables.pp: -------------------------------------------------------------------------------- 1 | // Benchmarks and controls for specific services should override the "service" tag 2 | locals { 3 | aws_well_architected_common_tags = { 4 | category = "Compliance" 5 | plugin = "aws" 6 | service = "AWS" 7 | } 8 | } 9 | 10 | variable "common_dimensions" { 11 | type = list(string) 12 | description = "A list of common dimensions to add to each control." 13 | # Define which common dimensions should be added to each control. 14 | # - account_id 15 | # - connection_name (_ctx ->> 'connection_name') 16 | # - region 17 | default = ["account_id", "region"] 18 | } 19 | 20 | variable "tag_dimensions" { 21 | type = list(string) 22 | description = "A list of tags to add as dimensions to each control." 23 | # A list of tag names to include as dimensions for resources that support 24 | # tags (e.g. "Owner", "Environment"). Default to empty since tag names are 25 | # a personal choice - for commonly used tag names see 26 | # https://docs.aws.amazon.com/general/latest/gr/aws_tagging.html#tag-categories 27 | default = [] 28 | } 29 | 30 | locals { 31 | 32 | # Local internal variable to build the SQL select clause for common 33 | # dimensions using a table name qualifier if required. Do not edit directly. 34 | common_dimensions_qualifier_sql = <<-EOQ 35 | %{~if contains(var.common_dimensions, "connection_name")}, __QUALIFIER___ctx ->> 'connection_name' as connection_name%{endif~} 36 | %{~if contains(var.common_dimensions, "region")}, __QUALIFIER__region%{endif~} 37 | %{~if contains(var.common_dimensions, "account_id")}, __QUALIFIER__account_id%{endif~} 38 | EOQ 39 | 40 | common_dimensions_qualifier_global_sql = <<-EOQ 41 | %{~if contains(var.common_dimensions, "connection_name")}, __QUALIFIER___ctx ->> 'connection_name' as connection_name%{endif~} 42 | %{~if contains(var.common_dimensions, "account_id")}, __QUALIFIER__account_id%{endif~} 43 | EOQ 44 | 45 | # Local internal variable to build the SQL select clause for tag 46 | # dimensions. Do not edit directly. 47 | tag_dimensions_qualifier_sql = <<-EOQ 48 | %{~for dim in var.tag_dimensions}, __QUALIFIER__tags ->> '${dim}' as "${replace(dim, "\"", "\"\"")}"%{endfor~} 49 | EOQ 50 | 51 | } 52 | 53 | locals { 54 | 55 | # Local internal variable with the full SQL select clause for common 56 | # dimensions. Do not edit directly. 57 | common_dimensions_sql = replace(local.common_dimensions_qualifier_sql, "__QUALIFIER__", "") 58 | common_dimensions_global_sql = replace(local.common_dimensions_qualifier_global_sql, "__QUALIFIER__", "") 59 | tag_dimensions_sql = replace(local.tag_dimensions_qualifier_sql, "__QUALIFIER__", "") 60 | 61 | } 62 | 63 | -------------------------------------------------------------------------------- /well_architected_framework/docs/well_architected_framework_overview.md: -------------------------------------------------------------------------------- 1 | To obtain the latest version of the official pillars, questions, and best practices, please see https://docs.aws.amazon.com/wellarchitected/latest/framework/appendix.html. 2 | 3 | ## Overview 4 | 5 | The AWS Well-Architected Framework helps you understand the pros and cons of decisions you make while building systems on AWS. By using the Framework you will learn architectural best practices for designing and operating reliable, secure, efficient, cost-effective, and sustainable systems in the cloud. 6 | 7 | The AWS Well-Architected Framework is based on six pillars: 8 | - Operational excellence: The ability to support development and run workloads effectively, gain insight into their operations, and to continuously improve supporting processes and procedures to deliver business value. 9 | - Security: The security pillar describes how to take advantage of cloud technologies to protect data, systems, and assets in a way that can improve your security posture. 10 | - Reliability: The reliability pillar encompasses the ability of a workload to perform its intended function correctly and consistently when it’s expected to. This includes the ability to operate and test the workload through its total lifecycle. This paper provides in-depth, best practice guidance for implementing reliable workloads on AWS. 11 | - Performance efficiency: The ability to use computing resources efficiently to meet system requirements, and to maintain that efficiency as demand changes and technologies evolve. 12 | - Cost optimization: The ability to run systems to deliver business value at the lowest price point. 13 | - Sustainability: The ability to continually improve sustainability impacts by reducing energy consumption and increasing efficiency across all components of a workload by maximizing the benefits from the provisioned resources and minimizing the total resources required. 14 | -------------------------------------------------------------------------------- /well_architected_framework/operational_excellence/operational_excellence.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_operational_excellence_common_tags = merge(local.well_architected_framework_common_tags, { 3 | pillar_id = "operationalExcellence" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_operational_excellence" { 8 | title = "Operational Excellence" 9 | description = "Operational excellence is a commitment to build software correctly while consistently delivering a great customer experience. It contains best practices for organizing your team, designing your workload, operating it at scale, and evolving it over time. Operational excellence helps your team to focus more of their time on building new features that benefit customers, and less time on maintenance and firefighting. To build correctly, we look to best practices that result in well-running systems, a balanced workload for you and your team, and most importantly, a great customer experience. The goal of operational excellence is to get new features and bug fixes into customers' hands quickly and reliably. Organizations that invest in operational excellence consistently delight customers while building new features, making changes, and dealing with failures. Along the way, operational excellence drives towards continuous integration and continuous delivery (CI/CD) by helping developers achieve high quality results consistently." 10 | children = [ 11 | benchmark.well_architected_framework_ops04, 12 | benchmark.well_architected_framework_ops05 13 | ] 14 | 15 | tags = local.well_architected_framework_operational_excellence_common_tags 16 | } 17 | -------------------------------------------------------------------------------- /well_architected_framework/operational_excellence/ops04.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_ops04_common_tags = merge(local.well_architected_framework_operational_excellence_common_tags, { 3 | question_id = "telemetry" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_ops04" { 8 | title = "OPS04 How do you design your workload so that you can understand its state?" 9 | description = "Design your workload so that it provides the information necessary across all components(for example, metrics, logs, and traces) for you to understand its internal state. This enables you to provide effective responses when appropriate." 10 | children = [ 11 | benchmark.well_architected_framework_ops04_bp01, 12 | benchmark.well_architected_framework_ops04_bp02 13 | ] 14 | 15 | tags = local.well_architected_framework_ops04_common_tags 16 | } 17 | 18 | benchmark "well_architected_framework_ops04_bp01" { 19 | title = "BP01 Implement application telemetry" 20 | description = "Application telemetry is the foundation for observability of your workload. Your application should emit telemetry that provides insight into the state of the application and the achievement of business outcomes. From troubleshooting to measuring the impact of a new feature, application telemetry informs the way you build, operate, and evolve your workload." 21 | 22 | children = [ 23 | aws_compliance.control.apigateway_stage_logging_enabled, 24 | aws_compliance.control.autoscaling_group_with_lb_use_health_check, 25 | aws_compliance.control.cloudfront_distribution_logging_enabled, 26 | aws_compliance.control.codebuild_project_logging_enabled, 27 | aws_compliance.control.ecs_task_definition_logging_enabled, 28 | aws_compliance.control.elastic_beanstalk_enhanced_health_reporting_enabled, 29 | aws_compliance.control.elb_application_classic_lb_logging_enabled, 30 | aws_compliance.control.rds_db_instance_cloudwatch_logs_enabled 31 | ] 32 | 33 | tags = merge(local.well_architected_framework_ops04_common_tags, { 34 | choice_id = "ops_telemetry_application_telemetry" 35 | risk = "high" 36 | }) 37 | } 38 | 39 | benchmark "well_architected_framework_ops04_bp02" { 40 | title = "BP02 Implement and configure workload telemetry" 41 | description = "Design and configure your workload to emit information about its internal state and current status, for example, API call volume, HTTP status codes, and scaling events. Use this information to help determine when a response is required." 42 | 43 | children = [ 44 | aws_compliance.control.cloudtrail_trail_enabled, 45 | aws_compliance.control.cloudtrail_trail_integrated_with_logs, 46 | aws_compliance.control.cloudwatch_alarm_action_enabled, 47 | aws_compliance.control.ec2_instance_detailed_monitoring_enabled, 48 | aws_compliance.control.vpc_flow_logs_enabled 49 | ] 50 | 51 | tags = merge(local.well_architected_framework_ops04_common_tags, { 52 | choice_id = "ops_telemetry_workload_telemetry" 53 | risk = "high" 54 | }) 55 | } 56 | -------------------------------------------------------------------------------- /well_architected_framework/operational_excellence/ops05.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_ops05_common_tags = merge(local.well_architected_framework_operational_excellence_common_tags, { 3 | question_id = "dev-integ" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_ops05" { 8 | title = "OPS05 How do you reduce defects, ease remediation, and improve flow into production?" 9 | description = "Adopt approaches that improve flow of changes into production, that enable refactoring, fast feedback on quality, and bug fixing. These accelerate beneficial changes entering production, limit issues deployed, and enable rapid identification and remediation of issues introduced through deployment activities." 10 | children = [ 11 | benchmark.well_architected_framework_ops05_bp03, 12 | benchmark.well_architected_framework_ops05_bp05 13 | ] 14 | 15 | tags = local.well_architected_framework_ops05_common_tags 16 | } 17 | 18 | benchmark "well_architected_framework_ops05_bp03" { 19 | title = "BP03 Use configuration management systems" 20 | description = "Use configuration management systems to make and track configuration changes. These systems reduce errors caused by manual processes and reduce the level of effort to deploy changes." 21 | 22 | children = [ 23 | aws_compliance.control.config_enabled_all_regions 24 | ] 25 | 26 | tags = merge(local.well_architected_framework_ops05_common_tags, { 27 | choice_id = "ops_dev_integ_conf_mgmt_sys" 28 | risk = "medium" 29 | }) 30 | } 31 | 32 | benchmark "well_architected_framework_ops05_bp05" { 33 | title = "BP05 Perform patch management" 34 | description = "Perform patch management to gain features, address issues, and remain compliant with governance. Automate patch management to reduce errors caused by manual processes, and reduce the level of effort to patch." 35 | 36 | children = [ 37 | aws_compliance.control.ssm_managed_instance_compliance_patch_compliant 38 | ] 39 | 40 | tags = merge(local.well_architected_framework_ops05_common_tags, { 41 | choice_id = "ops_dev_integ_patch_mgmt" 42 | risk = "medium" 43 | }) 44 | } 45 | -------------------------------------------------------------------------------- /well_architected_framework/reliability/rel01.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_rel01_common_tags = merge(local.well_architected_framework_reliability_common_tags, { 3 | question_id = "manage-service-limits" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_rel01" { 8 | title = "REL01 How do you manage service quotas and constraints?" 9 | description = "For cloud-based workload architectures, there are service quotas (which are also referred to as service limits). These quotas exist to prevent accidentally provisioning more resources than you need and to limit request rates on API operations so as to protect services from abuse. There are also resource constraints, for example, the rate that you can push bits down a fiber-optic cable, or the amount of storage on a physical disk." 10 | children = [ 11 | benchmark.well_architected_framework_rel01_bp03 12 | ] 13 | 14 | tags = local.well_architected_framework_rel01_common_tags 15 | } 16 | 17 | 18 | benchmark "well_architected_framework_rel01_bp03" { 19 | title = "BP03 Accommodate fixed service quotas and constraints through architecture" 20 | description = "Be aware of unchangeable service quotas, service constraints, and physical resource limits. Design architectures for applications and services to prevent these limits from impacting reliability." 21 | children = [ 22 | aws_compliance.control.lambda_function_concurrent_execution_limit_configured 23 | ] 24 | 25 | tags = merge(local.well_architected_framework_rel01_common_tags, { 26 | choice_id = "rel_manage_service_limits_aware_fixed_limits" 27 | risk = "medium" 28 | }) 29 | } 30 | -------------------------------------------------------------------------------- /well_architected_framework/reliability/rel02.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_rel02_common_tags = merge(local.well_architected_framework_reliability_common_tags, { 3 | question_id = "planning-network-topology" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_rel02" { 8 | title = "REL02 How do you plan your network topology?" 9 | description = "Workloads often exist in multiple environments. These include multiple cloud environments (both publicly accessible and private) and possibly your existing data center infrastructure. Plans must include network considerations such as intra- and inter-system connectivity, public IP address management, private IP address management, and domain name resolution." 10 | children = [ 11 | benchmark.well_architected_framework_rel02_bp01, 12 | benchmark.well_architected_framework_rel02_bp02, 13 | ] 14 | 15 | tags = local.well_architected_framework_rel02_common_tags 16 | } 17 | 18 | benchmark "well_architected_framework_rel02_bp01" { 19 | title = "BP01 Use highly available network connectivity for your workload public endpoints" 20 | description = "Building highly available network connectivity to public endpoints of your workloads can help you reduce downtime due to loss of connectivity and improve the availability and SLA of your workload. To achieve this, use highly available DNS, content delivery networks (CDNs), API gateways, load balancing, or reverse proxies." 21 | children = [ 22 | aws_compliance.control.cloudfront_distribution_configured_with_origin_failover, 23 | aws_compliance.control.cloudfront_distribution_waf_enabled, 24 | aws_compliance.control.elb_application_gateway_network_lb_multiple_az_configured, 25 | aws_compliance.control.elb_classic_lb_cross_zone_load_balancing_enabled, 26 | aws_compliance.control.elb_classic_lb_multiple_az_configured, 27 | aws_compliance.control.lambda_function_multiple_az_configured, 28 | aws_compliance.control.rds_db_cluster_multiple_az_enabled, 29 | aws_compliance.control.rds_db_instance_multiple_az_enabled, 30 | aws_compliance.control.s3_bucket_cross_region_replication_enabled 31 | ] 32 | 33 | tags = merge(local.well_architected_framework_rel02_common_tags, { 34 | choice_id = "rel_planning_network_topology_ha_conn_users" 35 | risk = "high" 36 | }) 37 | } 38 | 39 | benchmark "well_architected_framework_rel02_bp02" { 40 | title = "BP02 Provision redundant connectivity between private networks in the cloud and on-premises environments" 41 | description = "Use multiple AWS Direct Connect (DX) connections or VPN tunnels between separately deployed private networks. Use multiple DX locations for high availability. If using multiple AWS Regions, ensure redundancy in at least two of them. You might want to evaluate AWS Marketplace appliances that terminate VPNs. If you use AWS Marketplace appliances, deploy redundant instances for high availability in different Availability Zones." 42 | children = [ 43 | aws_compliance.control.ec2_instance_in_vpc, 44 | aws_compliance.control.ecs_cluster_instance_in_vpc, 45 | aws_compliance.control.es_domain_in_vpc, 46 | aws_compliance.control.lambda_function_in_vpc, 47 | aws_compliance.control.redshift_cluster_enhanced_vpc_routing_enabled, 48 | aws_compliance.control.vpc_vpn_tunnel_up 49 | ] 50 | 51 | tags = merge(local.well_architected_framework_rel02_common_tags, { 52 | choice_id = "rel_planning_network_topology_ha_conn_private_networks" 53 | risk = "high" 54 | }) 55 | } 56 | -------------------------------------------------------------------------------- /well_architected_framework/reliability/rel06.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_rel06_common_tags = merge(local.well_architected_framework_reliability_common_tags, { 3 | question_id = "monitor-aws-resources" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_rel06" { 8 | title = "REL06 How do you monitor workload resources?" 9 | description = "Logs and metrics are powerful tools to gain insight into the health of your workload. You can configure your workload to monitor logs and metrics and send notifications when thresholds are crossed or significant events occur. Monitoring enables your workload to recognize when low-performance thresholds are crossed or failures occur, so it can recover automatically in response." 10 | children = [ 11 | benchmark.well_architected_framework_rel06_bp01, 12 | benchmark.well_architected_framework_rel06_bp02 13 | ] 14 | 15 | tags = local.well_architected_framework_rel06_common_tags 16 | } 17 | 18 | benchmark "well_architected_framework_rel06_bp01" { 19 | title = "BP01 Monitor all components for the workload" 20 | description = "Monitor the components of the workload with Amazon CloudWatch or third-party tools. Monitor AWS services with AWS Health Dashboard. All components of your workload should be monitored, including the front-end, business logic, and storage tiers. Define key metrics, describe how to extract them from logs (if necessary), and set thresholds for invoking corresponding alarm events. Ensure metrics are relevant to the key performance indicators (KPIs) of your workload, and use metrics and logs to identify early warning signs of service degradation. For example, a metric related to business outcomes such as the number of orders successfully processed per minute, can indicate workload issues faster than technical metric, such as CPU Utilization. Use AWS Health Dashboard for a personalized view into the performance and availability of the AWS services underlying your AWS resources." 21 | children = [ 22 | aws_compliance.control.ec2_instance_detailed_monitoring_enabled, 23 | aws_compliance.control.apigateway_stage_logging_enabled, 24 | aws_compliance.control.acm_certificate_transparency_logging_enabled, 25 | aws_compliance.control.codebuild_project_logging_enabled, 26 | aws_compliance.control.ecs_task_definition_logging_enabled, 27 | aws_compliance.control.elb_application_classic_lb_logging_enabled, 28 | aws_compliance.control.lambda_function_cloudtrail_logging_enabled, 29 | aws_compliance.control.opensearch_domain_audit_logging_enabled, 30 | aws_compliance.control.rds_db_instance_logging_enabled, 31 | aws_compliance.control.route53_zone_query_logging_enabled, 32 | aws_compliance.control.s3_bucket_logging_enabled, 33 | aws_compliance.control.s3_bucket_object_logging_enabled, 34 | aws_compliance.control.waf_web_acl_logging_enabled 35 | ] 36 | 37 | tags = merge(local.well_architected_framework_rel06_common_tags, { 38 | choice_id = "rel_monitor_aws_resources_monitor_resources" 39 | risk = "high" 40 | }) 41 | } 42 | 43 | benchmark "well_architected_framework_rel06_bp02" { 44 | title = "BP02 Define and calculate metrics (Aggregation)" 45 | description = "Store log data and apply filters where necessary to calculate metrics, such as counts of a specific log event, or latency calculated from log event timestamps.Amazon CloudWatch and Amazon S3 serve as the primary aggregation and storage layers. For some services, such as AWS Auto Scaling and Elastic Load Balancing, default metrics are provided by default for CPU load or average request latency across a cluster or instance. For streaming services, such as VPC Flow Logs and AWS CloudTrail, event data is forwarded to CloudWatch Logs and you need to define and apply metrics filters to extract metrics from the event data. This gives you time series data, which can serve as inputs to CloudWatch alarms that you define to invoke alerts." 46 | children = [ 47 | aws_compliance.control.ecs_cluster_container_insights_enabled, 48 | aws_compliance.control.elastic_beanstalk_enhanced_health_reporting_enabled 49 | ] 50 | 51 | tags = merge(local.well_architected_framework_rel06_common_tags, { 52 | choice_id = "rel_planning_network_topology_ha_conn_users" 53 | risk = "high" 54 | }) 55 | } 56 | -------------------------------------------------------------------------------- /well_architected_framework/reliability/rel07.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_rel07_common_tags = merge(local.well_architected_framework_reliability_common_tags, { 3 | question_id = "adapt-to-changes" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_rel07" { 8 | title = "REL07 How do you design your workload to adapt to changes in demand?" 9 | description = "A scalable workload provides elasticity to add or remove resources automatically so that they closely match the current demand at any given point in time." 10 | children = [ 11 | benchmark.well_architected_framework_rel07_bp01, 12 | # benchmark.well_architected_framework_rel07_bp03 13 | ] 14 | 15 | tags = local.well_architected_framework_rel07_common_tags 16 | } 17 | 18 | benchmark "well_architected_framework_rel07_bp01" { 19 | title = "BP01 Use automation when obtaining or scaling resources" 20 | description = "When replacing impaired resources or scaling your workload, automate the process by using managed AWS services, such as Amazon S3 and AWS Auto Scaling. You can also use third-party tools and AWS SDKs to automate scaling. Managed AWS services include Amazon S3, Amazon CloudFront, AWS Auto Scaling, AWS Lambda, Amazon DynamoDB, AWS Fargate, and Amazon Route 53. AWS Auto Scaling lets you detect and replace impaired instances. It also lets you build scaling plans for resources including Amazon EC2 instances and Spot Fleets, Amazon ECS tasks, Amazon DynamoDB tables and indexes, and Amazon Aurora Replicas." 21 | children = [ 22 | aws_compliance.control.autoscaling_group_multiple_az_configured, 23 | aws_compliance.control.dynamodb_table_auto_scaling_enabled 24 | ] 25 | 26 | tags = merge(local.well_architected_framework_rel07_common_tags, { 27 | choice_id = "rel_adapt_to_changes_autoscale_adapt" 28 | risk = "high" 29 | }) 30 | } 31 | -------------------------------------------------------------------------------- /well_architected_framework/reliability/rel08.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_rel08_common_tags = merge(local.well_architected_framework_reliability_common_tags, { 3 | question_id = "tracking-change-management" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_rel08" { 8 | title = "REL08 How do you implement change?" 9 | description = "Controlled changes are necessary to deploy new functionality, and to ensure that the workloads and the operating environment are running known software and can be patched or replaced in a predictable manner. If these changes are uncontrolled, then it makes it difficult to predict the effect of these changes, or to address issues that arise because of them." 10 | children = [ 11 | benchmark.well_architected_framework_rel08_bp05 12 | ] 13 | 14 | tags = local.well_architected_framework_rel08_common_tags 15 | } 16 | 17 | benchmark "well_architected_framework_rel08_bp05" { 18 | title = "BP05 Deploy changes with automation" 19 | description = "Deployments and patching are automated to eliminate negative impact. Making changes to production systems is one of the largest risk areas for many organizations. We consider deployments a first-class problem to be solved alongside the business problems that the software addresses. Today, this means the use of automation wherever practical in operations, including testing and deploying changes, adding or removing capacity, and migrating data. AWS CodePipeline lets you manage the steps required to release your workload. This includes a deployment state using AWS CodeDeploy to automate deployment of application code to Amazon EC2 instances, on-premises instances, serverless Lambda functions, or Amazon ECS services." 20 | children = [ 21 | aws_compliance.control.rds_db_instance_automatic_minor_version_upgrade_enabled 22 | ] 23 | 24 | tags = merge(local.well_architected_framework_rel08_common_tags, { 25 | choice_id = "rel_tracking_change_management_automated_changemgmt" 26 | risk = "high" 27 | }) 28 | } 29 | -------------------------------------------------------------------------------- /well_architected_framework/reliability/rel09.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_rel09_common_tags = merge(local.well_architected_framework_reliability_common_tags, { 3 | question_id = "backing-up-data" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_rel09" { 8 | title = "REL09 How do you back up data?" 9 | description = "Back up data, applications, and configuration to meet your requirements for recovery time objectives (RTO) and recovery point objectives (RPO)." 10 | children = [ 11 | benchmark.well_architected_framework_rel09_bp02, 12 | benchmark.well_architected_framework_rel09_bp03 13 | ] 14 | 15 | tags = local.well_architected_framework_rel09_common_tags 16 | } 17 | 18 | benchmark "well_architected_framework_rel09_bp02" { 19 | title = "BP02 Secure and encrypt backups" 20 | description = "Control and detect access to backups using authentication and authorization. Prevent and detect if data integrity of backups is compromised using encryption." 21 | children = [ 22 | aws_compliance.control.backup_recovery_point_encryption_enabled, 23 | aws_compliance.control.dynamodb_table_encryption_enabled, 24 | aws_compliance.control.ec2_ebs_default_encryption_enabled, 25 | aws_compliance.control.ebs_volume_encryption_at_rest_enabled, 26 | aws_compliance.control.rds_db_instance_encryption_at_rest_enabled, 27 | aws_compliance.control.rds_db_snapshot_encrypted_at_rest, 28 | aws_compliance.control.s3_bucket_default_encryption_enabled 29 | ] 30 | 31 | tags = merge(local.well_architected_framework_rel09_common_tags, { 32 | choice_id = "rel_backing_up_data_secured_backups_data" 33 | risk = "high" 34 | }) 35 | } 36 | 37 | benchmark "well_architected_framework_rel09_bp03" { 38 | title = "BP03 Perform data backup automatically" 39 | description = "Control and detect access to backups using authentication and authorization. Prevent and detect if data integrity of backups is compromised using encryption." 40 | children = [ 41 | aws_compliance.control.backup_recovery_point_manual_deletion_disabled, 42 | aws_compliance.control.backup_recovery_point_min_retention_35_days, 43 | aws_compliance.control.dynamodb_table_in_backup_plan, 44 | aws_compliance.control.dynamodb_table_point_in_time_recovery_enabled, 45 | aws_compliance.control.dynamodb_table_protected_by_backup_plan, 46 | aws_compliance.control.ec2_instance_protected_by_backup_plan, 47 | aws_compliance.control.elasticache_redis_cluster_automatic_backup_retention_15_days, 48 | aws_compliance.control.fsx_file_system_protected_by_backup_plan, 49 | aws_compliance.control.rds_db_cluster_aurora_backtracking_enabled, 50 | aws_compliance.control.rds_db_cluster_aurora_protected_by_backup_plan, 51 | aws_compliance.control.rds_db_instance_backup_enabled 52 | ] 53 | 54 | tags = merge(local.well_architected_framework_rel09_common_tags, { 55 | choice_id = "rel_backing_up_data_automated_backups_data" 56 | risk = "high" 57 | }) 58 | } 59 | -------------------------------------------------------------------------------- /well_architected_framework/reliability/reliability.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_reliability_common_tags = merge(local.well_architected_framework_common_tags, { 3 | pillar_id = "reliability" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_reliability" { 8 | title = "Reliability" 9 | description = "The reliability pillar focuses on workloads performing their intended functions and how to recover quickly from failure to meet demands. Key topics include distributed system design, recovery planning, and adapting to changing requirements." 10 | children = [ 11 | benchmark.well_architected_framework_rel01, 12 | benchmark.well_architected_framework_rel02, 13 | benchmark.well_architected_framework_rel06, 14 | benchmark.well_architected_framework_rel07, 15 | benchmark.well_architected_framework_rel08, 16 | benchmark.well_architected_framework_rel09, 17 | ] 18 | 19 | tags = local.well_architected_framework_reliability_common_tags 20 | } 21 | -------------------------------------------------------------------------------- /well_architected_framework/security/sec01.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_sec01_common_tags = merge(local.well_architected_framework_security_common_tags, { 3 | question_id = "securely-operate" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_sec01" { 8 | title = "SEC01 How do you securely operate your workload?" 9 | description = "To operate your workload securely, you must apply overarching best practices to every area of security. Take requirements and processes that you have defined in operational excellence at an organizational and workload level, and apply them to all areas. Staying up to date with AWS and industry recommendations and threat intelligence helps you evolve your threat model and control objectives. Automating security processes, testing, and validation allow you to scale your security operations." 10 | children = [ 11 | benchmark.well_architected_framework_sec01_bp01, 12 | benchmark.well_architected_framework_sec01_bp02, 13 | benchmark.well_architected_framework_sec01_bp06, 14 | benchmark.well_architected_framework_sec01_bp08, 15 | ] 16 | 17 | tags = local.well_architected_framework_sec01_common_tags 18 | } 19 | 20 | benchmark "well_architected_framework_sec01_bp01" { 21 | title = "BP01 Separate workloads using accounts" 22 | description = "Establish common guardrails and isolation between environments (such as production, development, and test) and workloads through a multi-account strategy. Account-level separation is strongly recommended, as it provides a strong isolation boundary for security, billing, and access." 23 | children = [ 24 | aws_compliance.control.account_part_of_organizations 25 | ] 26 | 27 | tags = merge(local.well_architected_framework_sec01_common_tags, { 28 | choice_id = "sec_securely_operate_multi_accounts" 29 | risk = "high" 30 | }) 31 | } 32 | 33 | benchmark "well_architected_framework_sec01_bp02" { 34 | title = "BP02 Secure account root user and properties" 35 | description = "The root user is the most privileged user in an AWS account, with full administrative access to all resources within the account, and in some cases cannot be constrained by security policies. Disabling programmatic access to the root user, establishing appropriate controls for the root user, and avoiding routine use of the root user helps reduce the risk of inadvertent exposure of the root credentials and subsequent compromise of the cloud environment." 36 | children = [ 37 | // TODO: Should we add a control that uses the query iam_root_last_used? 38 | aws_compliance.control.iam_root_user_hardware_mfa_enabled, 39 | aws_compliance.control.iam_root_user_mfa_enabled, 40 | aws_compliance.control.iam_root_user_no_access_keys 41 | ] 42 | 43 | tags = merge(local.well_architected_framework_sec01_common_tags, { 44 | choice_id = "sec_securely_operate_multi_accounts" 45 | risk = "high" 46 | }) 47 | } 48 | 49 | benchmark "well_architected_framework_sec01_bp06" { 50 | title = "BP06 Automate testing and validation of security controls in pipelines" 51 | description = "Establish secure baselines and templates for security mechanisms that are tested and validated as part of your build, pipelines, and processes. Use tools and automation to test and validate all security controls continuously." 52 | children = [ 53 | aws_compliance.control.ec2_instance_ssm_managed, 54 | aws_compliance.control.ecr_repository_image_scan_on_push_enabled, 55 | ] 56 | 57 | tags = merge(local.well_architected_framework_sec01_common_tags, { 58 | choice_id = "sec_securely_operate_test_validate_pipeline" 59 | risk = "medium" 60 | }) 61 | } 62 | 63 | benchmark "well_architected_framework_sec01_bp08" { 64 | title = "BP08 Evaluate and implement new security services and features regularly" 65 | description = "Evaluate and implement security services and features from AWS and AWS Partners that allow you to evolve the security posture of your workload. The AWS Security Blog highlights new AWS services and features, implementation guides, and general security guidance." 66 | children = [ 67 | aws_compliance.control.codebuild_project_plaintext_env_variables_no_sensitive_aws_values, 68 | ] 69 | 70 | tags = merge(local.well_architected_framework_sec01_common_tags, { 71 | choice_id = "sec_securely_operate_implement_services_features" 72 | risk = "low" 73 | }) 74 | } 75 | -------------------------------------------------------------------------------- /well_architected_framework/security/sec02.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_sec02_common_tags = merge(local.well_architected_framework_security_common_tags, { 3 | question_id = "identities" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_sec02" { 8 | title = "SEC02 How do you manage identities for people and machines?" 9 | description = "There are two types of identities you need to manage when approaching operating secure AWS workloads. Understanding the type of identity you need to manage and grant access helps you ensure the right identities have access to the right resources under the right conditions. Human Identities: Your administrators, developers, operators, and end users require an identity to access your AWS environments and applications. These are members of your organization, or external users with whom you collaborate, and who interact with your AWS resources via a web browser, client application, or interactive command-line tools. Machine Identities: Your service applications, operational tools, and workloads require an identity to make requests to AWS services - for example, to read data. These identities include machines running in your AWS environment such as Amazon EC2 instances or AWS Lambda functions. You may also manage machine identities for external parties who need access. Additionally, you may also have machines outside of AWS that need access to your AWS environment." 10 | children = [ 11 | benchmark.well_architected_framework_sec02_bp01, 12 | benchmark.well_architected_framework_sec02_bp02, 13 | benchmark.well_architected_framework_sec02_bp03, 14 | benchmark.well_architected_framework_sec02_bp05 15 | ] 16 | 17 | tags = local.well_architected_framework_sec02_common_tags 18 | } 19 | 20 | benchmark "well_architected_framework_sec02_bp01" { 21 | title = "BP01 Use strong sign-in mechanisms" 22 | description = "Sign-ins (authentication using sign-in credentials) can present risks when not using mechanisms like multi-factor authentication (MFA), especially in situations where sign-in credentials have been inadvertently disclosed or are easily guessed. Use strong sign-in mechanisms to reduce these risks by requiring MFA and strong password policies." 23 | children = [ 24 | // TODO: Should we add a control that uses the query iam_root_last_used? 25 | aws_compliance.control.iam_account_password_policy_strong_min_reuse_24, 26 | aws_compliance.control.iam_user_hardware_mfa_enabled, 27 | aws_compliance.control.iam_user_mfa_enabled, 28 | aws_compliance.control.iam_user_console_access_mfa_enabled, 29 | aws_compliance.control.iam_root_user_no_access_keys, 30 | aws_compliance.control.iam_user_with_administrator_access_mfa_enabled, 31 | aws_compliance.control.sagemaker_notebook_instance_root_access_disabled 32 | ] 33 | 34 | tags = merge(local.well_architected_framework_sec02_common_tags, { 35 | choice_id = "sec_identities_enforce_mechanisms" 36 | risk = "high" 37 | }) 38 | } 39 | 40 | benchmark "well_architected_framework_sec02_bp02" { 41 | title = "BP02 Use temporary credentials" 42 | description = "When doing any type of authentication, it’s best to use temporary credentials instead of long-term credentials to reduce or eliminate risks, such as credentials being inadvertently disclosed, shared, or stolen." 43 | children = [ 44 | aws_compliance.control.iam_user_access_key_age_90, 45 | aws_compliance.control.iam_user_unused_credentials_90, 46 | aws_compliance.control.secretsmanager_secret_automatic_rotation_enabled, 47 | aws_compliance.control.secretsmanager_secret_last_changed_90_day, 48 | aws_compliance.control.secretsmanager_secret_rotated_as_scheduled, 49 | aws_compliance.control.secretsmanager_secret_unused_90_day 50 | ] 51 | 52 | tags = merge(local.well_architected_framework_sec02_common_tags, { 53 | choice_id = "sec_identities_unique" 54 | risk = "high" 55 | }) 56 | } 57 | 58 | benchmark "well_architected_framework_sec02_bp03" { 59 | title = "BP03 Store and use secrets securely" 60 | description = "A workload requires an automated capability to prove its identity to databases, resources, and third-party services. This is accomplished using secret access credentials, such as API access keys, passwords, and OAuth tokens. Using a purpose-built service to store, manage, and rotate these credentials helps reduce the likelihood that those credentials become compromised." 61 | children = [ 62 | aws_compliance.control.cloudformation_stack_output_no_secrets, 63 | aws_compliance.control.ec2_instance_user_data_no_secrets, 64 | aws_compliance.control.ecs_task_definition_container_environment_no_secret 65 | ] 66 | 67 | tags = merge(local.well_architected_framework_sec02_common_tags, { 68 | choice_id = "sec_identities_secrets" 69 | risk = "high" 70 | }) 71 | } 72 | 73 | benchmark "well_architected_framework_sec02_bp05" { 74 | title = "BP05 Audit and rotate credentials periodically" 75 | description = "Audit and rotate credentials periodically to limit how long the credentials can be used to access your resources. Long-term credentials create many risks, and these risks can be reduced by rotating long-term credentials regularly." 76 | children = [ 77 | aws_compliance.control.iam_user_access_key_age_90, 78 | aws_compliance.control.kms_cmk_rotation_enabled, 79 | aws_compliance.control.secretsmanager_secret_automatic_rotation_enabled 80 | ] 81 | 82 | tags = merge(local.well_architected_framework_sec02_common_tags, { 83 | choice_id = "sec_identities_audit" 84 | risk = "medium" 85 | }) 86 | } 87 | -------------------------------------------------------------------------------- /well_architected_framework/security/sec03.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_sec03_common_tags = merge(local.well_architected_framework_security_common_tags, { 3 | question_id = "permissions" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_sec03" { 8 | title = "SEC03 How do you manage permissions for people and machines?" 9 | description = "Manage permissions to control access to people and machine identities that require access to AWS and your workload. Permissions control who can access what, and under what conditions." 10 | children = [ 11 | benchmark.well_architected_framework_sec03_bp01, 12 | benchmark.well_architected_framework_sec03_bp02, 13 | benchmark.well_architected_framework_sec03_bp03, 14 | benchmark.well_architected_framework_sec03_bp04, 15 | benchmark.well_architected_framework_sec03_bp05, 16 | benchmark.well_architected_framework_sec03_bp06, 17 | benchmark.well_architected_framework_sec03_bp07, 18 | benchmark.well_architected_framework_sec03_bp08 19 | ] 20 | 21 | tags = local.well_architected_framework_sec03_common_tags 22 | } 23 | 24 | benchmark "well_architected_framework_sec03_bp01" { 25 | title = "BP01 Define access requirements" 26 | description = "Each component or resource of your workload needs to be accessed by administrators, end users, or other components. Have a clear definition of who or what should have access to each component, choose the appropriate identity type and method of authentication and authorization." 27 | children = [ 28 | aws_compliance.control.ec2_instance_uses_imdsv2, 29 | aws_compliance.control.ec2_instance_iam_profile_attached, 30 | aws_compliance.control.ecs_task_definition_user_for_host_mode_check, 31 | aws_compliance.control.cloudwatch_cross_account_sharing 32 | ] 33 | 34 | tags = merge(local.well_architected_framework_sec03_common_tags, { 35 | choice_id = "sec_permissions_define" 36 | risk = "high" 37 | }) 38 | } 39 | 40 | benchmark "well_architected_framework_sec03_bp02" { 41 | title = "BP02 Grant least privilege access" 42 | description = "It's a best practice to grant only the access that identities require to perform specific actions on specific resources under specific conditions. Use group and identity attributes to dynamically set permissions at scale, rather than defining permissions for individual users. Users should only have the permissions required to do their job. Users should only be given access to production environments to perform a specific task within a limited time period, and access should be revoked once that task is complete. Permissions should be revoked when no longer needed, including when a user moves onto a different project or job function. Administrator privileges should be given only to a small group of trusted administrators. Permissions should be reviewed regularly to avoid permission creep. Machine or system accounts should be given the smallest set of permissions needed to complete their tasks." 43 | children = [ 44 | aws_compliance.control.ecs_task_definition_container_readonly_root_filesystem, 45 | aws_compliance.control.emr_cluster_kerberos_enabled, 46 | aws_compliance.control.ec2_instance_iam_profile_attached 47 | ] 48 | 49 | tags = merge(local.well_architected_framework_sec03_common_tags, { 50 | choice_id = "sec_permissions_least_privileges" 51 | risk = "high" 52 | }) 53 | } 54 | 55 | benchmark "well_architected_framework_sec03_bp03" { 56 | title = "BP03 Establish emergency access process" 57 | description = "A process that allows emergency access to your workload in the unlikely event of an automated process or pipeline issue. This will help you rely on least privilege access, but ensure users can obtain the right level of access when they require it. For example, establish a process for administrators to verify and approve their request, such as an emergency AWS cross-account role for access, or a specific process for administrators to follow to validate and approve an emergency request." 58 | children = [ 59 | aws_compliance.control.iam_group_not_empty, 60 | aws_compliance.control.iam_policy_custom_no_blocked_kms_actions 61 | ] 62 | 63 | tags = merge(local.well_architected_framework_sec03_common_tags, { 64 | choice_id = "sec_permissions_emergency_process" 65 | risk = "high" 66 | }) 67 | } 68 | 69 | benchmark "well_architected_framework_sec03_bp04" { 70 | title = "BP04 Reduce permissions continuously" 71 | description = "As your teams determine what access is required, remove unneeded permissions and establish review processes to achieve least privilege permissions. Continually monitor and remove unused identities and permissions for both human and machine access. Permission policies should adhere to the least privilege principle. As job duties and roles become better defined, your permission policies need to be reviewed to remove unnecessary permissions. This approach lessens the scope of impact should credentials be inadvertently exposed or otherwise accessed without authorization." 72 | children = [ 73 | aws_compliance.control.iam_policy_no_star_star, 74 | ] 75 | 76 | tags = merge(local.well_architected_framework_sec03_common_tags, { 77 | choice_id = "sec_permissions_continuous_reduction" 78 | risk = "medium" 79 | }) 80 | } 81 | 82 | benchmark "well_architected_framework_sec03_bp05" { 83 | title = "BP05 Define permission guardrails for your organization" 84 | description = "Establish common controls that restrict access to all identities in your organization. For example, you can restrict access to specific AWS Regions, or prevent your operators from deleting common resources, such as an IAM role used for your central security team." 85 | children = [ 86 | aws_compliance.control.account_part_of_organizations, 87 | aws_compliance.control.iam_user_unused_credentials_90, 88 | ] 89 | 90 | tags = merge(local.well_architected_framework_sec03_common_tags, { 91 | choice_id = "sec_permissions_define_guardrails" 92 | risk = "medium" 93 | }) 94 | } 95 | 96 | benchmark "well_architected_framework_sec03_bp06" { 97 | title = "BP06 Manage access based on lifecycle" 98 | description = "Integrate access controls with operator and application lifecycle and your centralized federation provider. For example, remove a user's access when they leave the organization or change roles. AWS RAM, access to shared resources is automatically granted or revoked as accounts are moved in and out of the Organization or Organization Unit with which they are shared. This helps ensure that resources are only shared with the accounts that you intend." 99 | children = [ 100 | aws_compliance.control.iam_user_unused_credentials_90, 101 | aws_compliance.control.dms_replication_instance_not_publicly_accessible, 102 | aws_compliance.control.cloudwatch_log_group_retention_period_365, 103 | aws_compliance.control.codebuild_project_build_greater_then_90_days, 104 | aws_compliance.control.vpc_eip_associated, 105 | aws_compliance.control.ecr_repository_lifecycle_policy_configured, 106 | aws_compliance.control.iam_password_policy_expire_90, 107 | ] 108 | 109 | tags = merge(local.well_architected_framework_sec03_common_tags, { 110 | choice_id = "sec_permissions_lifecycle" 111 | risk = "low" 112 | }) 113 | } 114 | 115 | benchmark "well_architected_framework_sec03_bp07" { 116 | title = "BP07 Analyze public and cross-account access" 117 | description = "Continually monitor findings that highlight public and cross-account access. Reduce public access and cross-account access to only the specific resources that require this access. Know which of your AWS resources are shared and with whom. Continually monitor and audit your shared resources to verify they are shared with only authorized principals." 118 | children = [ 119 | aws_compliance.control.dms_replication_instance_not_publicly_accessible, 120 | aws_compliance.control.ebs_snapshot_not_publicly_restorable, 121 | aws_compliance.control.ec2_instance_not_publicly_accessible, 122 | aws_compliance.control.es_domain_in_vpc, 123 | aws_compliance.control.opensearch_domain_in_vpc, 124 | aws_compliance.control.emr_cluster_master_nodes_no_public_ip, 125 | aws_compliance.control.emr_account_public_access_blocked, 126 | aws_compliance.control.ec2_instance_in_vpc, 127 | aws_compliance.control.lambda_function_restrict_public_access, 128 | aws_compliance.control.lambda_function_in_vpc, 129 | aws_compliance.control.rds_db_instance_prohibit_public_access, 130 | aws_compliance.control.rds_db_snapshot_prohibit_public_access, 131 | aws_compliance.control.kms_cmk_policy_prohibit_public_access, 132 | aws_compliance.control.redshift_cluster_prohibit_public_access, 133 | aws_compliance.control.s3_bucket_policy_restrict_public_access, 134 | aws_compliance.control.s3_bucket_restrict_public_write_access, 135 | aws_compliance.control.sagemaker_notebook_instance_direct_internet_access_disabled, 136 | aws_compliance.control.secretsmanager_secret_unused_90_day, 137 | aws_compliance.control.autoscaling_launch_config_public_ip_disabled, 138 | aws_compliance.control.cloudtrail_bucket_not_public, 139 | aws_compliance.control.ecr_repository_prohibit_public_access, 140 | aws_compliance.control.eks_cluster_endpoint_restrict_public_access, 141 | aws_compliance.control.elb_application_classic_network_lb_prohibit_public_access, 142 | aws_compliance.control.s3_public_access_block_account, 143 | aws_compliance.control.sns_topic_policy_prohibit_public_access, 144 | aws_compliance.control.sqs_queue_policy_prohibit_public_access, 145 | aws_compliance.control.ssm_document_prohibit_public_access 146 | ] 147 | 148 | tags = merge(local.well_architected_framework_sec03_common_tags, { 149 | choice_id = "sec_permissions_analyze_cross_account" 150 | risk = "low" 151 | }) 152 | } 153 | 154 | benchmark "well_architected_framework_sec03_bp08" { 155 | title = "BP08 Share resources securely within your organization" 156 | description = "As the number of workloads grows, you might need to share access to resources in those workloads or provision the resources multiple times across multiple accounts. You might have constructs to compartmentalize your environment, such as having development, testing, and production environments. However, having separation constructs does not limit you from being able to share securely. By sharing components that overlap, you can reduce operational overhead and allow for a consistent experience without guessing what you might have missed while creating the same resource multiple times." 157 | children = [ 158 | aws_compliance.control.dms_replication_instance_not_publicly_accessible, 159 | aws_compliance.control.es_domain_in_vpc, 160 | aws_compliance.control.opensearch_domain_in_vpc, 161 | aws_compliance.control.ec2_instance_in_vpc, 162 | aws_compliance.control.lambda_function_in_vpc, 163 | aws_compliance.control.sagemaker_notebook_instance_direct_internet_access_disabled, 164 | aws_compliance.control.secretsmanager_secret_unused_90_day, 165 | aws_compliance.control.codebuild_project_with_user_controlled_buildspec, 166 | ] 167 | 168 | tags = merge(local.well_architected_framework_sec03_common_tags, { 169 | choice_id = "sec_permissions_share_securely" 170 | risk = "low" 171 | }) 172 | } 173 | -------------------------------------------------------------------------------- /well_architected_framework/security/sec04.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_sec04_common_tags = merge(local.well_architected_framework_security_common_tags, { 3 | question_id = "detect-investigate-events" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_sec04" { 8 | title = "SEC04 How do you detect and investigate security events?" 9 | description = "Capture and analyze events from logs and metrics to gain visibility. Take action on security events and potential threats to help secure your workload." 10 | children = [ 11 | benchmark.well_architected_framework_sec04_bp01, 12 | benchmark.well_architected_framework_sec04_bp02, 13 | benchmark.well_architected_framework_sec04_bp03 14 | ] 15 | 16 | tags = local.well_architected_framework_sec04_common_tags 17 | } 18 | 19 | benchmark "well_architected_framework_sec04_bp01" { 20 | title = "BP01 Configure service and application logging" 21 | description = "Retain security event logs from services and applications. This is a fundamental principle of security for audit, investigations, and operational use cases, and a common security requirement driven by governance, risk, and compliance (GRC) standards, policies, and procedures.An organization should be able to reliably and consistently retrieve security event logs from AWS services and applications in a timely manner when required to fulfill an internal process or obligation, such as a security incident response. Consider centralizing logs for better operational results." 22 | children = [ 23 | aws_compliance.control.apigateway_stage_logging_enabled, 24 | aws_compliance.control.opensearch_domain_audit_logging_enabled, 25 | aws_compliance.control.cloudtrail_trail_integrated_with_logs, 26 | aws_compliance.control.cloudtrail_s3_data_events_enabled, 27 | aws_compliance.control.acm_certificate_transparency_logging_enabled, 28 | aws_compliance.control.lambda_function_cloudtrail_logging_enabled, 29 | aws_compliance.control.cloudfront_distribution_logging_enabled, 30 | aws_compliance.control.cis_v150_3_10, 31 | aws_compliance.control.cis_v130_3_11, 32 | aws_compliance.control.eks_cluster_control_plane_audit_logging_enabled, 33 | aws_compliance.control.elb_application_classic_lb_logging_enabled, 34 | aws_compliance.control.rds_db_instance_cloudwatch_logs_enabled, 35 | aws_compliance.control.redshift_cluster_audit_logging_enabled, 36 | aws_compliance.control.route53_zone_query_logging_enabled, 37 | aws_compliance.control.s3_bucket_object_logging_enabled, 38 | aws_compliance.control.vpc_flow_logs_enabled 39 | ] 40 | 41 | tags = merge(local.well_architected_framework_sec04_common_tags, { 42 | choice_id = "sec_detect_investigate_events_app_service_logging" 43 | risk = "high" 44 | }) 45 | } 46 | 47 | benchmark "well_architected_framework_sec04_bp02" { 48 | title = "BP02 Analyze logs, findings, and metrics centrally" 49 | description = "Security operations teams rely on the collection of logs and the use of search tools to discover potential events of interest, which might indicate unauthorized activity or unintentional change. However, simply analyzing collected data and manually processing information is insufficient to keep up with the volume of information flowing from complex architectures. Analysis and reporting alone don’t facilitate the assignment of the right resources to work an event in a timely fashion." 50 | children = [ 51 | aws_compliance.control.es_domain_logs_to_cloudwatch, 52 | aws_compliance.control.cloudtrail_multi_region_trail_enabled, 53 | aws_compliance.control.rds_db_instance_logging_enabled, 54 | aws_compliance.control.vpc_flow_logs_enabled, 55 | aws_compliance.control.wafv2_web_acl_logging_enabled, 56 | aws_compliance.control.cloudtrail_security_trail_enabled, 57 | aws_compliance.control.redshift_cluster_audit_logging_enabled, 58 | aws_compliance.control.config_enabled_all_regions 59 | ] 60 | 61 | tags = merge(local.well_architected_framework_sec04_common_tags, { 62 | choice_id = "sec_detect_investigate_events_analyze_all" 63 | risk = "high" 64 | }) 65 | } 66 | 67 | benchmark "well_architected_framework_sec04_bp03" { 68 | title = "BP03 Automate response to events" 69 | description = "Using automation to investigate and remediate events reduces human effort and error, and allows you to scale investigation capabilities. Regular reviews will help you tune automation tools, and continuously iterate. In AWS, investigating events of interest and information on potentially unexpected changes into an automated workflow can be achieved using Amazon EventBridge. This service provides a scalable rules engine designed to broker both native AWS event formats (such as AWS CloudTrail events), as well as custom events you can generate from your application. Amazon GuardDuty also allows you to route events to a workflow system for those building incident response systems (AWS Step Functions), or to a central Security Account, or to a bucket for further analysis." 70 | children = [ 71 | aws_compliance.control.es_domain_logs_to_cloudwatch, 72 | aws_compliance.control.elb_application_classic_lb_logging_enabled, 73 | aws_compliance.control.cloudtrail_multi_region_trail_enabled, 74 | aws_compliance.control.rds_db_instance_logging_enabled, 75 | aws_compliance.control.vpc_flow_logs_enabled, 76 | aws_compliance.control.wafv2_web_acl_logging_enabled, 77 | aws_compliance.control.cloudtrail_security_trail_enabled, 78 | aws_compliance.control.redshift_cluster_audit_logging_enabled, 79 | ] 80 | 81 | tags = merge(local.well_architected_framework_sec04_common_tags, { 82 | choice_id = "sec_detect_investigate_events_auto_response" 83 | risk = "medium" 84 | }) 85 | } 86 | -------------------------------------------------------------------------------- /well_architected_framework/security/sec05.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_sec05_common_tags = merge(local.well_architected_framework_security_common_tags, { 3 | question_id = "network-protection" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_sec05" { 8 | title = "SEC05 How do you protect your network resources?" 9 | description = "Any workload that has some form of network connectivity, whether it's the internet or a private network, requires multiple layers of defense to help protect from external and internal network-based threats." 10 | children = [ 11 | benchmark.well_architected_framework_sec05_bp01, 12 | benchmark.well_architected_framework_sec05_bp02, 13 | benchmark.well_architected_framework_sec05_bp03, 14 | benchmark.well_architected_framework_sec05_bp04 15 | ] 16 | 17 | tags = local.well_architected_framework_sec05_common_tags 18 | } 19 | 20 | benchmark "well_architected_framework_sec05_bp01" { 21 | title = "BP01 Create network layers" 22 | description = "Group components that share sensitivity requirements into layers to minimize the potential scope of impact of unauthorized access. For example, a database cluster in a virtual private cloud (VPC) with no need for internet access should be placed in subnets with no route to or from the internet. Traffic should only flow from the adjacent next least sensitive resource. Consider a web application sitting behind a load balancer. Your database should not be accessible directly from the load balancer. Only the business logic or web server should have direct access to your database." 23 | children = [ 24 | aws_compliance.control.es_domain_in_vpc, 25 | aws_compliance.control.opensearch_domain_in_vpc, 26 | aws_compliance.control.ec2_instance_in_vpc, 27 | aws_compliance.control.lambda_function_in_vpc, 28 | aws_compliance.control.redshift_cluster_enhanced_vpc_routing_enabled, 29 | aws_compliance.control.elb_application_lb_waf_enabled, 30 | aws_compliance.control.apigateway_stage_use_waf_web_acl, 31 | aws_compliance.control.cloudfront_distribution_waf_enabled, 32 | aws_compliance.control.eks_cluster_endpoint_restrict_public_access, 33 | aws_compliance.control.sagemaker_model_network_isolation_enabled, 34 | aws_compliance.control.sagemaker_model_in_vpc, 35 | aws_compliance.control.sagemaker_notebook_instance_in_vpc, 36 | aws_compliance.control.sagemaker_training_job_network_isolation_enabled, 37 | aws_compliance.control.sagemaker_training_job_in_vpc 38 | ] 39 | 40 | tags = merge(local.well_architected_framework_sec05_common_tags, { 41 | choice_id = "sec_network_protection_create_layers" 42 | risk = "high" 43 | }) 44 | } 45 | 46 | benchmark "well_architected_framework_sec05_bp02" { 47 | title = "BP02 Control traffic at all layers" 48 | description = "When architecting your network topology, you should examine the connectivity requirements of each component. For example, if a component requires internet accessibility (inbound and outbound), connectivity to VPCs, edge services, and external data centers. A VPC allows you to define your network topology that spans an AWS Region with a private IPv4 address range that you set, or an IPv6 address range AWS selects. You should apply multiple controls with a defense in depth approach for both inbound and outbound traffic, including the use of security groups (stateful inspection firewall), Network ACLs, subnets, and route tables. Within a VPC, you can create subnets in an Availability Zone. Each subnet can have an associated route table that defines routing rules for managing the paths that traffic takes within the subnet. You can define an internet routable subnet by having a route that goes to an internet or NAT gateway attached to the VPC, or through another VPC." 49 | children = [ 50 | aws_compliance.control.dms_replication_instance_not_publicly_accessible, 51 | aws_compliance.control.ebs_snapshot_not_publicly_restorable, 52 | aws_compliance.control.ec2_instance_not_use_multiple_enis, 53 | aws_compliance.control.sagemaker_notebook_instance_direct_internet_access_disabled, 54 | aws_compliance.control.vpc_subnet_auto_assign_public_ip_disabled, 55 | aws_compliance.control.vpc_default_security_group_restricts_all_traffic, 56 | aws_compliance.control.apigateway_rest_api_authorizers_configured, 57 | aws_compliance.control.s3_bucket_acls_should_prohibit_user_access, 58 | aws_compliance.control.cis_v150_2_1_3 59 | ] 60 | 61 | tags = merge(local.well_architected_framework_sec05_common_tags, { 62 | choice_id = "sec_network_protection_layered" 63 | risk = "high" 64 | }) 65 | } 66 | 67 | benchmark "well_architected_framework_sec05_bp03" { 68 | title = "BP03 Automate network protection" 69 | description = "Automate protection mechanisms to provide a self-defending network based on threat intelligence and anomaly detection. For example, intrusion detection and prevention tools that can adapt to current threats and reduce their impact. A web application firewall is an example of where you can automate network protection, for example, by using the AWS WAF Security Automations solution to automatically block requests originating from IP addresses associated with known threat actors." 70 | children = [ 71 | aws_compliance.control.dms_replication_instance_not_publicly_accessible, 72 | aws_compliance.control.autoscaling_launch_config_public_ip_disabled, 73 | aws_compliance.control.vpc_network_acl_remote_administration, 74 | aws_compliance.control.vpc_security_group_allows_ingress_authorized_ports, 75 | aws_compliance.control.cis_v150_5_2, 76 | aws_compliance.control.vpc_security_group_restrict_ingress_tcp_udp_all, 77 | aws_compliance.control.vpc_security_group_restrict_ingress_common_ports_all, 78 | aws_compliance.control.vpc_security_group_restrict_ingress_kafka_port, 79 | aws_compliance.control.vpc_security_group_restricted_common_ports, 80 | aws_compliance.control.vpc_security_group_restrict_ingress_redis_port, 81 | aws_compliance.control.waf_web_acl_rule_attached, 82 | aws_compliance.control.waf_rule_group_rule_attached, 83 | aws_compliance.control.vpc_network_acl_unused, 84 | aws_compliance.control.vpc_default_security_group_restricts_all_traffic, 85 | aws_compliance.control.ec2_instance_no_launch_wizard_security_group, 86 | aws_compliance.control.route53_domain_privacy_protection_enabled, 87 | aws_compliance.control.route53_domain_transfer_lock_enabled 88 | ] 89 | 90 | tags = merge(local.well_architected_framework_sec05_common_tags, { 91 | choice_id = "sec_network_protection_auto_protect" 92 | risk = "medium" 93 | }) 94 | } 95 | 96 | benchmark "well_architected_framework_sec05_bp04" { 97 | title = "BP04 Implement inspection and protection" 98 | description = "Inspect and filter your traffic at each layer. You can inspect your VPC configurations for potential unintended access using VPC Network Access Analyzer. You can specify your network access requirements and identify potential network paths that do not meet them. For components transacting over HTTP-based protocols, a web application firewall can help protect from common attacks. AWS WAF is a web application firewall that lets you monitor and block HTTP(s) requests that match your configurable rules that are forwarded to an Amazon API Gateway API, Amazon CloudFront, or an Application Load Balancer. To get started with AWS WAF, you can use AWS Managed Rules in combination with your own, or use existing partner integrations." 99 | children = [ 100 | aws_compliance.control.guardduty_enabled, 101 | aws_compliance.control.vpc_flow_logs_enabled, 102 | aws_compliance.control.apigateway_rest_api_authorizers_configured 103 | ] 104 | 105 | tags = merge(local.well_architected_framework_sec05_common_tags, { 106 | choice_id = "sec_network_protection_inspection" 107 | risk = "low" 108 | }) 109 | } 110 | -------------------------------------------------------------------------------- /well_architected_framework/security/sec06.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_sec06_common_tags = merge(local.well_architected_framework_security_common_tags, { 3 | question_id = "protect-compute" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_sec06" { 8 | title = "SEC06 How do you protect your compute resources?" 9 | description = "Compute resources in your workload require multiple layers of defense to help protect from external and internal threats. Compute resources include EC2 instances, containers, AWS Lambda functions, database services, IoT devices, and more." 10 | children = [ 11 | benchmark.well_architected_framework_sec06_bp01, 12 | benchmark.well_architected_framework_sec06_bp02, 13 | benchmark.well_architected_framework_sec06_bp03, 14 | benchmark.well_architected_framework_sec06_bp04, 15 | benchmark.well_architected_framework_sec06_bp05, 16 | benchmark.well_architected_framework_sec06_bp06 17 | ] 18 | 19 | tags = local.well_architected_framework_sec06_common_tags 20 | } 21 | 22 | benchmark "well_architected_framework_sec06_bp01" { 23 | title = "BP01 Perform vulnerability management" 24 | description = "Frequently scan and patch for vulnerabilities in your code, dependencies, and in your infrastructure to help protect against new threats. Create and maintain a vulnerability management program. Regularly scan and patch resources such as Amazon EC2 instances, Amazon Elastic Container Service (Amazon ECS) containers, and Amazon Elastic Kubernetes Service (Amazon EKS) workloads. Configure maintenance windows for AWS managed resources, such as Amazon Relational Database Service (Amazon RDS) databases. Use static code scanning to inspect application source code for common issues. Consider web application penetration testing if your organization has the requisite skills or can hire outside assistance." 25 | children = [ 26 | aws_compliance.control.rds_db_instance_automatic_minor_version_upgrade_enabled, 27 | aws_compliance.control.cloudtrail_trail_validation_enabled, 28 | aws_compliance.control.cloudtrail_security_trail_enabled, 29 | aws_compliance.control.ec2_instance_uses_imdsv2, 30 | aws_compliance.control.ec2_instance_publicly_accessible_iam_profile_attached, 31 | aws_compliance.control.ssm_managed_instance_compliance_patch_compliant 32 | ] 33 | 34 | tags = merge(local.well_architected_framework_sec06_common_tags, { 35 | choice_id = "sec_protect_compute_vulnerability_management" 36 | risk = "high" 37 | }) 38 | } 39 | 40 | benchmark "well_architected_framework_sec06_bp02" { 41 | title = "BP02 Reduce attack surface" 42 | description = "Reduce your exposure to unintended access by hardening operating systems and minimizing the components, libraries, and externally consumable services in use. Start by reducing unused components, whether they are operating system packages or applications, for Amazon Elastic Compute Cloud (Amazon EC2)-based workloads, or external software modules in your code, for all workloads. You can find many hardening and security configuration guides for common operating systems and server software. For example, you can start with the Center for Internet Security and iterate." 43 | children = [ 44 | aws_compliance.control.lambda_function_in_vpc, 45 | aws_compliance.control.ecs_cluster_container_insights_enabled, 46 | aws_compliance.control.ecs_service_fargate_using_latest_platform_version 47 | ] 48 | 49 | tags = merge(local.well_architected_framework_sec06_common_tags, { 50 | choice_id = "sec_protect_compute_reduce_surface" 51 | risk = "high" 52 | }) 53 | } 54 | 55 | benchmark "well_architected_framework_sec06_bp03" { 56 | title = "BP03 Implement managed services" 57 | description = "Implement services that manage resources, such as Amazon Relational Database Service (Amazon RDS), AWS Lambda, and Amazon Elastic Container Service (Amazon ECS), to reduce your security maintenance tasks as part of the shared responsibility model. For example, Amazon RDS helps you set up, operate, and scale a relational database, automates administration tasks such as hardware provisioning, database setup, patching, and backups. This means you have more free time to focus on securing your application in other ways described in the AWS Well-Architected Framework. Lambda lets you run code without provisioning or managing servers, so you only need to focus on the connectivity, invocation, and security at the code level–not the infrastructure or operating system." 58 | children = [ 59 | aws_compliance.control.redshift_cluster_maintenance_settings_check, 60 | aws_compliance.control.ec2_instance_not_use_multiple_enis 61 | ] 62 | 63 | tags = merge(local.well_architected_framework_sec06_common_tags, { 64 | choice_id = "sec_protect_compute_implement_managed_services" 65 | risk = "medium" 66 | }) 67 | } 68 | 69 | benchmark "well_architected_framework_sec06_bp04" { 70 | title = "BP04 Automate compute protection" 71 | description = "Automate your protective compute mechanisms including vulnerability management, reduction in attack surface, and management of resources. The automation will help you invest time in securing other aspects of your workload, and reduce the risk of human error." 72 | children = [ 73 | aws_compliance.control.ec2_instance_iam_profile_attached, 74 | aws_compliance.control.ec2_instance_ssm_managed, 75 | aws_compliance.control.ec2_instance_not_use_multiple_enis, 76 | aws_compliance.control.ec2_stopped_instance_30_days 77 | ] 78 | 79 | tags = merge(local.well_architected_framework_sec06_common_tags, { 80 | choice_id = "sec_protect_compute_auto_protection" 81 | risk = "medium" 82 | }) 83 | } 84 | 85 | benchmark "well_architected_framework_sec06_bp05" { 86 | title = "BP05 Enable people to perform actions at a distance" 87 | description = "Removing the ability for interactive access reduces the risk of human error, and the potential for manual configuration or management. For example, use a change management workflow to deploy Amazon Elastic Compute Cloud (Amazon EC2) instances using infrastructure-as-code, then manage Amazon EC2 instances using tools such as AWS Systems Manager instead of allowing direct access or through a bastion host. AWS Systems Manager can automate a variety of maintenance and deployment tasks, using features including automation workflows, documents (playbooks), and the run command. AWS CloudFormation stacks build from pipelines and can automate your infrastructure deployment and management tasks without using the AWS Management Console or APIs directly." 88 | children = [ 89 | aws_compliance.control.ec2_instance_iam_profile_attached, 90 | aws_compliance.control.ec2_instance_ssm_managed, 91 | aws_compliance.control.ec2_instance_not_use_multiple_enis, 92 | aws_compliance.control.ec2_stopped_instance_30_days 93 | ] 94 | 95 | tags = merge(local.well_architected_framework_sec06_common_tags, { 96 | choice_id = "sec_protect_compute_actions_distance" 97 | risk = "low" 98 | }) 99 | } 100 | 101 | benchmark "well_architected_framework_sec06_bp06" { 102 | title = "BP06 Validate software integrity" 103 | description = "Implement mechanisms (for example, code signing) to validate that the software, code and libraries used in the workload are from trusted sources and have not been tampered with. For example, you should verify the code signing certificate of binaries and scripts to confirm the author, and ensure it has not been tampered with since created by the author. AWS Signer can help ensure the trust and integrity of your code by centrally managing the code- signing lifecycle, including signing certification and public and private keys. You can learn how to use advanced patterns and best practices for code signing with AWS Lambda. Additionally, a checksum of software that you download, compared to that of the checksum from the provider, can help ensure it has not been tampered with." 104 | children = [ 105 | aws_compliance.control.ebs_volume_unused, 106 | aws_compliance.control.ssm_managed_instance_compliance_association_compliant, 107 | aws_compliance.control.ssm_managed_instance_compliance_patch_compliant, 108 | aws_compliance.control.cloudtrail_trail_validation_enabled 109 | ] 110 | 111 | tags = merge(local.well_architected_framework_sec06_common_tags, { 112 | choice_id = "sec_protect_compute_validate_software_integrity" 113 | risk = "low" 114 | }) 115 | } 116 | -------------------------------------------------------------------------------- /well_architected_framework/security/sec08.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_sec08_common_tags = merge(local.well_architected_framework_security_common_tags, { 3 | question_id = "protect-data-rest" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_sec08" { 8 | title = "SEC08 How do you protect your data at rest?" 9 | description = "Protect your data at rest by implementing multiple controls, to reduce the risk of unauthorized access or mishandling." 10 | children = [ 11 | benchmark.well_architected_framework_sec08_bp01, 12 | benchmark.well_architected_framework_sec08_bp02, 13 | benchmark.well_architected_framework_sec08_bp03, 14 | benchmark.well_architected_framework_sec08_bp04 15 | ] 16 | 17 | tags = local.well_architected_framework_sec08_common_tags 18 | } 19 | 20 | benchmark "well_architected_framework_sec08_bp01" { 21 | title = "BP01 Implement secure key management" 22 | description = "By defining an encryption approach that includes the storage, rotation, and access control of keys, you can help provide protection for your content against unauthorized users and against unnecessary exposure to authorized users. AWS Key Management Service (AWS KMS) helps you manage encryption keys and integrates with many AWS services. This service provides durable, secure, and redundant storage for your AWS KMS keys. You can define your key aliases as well as key-level policies. The policies help you define key administrators as well as key users. Additionally, AWS CloudHSM is a cloud-based hardware security module (HSM) that allows you to easily generate and use your own encryption keys in the AWS Cloud. It helps you meet corporate, contractual, and regulatory compliance requirements for data security by using FIPS 140-2 Level 3 validated HSMs." 23 | children = [ 24 | aws_compliance.control.apigateway_stage_cache_encryption_at_rest_enabled, 25 | aws_compliance.control.backup_recovery_point_encryption_enabled, 26 | aws_compliance.control.codebuild_project_artifact_encryption_enabled, 27 | aws_compliance.control.codebuild_project_s3_logs_encryption_enabled, 28 | aws_compliance.control.kms_key_not_pending_deletion 29 | ] 30 | 31 | tags = merge(local.well_architected_framework_sec08_common_tags, { 32 | choice_id = "sec_protect_data_rest_key_mgmt" 33 | risk = "high" 34 | }) 35 | } 36 | 37 | benchmark "well_architected_framework_sec08_bp02" { 38 | title = "BP02 Enforce encryption at rest" 39 | description = "You should enforce the use of encryption for data at rest. Encryption maintains the confidentiality of sensitive data in the event of unauthorized access or accidental disclosure. Private data should be encrypted by default when at rest. Encryption helps maintain confidentiality of the data and provides an additional layer of protection against intentional or inadvertent data disclosure or exfiltration. Data that is encrypted cannot be read or accessed without first unencrypting the data. Any data stored unencrypted should be inventoried and controlled." 40 | children = [ 41 | aws_compliance.control.efs_file_system_encrypt_data_at_rest, 42 | aws_compliance.control.es_domain_encryption_at_rest_enabled, 43 | aws_compliance.control.opensearch_domain_encryption_at_rest_enabled, 44 | aws_compliance.control.rds_db_instance_encryption_at_rest_enabled, 45 | aws_compliance.control.rds_db_snapshot_encrypted_at_rest, 46 | aws_compliance.control.cloudtrail_trail_logs_encrypted_with_kms_cmk, 47 | aws_compliance.control.dynamodb_table_encryption_enabled, 48 | aws_compliance.control.ec2_ebs_default_encryption_enabled, 49 | aws_compliance.control.eks_cluster_secrets_encrypted, 50 | aws_compliance.control.glue_dev_endpoint_cloudwatch_logs_encryption_enabled, 51 | aws_compliance.control.glue_dev_endpoint_job_bookmarks_encryption_enabled, 52 | aws_compliance.control.glue_dev_endpoint_s3_encryption_enabled, 53 | aws_compliance.control.glue_job_s3_encryption_enabled, 54 | aws_compliance.control.glue_job_bookmarks_encryption_enabled, 55 | aws_compliance.control.glue_job_cloudwatch_logs_encryption_enabled, 56 | aws_compliance.control.sagemaker_notebook_instance_encrypted_with_kms_cmk, 57 | aws_compliance.control.sagemaker_training_job_inter_container_traffic_encryption_enabled, 58 | aws_compliance.control.sagemaker_training_job_volume_and_data_encryption_enabled 59 | ] 60 | 61 | tags = merge(local.well_architected_framework_sec08_common_tags, { 62 | choice_id = "sec_protect_data_rest_encrypt" 63 | risk = "high" 64 | }) 65 | } 66 | 67 | benchmark "well_architected_framework_sec08_bp03" { 68 | title = "BP03 Automate data at rest protection" 69 | description = "Use automated tools to validate and enforce data at rest controls continuously, for example, verify that there are only encrypted storage resources. You can automate validation that all EBS volumes are encrypted using AWS Config Rules. AWS Security Hub can also verify several different controls through automated checks against security standards. Additionally, your AWS Config Rules can automatically remediate noncompliant resources." 70 | children = [ 71 | aws_compliance.control.redshift_cluster_audit_logging_enabled, 72 | aws_compliance.control.redshift_cluster_kms_enabled, 73 | aws_compliance.control.s3_bucket_default_encryption_enabled, 74 | aws_compliance.control.sagemaker_endpoint_configuration_encryption_at_rest_enabled, 75 | aws_compliance.control.sagemaker_notebook_instance_encryption_at_rest_enabled, 76 | aws_compliance.control.sagemaker_notebook_instance_encrypted_with_kms_cmk 77 | ] 78 | 79 | tags = merge(local.well_architected_framework_sec08_common_tags, { 80 | choice_id = "sec_protect_data_rest_automate_protection" 81 | risk = "medium" 82 | }) 83 | } 84 | 85 | benchmark "well_architected_framework_sec08_bp04" { 86 | title = "BP04 Enforce access control" 87 | description = "To help protect your data at rest, enforce access control using mechanisms, such as isolation and versioning, and apply the principle of least privilege. Prevent the granting of public access to your data. Verify that only authorized users can access data on a need-to-know basis. Protect your data with regular backups and versioning to prevent against intentional or inadvertent modification or deletion of data. Isolate critical data from other data to protect its confidentiality and data integrity." 88 | children = [ 89 | aws_compliance.control.sns_topic_encrypted_at_rest, 90 | aws_compliance.control.s3_bucket_versioning_enabled, 91 | aws_compliance.control.account_part_of_organizations 92 | ] 93 | 94 | tags = merge(local.well_architected_framework_sec08_common_tags, { 95 | choice_id = "sec_protect_data_rest_access_control" 96 | risk = "low" 97 | }) 98 | } 99 | -------------------------------------------------------------------------------- /well_architected_framework/security/sec09.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_sec09_common_tags = merge(local.well_architected_framework_security_common_tags, { 3 | question_id = "protect-data-transit" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_sec09" { 8 | title = "SEC09 How do you protect your data in transit?" 9 | description = "Protect your data in transit by implementing multiple controls to reduce the risk of unauthorized access or loss." 10 | children = [ 11 | benchmark.well_architected_framework_sec09_bp01, 12 | benchmark.well_architected_framework_sec09_bp02, 13 | benchmark.well_architected_framework_sec09_bp03, 14 | benchmark.well_architected_framework_sec09_bp04 15 | ] 16 | 17 | tags = local.well_architected_framework_sec09_common_tags 18 | } 19 | 20 | benchmark "well_architected_framework_sec09_bp01" { 21 | title = "BP01 Implement secure key and certificate management" 22 | description = "Store encryption keys and certificates securely and rotate them at appropriate time intervals with strict access control. The best way to accomplish this is to use a managed service, such as AWS Certificate Manager (ACM). It lets you easily provision, manage, and deploy public and private Transport Layer Security (TLS) certificates for use with AWS services and your internal connected resources. TLS certificates are used to secure network communications and establish the identity of websites over the internet as well as resources on private networks. ACM integrates with AWS resources, such as Elastic Load Balancers (ELBs), AWS distributions, and APIs on API Gateway, also handling automatic certificate renewals. If you use ACM to deploy a private root CA, both certificates and private keys can be provided by it for use in Amazon Elastic Compute Cloud (Amazon EC2) instances, containers, and so on." 23 | children = [ 24 | aws_compliance.control.acm_certificate_expires_30_days, 25 | aws_compliance.control.elb_classic_lb_use_ssl_certificate, 26 | aws_compliance.control.elb_application_network_lb_use_ssl_certificate 27 | ] 28 | 29 | tags = merge(local.well_architected_framework_sec09_common_tags, { 30 | choice_id = "sec_protect_data_transit_key_cert_mgmt" 31 | risk = "high" 32 | }) 33 | } 34 | 35 | benchmark "well_architected_framework_sec09_bp02" { 36 | title = "BP02 Enforce encryption in transit" 37 | description = "Enforce your defined encryption requirements based on your organization's policies, regulatory obligations and standards to help meet organizational, legal, and compliance requirements. Only use protocols with encryption when transmitting sensitive data outside of your virtual private cloud (VPC). Encryption helps maintain data confidentiality even when the data transits untrusted networks. All data should be encrypted in transit using secure TLS protocols and cipher suites. Network traffic between your resources and the internet must be encrypted to mitigate unauthorized access to the data. Network traffic solely within your internal AWS environment should be encrypted using TLS wherever possible." 38 | children = [ 39 | aws_compliance.control.elb_application_lb_drop_http_headers, 40 | aws_compliance.control.elb_application_lb_redirect_http_request_to_https, 41 | aws_compliance.control.es_domain_node_to_node_encryption_enabled, 42 | aws_compliance.control.apigateway_rest_api_stage_use_ssl_certificate, 43 | aws_compliance.control.opensearch_domain_node_to_node_encryption_enabled, 44 | aws_compliance.control.opensearch_domain_https_required, 45 | aws_compliance.control.cloudfront_distribution_custom_origins_encryption_in_transit_enabled, 46 | aws_compliance.control.cloudfront_distribution_no_deprecated_ssl_protocol, 47 | aws_compliance.control.elb_listener_use_secure_ssl_cipher, 48 | aws_compliance.control.s3_bucket_enforces_ssl 49 | ] 50 | 51 | tags = merge(local.well_architected_framework_sec09_common_tags, { 52 | choice_id = "sec_protect_data_transit_encrypt" 53 | risk = "high" 54 | }) 55 | } 56 | 57 | benchmark "well_architected_framework_sec09_bp03" { 58 | title = "BP03 Automate detection of unintended data access" 59 | description = "Use tools such as Amazon GuardDuty to automatically detect suspicious activity or attempts to move data outside of defined boundaries. For example, GuardDuty can detect Amazon Simple Storage Service (Amazon S3) read activity that is unusual with the Exfiltration:S3/AnomalousBehavior finding. In addition to GuardDuty, Amazon VPC Flow Logs, which capture network traffic information, can be used with Amazon EventBridge to detect connections, both successful and denied. Amazon S3 Access Analyzer can help assess what data is accessible to who in your Amazon S3 buckets." 60 | children = [ 61 | aws_compliance.control.redshift_cluster_encryption_in_transit_enabled 62 | ] 63 | 64 | tags = merge(local.well_architected_framework_sec09_common_tags, { 65 | choice_id = "sec_protect_data_transit_auto_unintended_access" 66 | risk = "medium" 67 | }) 68 | } 69 | 70 | benchmark "well_architected_framework_sec09_bp04" { 71 | title = "BP04 Authenticate network communications" 72 | description = "Verify the identity of communications by using protocols that support authentication, such as Transport Layer Security (TLS) or IPsec. Using network protocols that support authentication, allows for trust to be established between the parties. This adds to the encryption used in the protocol to reduce the risk of communications being altered or intercepted. Common protocols that implement authentication include Transport Layer Security (TLS), which is used in many AWS services, and IPsec, which is used in AWS Virtual Private Network (AWS VPN)." 73 | children = [ 74 | aws_compliance.control.elb_classic_lb_use_tls_https_listeners, 75 | aws_compliance.control.vpc_flow_logs_enabled 76 | ] 77 | 78 | tags = merge(local.well_architected_framework_sec09_common_tags, { 79 | choice_id = "sec_protect_data_transit_authentication" 80 | risk = "low" 81 | }) 82 | } 83 | -------------------------------------------------------------------------------- /well_architected_framework/security/sec10.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_sec10_common_tags = merge(local.well_architected_framework_security_common_tags, { 3 | question_id = "incident-response" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_sec10" { 8 | title = "SEC10 How do you anticipate, respond to, and recover from incidents?" 9 | description = "Preparation is critical to timely and effective investigation, response to, and recovery from security incidents to help minimize disruption to your organization." 10 | children = [ 11 | benchmark.well_architected_framework_sec10_bp01 12 | ] 13 | 14 | tags = local.well_architected_framework_sec10_common_tags 15 | } 16 | 17 | benchmark "well_architected_framework_sec10_bp01" { 18 | title = "BP01 Identify key personnel and external resources" 19 | description = "Identify internal and external personnel, resources, and legal obligations that would help your organization respond to an incident. When you define your approach to incident response in the cloud, in unison with other teams (such as your legal counsel, leadership, business stakeholders, AWS Support Services, and others), you must identify key personnel, stakeholders, and relevant contacts. To reduce dependency and decrease response time, make sure that your team, specialist security teams, and responders are educated about the services that you use and have opportunities to practice hands-on." 20 | children = [ 21 | aws_compliance.control.iam_support_role 22 | ] 23 | 24 | tags = merge(local.well_architected_framework_sec10_common_tags, { 25 | choice_id = "sec_incident_response_identify_personnel" 26 | risk = "high" 27 | }) 28 | } 29 | -------------------------------------------------------------------------------- /well_architected_framework/security/sec11.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_sec11_common_tags = merge(local.well_architected_framework_security_common_tags, { 3 | question_id = "application-security" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_sec11" { 8 | title = "SEC11 How do you incorporate and validate the security properties of applications throughout the design, development, and deployment lifecycle?" 9 | description = "Preparation is critical to timely and effective investigation, response to, and recovery from security incidents to help minimize disruption to your organization." 10 | children = [ 11 | benchmark.well_architected_framework_sec11_bp02 12 | ] 13 | 14 | tags = local.well_architected_framework_sec11_common_tags 15 | } 16 | 17 | benchmark "well_architected_framework_sec11_bp02" { 18 | title = "BP01 Identify key personnel and external resources" 19 | description = "Training people, testing using automation, understanding dependencies, and validating the security properties of tools and applications help to reduce the likelihood of security issues in production workloads." 20 | children = [ 21 | aws_compliance.control.ecr_repository_image_scan_on_push_enabled 22 | ] 23 | 24 | tags = merge(local.well_architected_framework_sec11_common_tags, { 25 | choice_id = "sec_appsec_automate_testing_throughout_lifecycle" 26 | risk = "medium" 27 | }) 28 | } 29 | -------------------------------------------------------------------------------- /well_architected_framework/security/security.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_security_common_tags = merge(local.well_architected_framework_common_tags, { 3 | pillar_id = "security" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework_security" { 8 | title = "Security" 9 | description = "The security pillar focuses on protecting information and systems. Key topics include confidentiality and integrity of data, managing user permissions, and establishing controls to detect security events." 10 | children = [ 11 | benchmark.well_architected_framework_sec01, 12 | benchmark.well_architected_framework_sec02, 13 | benchmark.well_architected_framework_sec03, 14 | benchmark.well_architected_framework_sec04, 15 | benchmark.well_architected_framework_sec05, 16 | benchmark.well_architected_framework_sec06, 17 | benchmark.well_architected_framework_sec08, 18 | benchmark.well_architected_framework_sec09, 19 | benchmark.well_architected_framework_sec10, 20 | benchmark.well_architected_framework_sec11 21 | ] 22 | 23 | tags = local.well_architected_framework_security_common_tags 24 | } 25 | -------------------------------------------------------------------------------- /well_architected_framework/well_architected_framework.pp: -------------------------------------------------------------------------------- 1 | locals { 2 | well_architected_framework_common_tags = merge(local.aws_well_architected_common_tags, { 3 | type = "Benchmark" 4 | }) 5 | } 6 | 7 | benchmark "well_architected_framework" { 8 | title = "AWS Well-Architected Framework" 9 | description = "The AWS Well-Architected Framework describes key concepts, design principles, and architectural best practices for designing and running workloads in the cloud. By answering a few foundational questions, learn how well your architecture aligns with cloud best practices and gain guidance for making improvements." 10 | documentation = file("./well_architected_framework/docs/well_architected_framework_overview.md") 11 | 12 | children = [ 13 | benchmark.well_architected_framework_operational_excellence, 14 | benchmark.well_architected_framework_reliability, 15 | benchmark.well_architected_framework_security 16 | ] 17 | 18 | tags = local.well_architected_framework_common_tags 19 | } 20 | --------------------------------------------------------------------------------