

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# OpenSearch UI 애플리케이션을 위한 친숙한 URL 설정(셀프 서비스)
<a name="application-custom-domain"></a>

OpenSearch UI 애플리케이션에는와 같이 자동 생성된 URLs`https://application-{{name}}-{{id}}.{{Region}}.opensearch.amazonaws.com`. 이러한 URLs은 길고 기억하기 어렵습니다. 친숙한 URL(예: )을 설정할 수 있습니다`https://prod.example.com`. 이 URL은 애플리케이션으로 리디렉션되므로 AWS Management Console을 탐색하지 않고도 대시보드에 직접 액세스할 수 있습니다.

## 작동 방식
<a name="application-custom-domain-overview"></a>

이 솔루션은 CloudFront를 사용하여 친숙한 URL의 요청을 OpenSearch UI 애플리케이션 엔드포인트로 리디렉션합니다. 이 아키텍처는 다음 구성 요소로 구성됩니다.
+ **ACM 인증서** - 친숙한 URL에 HTTPS 암호화를 제공합니다.
+ **CloudFront KeyValueStore** - 하위 도메인 이름과 애플리케이션 URLs 간의 매핑을 저장합니다.
+ **CloudFront 함수** - KeyValueStore를 읽고 올바른 애플리케이션 URL로 302 리디렉션을 반환합니다.
+ **CloudFront 배포** - TLS를 사용하여 친숙한 URL을 제공하고 함수를 통해 요청을 라우팅합니다.
+ **Route 53 DNS 레코드** - CloudFront 배포에 대한 친숙한 URL을 가리킵니다.

친숙한 URL(예: `https://prod.example.com`)을 방문하면 CloudFront 함수가 해당 애플리케이션 URL을 조회하고 브라우저를 해당 URL로 리디렉션합니다. 애플리케이션은 인증을 직접 처리합니다.

