AWS Cloud Operations Blog

Customize Well-Architected Reviews using Custom Lenses and the AWS Well-Architected Tool

The AWS Well-Architected Tool (AWS WA Tool) lets you learn best practices for architecting workloads on the cloud, measure workloads against these best practices, and improve the workload by implementing best practices. These best practices have been curated under the AWS Well-Architected Framework (AWS WA Framework) and Lenses based on our tens of thousands of customer interactions, as well as lessons learned from building AWS services. In addition to best practices from the AWS WA Framework, organizations might need to customize or extend these best practices specifically for their workloads.

Custom lenses let you incorporate organizational and internal best practices (i.e., governance, legal, compliance) into a AWS WA Review in addition to the AWS WA Framework. This gives you a central location to measure how well your workloads incorporate best practices. The launch of custom lenses means that you can create your own pillars, questions and best practices, helpful resources, and improvement plans.

In this post, I walk through how to author custom lenses and import them into the AWS WA Tool. Then, I will show you how to use a custom lens in addition to the AWS WA Framework to review your workloads.

Create custom lenses

The AWS WA Tool makes it easy to create custom lenses by providing a template that you can use. The template outlines how the lens content must be defined, and it controls how the lens is presented within the AWS WA Tool.

I start by navigating to the AWS WA Tool on the AWS Management Console, and selecting Custom lenses. Since I do not have any custom lenses created, I choose to Create custom lens.

Custom lenses section of the AWS WA Tool console

I download the template to get started.

Create custom lens wizard

The downloaded template tells me how to structure the custom lens content, as well as all of the fields that must be filled out. The Lens format specification provides detailed information on the different fields available and how to use them.

{
	"schemaVersion": "2021-11-01",
	"name": "Replace with lens name",
	"description": "Replace with your description",
	"pillars": [{
		"id": "pillar_id_1",
		"name": "Pillar 1",
		"questions": [{
			"id": "pillar_1_q1",
			"title": "My first question",
			"description": "Description isn't a necessary property here for a question, but it might help your lens users.",
			"choices": [{
				"id": "choice1",
				"title": "Best practice #1",
				"helpfulResource": {
					"displayText": "It's recommended that you include a helpful resource text and URL for each choice for your users.",
					"url": "https://aws.amazon.com“
				},
				"improvementPlan": {
					"displayText": "You must have improvement plans per choice. It's optional whether or not to have a corresponding URL."
				}
			}, {
				"id": "choice2",
				"title": "Best practice #2",
				"helpfulResource": {
					"displayText": "It's recommended that you include a helpful resource text and URL for each choice for your users.",
					"url": "https://aws.amazon.com“
				},
				"improvementPlan": {
					"displayText": "You must have improvement plans per choice. It's optional whether or not to have a corresponding URL."
				}
			}],
			"riskRules": [{
				"condition": "choice1 && choice2",
				"risk": "NO_RISK"
			}, {
				"condition": "choice1 && !choice2",
				"risk": "MEDIUM_RISK"
			}, {
				"condition": "default",
				"risk": "HIGH_RISK"
			}]
		}]
	}]
}

Using the template, I first enter some metadata for the custom lens, such as giving it a name and a description. This helps users understand the purpose of this custom lens.

"schemaVersion": "2021-11-01",
"name": "Lambda lens",
"description": "Best practices for developing and deploying AWS Lambda functions.",

Then, I define three pillars to include in this lens – Operational Excellence, Security, and Performance Efficiency. You can use different pillar names, or specify a different number of pillars depending on your use-case.

"pillars": [{
        "id": "lambda_ops",
        "name": "Operational Excellence"
    },
    {
        "id": "lambda_sec",
        "name": "Security"
    },
    {
        "id": "lambda_perf",
        "name": "Performance"
    }
]

Now that the pillars have been defined, I create questions and best practices (choices) for each pillar. I start with the Operational Excellence pillar, and define a question with three possible choices having choice IDs – ops_q1_choice1, ops_q1_choice2, and ops_q1_choice3. To provide additional context for the best practices, I’ve provided a short description for each best practice under helpfulResource. Furthermore, I specify an improvement plan for each choice. This provides guidance to users of this custom lens on how to implement the corresponding choice (best practice). I can also include multiple links for both helpfulResource and improvementPlan that point to documentation that will help users understand the best practices better, as well as provide more guidance as part of the improvement plans. Lastly, I create rules for how users’ choices are evaluated, and what risk rating is generated for this question.

