Skip to content

Commit

Permalink
add documentation, prep for some new tags
Browse files Browse the repository at this point in the history
  • Loading branch information
badra001 committed May 11, 2026
1 parent 1d8c7db commit e664365
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 1 deletion.
106 changes: 106 additions & 0 deletions tags/main.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,110 @@
/* boc-nts :: tags
* # About
*
* This submodule allows one to easily set a number of tags, primarily the [finops tags](https://github.e.it.census.gov/terraform/cloud-information/blob/master/aws/documentation/naming-tagging-standard/tags/finops.md).
* Use of this module is **highly** recommended as it reduces errors from the wrong number of zeros in the finops project number, and does some validation
* checking as well. This takes as input a YAML file, but may also take the values in environment variables. A YAML file is recommended.
*
* ## Features
* * Formatting of FinOps Tags
* * project number
* * project name
* * project role
* * Merging legacy FinOps tags into new tag
* * Project Number
* * Project Name
* * ProjectRole
* * and many combinations
* * Migration Acceleration Program (MAP) Tagging
*
* These features are in progress.
*
* * CostAllocation
* * Environment
* * infrastructure
* * aws_organization
*
* ## YAML Fields
* ### finops
* This section takes four attributes
* * number: an integer corresponding to the assigned FinOps Project Number (>= 0)
* * name: string with the assigned FinOps Project Name (lowercase, underscores)
* * role: a string to append to the finops project name when used with a prefix of +, or to use verbatim. There is no need to
* repeat the same string in project name, simply use the + preix.
* * roles: a list of strings for which the module output `finops_roles[key]` will be created. We use this when we need
* to define a number of roles and make them selectable in the resource `tags()` attributes.
*
* ## Usage
*
* Create a terraform file such as `tags.tf` with the module call.
*
* ```hcl
* # tags.tf
* module "tags" {
* source = "git@github.e.it.census.gov:terraform-modules/boc-nts//tags"
* filename = format("%v/%v", path.root, "tags.yml")
*
* # optional, use to convert old finops and preserve Environemnt and CostAllocation tags
* legacy_tags = merge(
* var.account_tags,
* var.infrastructure_tags,
* var.application_tags,
* )
* }
* ```
*
* The module uses `tags.yml`, which looks like this:
*
* ```yaml
* # tags.yml
* finops:
* number: 31415
* name: org_app_env_sample
* roles:
* - lambda
* - log
* - parameter
* - role
* - s3
* - securitygroup
* ```
*
* Then, you'd use a couple of outputs of the module where tags would be present. Here is an example:
*
* ```hcl
* resource "aws_ssm_parameter" "config" {
* name = local.ssm_parameter_name
* description = format("Configuration parameter for %v", "my-parameter"
* type = "String"
* value = jsonencode({parameter="value"})
*
* tags = merge(
* local.base_tags,
* module.tags.tags,
* module.tags.finops_roles["parameter"],
* )
* }
* ```
*
* This will create a resoruce withe the following tags (assumes CostAllocation, Organization
* and Environment are set in the `var.*_tags` variables already:
*
* ```hcl
* tags = {
* "CostAllocation" = "directorate:org:app"
* "Organization" = "census:directorate:org"
* "boc:created_by" = "terraform"
* "finops_project_name" = "org_app_env_sample"
* "finops_project_number" = "fs0000031415"
* "finops_project_role" = "org_app_env_sample_parameter"
* }
* ```
*/

locals {
tags_in = var.filename != null && try(fileexists(var.filename), false) ? yamldecode(file(var.filename)) : yamldecode("{}")
tags_filenames_in = length(var.filenames) > 0 ? { for f in var.filenames : f => yamldecode(file(f)) if fileexists(f) } : {}
validity_checks = yamldecode(file("${path.module}/validity.yml"))
}


2 changes: 1 addition & 1 deletion tags/tags.finops.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ locals {
project_role = local._finops.role != null ? replace(replace(local._finops.role, "+", format("%v_", local._finops.name)), "/[^a-z0-9_]/", "") : null
}
finops_tags = { for k, v in local._finops_tags : k => v if v != null && k != "prefix" }
finops_roles = [for r in try(local.tags_in.finops["roles"], try(var.finops["roles"],[])) : lower(r)]
finops_roles = [for r in try(local.tags_in.finops["roles"], try(var.finops["roles"], [])) : lower(r)]
}

resource "terraform_data" "finops" {
Expand Down
54 changes: 54 additions & 0 deletions tags/tags.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
locals {
_infrastructure = length(try(local.tags_in.infrastructure, 0)) == 0 ? null : local.tags_in.infrastructure
_aws_organization = length(try(local.tags_in.aws_organization, 0)) == 0 ? null : local.tags_in.aws_organization
_cost_allocation = length(try(local.tags_in.cost_allocation, 0)) == 0 ? null : local.tags_in.cost_allocation
_environment = length(try(local.tags_in.environment, 0)) == 0 ? null : local.tags_in.environment
}

resource "terraform_data" "infrastructure" {
count = local._infrastructure != null ? 1 : 0
input = local._infrastructure

lifecycle {
precondition {
condition = contains(local.validity_checks.infrastructure, local._infrastructure)
error_message = "Invalid infrastructure organization."
}
}
}

resource "terraform_data" "aws_organization" {
count = local._aws_organization != null ? 1 : 0
input = local._aws_organization

lifecycle {
precondition {
condition = contains(local.validity_checks.aws_organization, local._aws_organization)
error_message = "Invalid AWS organization."
}
}
}

resource "terraform_data" "cost_allocation" {
count = local._cost_allocation != null ? 1 : 0
input = local._cost_allocation

lifecycle {
precondition {
condition = contains(local.validity_checks.cost_allocation, local._cost_allocation)
error_message = "Invalid AWS organization."
}
}
}

resource "terraform_data" "environment" {
count = local._environment != null ? 1 : 0
input = local._environment

lifecycle {
precondition {
condition = contains(local.validity_checks.environment, local._environment)
error_message = "Invalid AWS organization."
}
}
}
41 changes: 41 additions & 0 deletions tags/validity.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
aws_organization:
- ent-ew: 0
- ent-gov: 0
- lab-gov: 1
infrastructure:
- csvd: 0
- tco: 1
- ois: 2
environment:
- common
- cre
- dev
- ite
- prod
- qa
- sa
- services
- stage
- test
- uat
cost_allocation:
directorate:
- adcom
- addcp
- addp
- adep
- adfo
- adrm
- dir
- ocao
- ocfo
- ocio
- ppsi
category:
- core
- multi
- external
- shared
- cedsci
division:

0 comments on commit e664365

Please sign in to comment.