# Customization guide for the AWS Well Architected Mod: Part 2

> Learn how to add support for a new pillar, Sustainability, using a custom control.

By Steampipe Team
Published: 2023-07-12


In [part 1](https://steampipe.io/blog/extend-well-architected-1) we showed how you can extend the [AWS Well-Architected](https://hub.steampipe.io/mods/turbot/aws_well_architected) mod with a benchmark that helps you assess your infrastructure for enviromental impacts targeted by the [Sustainability](https://docs.aws.amazon.com/wellarchitected/latest/framework/sustainability.html) pillar. The AWS Well-Architected mod is an example of how to [reuse and remix](https://steampipe.io/blog/remixing-dashboards) existing benchmarks and dashboards: it cherrypicks controls from [AWS Compliance](https://hub.steampipe.io/mods/turbot/aws_compliance) which provides more than 780 controls. The Sustainability benchmark we added in part 1 follows the same strategy: find and reuse existing controls. But what if you want to check something that isn't covered by an existing control? It's easy to add your own custom controls, and in this post we'll show you how.

The [SUS 4](https://docs.aws.amazon.com/wellarchitected/latest/framework/sus-04.html) section of the Well-Architected framework relates to data. One of the recommended best practices is [SUS04-BP02 Use technologies that support data access and storage patterns](https://docs.aws.amazon.com/wellarchitected/latest/framework/sus_sus_data_a3.html). To align with that best practice, you may want to take advantage of [S3 Intelligent-Tiering storage](https://aws.amazon.com/s3/storage-classes/intelligent-tiering/). There isn't yet an existing control that checks whether the feature is enabled for your S3 buckets. So let's create one!


## Fork and clone the AWS Well-Architected mod

To get started, create a [fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo#forking-a-repository) of the mod in your GitHub account. Then clone it.

```
git clone https://github.com/judell/steampipe-mod-aws-well-architected
cd steampipe-mod-aws-well-architected
```

 And install the dependent mod, AWS Compliance.

```
$ steampipe mod install

Installed 1 mod:

aws_well_architected
└── github.com/turbot/steampipe-mod-aws-compliance@v0.67.0
```

If you do nothing else at this point, running `steampipe dashboard` will display both AWS Compliance and AWS Well-Architected just as happens when you use the AWS Well-Architected mod directly.

<div style={{"width":"60%"}}>

![waf 01](/images/blog/2023-06-extending-well-architected/waf-01.png)

</div>

## Define a new second-level benchmark for the Sustainability pillar

The existing pillars live in subdirectories of `well-architected-framework`. Create a new subdirectory there, called `sustainability`, and within it a new file, `sustainability.sp`:

```
locals {
  well_architected_framework_sustainability_common_tags = merge(local.well_architected_framework_common_tags, {
    pillar_id = "sustainability"
  })
}

benchmark "well_architected_framework_sustainability" {
  title       = "sustainability"
  description = "The Sustainability pillar addresses the long-term environmental, economic, and societal impact of your business activities."
  children    = [
    benchmark.well_architected_framework_sus04
  ]

  tags = local.well_architected_framework_sustainability_common_tags
}
```

We've yet to define `benchmark.well_architected_framework_sus04`. But first, refer to the new benchmark from the top-level `well_architected_framework.sp`:

```
benchmark "well_architected_framework" {
  title         = "AWS Well-Architected Framework"
  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."
  documentation = file("./well_architected_framework/docs/well_architected_framework_overview.md")

  children = [
    benchmark.well_architected_framework_operational_excellence,
    benchmark.well_architected_framework_reliability,
    benchmark.well_architected_framework_security,
    benchmark.well_architected_framework_sustainability
  ]

  tags = local.well_architected_framework_common_tags
}
```

## Define a third-level benchmark for a topic

Now create a new file, `sus04.sp`, which defines `benchmark.well_architected_framework_sus04` as cited above.

```
locals {
  well_architected_framework_sus04_common_tags = merge(local.well_architected_framework_sustainability_common_tags, {
    question_id = "sus_data"
  })
}

benchmark "well_architected_framework_sus04" {
  title       = "SUS04 How do you take advantage of data management policies and patterns to support your sustainability goals?"
  description = "Implement data management practices to reduce the provisioned storage required to support your workload, and the resources required to use it. Understand your data, and use storage technologies and configurations that more effectively support the business value of the data and how it’s used. Lifecycle data to more efficient, less performant storage when requirements decrease, and delete data that’s no longer required."
  children    = [
    control.s3_buckets_use_intelligent_tiering
  ]

  tags = merge(local.well_architected_framework_sus04_common_tags, {
    choice_id = "sus_sus_data_a3"
  })
}
```

Refer to the [Aligning tags](https://steampipe.io/blog/extend-well-architected-1#aligning-tags) to see how you can use the [aws_wellarchitected_answer](https://hub.steampipe.io/plugins/turbot/aws/tables/aws_wellarchitected_answer) table to find values for `question_id` and `choice_id`.

If we were cherrypicking existing controls, their names would be fully qualified in the `children` list. In part 1, for example, we reused a control from the [AWS Thrifty](https://hub.steampipe.io/mods/turbot/aws_thrifty) mod like so. 

```
  children = [
    aws_thrifty.control.ecs_cluster_low_utilization,
  ]
```

In this case, our custom control belongs to the mod we're creating so we don't need to fully qualify its name. Note that, as per this example from [the documentation](https://steampipe.io/docs/mods/mod-dependencies#mod-dependencies), you can mix both flavors in a benchmark's `children` list:

```
benchmark "my_mod_public_resources" {
  title       = "Public Resources"
  description = "Resources that are public."
  children = [
    aws_compliance.control.dms_replication_instance_not_publicly_accessible,
    aws_compliance.control.s3_bucket_restrict_public_write_access,
    control.my_mod_public_ec2,
  ]
}
```

## Define a new control

We've defined the `well_architected_framework_sus04` benchmark to expect a control called `s3_buckets_use_intelligent_tiering`. Like all controls, it will be powered by a query that returns [three required columns](https://steampipe.io/docs/reference/mod-resources/control#required-control-columns): `status`, `reason`, and `resource`. Here's a query that enumerates S3 buckets, and joins with the [aws_s3_bucket_intelligent_tiering_configuration] (https://hub.steampipe.io/plugins/turbot/aws/tables/aws_s3_bucket_intelligent_tiering_configuration) table.

```
query "s3_buckets_use_intelligent_tiering" {
  sql = <<EOQ
    select
      b.name as resource,
      case when i.status = 'Enabled' then 'ok' else 'alarm' end as status,
      case when i.status = 'Enabled' 
        then b.name || ' uses intelligent tiering.'
        else b.name || ' does not use intelligent tiering.'
      end as reason,
      b.account_id,
      b.region
    from
      aws_s3_bucket b
    left join
      aws_s3_bucket_intelligent_tiering_configuration i 
    on 
      b.name = i.bucket_name
  EOQ
}
```

The new control refers to that query.

```
control "s3_buckets_use_intelligent_tiering" {
  title         = "Use S3 intelligent tiering"
  description   = "S3 buckets should use intelligent tiering"
  query         = query.s3_buckets_use_intelligent_tiering
}
```

Per the [documentation](https://steampipe.io/docs/reference/mod-resources/control), a control can use either `query = ` as we're doing here to refer to a separately-defined query, or `sql =` to include the query within the control. We recommend the `query` approach, so that a query like `s3_buckets_use_intelligent_tiering` is also avaiable in other contexts.

And voilà! The new benchmark is up and running.

![benchmark with custom control](/images/blog/2023-07-extending-well-architected-2/intelligent-tiering-benchmark.png)

## Next steps

You can, of course, use your fork of the Well-Architected mod privately. But we hope you'll want to contribute new mappings that improve the Well-Architected mod for everyone. For example, here's a [pull request](https://github.com/turbot/steampipe-mod-aws-well-architected/pull/29) for the new benchmark and custom control we've defined here.

Do you have other ideas for extending the Well-Architected mod? Give them a try and [let us know](https://steampipe.io/community/join) how it goes!