"questions": [{
	"id": "lambda_ops_q1",
	"title": "How do you understand the health of your Lambda functions?",
	"description": "In distributed environments such as serverless architectures, observability is key to understanding if the workload is behaving as expected.",
	"choices": [{
			"number": 1,
			"id": "ops_q1_choice1",
			"title": "Review metrics and establish alarms.",
			"helpfulResource": {
				"displayText": "Configure your functions so appropriate metrics and logs are generated. Use this data to establish thresholds and create alerts when these thresholds are exceeded.",
				"url": "https://docs.aws.amazon.com/lambda/latest/dg/monitoring-metrics.html"
			},
			"improvementPlan": {
				"displayText": "Ensure that you have reviewed your Lambda function metrics and created appropriate alarms.",
				"url": "https://docs.aws.amazon.com/wellarchitected/latest/serverless-applications-lens/best-practices.html#metrics-and-alerts"
			}
		},
		{
			"number": 2,
			"id": "ops_q1_choice2",
			"title": "Publish insightful logs.",
			"helpfulResource": {
				"displayText": "Your Lambda functions should generate logs that helps with understanding the activity that took place during function execution. DO NOT USE generic log statements like 'something broke'.",
				"url": "https://docs.aws.amazon.com/lambda/latest/dg/python-logging.html"
			},
			"improvementPlan": {
				"displayText": "Ensure that your functions are publishing logs in a standardized format and with enough detail to help understand the activities that took place during function execution.",
				"url": "https://docs.aws.amazon.com/wellarchitected/latest/serverless-applications-lens/best-practices.html#centralized-and-structured-logging"
			},
			"additionalResources": [{
					"type": "HELPFUL_RESOURCE",
					"content": [{
							"displayText": "AWS Lambda function logging in Java",
							"url": "https://docs.aws.amazon.com/lambda/latest/dg/java-logging.html"
						},
						{
							"displayText": "AWS Lambda function logging in Node.js",
							"url": "https://docs.aws.amazon.com/lambda/latest/dg/nodejs-logging.html"
						}
					]
				},
				{
					"type": "IMPROVEMENT_PLAN",
					"content": [{
						"displayText": "Complexities and Best Practices for AWS Lambda Logging",
						"url": "https://aws.amazon.com/blogs/apn/complexities-and-best-practices-for-aws-lambda-logging/"
					}]
				}
			]
		},
		{
			"number": 3,
			"id": "ops_q1_choice3",
			"title": "Enable distributed tracing",
			"description": "For this choice, there are additional details that I can provide that are relevant for understanding this choice.",
			"helpfulResource": {
				"displayText": "Due to the distributed nature of serverless architectures, it is important to have distributred tracing.",
				"url": "https://aws.amazon.com/xray/"
			},
			"improvementPlan": {
				"displayText": "Use services like AWS X-Ray to enable distributed tracing and visual service maps.",
				"url": "https://docs.aws.amazon.com/wellarchitected/latest/serverless-applications-lens/best-practices.html#distributed-tracing"
			}
		}
	],
	"riskRules": [{
		"condition": "ops_q1_choice1 && ops_q1_choice2 && ops_q1_choice3",
		"risk": "NO_RISK"
	}, {
		"condition": "ops_q1_choice1 && (ops_q1_choice2 || ops_q1_choice3)",
		"risk": "MEDIUM_RISK"
	}, {
		"condition": "default",
		"risk": "HIGH_RISK"
	}]
}]

I follow this process to define questions and best practices for the other pillars in the custom lens. Once the lens has been authored, I will import it into the AWS WA Tool so that I can use it to review workloads. Importing it is as simple as selecting the custom lens JSON file and uploading it on the AWS WA Tool console.

Additionally, I can add tags to the custom lens to help with resource management. In this case, I have specified LoB (Line of Business) as the tag key and Retail as the tag value to ensure that users are aware that this custom lens is intended for the Retail business only.

Tag and upload custom lens file to AWS WA Tool

The WA Tool also provides the capability to preview the custom lens before publishing it. This allows me to verify the “look and feel” of the custom lens, the helpful resources available for the best practices defined, the rules evaluation, and the improvement plans, without having to apply the custom lens to a workload first. Using the preview, I can select different combinations of best practices for each question and ascertain that the improvement plan being generated is accurate. Depending on the improvement plans generated during the preview, I can edit my custom lens template to update the rules for how user choices are evaluated, upload the new file and preview changes until the custom lens is exactly what I had envisioned. This makes custom lens development very efficient.

Preview of the custom lens on the AWS WA Tool

Once I am satisfied with the custom lens, I exit out of the preview and the custom lens is now available on the AWS WA Tool with a status of DRAFT, and my AWS account ID listed as the owner.

Custom lens uploaded with a status of DRAFT

The custom lens must be published before it can be used to review workloads. I select the Lambda lens, which is currently under DRAFT, and select Publish lens. I enter a version for the custom lens that I have uploaded, and select Publish. The version helps end users identify which lens version is currently applied to a workload.

