milliHQ / terraform-aws-next-js

Terraform module for building and deploying Next.js apps to AWS. Supports SSR (Lambda), Static (S3) and API (Lambda) pages.
https://registry.terraform.io/modules/milliHQ/next-js/aws
Apache License 2.0
1.47k stars 151 forks source link

tf-next deploy command outputs broken URL #342

Closed PythonMove closed 2 years ago

PythonMove commented 2 years ago

Hi,

I am trying out for the first time this package (latest canary version). I am struggling to deploy a nextJS 12 application. The deployment command outputs success but the URL is clearly wrong:

milliVolt CLI 1.0.0-canary.4

success Deployment package uploaded
success Deployment ready
> Available at: https://94f8427d66a59c30fff70cbdf335d36cundefined/ (copied to clipboard) 

When I go to the cloudfront alias URL, I get 500 with Code: PROXY_MISSING_CONFIG. I haven't found any proxy configuration documentation, and google also is not helpful, so I am in dark here. Has anyone encountered the issue so far and resolved this?

I am using tf-next installed locally in the project folder. Here are steps that I have taken:

terraform init
TF_VAR_stage='dev' terraform plan -out tfplan
terraform apply tfplan
npx tf-next@canary build
npx tf-next@canary deploy --endpoint https://REDACTED.execute-api.eu-central-1.amazonaws.com

Terraform deployment was successful. Both tf-next build and deploy commands were also successful, but as you can see above, the URL is broken.

This is my terraform configuration at main.tf:

########################################################################################################################
# Terraform
########################################################################################################################
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}

########################################################################################################################
# Providers
########################################################################################################################
# Main region where the resources should be created in
# Should be close to the location of your viewers
provider "aws" {
  region = "eu-central-1"
}

# Provider used for creating the Lambda@Edge function which must be deployed
# to us-east-1 region (Should not be changed)
provider "aws" {
  alias  = "global_region"
  region = "us-east-1"
}

########################################################################################################################
# Variables
########################################################################################################################
variable "stage" {
  description = "Project stage."
  default     = "dev"
  type        = string

  validation {
    condition = contains(["dev", "staging", "production"], var.stage)
    error_message = "Allowed stages are: dev, staging and production."
  }
}

########################################################################################################################
# Locals
########################################################################################################################
locals {
  custom_domain_zone_name = "redacted-zone-name"
  custom_domain = var.stage == "production" ? "redacted.production.domain" : "${var.stage}-redacted.development.domain"
  # A wildcard domain(ex: *.example.com) has to be added when using atomic deployments:
  aliases = [local.custom_domain]
}

########################################################################################################################
# Data
########################################################################################################################
# Get the hosted zone for the custom domain
data "aws_route53_zone" "custom_domain_zone" {
  name = local.custom_domain_zone_name
}

# Get the ACM certificate to be used with CloudFront
data "aws_acm_certificate" "cloudfront_acm_certificate" {
  provider = aws.global_region

  domain      = "*.redacted.domain"
  types       = ["AMAZON_ISSUED"]
  most_recent = true
}

########################################################################################################################
# Terraform Next.js Module
########################################################################################################################
module "tf_next" {
  source  = "milliHQ/next-js/aws"
  version = "1.0.0-canary.4"

  cloudfront_aliases             = local.aliases
  cloudfront_acm_certificate_arn = data.aws_acm_certificate.cloudfront_acm_certificate.arn

  deployment_name = "redacted-deployment-name"

  providers = {
    aws.global_region = aws.global_region
  }
}

########################################################################################################################
# Resources
########################################################################################################################
# Create a new record in Route 53 for the domain
resource "aws_route53_record" "cloudfront_alias_domain" {
  for_each = toset(local.aliases)

  zone_id = data.aws_route53_zone.custom_domain_zone.zone_id
  name    = each.key
  type    = "A"

  alias {
    name                   = module.tf_next.cloudfront_domain_name
    zone_id                = module.tf_next.cloudfront_hosted_zone_id
    evaluate_target_health = false
  }
}

########################################################################################################################
# Outputs
########################################################################################################################
output "api_endpoint" {
  value = module.tf_next.api_endpoint
}

output "api_endpoint_access_policy_arn" {
  value = module.tf_next.api_endpoint_access_policy_arn
}
ofhouse commented 2 years ago

Sorry for the late reply, seems that the custom domain was not set correctly on the tf_next module, since the required parameters for enable_multiple_deployments and multiple_deployments_base_domain are missing in your configuration.

Adding them should fix the setup:

########################################################################################################################
# Terraform Next.js Module
########################################################################################################################
module "tf_next" {
  source  = "milliHQ/next-js/aws"
  version = "1.0.0-canary.4"

  cloudfront_aliases             = local.aliases
  cloudfront_acm_certificate_arn = data.aws_acm_certificate.cloudfront_acm_certificate.arn

  deployment_name = "redacted-deployment-name"

+ enable_multiple_deployments      = true
+ multiple_deployments_base_domain = "*.redacted.domain"

  providers = {
    aws.global_region = aws.global_region
  }
}
PythonMove commented 2 years ago

Hi,

Thank you for the response. Changes to the main.tf proposed by you indeed helped. Thank you very much!

With that said, I have another question If I may. The current tf_next module looks like this:

module "tf_next" {
  source  = "milliHQ/next-js/aws"
  version = "1.0.0-canary.5"

  create_image_optimization = false

  enable_multiple_deployments      = true
  multiple_deployments_base_domain = local.acm_certificate_domain

  cloudfront_aliases             = local.aliases
  cloudfront_acm_certificate_arn = data.aws_acm_certificate.cloudfront_acm_certificate.arn

  deployment_name = "redacted-deployment-name"

  providers = {
    aws.global_region = aws.global_region
  }
}

On the deployed website, some images are not being loaded (404 from S3). Images that were loaded, were imported in NextJS components in .css files, while files that were not loaded, were imported in .tsx files. Do you think this can be an issue in the tf-next source code, or my codebase?

ofhouse commented 2 years ago

If your code relies on the image component (next/image), it is currently not supported by the v1.0.0-canary version (only works for the previous version v0.x).

Support for it is tracked here: #339

PythonMove commented 2 years ago

Thanks for the response.

Indeed, the code relies on the image component. I will look forward to the support of image components. This concludes all my questions, thank you for your support :)