Cost Optimization With Cloud Blueprints and Guardrails

AUTHOR
Chris Reuter
PUBLISH DATE
October 24, 2024

Cloud services have enabled several paradigm shifts: faster development, new product possibilities, and entire new companies & industries.

However, the elasticity and low barrier to entry of cloud services also can result in cost impact. The usage-based model can result in cloud spend that is higher than expected (see 1, 2, 3).

As we have progressed along the cloud maturity curve, providers (AWS, GCP, Azure) now support a wide variety of use cases and customers with their services. This means that any given use case can involve several resources and hundreds of parameters. Included in these parameters are many cost-sensitive settings:

  • VM instance size or type
  • Storage type
  • Monitoring and logging
  • DR/backup
  • Region and availability

Groups responsible for monitoring and controlling cloud spend are typically central teams, overlayed across lines of business or organizational units. While this gives them broad visibility and responsibility, it also means that they are often several degrees from individual developers who are making and implementing cloud configuration decisions.

Given their distance from developer workflows, FinOps and Cloud Economics teams need a way to inject sensible cost decisions into developer workflows without getting in the way. Many of these cost decisions are highly context-dependent: consider the instance sizes and settings you might allow in a test environment versus a production environment, for example.

How Resourcely fits in

Resourcely Blueprints and Guardrails enable FinOps and Cloud Economics teams to save money and control spend with Guardrails. For example, restrict the use of costly EC2 instance sizes in non-production environments and control unnecessary logging and monitoring on RDS instances.

Guardrails are policies that restrict developer inputs at configuration time, as well as blocking infrastructure creation as part of a company’s CI/CD pipeline. These policies are written using Really, Resourcely’s policy-as-code language built for infrastructure.

Blueprints are created by platform, infrastructure, or DevOps teams: giving developers a recommended pattern for deploying cloud resources. You can read more about Blueprints here. With a Blueprint, creators can determine what fields developers are exposed to while hardcoding other fields.

The combination of Blueprints and Guardrails can be utilized to give varying level of guidance or control to central teams.

Example: Adding descriptions and defaults to an EC2 Blueprint (basic cost guidance)

We’ll start by giving a developer light guidance with a description and default on a cost-sensitive field. Consider an AWS EC2 instance created using Terraform:


resource "aws_instance" "my-ec2-instance" {
  ami           = "ami-005e54dee72cc1d00" # AMI from AWS docs
  instance_type = "t3.micro"
}

Turn this Terraform into a Resourcely Blueprint with the addition of {{ variables }}. Copy the below Blueprint into Foundry to see the form that is created


---
constants:
  __name: "{{ name }}_{{ __guid }}"
---

resource "aws_instance" "{{ __name }}" {
  ami           = "ami-005e54dee72cc1d00" # AMI from AWS docs
  instance_type = "{{ instance_type | default: "t3.micro" | desc: "AWS instance type. Best practice is to use .micro instances unless in production." }}"

// This is for demonstration purposes only

In the resulting form on the Developer Experience tab, you can see that instance type is exposed as a choice to a developer. This is a potentially impactful choice, especially given the cost of 16xlarge instance sizes. We have added a default instance type, and a description to give developers more information to help them make a decision.

We are not yet restricting input values at all, and is an example of giving light guidance to developers. Save your Blueprint and add some metadata, to make it available for future use.

Adding cost optimization Guardrails (Intermediate cost guidance)

Let’s increase our level of guidance by utilizing the following Guardrail:


GUARDRAIL "Prevent Large AWS instance sizes"
  WHEN aws_instance
    REQUIRE instance_type NOT MATCHES "*large*"
  OVERRIDE WITH APPROVAL @default

Navigate to Foundry, create a new Guardrail, and copy the above code into the editor. Add metadata and save it. If you navigate back to the Blueprint that you just created, you’ll now see this Guardrail is exposed within your developer form (represented by the lock).

The populated instance type list has been restricted to remove any instance types of size large or greater.

Developers can “unlock” the Guardrail to choose an instance type that violates our policy. However, this PR will be blocked as part of our CI process:

Guardrails allow FinOps teams to review and approve (or reject) any potentially costly infrastructure changes, even if they are changes that happen outside of Resourcely.

Making our guidance strict or contextual (Advanced cost guidance)

It is possible to make our guidance even more custom:

Hardcoding our golden patterns

Sometimes a team will want to allow only a single parameter, without giving teams the ability to make changes. Hardcoding a value in a Blueprint will not expose it to developers. In the below Blueprint example, only a name variable will be exposed. This allows cost-sensitive companies to mandate cost-reducing parameters without giving developers the ability to deviate.


---
constants:
  __name: "{{ name }}_{{ __guid }}"
---

resource "aws_instance" "{{ __name }}" {
  ami           = "ami-005e54dee72cc1d00" # AMI from AWS docs
  instance_type = "t3.micro" # We hardcoded our instance type value here
}

// This is for demonstration purposes only

Context-driven Guardrails

Guardrails can be optionally applied using context, which allows for branching logic. Let’s say you want to only allow (expensive) enhanced monitoring on a database when the environment is production. Otherwise, when the environment is not production, we want to not allow enhanced monitoring.


GUARDRAIL "Disallow enhanced monitoring for non-prod environments"
  WHEN aws_db_instance AND CONTEXT env != "prod"
    REQUIRE monitoring_interval = 0

When environment is test, a Guardrail is enabled and enforced on our form and during CI. Developers can’t choose a monitoring_interval ≠ 0, and if they do it will fail during their pipeline. This saves us the cost of enhanced monitoring for inconsequential applications:

When environment is production, our Guardrail disappears and developers are free to choose a monitoring_interval (therefore enabling enhanced monitoring):

Try them out for yourself

Cost optimization is of growing importance at companies who find their cloud spend increasing. Resourcely gives FinOps, Cloud Economics, and other spend-concious teams the ability to govern cloud spend without slowing developers down or causing unnecessary friction.

You can improve your cloud spend posture with Resourcely, free! Sign up at https://portal.resourcely.io., and take advantage of these pre-built cost optimization resources.

Ready to get started?

Set up a time to talk to our team to get started with Resourcely.

Get in touch

More posts

View all
August 29, 2024

Configuration Perspectives: AWS RDS

Your guide to configuring RDS with many stakeholders
November 11, 2024

Configuration perspectives: AWS S3

Best practices for configuring S3 using Terraform, while taking into account input from a variety of stakeholders

Talk to a Human

See Resourcely in action and learn how it can help you secure and manage your cloud infrastructure today!