When making updates to the custom lens, you can select if you want to make a major or minor version change. Major version changes should typically be used for substantial changes that impact the custom lens meaning. These changes notify users of the previous lens version that a new version is available, but they aren’t automatically applied to workloads using the lens. Minor version changes are suited for small changes, such as text changes or updates to the URL, and they’re automatically applied to workloads using the custom lens. See Publishing an update to a custom lens to learn more about making major and minor changes and publishing updates to a custom lens.

Specify version name for custom lens

The custom lens has been published as indicated by PUBLISHED under status, along with the version number that I provided. Now, I can start reviewing workloads using this custom lens.

New custom lens that was created is available for use

Review workloads using custom lenses

I will define a new workload on the AWS WA Tool, and then apply this custom lens to it. Review  the walkthrough of the AWS WA Tool to learn how to define new workloads. On the Apply lenses page, I can see the custom lens that I just created. Note that you can distinguish between official AWS content and custom lenses by looking at the Author field. I will select the custom lens, and then finish defining the workload.

Apply newly created custom lens when defining a new workload

Now that the workload has been defined, I will start reviewing it using the custom lens.

Start reviewing the workload using the custom lens

I can see the pillars that I defined on the left. Expanding the Operational Excellence pillar displays the question that I entered in the custom lens file, along with the choices/best practices that I provided for the question.

Questions, best practices, and pillars from the custom lens on the AWS WA tool when reviewing a workload

Selecting Info next to the best practices shows the help text that was specified under helpfulResource in the custom lens JSON file to provide users with additional context regarding the best practice.

Helpful resources defined in the custom lens as it appears during a review of a workload using the custom lens

Now I can measure my workload against my custom lens and select which best practices I am currently performing from each of my custom questions. After I complete my custom lens review, I will be presented with my various risks based on how I answered each question (defined in the riskRules section of the JSON template). I have answered all three questions in the custom lens, and the workload appears to have one High Risk.

3/3 questions answered from the custom lens, one High Risk detected, and zero Medium risks

Breakdown of risks across different pillars. One High Risk in the Operational Excellence pillar. No risks in the other pillars.

I can drill down to see the spread of risks across different pillars/topics. It appears that the High risk is in the Operational Excellence pillar.

Finally, I can review the improvement plans that provide guidance for how to implement those missing best practices. This is the custom improvement plan that was specified for each best practice in the custom lens JSON file.

Improvement plan for the High Risk

Share custom lenses

The AWS WA Tool supports sharing custom lenses with other AWS accounts and AWS Identity and Access Management (IAM) users, AWS Organizations, and organization units (OUs). This lets you scale these best practices across different teams within your organization.

To share custom lenses with AWS accounts or IAM users, I navigate to the Custom lenses section of the AWS WA Tool, and select the lens that I want to share. Then, I specify the 12-digit AWS account ID or ARN of the IAM user, or both, and select Create. Note that lenses must be in the Published state before they can be shared.

Create custom lens share wizard with AWS Account ID entered for IAM Principals

I can also share the custom lens with an entire AWS Organization or individual OUs following a similar process.

Create custom lens share wizard with Grant permissions to the entire Organization selected

After creating the custom lens share, I can review the status of the custom lens share invite by visiting the Shares tab for the custom lens. I see that the invite is still Pending.

Status of the custom lens share is Pending

Accept a custom lens share

The lens share request must be accepted by the other AWS account or IAM user before it can be used. To do this, I switch to the account that I shared the lens with, and navigate to the Share invitations section of the AWS WA Tool console. I see the share invitation for the custom lens, and I can choose to Accept or Reject. Since I know the source of the custom lens (me), I will Accept the invite.

Custom lens share invitation on the second AWS account

Navigating to the Custom lenses section, under the Shared with me tab, I can see that the custom lens is now available to use in this AWS account. I can apply this lens and use it to review workloads as described earlier in this post.

Custom lens shared listed under "Shared with me" tab on the custom lenses section of the AWS WA Tool on the second AWS account

Conclusion

In this post, I walked through how to create custom lenses within the AWS WA Tool to extend the best practice guidance provided by the AWS WA Framework, and also meet the governance needs of your organization. With the ability to share custom lenses across different AWS accounts, IAM users, and AWS Organizations, you can scale standards and best practices across multiple teams from a central location.

For more information on using custom lenses on the AWS WA Tool, visit:

About the author

Mahanth Jayadeva

Mahanth Jayadeva is a Solutions Architect at Amazon Web Services (AWS) on the AWS Well-Architected team. He works with customers and AWS Partner Network partners of all sizes to help them build secure, high-performing, resilient, and efficient infrastructure for their applications. He spends his free time playing with his pup, Cosmo, and learning more about astronomy. He is an avid gamer.