자습서: 제품 만들기 및 게시
적용 대상: 모든 API Management 계층
Azure API Management에서 제품에는 하나 이상의 API, 사용 할당량 및 사용 약관이 포함됩니다. 제품이 게시되면 개발자는 제품을 구독하고 제품의 API를 사용할 수 있습니다.
이 자습서에서는 다음을 하는 방법을 알아볼 수 있습니다.
- 제품 생성 및 게시
- 제품에 API 추가
- 제품 API에 액세스
필수 조건
- Azure API Management 용어를 익힙니다.
- 다음 빠른 시작 Azure API Management 인스턴스 만들기를 완료합니다.
- 또한, 다음 자습서 첫 번째 API 가져오기 및 게시를 완료합니다.
제품 생성 및 게시
Azure Portal에 로그인하고 API Management 인스턴스로 이동합니다.
왼쪽 탐색 창에서 제품>+ 추가를 선택합니다.
제품 추가 창에서, 다음 표에 설명된 값을 입력하여 제품을 만듭니다.
속성 설명 Display name 개발자 포털에 표시하려는 이름입니다. 설명 제품의 용도, 제품에서 액세스할 수 있는 API, 기타 정보 등 제품 정보를 입력합니다. State(상태) 개발자 포털에 제품을 게시하려면 게시를 선택합니다. 개발자가 제품의 API를 검색할 수 있으려면 먼저 제품을 게시해야 합니다. 기본값으로 새 제품은 게시되지 않습니다. 구독 필요 사용자가 제품을 사용하기 위해 구독해야 하고(제품이 보호됨) 제품의 API에 액세스하려면 구독 키를 사용해야 하는지 여부를 선택합니다. 구독이 필요하지 않은 경우(제품이 공개) 제품의 API에 액세스하는 데 구독 키가 필요하지 않습니다. 이 문서 뒷부분의 제품 API에 대한 액세스를 참조하세요. 승인 필요 관리자가 이 제품에 대한 구독 시도를 검토하고 허용하거나 거부하도록 하려면 선택합니다. 선택하지 않으면 구독 시도가 자동으로 승인됩니다. 구독 수 제한 필요하다면 여러 동시 구독의 수를 제한합니다. 약관 구독자가 제품을 사용하기 위해 허용해야 하는 제품의 사용 약관을 포함할 수 있습니다. API 하나 이상의 API를 선택합니다. 제품을 만든 후 API를 추가할 수도 있습니다. 자세한 내용은 이 문서의 뒷부분에 나오는 제품에 API 추가를 참조하세요.
제품이 열려 있는 경우(구독이 필요하지 않음) 다른 열려 있는 제품과 연결되지 않은 API만 추가할 수 있습니다.만들기를 선택하여 새 제품을 만듭니다.
주의
구독이 필요하지 않은 제품을 구성할 때는 주의합니다. 이 구성은 지나치게 관대할 수 있으며 제품의 API를 특정 API 보안 위협에 더 취약하게 만들 수 있습니다.
구성 더 추가
저장 후 제품을 계속 구성합니다. API Management 인스턴스의 제품 창에서 제품을 선택합니다. 추가 또는 업데이트:
항목 | 설명 |
---|---|
설정 | 제품 메타데이터 및 상태 데이터 |
API | 제품과 연결된 API |
정책 | 제품 API에 적용되는 정책 |
Access Control | 개발자 또는 게스트에게 제품 표시 여부 |
구독 | 제품 구독자 |
제품에 여러 API 추가
제품은 하나 이상의 API와 연결됩니다. 여러 API를 포함하고 개발자 포털을 통해 개발자에게 제공할 수 있습니다. 제품 만들기 중에 기존 API를 하나 이상 추가할 수 있습니다. 나중에 제품 설정 페이지에서 또는 API를 만드는 동안 제품에 API를 추가할 수 있습니다.
기존 제품에 API 추가
- API Management 인스턴스의 왼쪽 탐색 영역에서 제품을 선택합니다.
- 제품을 선택한 다음 API를 선택합니다.
- + API 추가를 선택합니다.
- 하나 이상의 API를 선택한 다음, 선택을 선택합니다.
제품 API에 대한 액세스
제품을 게시한 후 개발자는 API에 액세스할 수 있습니다. 제품 구성 방법에 따라 액세스를 위해 제품에 구독해야 할 수도 있습니다.
보호된 제품 - 개발자는 먼저 보호된 제품에 구독해야 제품 API에 액세스할 수 있습니다. 구독하면 해당 제품의 모든 API에 액세스할 수 있는 구독 키를 받습니다. API Management 인스턴스를 만든 경우 사용자는 이미 관리자이므로 기본적으로 모든 제품을 구독한 상태가 됩니다. 자세한 내용은 Azure API Management의 구독을 참조하세요.
클라이언트가 유효한 제품 구독 키로 API 요청을 하면 API Management가 요청을 처리하고 제품 컨텍스트에서 액세스를 허용합니다. 제품에 대해 구성된 정책 및 액세스 제어 규칙을 적용할 수 있습니다.
팁
REST API 또는 PowerShell 명령을 통해 사용자 구독을 만들거나 사용자 지정 구독 키가 포함된 제품으로 업데이트할 수 있습니다.
공개 제품 - 개발자는 구독 키 없이 공개 제품의 API에 액세스할 수 있습니다. 그러나 OAuth 2.0, 클라이언트 인증서, 호출자 IP 주소 제한 등 API에 대한 클라이언트 액세스를 보호하기 위해 다른 메커니즘을 구성할 수 있습니다.
참고 항목
개발자가 알아보거나 구독할 수 있도록 오픈 제품은 개발자 포털에 나열되지 않습니다. 관리자 그룹에만 표시됩니다. 구독 키 없이 액세스할 수 있는 API를 개발자에게 알리기 위해서는 다른 메커니즘을 사용해야 합니다.
클라이언트가 구독 키 없이 API 요청을 하는 경우:
API Management는 API가 공개 제품과 연결되어 있는지 확인합니다. API는 최대 하나의 공개 제품과 연결할 수 있습니다.
공개 제품이 있으면 해당 열린 제품의 컨텍스트에서 요청을 처리합니다. 공개 제품에 대해 구성된 정책 및 액세스 제어 규칙을 적용할 수 있습니다.
자세한 내용은 API Management에서 구독 키가 있거나 없는 요청을 처리하는 방법을 참조하세요.
다음 단계
이 자습서에서는 다음 작업 방법을 알아보았습니다.
- 제품 생성 및 게시
- 제품에 API 추가
- 제품 API에 액세스
다음 자습서를 진행합니다.
이 문서에서는 Terraform을 사용하여 Azure API Management 인스턴스, API, 제품, 그룹 및 제품과 API 간의 연결, 제품 및 그룹을 만듭니다.
Terraform은 클라우드 인프라의 정의, 프리뷰 및 배포를 사용합니다. Terraform을 사용하는 경우 HCL 구문를 사용하여 구성 파일을 만듭니다. HCL 구문을 사용하면 클라우드 공급자(예: Azure) 그리고 클라우드 인프라를 구성하는 요소를 지정할 수 있습니다. 구성 파일을 만든 후 배포되기 전에 인프라 변경을 미리 볼 수 있는 실행 계획를 만듭니다. 변경 내용을 확인 한 후에는 실행 계획을 적용하여 인프라를 배포합니다.
- Terraform의 필수 버전과 필요한 공급자를 지정합니다.
- 리소스 그룹 이름 접두사, 리소스 그룹 위치 및 API 정의 가져오기에 대한 콘텐츠 형식 및 값에 대한 변수를 정의합니다.
- 임의 이름을 사용하여 리소스 그룹을 만듭니다.
- 임의 이름을 사용하여 API Management 서비스를 만듭니다.
- 임의 이름을 사용하여 API를 만듭니다.
- API Management 서비스에서 임의로 이름이 있는 제품을 만듭니다.
- 임의 이름을 사용하여 그룹을 만듭니다.
- API를 제품과 연결합니다.
- 그룹을 제품과 연결합니다.
- 리소스 그룹, API Management 서비스, API, 제품 및 그룹의 이름과 같은 임의 값을 출력합니다.
필수 조건
활성 구독이 있는 Azure 계정을 만듭니다. 무료로 계정을 만들 수 있습니다.
Terraform을 설치 및 구성합니다.
Terraform 코드 구현
참고 항목
이 문서의 샘플 코드는 Azure Terraform GitHub 리포지토리에 있습니다. Terraform의 현재 및 이전 버전의 테스트 결과가 포함된 로그 파일을 볼 수 있습니다.
샘플 Terraform 코드를 테스트 및 실행할 디렉터리를 만들고 현재 디렉터리로 만듭니다.
이름이 지정된
main.tf
파일을 만들고 다음 코드를 삽입합니다.resource "random_pet" "rg_name" { prefix = var.resource_group_name_prefix } resource "azurerm_resource_group" "rg" { location = var.resource_group_location name = random_pet.rg_name.id } resource "random_string" "apim_service_name" { length = 8 lower = true numeric = false special = false upper = false } resource "azurerm_api_management" "apim_service" { name = "${random_string.apim_service_name.result}-apim-service" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name publisher_name = "Example Publisher" publisher_email = "publisher@example.com" sku_name = "Developer_1" tags = { Environment = "Example" } policy { xml_content = <<XML <policies> <inbound /> <backend /> <outbound /> <on-error /> </policies> XML } } resource "random_string" "api_name" { length = 8 lower = true numeric = false special = false upper = false } resource "random_string" "content_value" { length = 8 lower = true numeric = false special = false upper = false } resource "azurerm_api_management_api" "api" { name = "${random_string.api_name.result}-api" resource_group_name = azurerm_resource_group.rg.name api_management_name = azurerm_api_management.apim_service.name revision = "1" display_name = "${random_string.api_name.result}-api" path = "example" protocols = ["https", "http"] description = "An example API" import { content_format = var.open_api_spec_content_format content_value = var.open_api_spec_content_value } } resource "random_string" "product_name" { length = 8 lower = true numeric = false special = false upper = false } resource "azurerm_api_management_product" "product" { product_id = "${random_string.product_name.result}-product" resource_group_name = azurerm_resource_group.rg.name api_management_name = azurerm_api_management.apim_service.name display_name = "${random_string.product_name.result}-product" subscription_required = true approval_required = false published = true description = "An example Product" } resource "random_string" "group_name" { length = 8 lower = true numeric = false special = false upper = false } resource "azurerm_api_management_group" "group" { name = "${random_string.group_name.result}-group" resource_group_name = azurerm_resource_group.rg.name api_management_name = azurerm_api_management.apim_service.name display_name = "${random_string.group_name.result}-group" description = "An example group" } resource "azurerm_api_management_product_api" "product_api" { resource_group_name = azurerm_resource_group.rg.name api_management_name = azurerm_api_management.apim_service.name product_id = azurerm_api_management_product.product.product_id api_name = azurerm_api_management_api.api.name } resource "azurerm_api_management_product_group" "product_group" { resource_group_name = azurerm_resource_group.rg.name api_management_name = azurerm_api_management.apim_service.name product_id = azurerm_api_management_product.product.product_id group_name = azurerm_api_management_group.group.name }
이름이 지정된
outputs.tf
파일을 만들고 다음 코드를 삽입합니다.output "resource_group_name" { value = azurerm_resource_group.rg.name } output "apim_service_name" { value = azurerm_api_management.apim_service.name } output "api_name" { value = azurerm_api_management_api.api.name } output "product_name" { value = azurerm_api_management_product.product.product_id } output "group_name" { value = azurerm_api_management_group.group.name } output "service_id" { description = "The ID of the API Management Service created" value = azurerm_api_management.apim_service.id } output "gateway_url" { description = "The URL of the Gateway for the API Management Service" value = azurerm_api_management.apim_service.gateway_url } output "service_public_ip_addresses" { description = "The Public IP addresses of the API Management Service" value = azurerm_api_management.apim_service.public_ip_addresses } output "api_outputs" { description = "The IDs, state, and version outputs of the APIs created" value = { id = azurerm_api_management_api.api.id is_current = azurerm_api_management_api.api.is_current is_online = azurerm_api_management_api.api.is_online version = azurerm_api_management_api.api.version version_set_id = azurerm_api_management_api.api.version_set_id } } output "product_id" { description = "The ID of the Product created" value = azurerm_api_management_product.product.id } output "product_api_id" { description = "The ID of the Product/API association created" value = azurerm_api_management_product_api.product_api.id } output "product_group_id" { description = "The ID of the Product/Group association created" value = azurerm_api_management_product_group.product_group.id }
이름이 지정된
providers.tf
파일을 만들고 다음 코드를 삽입합니다.terraform { required_version = ">=1.0" required_providers { azurerm = { source = "hashicorp/azurerm" version = "~>3.0" } random = { source = "hashicorp/random" version = "~>3.0" } } } provider "azurerm" { features {} }
이름이 지정된
variables.tf
파일을 만들고 다음 코드를 삽입합니다.variable "resource_group_name_prefix" { type = string default = "rg" description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription." } variable "resource_group_location" { type = string default = "eastus" description = "Location of the resource group." } variable "open_api_spec_content_format" { type = string default = "swagger-link-json" description = "The format of the content from which the API Definition should be imported. Possible values are: openapi, openapi+json, openapi+json-link, openapi-link, swagger-json, swagger-link-json, wadl-link-json, wadl-xml, wsdl and wsdl-link." validation { condition = contains(["openapi", "openapi+json", "openapi+json-link", "openapi-link", "swagger-json", "swagger-link-json", "wadl-link-json", "wadl-xml", "wsdl", "wsdl-link"], var.open_api_spec_content_format) error_message = "open_api_spec_content_format must be one of the following: openapi, openapi+json, openapi+json-link, openapi-link, swagger-json, swagger-link-json, wadl-link-json, wadl-xml, wsdl and wsdl-link." } } variable "open_api_spec_content_value" { type = string default = "https://petstore3.swagger.io/api/v3/openapi.json" description = "The Content from which the API Definition should be imported. When a content_format of *-link-* is specified this must be a URL, otherwise this must be defined inline." }
Terraform 초기화
terraform init를 실행하여 Terraform 배포를 초기화합니다. 이 명령은 Azure 리소스를 관리하는 데 필요한 Azure 공급자를 다운로드합니다.
terraform init -upgrade
주요 정보:
-upgrade
매개 변수는 필요한 공급자 플러그 인을 구성의 버전 제약 조건을 준수하는 최신 버전으로 업그레이드합니다.
Terraform 실행 계획 만들기
terraform plan을 실행하여 실행 계획을 만듭니다.
terraform plan -out main.tfplan
주요 정보:
terraform plan
명령은 실행 계획을 만들지만 실행하지는 않습니다. 대신 구성 파일에 지정된 구성을 만드는 데 필요한 작업을 결정합니다. 이 패턴을 사용하면 실제 리소스를 변경하기 전에 실행 계획이 예상과 일치하는지 확인할 수 있습니다.- 선택 사항인
-out
매개 변수를 사용하여 계획의 출력 파일을 지정할 수 있습니다.-out
매개 변수를 사용하면 검토한 계획이 정확하게 적용됩니다.
Terraform 실행 계획 적용
terraform apply를 실행하여 실행 계획을 클라우드 인프라에 적용합니다.
terraform apply main.tfplan
주요 정보:
- 예시
terraform apply
명령은 이전에terraform plan -out main.tfplan
를 실행했다고 가정합니다. -out
매개 변수에 다른 파일 이름을 지정한 경우terraform apply
에 대한 호출에서 동일한 파일 이름을 사용합니다.-out
매개 변수를 사용하지 않은 경우 매개 변수 없이terraform apply
를 호출합니다.
결과 확인
Azure API Management를 보려면 실행 az apim show
합니다.
az apim show --<apim_service_name> --<resource_group_name>
리소스 정리
Terraform을 통해 리소스를 만들 필요가 더 이상 없으면 다음 단계를 수행합니다.
terraform 플랜을 실행하고
destroy
플래그를 지정합니다.terraform plan -destroy -out main.destroy.tfplan
주요 정보:
terraform plan
명령은 실행 계획을 만들지만 실행하지는 않습니다. 대신 구성 파일에 지정된 구성을 만드는 데 필요한 작업을 결정합니다. 이 패턴을 사용하면 실제 리소스를 변경하기 전에 실행 계획이 예상과 일치하는지 확인할 수 있습니다.- 선택 사항인
-out
매개 변수를 사용하여 계획의 출력 파일을 지정할 수 있습니다.-out
매개 변수를 사용하면 검토한 계획이 정확하게 적용됩니다.
terraform apply를 실행하여 실행 계획을 적용합니다.
terraform apply main.destroy.tfplan
Azure의 Terraform 문제 해결
Azure에서 Terraform을 사용할 때 발생하는 일반적인 문제를 해결합니다.
다음 단계
빈 API 및 모의 API 응답을 만듭니다.