## 사전 조건
<a name="application-custom-domain-prerequisites"></a>
+ 엔드포인트 URL이 있는 하나 이상의 OpenSearch UI 애플리케이션. URLs
+ 소유한 도메인 이름(예: `example.com`).
+ 도메인에 대한 Route 53의 퍼블릭 호스팅 영역입니다. 없는 경우 자세한 내용은 섹션을 참조하세요[Route 53 없이 설정(수동 구성)](#application-custom-domain-without-route53).
+ 애플리케이션 URL 매핑 파일을 저장할 Amazon S3 버킷입니다.

## 를 사용하여 배포 AWS CloudFormation
<a name="application-custom-domain-deploy-cfn"></a>

다음 절차에 따라 CloudFormation 템플릿을 사용하여 친숙한 URL 리디렉션 인프라를 배포합니다.

**OpenSearch UI 애플리케이션에 대한 친숙한 URL을 설정하려면**

1. 표시 이름을 애플리케이션 URLs에 매핑하는 JSON 파일을 생성합니다. 각 키는 하위 도메인이 됩니다(예: 키는이 `prod`됨`https://prod.example.com`).

   ```
   {
     "data": [
       {"key": "prod", "value": "https://application-prod-abc123.us-west-2.opensearch.amazonaws.com"},
       {"key": "staging", "value": "https://application-staging-def456.us-east-1.opensearch.amazonaws.com"},
       {"key": "analytics", "value": "https://application-analytics-ghi789.eu-west-1.opensearch.amazonaws.com"}
     ]
   }
   ```

   이 파일을 `opensearch-ui-friendly-url-app-mappings-v1.json`로 저장합니다. `v1` 접미사는 이를 매핑의 첫 번째 버전으로 식별합니다. 매핑을 업데이트할 때이 버전이 증가합니다.

1. 계정의 Amazon S3 버킷에 매핑 파일을 업로드합니다.

   ```
   aws s3 cp opensearch-ui-friendly-url-app-mappings-v1.json \
     s3://{{your-bucket-name}}/opensearch-ui-friendly-url-app-mappings-v1.json
   ```

1. 버킷 정책을 추가하여 매핑 파일을 읽을 수 있는 권한을 CloudFront에 부여합니다. {{your-bucket-name}} 및 {{your-account-id}}를 값으로 바꿉니다.

   ```
   aws s3api put-bucket-policy \
     --bucket {{your-bucket-name}} \
     --policy '{
       "Version": "2012-10-17",
       "Statement": [{
         "Sid": "AllowCloudFrontKVSImport",
         "Effect": "Allow",
         "Principal": {"Service": "cloudfront.amazonaws.com"},
         "Action": "s3:GetObject",
         "Resource": "arn:aws:s3:::{{your-bucket-name}}/*",
         "Condition": {"StringEquals": {"aws:SourceAccount": "{{your-account-id}}"}}
       }]
     }'
   ```
**참고**  
이 버킷 정책은 CloudFront가 KeyValueStore 생성 중에 매핑 파일을 읽을 수 있도록 허용합니다. 그렇지 않으면 "SourceARN에 액세스할 수 없음" 오류와 함께 스택 배포가 실패합니다.

1. 다음 옵션 중 하나를 사용하여 CloudFormation 스택을 배포합니다.

   **옵션 1: 스택 시작(권장)**

   다음 URL을 복사하여 브라우저에 붙여 넣어 템플릿이 미리 로드된 AWS CloudFormation 빠른 생성 페이지를 엽니다. 파라미터를 입력하고 **스택 생성을** 선택합니다.

   ```
   https://us-east-1.console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/quickcreate?templateURL=https://opensearch-ui-quickstart-sample-cfn-templates.s3.us-west-2.amazonaws.com/opensearch-ui-friendly-url/main.yaml&stackName=opensearch-ui-friendly-url&param_MappingsVersion=v1
   ```

   **옵션 2: AWS CLI**

   자리 표시자 값을 자신의 값으로 바꿉니다.

   ```
   aws cloudformation create-stack \
     --stack-name opensearch-ui-friendly-url \
     --template-url https://opensearch-ui-quickstart-sample-cfn-templates.s3.us-west-2.amazonaws.com/opensearch-ui-friendly-url/main.yaml \
     --parameters \
       ParameterKey=DomainName,ParameterValue={{your-domain.com}} \
       ParameterKey=HostedZoneId,ParameterValue={{Z0123456789ABCDEFG}} \
       ParameterKey=MappingsBucket,ParameterValue={{your-bucket-name}} \
       ParameterKey=MappingsKey,ParameterValue=opensearch-ui-friendly-url-app-mappings-v1.json \
       ParameterKey=MappingsVersion,ParameterValue=v1 \
     --region us-east-1
   ```

1.  AWS CLI(옵션 2)를 사용한 경우 `us-east-1` 리전에 스택을 배포합니다. CloudFront에서는 ACM 인증서가에 있어야 합니다`us-east-1`. OpenSearch UI 애플리케이션은 [ OpenSearch UI에 대해 지원되는 모든 리전 및 할당량에](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/opensearch-ui-endpoints-quotas.html) 있을 수 있습니다.

1. 스택이 완료될 때까지 기다립니다(약 15분). 진행 상황을 모니터링할 수 있습니다.

   ```
   aws cloudformation wait stack-create-complete \
     --stack-name opensearch-ui-friendly-url \
     --region us-east-1
   ```

1. 리디렉션을 테스트합니다. 브라우저를 열고 로 이동합니다`https://{{prod}}.{{your-domain.com}}`. OpenSearch UI 애플리케이션으로 리디렉션되어야 합니다.

   를 사용하여 확인할 수도 있습니다`curl`.

   ```
   curl -I https://{{prod}}.{{your-domain.com}}
   # Expected: HTTP/2 302
   # location: https://application-prod-abc123.us-west-2.opensearch.amazonaws.com
   ```

### CloudFormation 템플릿 소스
<a name="application-custom-domain-template-source"></a>

다음은 위의 스택 시작 링크 및 CLI 명령에서 사용하는 전체 CloudFormation 템플릿입니다. 에서 직접 다운로드할 수도 있습니다`https://opensearch-ui-quickstart-sample-cfn-templates.s3.us-west-2.amazonaws.com/opensearch-ui-friendly-url/main.yaml`.

```
AWSTemplateFormatVersion: '2010-09-09'
Metadata:
  TemplateVersion: '1.0.0'
  LastUpdated: '2026-08-05'
  Author: 'OpenSearch UI Team'
Description: >
  OpenSearch UI Friendly URL - Creates a CloudFront distribution with a CloudFront Function
  that redirects friendly subdomain URLs to OpenSearch Application endpoints.
  Deploy this template in us-east-1 (required for ACM certificates used with CloudFront).

Parameters:
  DomainName:
    Type: String
    Description: "Your domain name (e.g., example.com or subdomain.example.com)"
    AllowedPattern: "^[a-zA-Z0-9][a-zA-Z0-9-]*(\\.[a-zA-Z0-9][a-zA-Z0-9-]*)+$"
  HostedZoneId:
    Type: AWS::Route53::HostedZone::Id
    Description: "Route 53 Hosted Zone ID for your domain"
  MappingsBucket:
    Type: String
    Description: "S3 bucket name containing your app mappings JSON file"
  MappingsKey:
    Type: String
    Description: "S3 key (path) to your app mappings JSON file"
    Default: "opensearch-ui-friendly-url-app-mappings.json"
  MappingsVersion:
    Type: String
    Description: "Version identifier for your mappings (change this when updating mappings, e.g., v1, v2, v3)"
    Default: "v1"
    AllowedPattern: "^[a-zA-Z0-9-]+$"

Resources:
  # 1. Wildcard TLS Certificate (DNS validated via Route 53)
  Certificate:
    Type: AWS::CertificateManager::Certificate
    Properties:
      DomainName: !Sub "*.${DomainName}"
      ValidationMethod: DNS
      DomainValidationOptions:
        - DomainName: !Sub "*.${DomainName}"
          HostedZoneId: !Ref HostedZoneId

  # 2. CloudFront KeyValueStore with S3 import for app mappings
  AppMappingStore:
    Type: AWS::CloudFront::KeyValueStore
    Properties:
      Name: !Sub "${AWS::StackName}-kvs-${MappingsVersion}"
      Comment: !Sub "OpenSearch UI app mappings ${MappingsVersion} for ${DomainName}"
      ImportSource:
        SourceType: S3
        SourceArn: !Sub "arn:aws:s3:::${MappingsBucket}/${MappingsKey}"

  # 3. CloudFront Function (reads KVS, returns 302 redirect)
  RedirectFunction:
    Type: AWS::CloudFront::Function
    Properties:
      Name: !Sub "${AWS::StackName}-fn"
      AutoPublish: true
      FunctionConfig:
        Comment: !Sub "Redirects friendly URLs to OpenSearch Application endpoints (${MappingsVersion})"
        Runtime: cloudfront-js-2.0
        KeyValueStoreAssociations:
          - KeyValueStoreARN: !GetAtt AppMappingStore.Arn
      FunctionCode: !Sub |
        import cf from 'cloudfront';

        const kvsHandle = cf.kvs("${AppMappingStore.Id}");

        async function handler(event) {
          var request = event.request;
          var host = request.headers.host.value;
          
          // Extract subdomain prefix (e.g., "app1" from "app1.example.com")
          var subdomain = host.split('.')[0];
          
          try {
            var targetUrl = await kvsHandle.get(subdomain);
            return {
              statusCode: 302,
              statusDescription: 'Found',
              headers: {
                'location': { value: targetUrl },
                'cache-control': { value: 'no-cache, no-store, must-revalidate' }
              }
            };
          } catch (e) {
            // Key not found - return 404
            return {
              statusCode: 404,
              statusDescription: 'Not Found',
              headers: {
                'content-type': { value: 'text/html' }
              },
              body: {
                encoding: 'text',
                data: '<html><body><h1>Application Not Found</h1><p>No OpenSearch application is mapped to the requested subdomain.</p></body></html>'
              }
            };
          }
        }

  # 4. CloudFront Distribution
  Distribution:
    Type: AWS::CloudFront::Distribution
    DependsOn: Certificate
    Properties:
      DistributionConfig:
        Enabled: true
        Comment: !Sub "OpenSearch UI Friendly URL for ${DomainName}"
        Aliases:
          - !Sub "*.${DomainName}"
        ViewerCertificate:
          AcmCertificateArn: !Ref Certificate
          SslSupportMethod: sni-only
          MinimumProtocolVersion: TLSv1.2_2021
        DefaultCacheBehavior:
          ViewerProtocolPolicy: redirect-to-https
          AllowedMethods:
            - GET
            - HEAD
          CachedMethods:
            - GET
            - HEAD
          CachePolicyId: "4135ea2d-6df8-44a3-9df3-4b5a84be39ad"  # AWS managed CachingDisabled policy
          TargetOriginId: dummy-origin
          FunctionAssociations:
            - EventType: viewer-request
              FunctionARN: !GetAtt RedirectFunction.FunctionMetadata.FunctionARN
        Origins:
          - Id: dummy-origin
            DomainName: "example.com"
            CustomOriginConfig:
              OriginProtocolPolicy: https-only
        HttpVersion: http2and3
        IPV6Enabled: true
        PriceClass: PriceClass_All

  # 5. Wildcard DNS record pointing to CloudFront
  WildcardDnsRecord:
    Type: AWS::Route53::RecordSet
    Properties:
      HostedZoneId: !Ref HostedZoneId
      Name: !Sub "*.${DomainName}"
      Type: A
      AliasTarget:
        HostedZoneId: Z2FDTNDATAQYW2  # CloudFront's fixed hosted zone ID (constant for all distributions)
        DNSName: !GetAtt Distribution.DomainName
        EvaluateTargetHealth: false

Outputs:
  CloudFrontDomain:
    Description: "CloudFront distribution domain name"
    Value: !GetAtt Distribution.DomainName
  CertificateArn:
    Description: "ACM Certificate ARN"
    Value: !Ref Certificate
  KeyValueStoreArn:
    Description: "CloudFront KeyValueStore ARN"
    Value: !GetAtt AppMappingStore.Arn
  ExampleUrl:
    Description: "Example friendly URL"
    Value: !Sub "https://prod.${DomainName}"
  MappingsFileLocation:
    Description: "S3 location of your app mappings file"
    Value: !Sub "s3://${MappingsBucket}/${MappingsKey}"
  CurrentMappingsVersion:
    Description: "Current mappings version deployed"
    Value: !Ref MappingsVersion
  TemplateVersion:
    Description: "Template version and last updated date"
    Value: "1.0.0 (2026-08-05)"
```

### 애플리케이션 추가 또는 제거
<a name="application-custom-domain-add-apps"></a>

애플리케이션 매핑을 추가, 업데이트 또는 제거하려면 새 버전의 S3 매핑 파일을 생성하고 스택을 새 버전으로 업데이트합니다. 버전이 지정된 접근 방식은 S3 파일을 신뢰할 수 있는 소스로 유지하며 언제든지 새 구성으로 롤백하거나 이전 버전으로 롤백할 수 있습니다.

1. 매핑 파일을 편집하여 항목을 추가하거나 제거합니다. 증분 버전 접미사(예: )와 함께 저장합니다`opensearch-ui-friendly-url-app-mappings-v2.json`.

1. 새 버전을 S3에 업로드합니다.

   ```
   aws s3 cp opensearch-ui-friendly-url-app-mappings-v2.json \
     s3://{{your-bucket-name}}/opensearch-ui-friendly-url-app-mappings-v2.json
   ```

1. 새 `MappingsKey` 및 로 스택을 업데이트합니다`MappingsVersion`.

   **콘솔 사용:** [CloudFormation 콘솔](https://console.aws.amazon.com/cloudformation/)을 열고 스택을 선택한 다음 **업데이트를** 선택하고 **현재 템플릿 사용을** 선택한 다음 `MappingsKey` 및 `MappingsVersion` 파라미터를 새 값으로 업데이트합니다.

   ** AWS CLI 사용:**

   ```
   aws cloudformation update-stack \
     --stack-name opensearch-ui-friendly-url \
     --use-previous-template \
     --parameters \
       ParameterKey=DomainName,UsePreviousValue=true \
       ParameterKey=HostedZoneId,UsePreviousValue=true \
       ParameterKey=MappingsBucket,UsePreviousValue=true \
       ParameterKey=MappingsKey,ParameterValue=opensearch-ui-friendly-url-app-mappings-v2.json \
       ParameterKey=MappingsVersion,ParameterValue=v2 \
     --region us-east-1
   ```

**중요**  
매핑을 업데이트할 때마다 `MappingsVersion` 파라미터를 변경해야 합니다. 버전은 KeyValueStore 이름을 구동하여 KeyValueStore를 업데이트된 데이터로 대체 CloudFormation 하도록 트리거합니다. 명확성을 위해 `MappingsKey` 파일 이름과를 동기화`MappingsVersion`(예: `...-v2.json`와 동기화`MappingsVersion=v2`)된 상태로 유지합니다.

이전 버전으로 롤백하려면 이전 파일 및 버전을 가리키는 스택을 업데이트합니다.

**콘솔 사용:** [CloudFormation 콘솔](https://console.aws.amazon.com/cloudformation/)을 열고 스택을 선택한 다음 **업데이트를** 선택하고 **현재 템플릿 사용을** 선택한 다음를 설정하고 이전 값(예: `v1`)으로 `MappingsKey` `MappingsVersion` 돌아갑니다.

** AWS CLI 사용:**

```
aws cloudformation update-stack \
  --stack-name opensearch-ui-friendly-url \
  --use-previous-template \
  --parameters \
    ParameterKey=DomainName,UsePreviousValue=true \
    ParameterKey=HostedZoneId,UsePreviousValue=true \
    ParameterKey=MappingsBucket,UsePreviousValue=true \
    ParameterKey=MappingsKey,ParameterValue=opensearch-ui-friendly-url-app-mappings-v1.json \
    ParameterKey=MappingsVersion,ParameterValue=v1 \
  --region us-east-1
```

이 버전 관리형 접근 방식을 사용하면 S3 파일을 각 구성 버전의 최종 레코드로 유지하면서 필요에 따라 애플리케이션 매핑을 롤포워드하거나 롤백할 수 있는 완전한 제어가 가능합니다.

## Route 53 없이 설정(수동 구성)
<a name="application-custom-domain-without-route53"></a>

도메인이 Route 53 이외의 DNS 공급자에 의해 관리되는 경우 AWS 관리 콘솔에서 친숙한 URL 리디렉션을 수동으로 설정할 수 있습니다. 이 접근 방식은 매핑에 Amazon S3를 사용하지 않습니다. CloudFront 콘솔에서 직접 키-값 페어를 관리합니다.

**Route 53 없이 친숙한 URL 리디렉션을 설정하려면**

1. 

**ACM에서 인증서 요청**

   1. `us-east-1` 리전의 [https://console.aws.amazon.com/acm/](https://console.aws.amazon.com/acm/) ACM 콘솔을 엽니다.

   1. **인증서 요청을** 선택합니다.

   1. **도메인 이름**에 `*.{{your-domain.com}}` (와일드카드 인증서)를 입력합니다.

   1. **검증 방법**에서 **DNS 검증**을 선택합니다.

   1. **요청**을 선택합니다.

   1. 인증서 세부 정보 페이지의 **도메인 검증** 아래에 CNAME 레코드 이름과 값을 기록해 둡니다. DNS 공급자에서이 CNAME 레코드를 생성하여 도메인 소유권을 검증합니다.

   1. 인증서 상태가 **발급됨**으로 변경될 때까지 기다립니다(일반적으로 DNS 레코드 생성 후 5\~30분).

1. 

**CloudFront KeyValueStore 생성**

   1. [https://console.aws.amazon.com/cloudfront/](https://console.aws.amazon.com/cloudfront/)에서 CloudFront 콘솔을 엽니다.

   1. 탐색 창에서 **함수**를 선택합니다. 그런 다음 **KeyValueStores** 탭을 선택합니다.

   1. **KeyValueStore 생성** 버튼을 선택합니다.

   1. 이름(예: `opensearch-ui-friendly-url-app-mappings-store`)을 입력합니다.

   1. **생성(Create)**을 선택합니다.

   1. 생성 후 **편집**을 선택하여 키-값 페어를 추가합니다. 각 애플리케이션에 대해 키(와 같은 하위 도메인 이름`prod`)와 값(전체 OpenSearch UI 애플리케이션 URL)을 추가합니다.

1. 

**CloudFront 함수 생성**

   1. [https://console.aws.amazon.com/cloudfront/](https://console.aws.amazon.com/cloudfront/)에서 CloudFront 콘솔을 엽니다.

   1. 탐색 창에서 **함수**를 선택합니다.

   1. **함수** 탭에서 **함수 생성을** 선택합니다.

   1. 함수의 이름을 입력합니다(예: `opensearch-ui-friendly-url-redirect-function`).

   1. **런타임**에서 **cloudfront-js-2.0**을 선택합니다.

   1. 함수 코드를 다음으로 바꿉니다.

      ```
      import cf from 'cloudfront';
      
      const kvsHandle = cf.kvs("{{YOUR_KVS_ID}}");
      
      async function handler(event) {
        var request = event.request;
        var host = request.headers.host.value;
        var subdomain = host.split('.')[0];
      
        try {
          var targetUrl = await kvsHandle.get(subdomain);
          return {
            statusCode: 302,
            statusDescription: 'Found',
            headers: {
              'location': { value: targetUrl },
              'cache-control': { value: 'no-cache, no-store, must-revalidate' }
            }
          };
        } catch (e) {
          return {
            statusCode: 404,
            statusDescription: 'Not Found',
            headers: { 'content-type': { value: 'text/html' } },
            body: {
              encoding: 'text',
              data: '<html><body><h1>Application Not Found</h1><p>No OpenSearch application is mapped to the requested subdomain.</p></body></html>'
            }
          };
        }
      }
      ```

      {{YOUR\_KVS\_ID}}를 생성한 KeyValueStore의 ID로 바꿉니다(KeyValueStore 세부 정보 페이지에서 볼 수 있음).

   1. **KeyValueStore 연결**에서 생성한 KeyValueStore를 연결합니다.

   1. **변경 사항 저장**을 선택한 다음 **함수 게시**를 선택합니다.

1. 

**CloudFront 배포 생성**

   1. CloudFront 콘솔에서 **배포 생성을** 선택합니다.

   1. **오리진 도메인**에 유효한 도메인(예: `example.com`)을 입력합니다. 함수가 응답에 도달하기 전에 응답을 반환하기 때문에 오리진에 연결되지 않습니다.

   1. **기본 캐시 동작**의 **뷰어 프로토콜 정책**에서 **HTTP를 HTTPS로 리디렉션**을 선택합니다.

   1. **캐시 정책**에서 **CachingDisabled** 선택합니다.

   1. **함수 연결의** **뷰어 요청**에서 CloudFront 함수를 선택합니다.

   1. **설정**에서 **대체 도메인 이름(CNAMEs)**에를 입력합니다`*.{{your-domain.com}}`.

   1. **사용자 지정 SSL 인증서**에서 ACM에서 생성한 인증서를 선택합니다.

   1. **배포 생성**을 선택합니다.

   1. 배포 도메인 이름(예: `d1234abcdef8.cloudfront.net`)을 기록해 둡니다.

1. 

**공급자에서 DNS 구성**

   DNS 공급자에서 CloudFront 배포 도메인 이름(예: )`*.{{your-domain.com}}`을 가리키는 CNAME 레코드를 생성합니다`d1234abcdef8.cloudfront.net`.
**참고**  
일부 DNS 공급자는 와일드카드 CNAME 레코드를 지원하지 않습니다. 이 경우 사용하려는 각 하위 도메인에 대해 개별 CNAME 레코드를 생성합니다(예: , `prod.your-domain.com``staging.your-domain.com`).

### 애플리케이션 매핑 수동 추가
<a name="application-custom-domain-manual-add-apps"></a>

초기 수동 설정 후 새 애플리케이션 매핑을 추가하려면:

1. [https://console.aws.amazon.com/cloudfront/](https://console.aws.amazon.com/cloudfront/)에서 CloudFront 콘솔을 엽니다.

1. 탐색 창에서 **함수**를 선택합니다. 그런 다음 **KeyValueStores** 탭을 선택합니다.

1. KeyValueStore 이름(예: `opensearch-ui-friendly-url-app-mappings-store`)을 선택합니다.

1. **편집**을 선택합니다.

1. **페어 추가**를 선택합니다. 하위 도메인 이름을 키로 입력하고 전체 OpenSearch UI 애플리케이션 URL을 값으로 입력합니다.

1. **변경 사항 저장**을 선택합니다.

새 표시 URL은 저장 후 즉시 사용할 수 있습니다.

## 정리
<a name="application-custom-domain-cleanup"></a>

친숙한 URL 리디렉션 인프라를 제거하려면 다음 명령을 실행합니다.

```
aws cloudformation delete-stack \
  --stack-name opensearch-ui-friendly-url \
  --region us-east-1
```

이 명령은 CloudFront 배포, 함수, KeyValueStore, ACM 인증서 및 DNS 레코드를 제거합니다. OpenSearch UI 애플리케이션에는 영향을 주지 않습니다.

## 문제 해결
<a name="application-custom-domain-troubleshooting"></a>

ACM 인증서는에 유지됩니다. `Pending validation`   
도메인의 DNS가 Route 53에 올바르게 위임되었는지(또는 DNS 공급자에서 검증 CNAME을 생성했는지) 확인합니다. `dig {{your-domain}} NS`를 사용하여 네임서버를 확인합니다.

브라우저에 인증서 오류가 표시됨  
ACM 인증서가 도메인을 와일드카드()로 포함하는지 확인합니다`*.your-domain.com`. 인증서는 `us-east-1` 리전에 있어야 합니다.

404 애플리케이션을 찾을 수 없음  
액세스하려는 하위 도메인에 KeyValueStore에 매핑이 없습니다. 키가 매핑 파일에 있는지 확인하고 마지막 변경 후 스택을 업데이트했는지(또는 페어를 수동으로 추가했는지) 확인합니다.

CloudFront 배포에 15분 이상 `Deploying` 상태 표시  
CloudFront 배포는 전 세계에 배포하는 데 최대 15분이 걸릴 수 있습니다. 배포 시간이 더 오래 걸리는 경우 CloudFront 콘솔에서 오류 세부 정보를 확인하세요.

스택 생성 중에 SourceARN에 액세스할 수 없는 오류입니다.  
S3 버킷 정책이 매핑 파일을 읽을 수 있는 `cloudfront.amazonaws.com` 권한을 부여하는지 확인합니다. 또한 스택을 배포하는 IAM 역할에 버킷에 대한 `s3:GetObject`, `s3:HeadObject`및 `s3:GetBucketLocation` 권한이 있는지 확인합니다.