# VPC Endpoint

### VPC Endpoint 역할

* VPC Endpoint는 다른 AWS 서비스를 사용할 때 AWS 내부망을 사용하여 내부 통신을 하고자 할 때 사용합니다.
* VPC Endpoint를 사용하면 인터넷을 타고 나가지 않기 때문에 외부로부터 통신을 안전하게 보호할 수 있고, 내부망을 타기 때문에 속도가 향상될 수 있습니다.
* <https://docs.aws.amazon.com/ko_kr/vpc/latest/userguide/vpc-endpoints.html>

### Gateway형 Endpoint

* 인터넷으로 API통신을 하는 S3와 DynamoDB는 Gateway 형으로 Endpoint가 생성됩니다.&#x20;
* Gateway형 Endpoint는 따로 보안그룹을 생성하실 필요가 없습니다.

### Interface 형 Endpoint

* 기타 서비스들은 Interface형으로 Endpoint를 생성하실 수 있습니다.
* Interface형 Endpoint는 별도로 보안그룹이 필요합니다.
* 보안그룹은 기본적으로 443포트 인바운드를 허용해주시면 됩니다.&#x20;
* 본 실습에서는 API Gateway와 Secrets Manager에 대한 VPC Endpoint를 생성하도록 하겠습니다.

```hcl
# Gateway Type Endpoint ( S3, DynamoDB )
## S3 Endpoint
resource "aws_vpc_endpoint" "s3_endpoint" {
  vpc_id       = aws_vpc.default.id
  service_name = "com.amazonaws.${var.aws_region}.s3"
  
  tags = {
   Name = "s3-${var.shard_id}"
  }
}

# Add vpc endpoint to route table of private subnet
resource "aws_vpc_endpoint_route_table_association" "s3_endpoint_routetable" {
  count           = length(var.availability_zones)
  vpc_endpoint_id = aws_vpc_endpoint.s3_endpoint.id
  route_table_id  = aws_route_table.private[count.index].id
}


## DynamoDB Endpoint
resource "aws_vpc_endpoint" "dynamodb_endpoint" {
  vpc_id       = aws_vpc.default.id
  service_name = "com.amazonaws.${var.aws_region}.dynamodb"

  tags = {
   Name = "dynamodb-${var.shard_id}"
  }
}

# Add vpc endpoint to route table of private subnet
resource "aws_vpc_endpoint_route_table_association" "dynamodb_endpoint_routetable" {
  count           = length(var.availability_zones)
  vpc_endpoint_id = aws_vpc_endpoint.dynamodb_endpoint.id
  route_table_id  = aws_route_table.private[count.index].id
}


# Interface Type Endpoint 
# Security Group of VPC Endpoint (API Gateway)
resource "aws_security_group" "apigateway_vpc_endpoint_sg" {
  name = "apigateway_vpc_endpoint-${var.vpc_name}"
  vpc_id = aws_vpc.default.id

  ingress {
    from_port = 443
    to_port = 443
    protocol = "TCP"

    cidr_blocks = [
      "10.0.0.0/8"
    ]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["10.0.0.0/8"]
    description = "Internal outbound any traffic"
  }

  tags = {
    Name = "apigateway-${var.vpc_name}"
  }
}

## API Gateway Endpoint
resource "aws_vpc_endpoint" "apigateway_endpoint" {
  vpc_id            = aws_vpc.default.id
  service_name      = "com.amazonaws.${var.aws_region}.execute-api"
  vpc_endpoint_type = "Interface"

  security_group_ids = [
    aws_security_group.apigateway_vpc_endpoint_sg.id
  ]

  private_dns_enabled = true
  auto_accept         = true

  tags = {
   Name = "apigateway-${var.shard_id}"
  }
}

resource "aws_vpc_endpoint_subnet_association" "apigateway_endpoint" {
  count           = length(var.availability_zones)
  vpc_endpoint_id = aws_vpc_endpoint.apigateway_endpoint.id
  subnet_id       = element(aws_subnet.private.*.id, count.index)
}

## Secrets Manager Endpoint
# Security Group of VPC Endpoint (Secrets Manager)
resource "aws_security_group" "secretsmanager_vpc_endpoint_sg" {
  name = "secretsmanager_vpc_endpoint-${var.vpc_name}"
  vpc_id = aws_vpc.default.id

  ingress {
    from_port = 443
    to_port = 443
    protocol = "TCP"

    cidr_blocks = [
      "10.0.0.0/8"
    ]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["10.0.0.0/8"]
    description = "Internal outbound any traffic"
  }

  tags = {
    Name = "secretsmanager-${var.vpc_name}"
  }
}

# Secrets Manager VPC Endpoint
resource "aws_vpc_endpoint" "secretsmanager_endpoint" {
  vpc_id = aws_vpc.default.id
  service_name = "com.amazonaws.${var.aws_region}.secretsmanager"
  vpc_endpoint_type = "Interface"

  security_group_ids = [
    aws_security_group.secretsmanager_vpc_endpoint_sg.id
  ]

  private_dns_enabled = true
  auto_accept = true

  tags = {
   Name = "secretsmanager-${var.shard_id}"
  }
}

resource "aws_vpc_endpoint_subnet_association" "secretsmanager_endpoint" {
  count           = length(var.availability_zones)
  vpc_endpoint_id = aws_vpc_endpoint.secretsmanager_endpoint.id
  subnet_id = aws_subnet.private[count.index].id
}
```

Terraform apply를 하시고 콘솔에서 확인해보시면 Endpoint가 생성된 것을 확인하실 수 있습니다.&#x20;

<figure><img src="/files/IU59H122xvOioKYwGYMa" alt=""><figcaption></figcaption></figure>

라우팅 테이블을 확인해보면, Gateway형 Endpoint가 추가되어 있는 것을 보실 수 있습니다.

<figure><img src="/files/m2lbXkKfIu5QGYk026gt" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://terraform201.devart.tv/1.-vpc/vpc-endpoint.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
