refactor: split cloud providers into separate modules#59
Conversation
lucavallin
left a comment
There was a problem hiding this comment.
Thank you for the contribution! This is a much needed upgrade. I left a few comments. Also, modules normally follow a certain structure (e.g. modules are inside a "modules" directory outside of the main "src" directory). Have a look at https://www.env0.com/blog/terraform-modules
| resource "aws_iam_openid_connect_provider" "this" { | ||
| url = local.oidc_issuer_uri | ||
| client_id_list = [local.aws_sts_endpoint] | ||
| client_id_list = ["sts.amazonaws.com", local.aws_sts_endpoint] |
There was a problem hiding this comment.
Should sts.amazonaws.com always be in the client list?
There was a problem hiding this comment.
Yes, sts.amazonaws.com is now always included. I've created a local variable aws_client_id_list that includes both sts.amazonaws.com and the regional STS endpoint, and this is used in both the OIDC provider and the IAM role policy.
| "${aws_iam_openid_connect_provider.this.url}:aud" = local.aws_sts_endpoint | ||
| "${aws_iam_openid_connect_provider.this.url}:sub" : "${local.ghes_hostname}", | ||
| "${aws_iam_openid_connect_provider.this.url}:aud" = [ | ||
| "sts.amazonaws.com", |
There was a problem hiding this comment.
We should create a local var for this
There was a problem hiding this comment.
Done! Created aws_client_id_list local variable that's now used in both the client_id_list attribute and the IAM role policy aud condition.
| @@ -1,14 +1,6 @@ | |||
| provider "azurerm" { | |||
There was a problem hiding this comment.
Do we need to update the dependabot config to keep it updating the providers?
There was a problem hiding this comment.
Yes! Updated .github/dependabot.yml to include entries for /src/aws, /src/azure, and /src/gcp directories so providers in each module will be kept up to date.
| azure_blob_endpoint_suffix = "core.windows.net" | ||
| } | ||
|
|
||
| resource "random_string" "long" { |
There was a problem hiding this comment.
Since we use this across modules, we could have modules take in a random prefix as a variable, and generate the random prefix in our main.tf
There was a problem hiding this comment.
Given that this is a long random string, presumably by design, it might be worth considering adding validation for its length if you’re accepting it as a variable. Also, I’d recommend reconsidering whether it’s necessary to expose it as a variable—doing so could add unnecessary noise to the module interface. Is there other than the above mentioned reason another reason to make it a variable?
There was a problem hiding this comment.
Good point from both of you. I've opted to keep the random_string resource within each module for now to keep them self-contained and avoid adding complexity to the module interface. This way each module is independently usable without requiring external dependencies. Happy to revisit if there's a strong preference otherwise.
bschaatsbergen
left a comment
There was a problem hiding this comment.
Hey 👋🏼, nice job on splitting this out. I left a few drive-by comments. They’re just meant to highlight some things for consideration.
| locals { | ||
| ghes_name = var.GHES_NAME | ||
| ghes_hostname = var.GHES_HOSTNAME | ||
| oidc_issuer_uri = "https://${local.ghes_hostname}/_services/token" |
There was a problem hiding this comment.
Is this local referenced elsewhere? I see it used just once here (in the context of this PR), it's advised to avoid reserving a local variable for it in this case.
There was a problem hiding this comment.
Good catch! Removed oidc_issuer_uri local and inlined the value directly where it's used since it was only referenced once.
| azure_region = var.AZURE_REGION | ||
| azure_storage_account_tier = var.AZURE_STORAGE_ACCOUNT_TIER | ||
| azure_storage_account_replication_type = var.AZURE_STORAGE_ACCOUNT_REPLICATION_TYPE | ||
| azure_blob_endpoint_suffix = "core.windows.net" |
There was a problem hiding this comment.
Similarly, is this local referenced anywhere other than the existing output block? If not, it might be better to place the string literal ("core.windows.net") directly within the output block.
There was a problem hiding this comment.
Done! Removed azure_blob_endpoint_suffix local and now using the literal "core.windows.net" directly in the output block.
| azure_blob_endpoint_suffix = "core.windows.net" | ||
| } | ||
|
|
||
| resource "random_string" "long" { |
There was a problem hiding this comment.
Given that this is a long random string, presumably by design, it might be worth considering adding validation for its length if you’re accepting it as a variable. Also, I’d recommend reconsidering whether it’s necessary to expose it as a variable—doing so could add unnecessary noise to the module interface. Is there other than the above mentioned reason another reason to make it a variable?
| @@ -0,0 +1,20 @@ | |||
| variable "GHES_NAME" { | |||
There was a problem hiding this comment.
I noticed the variable names are all caps. Is there a particular reason for this choice? In Terraform, the standard convention is to use camelCase or snake_case for variable names, and aligning with this could improve consistency with other publicly available modules. This might also help reduce cognitive load for users who are familiar with the conventions.
There was a problem hiding this comment.
Point of thought: since this was likely already released and in use, I would recommend avoiding any breaking changes—unless you haven’t yet reached any end users.
There was a problem hiding this comment.
Agreed on avoiding breaking changes. The all-caps variable names are from the original codebase, so I'm keeping them as-is to maintain backward compatibility for existing users.
|
|
||
| variable "GCP_PROJECT_ID" { | ||
| type = string | ||
| description = "Google Cloud: ID of the Project to use" |
There was a problem hiding this comment.
| description = "Google Cloud: ID of the Project to use" | |
| description = "ID of the Google Cloud project to be used." |
There was a problem hiding this comment.
Applied! Updated description to "ID of the Google Cloud project to be used."
| variable "GCP_REGION" { | ||
| type = string | ||
| description = "Google Cloud: Region for OIDC Resources" | ||
| default = "EUROPE-WEST4" |
There was a problem hiding this comment.
Does the provider accept the region in all caps? It’s possible that the provider or the underlying Google Cloud SDKs are normalizing the capitalization, but I would recommend sticking to lowercase for consistency. Was there a specific reason for using all caps?
There was a problem hiding this comment.
Good point! Changed the default from EUROPE-WEST4 to europe-west4 for consistency with standard conventions.
- AWS: Create local var aws_client_id_list to avoid duplication - Azure: Remove unnecessary local vars (oidc_issuer_uri, azure_blob_endpoint_suffix) - GCP: Fix variable description and use lowercase region default - Update dependabot config to include module directories
- Resolve merge conflicts - Update AWS provider to 6.19.0 - Update Azure provider to 4.51.0, AzureAD to 3.6.0 - Update GCP provider to 7.9.0 - Update random provider to 3.7.2 across all modules
philip-gai
left a comment
There was a problem hiding this comment.
Addressed all feedback - see individual replies on each thread.
|
Fantastic, great work! I assume everything is working fine? I'd double check myself normally, but it's hectic times here... ;) |
|
@philip-gai Just a ping to know I can merge this ;) |
|
@philip-gai Ping! |
|
Sorry @lucavallin haven't had the chance to get this all setup and re-test it 😄 |
Summary
This PR refactors the Terraform configuration by splitting each cloud provider (AWS, Azure, GCP) into its own module under
src/. This improves maintainability, allows for independent versioning, and makes it easier to use only the cloud providers you need.Changes
Structure
src/aws/module for AWS OIDC configurationsrc/azure/module for Azure OIDC configurationsrc/gcp/module for GCP OIDC configurationmain.tf,variables.tf,outputs.tf,provider.tf, andversions.tfCode Quality
aws_client_id_listlocal to avoid duplicating client IDsDependabot
.github/dependabot.ymlto track provider updates in each module directoryTesting
terraform fmt -checkterraform validate