Amazon API Gateway の REST API に Amazon Cognito 認証を追加する検証をしてみた

まずは Amazon API Gateway の REST API を Terraform で構築

provider "aws" {
  region = "ap-northeast-1"
}

resource "aws_api_gateway_rest_api" "example" {
  name = "example"
}

resource "aws_api_gateway_resource" "example" {
  rest_api_id = aws_api_gateway_rest_api.example.id
  parent_id   = aws_api_gateway_rest_api.example.root_resource_id
  path_part   = "example"
}

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

resource "aws_api_gateway_integration" "example" {
  rest_api_id             = aws_api_gateway_rest_api.example.id
  resource_id             = aws_api_gateway_resource.example.id
  http_method             = aws_api_gateway_method.example.http_method
  type                    = "HTTP_PROXY"
  integration_http_method = "GET"
  uri                     = "http://inet-ip.info/json"
}

resource "aws_api_gateway_deployment" "example" {
  rest_api_id = aws_api_gateway_rest_api.example.id

  triggers = {
    redeployment = sha1(jsonencode([
      aws_api_gateway_resource.example.id,
      aws_api_gateway_method.example.id,
      aws_api_gateway_integration.example.id,
    ]))
  }

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_api_gateway_stage" "example" {
  deployment_id = aws_api_gateway_deployment.example.id
  rest_api_id   = aws_api_gateway_rest_api.example.id
  stage_name    = "v1"
}

output "api_invoke_url" {
  value = aws_api_gateway_stage.example.invoke_url
}
terraform init

terraform plan

terraform apply -auto-approve

Curl で REST API にアクセスして動作確認

curl -s $(terraform output api_invoke_url | jq -r .)/example | head
{
 "ipAddress": "35.75.130.11",
 "asn": {
  "AutonomousSystemNumber": 16509,
  "AutonomousSystemOrganization": "AMAZON-02"
 },
 "city": {
  "City": {
   "GeoNameID": 1850147,
   "Names": {

Amazon Cognito を Terraform に追加

resource "aws_cognito_user_pool" "example" {
  name = "example"
}

resource "aws_cognito_resource_server" "example" {
  name         = "example"
  identifier   = "https://${aws_api_gateway_rest_api.example.id}.execute-api.ap-northeast-1.amazonaws.com/"
  user_pool_id = aws_cognito_user_pool.example.id

  scope {
    scope_name        = "all"
    scope_description = "Get access to all API Gateway endpoints."
  }
}

resource "aws_cognito_user_pool_client" "example" {
  name                                 = "example"
  user_pool_id                         = aws_cognito_user_pool.example.id
  generate_secret                      = true
  allowed_oauth_flows                  = ["client_credentials"]
  supported_identity_providers         = ["COGNITO"]
  allowed_oauth_flows_user_pool_client = true
  allowed_oauth_scopes                 = aws_cognito_resource_server.example.scope_identifiers
}

output "client_id" {
  value = aws_cognito_user_pool_client.example.id
}

output "client_secret" {
  value     = aws_cognito_user_pool_client.example.client_secret
  sensitive = true
}

resource "aws_api_gateway_authorizer" "example" {
  name          = "example"
  type          = "COGNITO_USER_POOLS"
  rest_api_id   = aws_api_gateway_rest_api.example.id
  provider_arns = ["${aws_cognito_user_pool.example.arn}"]
}

resource "aws_cognito_user_pool_domain" "example" {
  domain       = "mnrst"
  user_pool_id = aws_cognito_user_pool.example.id
}

Amazon API Gateway の Method に Amazon Cognito 認証を追加

resource "aws_api_gateway_method" "example" {
  rest_api_id          = aws_api_gateway_rest_api.example.id
  resource_id          = aws_api_gateway_resource.example.id
  http_method          = "GET"
#   authorization        = "NONE"
  authorization        = "COGNITO_USER_POOLS"
  authorizer_id        = aws_api_gateway_authorizer.example.id
  authorization_scopes = aws_cognito_resource_server.example.scope_identifiers
}
terraform plan

terraform apply -auto-approve

マネージメントコンソールで Deploy API 後に動作確認

curl -s $(terraform output api_invoke_url | jq -r .)/example | head
{"message":"Unauthorized"}

Amazon Cognito からアクセストークンを取得して REST API にアクセス

CLIENT_ID=$(terraform output client_id | jq -r .)
CLIENT_PW=$(terraform output client_secret | jq -r .)
COGNITO_EP=https://mnrst.auth.ap-northeast-1.amazoncognito.com

TOKEN=$(curl -s "$COGNITO_EP/oauth2/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=$CLIENT_ID&client_secret=$CLIENT_PW" \
  | jq -r .access_token)

curl -s $(terraform output api_invoke_url | jq -r .)/example \
  -H "Authorization: Bearer $TOKEN" | head
{
 "ipAddress": "3.112.162.176",
 "asn": {
  "AutonomousSystemNumber": 16509,
  "AutonomousSystemOrganization": "AMAZON-02"
 },
 "city": {
  "City": {
   "GeoNameID": 1850147,
   "Names": {

検証が終わったら後片付け

terraform destroy -auto-approve
タグ: , , ,