├── .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 | 
7 |
8 | Or in a terminal:
9 | 
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 |
--------------------------------------------------------------------------------