자 이제 bastion host를 비롯해서 세개의 EC2를 띄웠으니 api gateway를 이용해서 요청을 라우팅해주는 api gateway를 설정해보겠습니다.
resource "aws_api_gateway_rest_api" "meme_gateway" {
name = "MemeGateway"
endpoint_configuration {
types = ["REGIONAL"]
}
}
먼제 이런식으로 api gateway중 rest api 를 먼저 생성해줍니다.
=> can be configured via importing an OpenAPI specification in the body argument (이방식 사용 x)
=> other Terraform resources to manage the resources (aws_api_gateway_resource resource), methods (aws_api_gateway_method resource), integrations (aws_api_gateway_integration resource), etc.(이방식)
name - (Required) Name of the REST API.
policy - (Optional) JSON formatted policy document that controls access to the API Gateway.
endpoint_configuration
types - (Required) List of endpoint types. This resource currently only supports managing a single value.
Valid values: EDGE, REGIONAL or PRIVATE. If unspecified, defaults to EDGE. If set to PRIVATE recommend to set put_rest_api_mode = merge to not cause the endpoints and associated Route53 records to be deleted.
=> When API requests predominantly originate from an EC2 instance or services within the same region as the API is deployed, a regional API endpoint will typically lower the latency of connections and is recommended for such scenarios.
위와 같은 이유때문에 regional 을 사용하였습니다.
resource "aws_api_gateway_resource" "api" {
parent_id = aws_api_gateway_rest_api.meme_gateway.root_resource_id
rest_api_id = aws_api_gateway_rest_api.meme_gateway.id
path_part = "api"
}
resource "aws_api_gateway_resource" "proxy" {
rest_api_id = aws_api_gateway_rest_api.meme_gateway.id
parent_id = aws_api_gateway_resource.v1.id
path_part = "{proxy+}"
}
rest_api_id - (Required) ID of the associated REST API
parent_id - (Required) ID of the parent API resource
path_part - (Required) Last path segment of this API resource.
이런식으로 본인에게 맞는 resource를 생성해주면 됩니다
저는 이런식의 api gateway구성을 위해 여러개의 resource와 method를 생성했습니다.
resource "aws_api_gateway_method" "signup_method" {
rest_api_id = aws_api_gateway_rest_api.meme_gateway.id
resource_id = aws_api_gateway_resource.signup_proxy.id
http_method = "ANY"
authorization = "NONE"
request_parameters = {
"method.request.path.proxy" = true
}
}
이런식으로 method생성을 하였습니다.
rest_api_id - (Required) ID of the associated REST API
resource_id - (Required) API resource ID
http_method - (Required) HTTP Method (GET, POST, PUT, DELETE, HEAD, OPTIONS, ANY)
authorization - (Required) Type of authorization used for the method (NONE, CUSTOM, AWS_IAM, COGNITO_USER_POOLS)
authorizer_id - (Optional) Authorizer id to be used when the authorization is CUSTOM or COGNITO_USER_POOLS
authorization_scopes - (Optional) Authorization scopes used when the authorization is COGNITO_USER_POOLS
request_parameters - (Optional) Map of request parameters (from the path, query string and headers) that should be passed to the integration. The boolean value indicates whether the parameter is required (true) or optional (false). For example: request_parameters = {"method.request.header.X-Some-Header" = true "method.request.querystring.some-query-param" = true} would define that the header X-Some-Header and the query string some-query-param must be provided in the request.
resource와 method를 모두 설정하였다면 이제 통합을 해야한다
resource "aws_api_gateway_integration" "SignUpIntegration" {
rest_api_id = aws_api_gateway_rest_api.meme_gateway.id
resource_id = aws_api_gateway_resource.signup_proxy.id
http_method = aws_api_gateway_method.signup_method.http_method
type = "HTTP_PROXY"
uri = "http://${aws_eip.meme_auth_ec2.public_ip}:8080/api/v1/signup/{proxy}"
integration_http_method = "ANY"
timeout_milliseconds = 29000
cache_key_parameters = ["method.request.path.proxy"]
request_parameters = {
"integration.request.path.proxy" = "method.request.path.proxy"
}
}
rest_api_id - (Required) ID of the associated REST API.
resource_id - (Required) API resource ID.
http_method - (Required) HTTP method (GET, POST, PUT, DELETE, HEAD, OPTION, ANY) when calling the associated resource.
integration_http_method - (Optional) Integration HTTP method (GET, POST, PUT, DELETE, HEAD, OPTIONs, ANY, PATCH) specifying how API Gateway will interact with the back end. Required if type is AWS, AWS_PROXY, HTTP or HTTP_PROXY. Not all methods are compatible with all AWS integrations. e.g., Lambda function can only be invoked via POST.
type - (Required) Integration input's type. Valid values are HTTP (for HTTP backends), MOCK (not calling any real backend), AWS (for AWS services), AWS_PROXY (for Lambda proxy integration) and HTTP_PROXY (for HTTP proxy integration). An HTTP or HTTP_PROXY integration with a connection_type of VPC_LINK is referred to as a private integration and uses a VpcLink to connect API Gateway to a network load balancer of a VPC.
api gateway를 배포하기 위해서는 다음 aws_api_gateway_deployment의 리소스를 생성해야한다
resource "aws_api_gateway_deployment" "meme_gateway" {
depends_on = [
aws_api_gateway_integration.ApiV0Integration, aws_api_gateway_integration.ApiV1Integration,
aws_api_gateway_integration.auth_integration, aws_api_gateway_integration.service_integration,
aws_api_gateway_integration.SignUpIntegration, aws_api_gateway_integration.ReissueIntegration,
aws_api_gateway_integration.LoginIntegration
]
rest_api_id = aws_api_gateway_rest_api.meme_gateway.id
stage_name = "prod"
}
rest_api_id - (Required) REST API identifier.
stage_name - (Optional) Name of the stage to create with this deployment. If the specified stage already exists, it will be updated to point to the new deployment. We recommend using the aws_api_gateway_stage resource instead to manage stages.
만약 요청에 authorizer를 추가하고싶다면
resource "aws_api_gateway_authorizer" "demo" {
name = "authorizer"
rest_api_id = aws_api_gateway_rest_api.meme_gateway.id
authorizer_uri = aws_lambda_function.terraform_lambda_func.invoke_arn
authorizer_credentials = aws_iam_role.invocation_role.arn
}```
이런식으로 authorizer를 추가하면 됩니다! 자세한 내용은 다음 글에서 소개하겠습니다.