Skip to content

Commit

Permalink
Miguelhar.ocr (#292)
Browse files Browse the repository at this point in the history
  • Loading branch information
miguelhar authored Nov 19, 2024
1 parent bedae2f commit b59f5ef
Show file tree
Hide file tree
Showing 5 changed files with 213 additions and 0 deletions.
106 changes: 106 additions & 0 deletions modules/capacity-reservation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# capacity-reservation

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.7.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | ~> 5.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | ~> 5.0 |
| <a name="provider_terraform"></a> [terraform](#provider\_terraform) | n/a |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [aws_ec2_capacity_reservation.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_capacity_reservation) | resource |
| [terraform_data.describe_capacity_reservation](https://registry.terraform.io/providers/hashicorp/terraform/latest/docs/resources/data) | resource |
| [aws_availability_zone.zone_ids](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zone) | data source |
| [aws_ec2_instance_type_offerings.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ec2_instance_type_offerings) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_instance_capacity"></a> [instance\_capacity](#input\_instance\_capacity) | Creates a capacity reservation for each instance\_type on each zone.<br> instance\_types = List of instance types to create a capacity reservation for.<br> capacity = Number of instances to reserve<br> availability\_zone\_ids = List of azs to create a capacity reservation in.<br> } | <pre>map(object({<br> instance_types = list(string)<br> capacity = number<br> availability_zone_ids = list(string)<br> }))</pre> | `{}` | no |
| <a name="input_region"></a> [region](#input\_region) | AWS region for the deployment | `string` | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_capacity_reservation"></a> [capacity\_reservation](#output\_capacity\_reservation) | Capacity Reservations information. |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

## Usage

Create the following files:
* `main.tf`. :warning: Update with intended module version(using `main` in the example below).
* `capacity.auto.tfvars`. :warning: Update with appropriate values.

`main.tf`

```hcl
variable "instance_capacity" {
description = "Additional EKS managed node groups definition."
type = map(object({
instance_types = list(string)
capacity = number
availability_zone_ids = list(string)
}))
default = {}
}
variable "region" {
default = "us-west-2"
}
module "capacity_reservation" {
source = "github.com/dominodatalab/terraform-aws-eks.git//modules/capacity-reservation?ref=main"
instance_capacity = var.instance_capacity
region = var.region
}
output "capacity_reservation" {
value = module.capacity_reservation.capacity_reservation
}
provider "aws" {
region = var.region
}
```

`capacity.auto.tfvars`

```hcl
region = "us-west-2"
instance_capacity = {
custom_1 = {
availability_zone_ids = ["usw2-az1", "usw2-az4"]
capacity = 4
instance_types = ["trn1.2xlarge"]
}
custom_2 = {
availability_zone_ids = ["usw2-az1", "usw2-az4"]
capacity = 4
instance_types = ["i4i.32xlarge"]
}
custom_3 = {
availability_zone_ids = ["usw2-az1", "usw2-az3"]
capacity = 4
instance_types = ["p3.8xlarge"]
}
}
```
67 changes: 67 additions & 0 deletions modules/capacity-reservation/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
locals {
capacity_reservations = merge(flatten([
for ng_name, ng in var.instance_capacity : [
for az_id in ng.availability_zone_ids : {
for type in ng.instance_types : "${type}-${az_id}" => {
capacity = ng.capacity
instance_type = type
az = data.aws_availability_zone.zone_ids[az_id].name
}
}
]
])...)
zone_ids = toset(flatten([for ng in var.instance_capacity :
ng.availability_zone_ids
]))

instance_types = toset([for cr in local.capacity_reservations : cr.instance_type])
}

data "aws_availability_zone" "zone_ids" {
for_each = local.zone_ids
zone_id = each.key
}


data "aws_ec2_instance_type_offerings" "this" {
for_each = local.instance_types

filter {
name = "instance-type"
values = [each.key]
}

location_type = "availability-zone"
}


resource "aws_ec2_capacity_reservation" "this" {
for_each = local.capacity_reservations
instance_type = each.value.instance_type
instance_platform = "Linux/UNIX"
availability_zone = each.value.az
instance_count = each.value.capacity

lifecycle {
precondition {
condition = contains(data.aws_ec2_instance_type_offerings.this[each.value.instance_type].locations, each.value.az)
error_message = <<-EOM
Instance type ${each.value.instance_type} is NOT available in availability_zone ${each.value.az}.
available = ${jsonencode(data.aws_ec2_instance_type_offerings.this[each.value.instance_type].locations)}
EOM
}
}
}

resource "terraform_data" "describe_capacity_reservation" {
for_each = aws_ec2_capacity_reservation.this

provisioner "local-exec" {
command = <<EOT
aws ec2 describe-capacity-reservations --capacity-reservation-ids ${each.value.id} --region ${var.region}
EOT
interpreter = ["/bin/bash", "-c"]
}

depends_on = [aws_ec2_capacity_reservation.this]
}
4 changes: 4 additions & 0 deletions modules/capacity-reservation/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
output "capacity_reservation" {
description = "Capacity Reservations information."
value = aws_ec2_capacity_reservation.this
}
27 changes: 27 additions & 0 deletions modules/capacity-reservation/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

variable "instance_capacity" {
description = <<EOF
Creates a capacity reservation for each instance_type on each zone.
instance_types = List of instance types to create a capacity reservation for.
capacity = Number of instances to reserve
availability_zone_ids = List of azs to create a capacity reservation in.
}
EOF
nullable = false
type = map(object({
instance_types = list(string)
capacity = number
availability_zone_ids = list(string)
}))
default = {}
}

variable "region" {
type = string
description = "AWS region for the deployment"
nullable = false
validation {
condition = can(regex("(us(-gov)?|ap|ca|cn|eu|sa|me|af)-(central|(north|south)?(east|west)?)-[0-9]", var.region))
error_message = "The provided region must follow the format of AWS region names, e.g., us-west-2, us-gov-west-1."
}
}
9 changes: 9 additions & 0 deletions modules/capacity-reservation/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_version = ">= 1.7.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

0 comments on commit b59f5ef

Please sign in to comment.