简体   繁体   中英

how to edit index html file after creating website s3 and apigateway via teraform?

this tf code creates s3 that will host website. Index file has old api endpoint. It creates s3 bucket, edits for static hosting, and uploads 4 s3 objects.

resource "aws_s3_bucket" "frontend_vote" {
  bucket = "frontend-bucket-${var.vote}-${var.def_region}"
}

resource "aws_s3_bucket_policy" "frontend_vote_s3_bucket_policy" {
  bucket     = aws_s3_bucket.frontend_vote.id
  policy     = data.aws_iam_policy_document.frontend_vote_s3_bucket_policy.json
  depends_on = [aws_s3_bucket.frontend_vote]

}

data "aws_iam_policy_document" "frontend_vote_s3_bucket_policy" {
  statement {
    sid = "PublicReadGetObject"

    principals {
      type        = "*"
      identifiers = ["*"]
    }

    actions = [
      "s3:GetObject"
    ]

    resources = ["${aws_s3_bucket.frontend_vote.arn}/*"]

  }

  statement {
    actions   = ["s3:GetObject"]
    resources = ["${aws_s3_bucket.frontend_vote.arn}/*"]

    principals {
      type        = "AWS"
      identifiers = [aws_cloudfront_origin_access_identity.frontend_vote_cloudfront_oai.iam_arn]
    }
  }

}

resource "aws_cloudfront_origin_access_identity" "frontend_vote_cloudfront_oai" {
  comment    = "frontend_vote origin"
  depends_on = [aws_s3_bucket.frontend_vote]
}

resource "aws_s3_bucket_ownership_controls" "frontend_vote-bucket-ownership" {
  bucket = aws_s3_bucket.frontend_vote.id

  rule {
    object_ownership = "BucketOwnerEnforced"
  }

  depends_on = [aws_s3_bucket.frontend_vote]
}

resource "aws_s3_bucket_website_configuration" "frontend_vote-static" {
  bucket = aws_s3_bucket.frontend_vote.bucket

  index_document {
    suffix = "index.html"
  }

  depends_on = [aws_s3_bucket.frontend_vote, aws_s3_object.index_file_vote]

}

resource "aws_s3_object" "index_file_vote" {
  bucket = aws_s3_bucket.frontend_vote.id
  key    = "index.html"
  source = "./vote/index.html"

  depends_on = [aws_s3_bucket.frontend_vote]

}

resource "aws_s3_object" "myicon_vote" {
  bucket = aws_s3_bucket.frontend_vote.id
  key    = "myicon.png"
  source = "./vote/myicon.png"

  depends_on = [aws_s3_bucket.frontend_vote]

}

resource "aws_s3_object" "stylecss_vote" {
  bucket = aws_s3_bucket.frontend_vote.id
  key    = "style.css"
  source = "./vote/style.css"

  depends_on = [aws_s3_bucket.frontend_vote]
}

then apigateway is created via tf, 2 routes, 2 integrations:

# ###########################################
# # api gateway
# ###########################################

resource "aws_apigatewayv2_api" "main_apigateway" {
  name          = var.apigateway_name
  protocol_type = "HTTP"
  cors_configuration {
    allow_credentials = false
    allow_headers     = ["accept", "content-type"]
    allow_methods = [
      "GET",
      "OPTIONS",
      "POST",
    ]
    allow_origins = [
      # "*",
      "https://${aws_cloudfront_distribution.cloudfront_result.domain_name}",
      "https://${aws_cloudfront_distribution.cloudfront_vote.domain_name}"
    ]
    expose_headers = []
    max_age        = 0
  }
}

resource "aws_apigatewayv2_stage" "default" {
  api_id      = aws_apigatewayv2_api.main_apigateway.id
  name        = "$default"
  auto_deploy = true
}

# ###########################################
# # VOTE lambda backend integration
# ###########################################

resource "aws_apigatewayv2_integration" "vote_integration" {
  api_id = aws_apigatewayv2_api.main_apigateway.id
  # integration_uri  = aws_lambda_function.vote_lambda_backend.invoke_arn
  integration_uri        = aws_lambda_function.vote_lambda_backend.arn
  integration_type       = "AWS_PROXY"
  payload_format_version = "2.0"

}

resource "aws_apigatewayv2_route" "vote_route" {
  api_id    = aws_apigatewayv2_api.main_apigateway.id
  route_key = "POST /voting"
  target    = "integrations/${aws_apigatewayv2_integration.vote_integration.id}"
}


# resource "aws_iam_role_policy_attachment" "vote_policy_basic_execution_attachment" {
#   role       = aws_iam_role.vote_lambda_iam_role.name
#   policy_arn = "arn:aws:iam:aws:policy/service-role/AWSLambdaBasicExecutionRole"
# }


resource "aws_lambda_permission" "vote_permission" {
  statement_id  = "AllowExecutionFromAPIGateway"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.vote_lambda_backend.function_name
  principal     = "apigateway.amazonaws.com"
  source_arn    = "${aws_apigatewayv2_api.main_apigateway.execution_arn}/*/*/voting"
}

# ###########################################
# # RESULT lambda backend integration
# ###########################################

resource "aws_apigatewayv2_integration" "result_integration" {
  api_id = aws_apigatewayv2_api.main_apigateway.id
  # integration_uri  = aws_lambda_function.result_lambda_backend.invoke_arn
  integration_uri        = aws_lambda_function.result_lambda_backend.arn
  integration_type       = "AWS_PROXY"
  payload_format_version = "2.0"
}

resource "aws_apigatewayv2_route" "result_route" {
  api_id    = aws_apigatewayv2_api.main_apigateway.id
  route_key = "GET /results"
  target    = "integrations/${aws_apigatewayv2_integration.result_integration.id}"
}


resource "aws_lambda_permission" "result_permission" {
  statement_id  = "AllowExecutionFromAPIGateway"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.result_lambda_backend.function_name
  principal     = "apigateway.amazonaws.com"
  source_arn    = "${aws_apigatewayv2_api.main_apigateway.execution_arn}/*/*/results"
}

that new api endpoint i want to put it in my index.html. How to replace old api with newly created one? Via bash?

index file:

<!DOCTYPE html>
<html>
  < SOME CODE>
        

    <script>
    
      var backend_url = "https://5y7dfynd34.execute-api.us-east-1.amazonaws.com/voting" #this backend is old 


       SOME OTHER CODE
    </script>
  </body>
</html>

I dont think using environm vars like in terraform aws_lambda will work here.

You can pass variable to template file.

Lets convert your index.html to index.html.tpl on vote directory.

index.html.tpl

<!DOCTYPE html>
<html>
  <SOME CODE>
        

    <script>
    
      var backend_url = ${backend_api_url}

       SOME OTHER CODE
    </script>
  </body>
</html>

Then you can pass variable to template file with templatefile function. You just need to change from source to content in your resource.

resource "aws_s3_object" "index_file_vote" {
    bucket = aws_s3_bucket.frontend_vote.id
    key    = "index.html"
    content = templatefile("./vote/index.html.tpl", {
        backend_api_url = var.your_backend_api_url
    })
  
    depends_on = [aws_s3_bucket.frontend_vote] 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM