12
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

朝日新聞社Advent Calendar 2024

Day 4

Terraformを使用して、API Gatewayでrobots.txtを返す

Last updated at Posted at 2024-12-03

CTO室の尾崎です。
最近は、インフラの構成や設定をコード化するIaCツールがいくつかありますが、
今回は、Terraformを使用して、API Gatewayでrobots.txtを返すプログラムを紹介します。

API Gateway、Lambdaなどを使ってサーバレスな構成でAPIやWebページを公開する際、
検索エンジンにサイトマップなど正しくサイトをクロールさせたい、あるいは、クロール不要なページが引っかかってほしくないなどあると思います。

そんな時には、robots.txtをWebページに設置して、さまざまな検索エンジンのクローラーに対して指示することができます。
robots.txtはWebページのクローラーに対する指示を記述するためのファイルです。
別途Lambda関数を定義して、robots.txtを返すこともできるのですが、
今回はAPI Gatewayのみでrobots.txtを返す手順をご紹介します。
robots.txtの詳細な仕様については以下をご参照ください。
https://developers.google.com/search/docs/crawling-indexing/robots/intro?hl=ja

Terraformの環境

TerraformはApple MacBook Air(M2)の環境で以下のバージョンで動作確認しました。

$ terraform -v
Terraform v1.7.4
on linux_arm64
+ provider registry.terraform.io/hashicorp/archive v2.4.2
+ provider registry.terraform.io/hashicorp/aws v5.37.0

API Gatewayの作成

今回は、TerraformでAPI Gatewayを定義しています。apigateway.tfというファイルを作成し、次のように記述します。

resource "aws_api_gateway_rest_api" "my_api" {
  name        = "my-api"
  description = "My API Gateway"

  endpoint_configuration {
    types = ["REGIONAL"]
  }
}

resource "aws_api_gateway_resource" "robots" {
  rest_api_id = aws_api_gateway_rest_api.my_api.id
  parent_id   = aws_api_gateway_rest_api.my_api.root_resource_id
  path_part   = "robots.txt"
}

resource "aws_api_gateway_method" "robots_method" {
  rest_api_id   = aws_api_gateway_rest_api.api.id
  authorization = "NONE"
  http_method   = "GET"
  resource_id   = aws_api_gateway_resource.robots.id
}

resource "aws_api_gateway_method_response" "robots_response" {
  rest_api_id = aws_api_gateway_rest_api.api.id
  resource_id = aws_api_gateway_resource.robots.id
  http_method = aws_api_gateway_method.robots_method.http_method
  status_code = "200"
  response_models = {
    "text/plain" = "Empty"
  }
}

resource "aws_api_gateway_integration" "robots_integration" {
  rest_api_id             = aws_api_gateway_rest_api.api.id
  resource_id             = aws_api_gateway_resource.robots.id
  http_method             = aws_api_gateway_method.robots_method.http_method
  type                    = "MOCK"
  request_templates = {
    "application/json" = <<EOF
{"statusCode" : 200}
EOF
  }
}

resource "aws_api_gateway_integration_response" "robots_integration_response" {
  rest_api_id = aws_api_gateway_rest_api.api.id
  resource_id = aws_api_gateway_resource.robots.id
  http_method = aws_api_gateway_method.robots_method.http_method
  status_code = aws_api_gateway_method_response.robots_response.status_code

  response_templates = {
    "text/plain" = <<EOF
User-agent: *
Disallow: /
EOF
  }
}

この設定では、「my-api」という名前のAPI Gatewayと、その中にrobots.txtというパスを持つリソースをGETメソッドで作成しています。
Typeを「MOCK」にして、モック統合することにより、バックエンドにLambdaを利用することなく、API Gatewayのみでレスポンスを生成できます。
ステータスコード200 OK を返すように定義し、統合レスポンスの定義に、テキストとして、robots.txtの内容を記述します。
今回は、サイト全体のクロールを許可しない設定で記述しています。
このあたりは、サイトの方針に沿って書き換えていただければと思います。

robots.txt
User-agent: *
Disallow: /

この構成により、GET リクエストが /robots.txt に届いたときにrobots.txtが返るようになります。

デプロイの設定

以上の変更をAPI Gatewayに適用するため、apigateway.tfにaws_api_gateway_deploymentリソースを使って以下を追記しデプロイできるようにします。

resource "aws_api_gateway_deployment" "my_api_deployment" {
  depends_on = [
    aws_api_gateway_integration.robots_integration,
    aws_api_gateway_method.robots_method
  ]

  rest_api_id = aws_api_gateway_rest_api.my_api.id
  stage_name  = "production"
}

以上でTerraformを使ってAWS API Gatewayでrobots.txtを返す設定ができます。
このTerraform設定を適用するには、terraform initで初期化を行い、terraform applyでリソースをAWSにデプロイします。

ご参考までに、TerraformのAWSプロバイダーの詳細なドキュメントはTerraform Registryを確認してください。

デプロイしたら、ブラウザなどで
/robots.txtにアクセスしてみて、robots.txtが表示されるか確認してみてください。

12
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?