Home > Net >  How can I re-use a configuration (local module) with my Terraform project?
How can I re-use a configuration (local module) with my Terraform project?

Time:02-01

I'm quite new to Terraform, so I guess I consider Terraform modules as "functions" that I can re-use but that's wrong. I had a scenario where I had to deploy a static web site to cloudfront and s3 bucket. At first, I configured this as raw files in my project: https://github.com/tal-rofe/tf-old/tree/main/terraform/core - you can see I have s3.tf and cloudfront.tf files, raw in my project.

But then I had to deploy an another static web application. So, because now I need 2 applications to be deployed, I could duplicate my code and create x-cloudfront.tf, x-s3.tf and y-cloudfront.tf, y-s3.tf files with same exact configuration, just differ with the domains I guess. So instead of doing so, I tried to create a module which creates s3 and cloudfront resources, and then in my project, I could re-use this module to create 2 web applications.

So I have this project: https://github.com/tal-rofe/tf-new

And here I created a module: https://github.com/tal-rofe/tf-new/tree/main/terraform/modules/static-app

As you can see I have variables.tf file:

variable "domain_name" {
  description = "The domain name of the application"
  type        = string
}

variable "zone_id" {
  description = "The zone identifier to set domain of the application in"
  type        = string
}

variable "acm_certificate_arn" {
  description = "The certificate ARN"
  type        = string
}

variable "s3_bucket_name" {
  description = "The bucket name of the S3 bucket for the application"
  type        = string
}

variable "common_tags" {
  description = "The tags for all created resources"
  type        = map(string)
  default     = {}
}

variable "cloudfront_tags" {
  description = "The tags for Cloudfront resource"
  type        = map(string)
}

variable "www_redirect_bucket_tags" {
  description = "The tags for a bucket to redirect www to non-www"
  type        = map(string)
}

variable "s3_bucket_tags" {
  description = "The tags for a bucket to redirect www to non-www"
  type        = map(string)
}

and output.tf file:

output "cloudfront_distribution_id" {
  description = "The distribution ID of deployed Cloudfront"
  value       = module.cdn.cloudfront_distribution_id
}

And all other files within this module are dedicated for setting up the relevant resources, using another public modules released. So If I do so, I could, in my project, to use this module twice, provide different inputs in each declaration, and get the cloudfront_distribution_id output from each.

This is why I have these 2 files, using this module: https://github.com/tal-rofe/tf-new/blob/main/terraform/core/docs-static.tf and https://github.com/tal-rofe/tf-new/blob/main/terraform/core/frontend-static.tf

And then, I want to output from my project the 2 created cloudfront distributions IDs:

output "frontend_cloudfront_distribution_id" {
  description = "The distribution ID of deployed Cloudfront frontend"
  value       = module.frontend-static.cloudfront_distribution_id
}

output "docs_cloudfront_distribution_id" {
  description = "The distribution ID of deployed Cloudfront docs"
  value       = module.docs-static.cloudfront_distribution_id
}

So when I start applying this whole project with terraform, I don't get these 2 outputs, but I only get one output, called cloudfront_distribution_id. So it seems like I get the output of the custom module I created. But I want to get the outputs of my main project.

So I don't understand what did I do wrong in providing this custom module?

I apply my configuration using GitHub action with these steps:

            - name: Terraform setup
              uses: hashicorp/setup-terraform@v2
              with:
                terraform_wrapper: false

            - name: Terraform core init
              env:
                  TERRAFORM_BACKEND_S3_BUCKET: ${{ secrets.TERRAFORM_BACKEND_S3_BUCKET }}
                  TERRAFORM_BACKEND_DYNAMODB_TABLE: ${{ secrets.TERRAFORM_BACKEND_DYNAMODB_TABLE }}
              run: |
                terraform -chdir="./terraform/core" init \
                -backend-config="bucket=$TERRAFORM_BACKEND_S3_BUCKET" \
                -backend-config="dynamodb_table=$TERRAFORM_BACKEND_DYNAMODB_TABLE" \
                -backend-config="region=$AWS_REGION"
                
            - name: Terraform core plan
              run: terraform -chdir="./terraform/core" plan -no-color -out state.tfplan

            - name: Terraform core apply
              run: terraform -chdir="./terraform/core" apply state.tfplan

CodePudding user response:

You are running terraform apply from the terraform/modules/static-app folder of your project. You need to be running it from the terraform/core folder.

You should always run terraform apply from within the core/root/base folder of your Terraform code.

  • Related