

# Node.js 다중 검사 블루프린트에 대한 JSON 구성 작성
<a name="CloudWatch_Synthetics_WritingCanary_Multichecks"></a>

Node.js 다중 검사 블루프린트를 사용하면 단일 카나리 실행 내에서 여러 가지 검증 검사를 수행하는 카나리를 생성할 수 있습니다. 이 블루프린트는 여러 엔드포인트를 테스트하거나, 애플리케이션의 다양한 측면을 검증하거나, 일련의 관련된 검사를 순차적으로 수행하려는 경우에 유용합니다.

**Topics**
+ [루트 구성 구조](#root-configuration-structure)
+ [글로벌 설정](#global-settings)
+ [변수 및 데이터 관리](#variables-data-management)
+ [단계 정의](#step-definitions)
+ [검사 유형](#check-types)
+ [인증 방법](#authentication-methods)
+ [어설션 및 검증](#assertions-validation)
+ [데이터 추출](#data-extraction)

## 루트 구성 구조
<a name="root-configuration-structure"></a>

루트 구성은 고급 API 블루프린트 카나리의 전체 구조를 정의합니다.


**스키마 속성**  

| 속성 | Type | 필수 | 설명 | 
| --- | --- | --- | --- | 
|  globalSettings  | 객체 | 아니요 | 모든 단계에 적용되는 기본 구성 | 
|  variables  | 객체 | 아니요 | 단계 전체에서 재사용 가능한 값(최대 10개) | 
|  steps  | 객체 |  예  | 모니터링 단계 수집(1\$110단계) | 

 **예제** 

```
{
  "globalSettings": {
    "stepTimeout": 30000,
    "userAgent": "CloudWatch-Synthetics-Advanced/1.0"
  },
  "variables": {
    "baseUrl": "https://api.example.com",
    "apiVersion": "v1"
  },
  "steps": {
    "1": {
      "stepName": "healthCheck",
      "checkerType": "HTTP",
      "url": "${baseUrl}/health",
      "httpMethod": "GET"
    }
  }
}
```

 **검증 규칙** 
+ 하나 이상의 단계를 포함해야 함
+ 최대 10단계 허용
+ `globalSettings`, ` variables`, `steps` 이외의 추가 속성은 허용되지 않음

## 글로벌 설정
<a name="global-settings"></a>

전역 설정은 단계 수준에서 재정의되지 않는 한 모든 단계에 적용되는 기본 구성을 제공합니다.

 **속성** 


**전역 설정 속성**  

| 속성 | Type | 기본값 | Range | 설명 | 
| --- | --- | --- | --- | --- | 
|  stepTimeout  | 정수 | 30000 | 5000\$1300000 | 모든 단계의 기본 제한 시간(밀리초) | 

 **예제** 

```
{
  "globalSettings": {
    "stepTimeout": 60000,
            
  }
}
```

## 변수 및 데이터 관리
<a name="variables-data-management"></a>

변수를 사용하면 `${variableName}` 구문을 사용하여 구성 전체에서 참조할 수 있는 재사용 가능한 값을 정의할 수 있습니다.

 **변수 속성** 


| 속성 | Type | 설명 | 
| --- | --- | --- | 
| 변수 이름 | 문자열 | ^[a-zA-Z][a-zA-Z0-9\$1]\$1\$1 패턴과 일치해야 함 | 
| 변수 값 | 문자열 | 문자열 값 | 

 **제한 사항 ** 
+ 구성당 최대 10개의 변수
+ 변수 이름은 문자로 시작해야 함
+ 변수 이름에는 문자, 숫자, 밑줄을 포함할 수 있음
+ 스키마에 지정되지 않은 최대 길이

 **예제** 

```
{
  "variables": {
    "baseUrl": "https://api.example.com",
    "apiKey": "${AWS_SECRET:my-api-key}",
    "timeout": "30000",
    "userEmail": "test@example.com"
  }
}
```

 **구성 사용** 

```
{
  "steps": {
    "1": {
      "url": "${baseUrl}/users",
      "timeout": "${timeout}",
      "headers": {
        "Authorization": "Bearer ${apiKey}"
      }
    }
  }
}
```

## 단계 정의
<a name="step-definitions"></a>

단계는 개별 모니터링 작업을 정의합니다. 각 단계에는 1\$110까지의 번호가 지정되며 특정 유형의 검사가 포함됩니다.

 *공통 단계 속성* 


| 속성 | Type | 필수 | 설명 | 
| --- | --- | --- | --- | 
|  stepName  | 문자열 |  예  | 단계의 고유 식별자 | 
|  checkerType  | 문자열 |  예  | 검사 유형: HTTP, DNS, SSL,  TCP  | 
|  extractors  | 배열 | 아니요 | 데이터 추출 구성 | 

 *단계 이름 검증* 
+ 패턴 - ^[a-zA-Z][a-zA-Z0-9\$1-]\$1\$1
+ 최대 길이 - 64자
+ 문자로 시작해야 함

 *단계 번호 지정* 
+ 단계는 문자열 키로 번호가 지정됨: "1", "2", ..., "10"
+ 패턴: ^([1-9]\$110)\$1
+ 최소 1개의 단계 필요
+ 최대 10단계 허용

 *예제* 

```
{
  "steps": {
    "1": {
      "stepName": "loginAPI",
      "checkerType": "HTTP",
      "url": "https://api.example.com/login",
      "httpMethod": "POST"
    },
    "2": {
      "stepName": "dnsCheck",
      "checkerType": "DNS",
      "domain": "example.com"
    }
  }
}
```

## 검사 유형
<a name="check-types"></a>

### HTTP 검사
<a name="http-types"></a>

포괄적인 요청 및 응답 검증을 통해 웹 엔드포인트 및 API를 모니터링합니다.

 **필수 속성** 


| 속성 | Type | 설명 | 
| --- | --- | --- | 
|  url  | 문자열 | 대상 URL(올바른 URI 형식이어야 함) | 
|  httpMethod  | 문자열 | HTTP 메서드: GET, POST, PUT,  PATCH, DELETE, HEAD, OPTIONS  | 

 **선택적 속성** 


| 속성 | Type | 기본값 | Range | 설명 | 
| --- | --- | --- | --- | --- | 
|  timeout  | 정수 | 30000 | 5000\$1300000 | 요청 제한 시간(밀리초) | 
|  waitTime  | 정수 | 0 | 0-60 | 요청까지 걸리는 지연 시간(초) | 
|  headers  | 객체 | - | - | 사용자 지정 HTTP 헤더 | 
|  body  | 문자열 | - | - | POST/PUT 작업에 대한 요청 본문 | 
|  authentication  | 객체 | - | - | 인증 구성 | 
|  assertions  | 배열 | - | - | 응답 검증 규칙 | 

 **예제** 

```
{
  "stepName": "createUser",
  "checkerType": "HTTP",
  "url": "https://api.example.com/users",
  "httpMethod": "POST",
  "timeout": 15000,
  "headers": {
    "Content-Type": "application/json",
    "X-API-Version": "v1"
  },
  "body": "{\"name\":\"John Doe\",\"email\":\"john@example.com\"}",
  "authentication": {
    "type": "API_KEY",
    "apiKey": "${AWS_SECRET:api-credentials}",
    "headerName": "X-API-Key"
  },
  "assertions": [
    {
      "type": "STATUS_CODE",
      "operator": "EQUALS",
      "value": 201
    }
  ]
}
```

### DNS 검사
<a name="dns-types"></a>

DNS 확인 및 레코드 정보를 검증합니다.

 **필수 속성** 


| 속성 | Type | 설명 | 
| --- | --- | --- | 
|  domain  | 문자열 | 쿼리할 도메인 이름(호스트 이름 형식) | 

 **선택적 속성** 


| 속성 | Type | 기본값 | 설명 | 
| --- | --- | --- | --- | 
|  recordType  | 문자열 | "A" | DNS 레코드 유형: A, CNAME, MX,  TXT, NS  | 
|  nameserver  | 문자열 | - | 쿼리할 특정 DNS 서버 | 
|  timeout  | 정수 | 30000 | 쿼리 제한 시간(5000\$1300000ms) | 
|  port  | 정수 | 53 | DNS 서버 포트(1\$165535) | 
|  protocol  | 문자열 | "UDP" | 프로토콜: UDP 또는 TCP | 
|  assertions  | 배열 | - | DNS 응답 검증 규칙 | 

 **예제** 

```
{
  "stepName": "dnsResolution",
  "checkerType": "DNS",
  "domain": "example.com",
  "recordType": "A",
  "nameserver": "8.8.8.8",
  "timeout": 10000,
  "assertions": [
    {
      "type": "RECORD_VALUE",
      "operator": "CONTAINS",
      "value": "192.168"
    }
  ]
}
```

### SSL 검사
<a name="ssl-types"></a>

SSL 인증서 상태 및 구성을 모니터링합니다.

 **필수 속성** 


| 속성 | Type | 설명 | 
| --- | --- | --- | 
|  hostname  | 문자열 | 대상 호스트 이름(호스트 이름 형식) | 

 **선택적 속성** 


| 속성 | Type | 기본값 | 설명 | 
| --- | --- | --- | --- | 
|  port  | 정수 | 443 | SSL 포트(1\$165535) | 
|  timeout  | 정수 | 30000 | 연결 제한 시간(5000\$1300000ms) | 
|  sni  | 부울 | TRUE | 서버 이름 표시 | 
|  verifyHostname  | 부울 | TRUE | 호스트 이름 확인 | 
|  allowSelfSigned  | 부울 | FALSE | 자체 서명 인증서 수락 | 
|  assertions  | 배열 | - | 인증서 검증 규칙 | 

 **예제** 

```
{
  "stepName": "sslCertCheck",
  "checkerType": "SSL",
  "hostname": "secure.example.com",
  "port": 443,
  "sni": true,
  "verifyHostname": true,
  "assertions": [
    {
      "type": "CERTIFICATE_EXPIRY",
      "operator": "GREATER_THAN",
      "value": 30,
      "unit": "DAYS"
    }
  ]
}
```

### TCP 검사
<a name="tcp-types"></a>

TCP 포트 연결 및 응답 검증을 테스트합니다.

 **필수 속성** 


| 속성 | Type | 설명 | 
| --- | --- | --- | 
|  hostname  | 문자열 | 대상 호스트 이름(호스트 이름 형식) | 
|  port  | 정수 | 대상 포트(1\$165535) | 

 **선택적 속성** 


| 속성 | Type | 기본값 | 설명 | 
| --- | --- | --- | --- | 
|  timeout  | 정수 | 30000 | 전체 제한 시간(5000\$1300000ms) | 
|  connectionTimeout  | 정수 | 3000 | 연결 제한 시간(5000\$1300000ms) | 
|  readTimeout  | 정수 | 2000 | 데이터 읽기 제한 시간(5000\$1300000ms) | 
|  sendData  | 문자열 | - | 연결 후 전송할 데이터 | 
|  expectedResponse  | 문자열 | - | 예상 응답 데이터 | 
|  encoding  | 문자열 | "UTF-8" | 데이터 인코딩: UTF-8, ASCII, HEX  | 
|  assertions  | 배열 | - | 연결 및 응답 검증 | 

 **예제** 

```
{
  "stepName": "databaseConnection",
  "checkerType": "TCP",
  "hostname": "db.example.com",
  "port": 3306,
  "connectionTimeout": 5000,
  "sendData": "SELECT 1",
  "expectedResponse": "1",
  "assertions": [
    {
      "type": "CONNECTION_SUCCESSFUL",
      "value": true
    }
  ]
}
```

## 인증 방법
<a name="authentication-methods"></a>

 **인증 없음** 

```
{
  "type": "NONE"
}
```

 **기본 인증** 


| 속성 | Type | 필수 | 설명 | 
| --- | --- | --- | --- | 
|  type  | 문자열 |  예  | "BASIC"이어야 합니다. | 
|  username  | 문자열 |  예  | 인증에 사용할 사용자 이름 | 
|  password  | 문자열 |  예  | 인증에 사용할 암호 | 

 **예제** 

```
{
  "type": "BASIC",
  "username": "admin",
  "password": "${AWS_SECRET:basic-auth:password}"
}
```

 **API 키 인증** 


| 속성 | Type | 필수 | 기본값 | 설명 | 
| --- | --- | --- | --- | --- | 
|  type  | 문자열 |  예  | - | "API\$1KEY"이어야 합니다. | 
|  apiKey  | 문자열 |  예  | - | API 키 값 | 
|  headerName  | 문자열 | No | "X-API-Key" | API 키의 헤더 이름 | 

 **예제** 

```
{
  "type": "API_KEY",
  "apiKey": "${AWS_SECRET:api-credentials}",
  "headerName": "Authorization"
}
```

 **OAuth 클라이언트 자격 증명** 


| 속성 | Type | 필수 | 기본값 | 설명 | 
| --- | --- | --- | --- | --- | 
|  type  | 문자열 |  예  | - | "OAUTH\$1CLIENT\$1CREDENTIALS"이어야 합니다. | 
|  tokenUrl  | 문자열 |  예  | - | OAuth 토큰 엔드포인트 URL | 
|  clientId  | 문자열 |  예  | - | OAuth 클라이언트 ID | 
|  clientSecret  | 문자열 |  예  | - | OAuth 클라이언트 보안 암호 | 
|  scope  | 문자열 | No | - | OAuth 범위 | 
|  audience  | 문자열 | No | - | OAuth 대상 | 
|  resource  | 문자열 | No | - | OAuth 리소스 | 
|  tokenApiAuth  | 배열 | 아니요 | - | 토큰 API 인증 메서드: BASIC\$1AUTH\$1HEADER, REQUEST\$1BODY  | 
|  tokenCacheTtl  | 정수 | 아니요 | 3600 | 토큰 캐시 TTL(최소 60초) | 

 **예제** 

```
{
  "type": "OAUTH_CLIENT_CREDENTIALS",
  "tokenUrl": "https://auth.example.com/oauth/token",
  "clientId": "${AWS_SECRET:oauth-creds:client_id}",
  "clientSecret": "${AWS_SECRET:oauth-creds:client_secret}",
  "scope": "read write",
  "tokenCacheTtl": 7200
}
```

 **AWS 서명(버전 4)** 


| 속성 | Type | 필수 | 설명 | 
| --- | --- | --- | --- | 
|  type  | 문자열 |  예  | "SIGV4"이어야 합니다. | 
|  service  | 문자열 |  예  | AWS 서비스의 이름(예: "execute-api") | 
|  region  | 문자열 |  예  | AWS 리전 | 
|  roleArn  | 문자열 |  예  | 서명을 위한 IAM 역할 ARN | 

 **예제** 

```
{
  "type": "SIGV4",
  "service": "execute-api",
  "region": "us-east-1",
  "roleArn": "arn:aws:iam::123456789012:role/SyntheticsRole"
}
```

## 어설션 및 검증
<a name="assertions-validation"></a>

### HTTP 어설션
<a name="http-assertions"></a>

 **상태 코드 어설션** 


| 속성 | Type | 필수 | 설명 | 
| --- | --- | --- | --- | 
|  type  | 문자열 |  예  | "STATUS\$1CODE"이어야 합니다. | 
|  operator  | 문자열 |  예  | EQUALS, NOT\$1EQUALS, GREATER\$1THAN,  LESS\$1THAN, IN\$1RANGE | 
|  value  | 정수 | 조건부 | HTTP 상태 코드(100\$1599) | 
|  rangeMin  | 정수 | 조건부 | 최소 범위 값(IN\$1RANGE에 사용) | 
|  rangeMax  | 정수 | 조건부 | 최대 범위 값(IN\$1RANGE에 사용) | 

```
{
  "type": "STATUS_CODE",
  "operator": "EQUALS",
  "value": 200
}
```

 **응답 시간 어설션** 


| 속성 | Type | 필수 | 기본값 | 설명 | 
| --- | --- | --- | --- | --- | 
|  type  | 문자열 |  예  | - | "RESPONSE\$1TIME"이어야 합니다. | 
|  operator  | 문자열 |  예  | - | LESS\$1THAN, GREATER\$1THAN, EQUALS | 
|  value  | number |  예  | - | 시간 값(최소 0) | 
|  unit  | 문자열 | No | "MILLISECONDS" | "MILLISECONDS"이어야 합니다. | 

```
{
  "type": "RESPONSE_TIME",
  "operator": "LESS_THAN",
  "value": 500,
  "unit": "MILLISECONDS"
}
```

 **헤드 어설션** 


| 속성 | Type | 필수 | 설명 | 
| --- | --- | --- | --- | 
|  type  | 문자열 |  예  | "HEADER"이어야 합니다. | 
|  headerName  | 문자열 |  예  | 검증할 헤더 이름 | 
|  operator  | 문자열 |  예  | EQUALS, NOT\$1EQUALS, CONTAINS,  NOT\$1CONTAINS, REGEX\$1MATCH, EXIST | 
|  value  | 문자열/부울 | 조건부 | 예상 값(EXIST 연산자의 경우 부울) | 

```
{
  "type": "HEADER",
  "headerName": "Content-Type",
  "operator": "CONTAINS",
  "value": "application/json"
}
```

 **본문 어설션** 


| 속성 | Type | 필수 | 기본값 | 설명 | 
| --- | --- | --- | --- | --- | 
|  type  | 문자열 |  예  | - | "BODY"이어야 합니다. | 
|  target  | 문자열 | No | "JSON" | JSON 또는 TEXT | 
|  path  | 문자열 | 조건부 | - | JSONPath(JSON 대상에 필요) | 
|  operator  | 문자열 |  예  | - | CONTAINS, NOT\$1CONTAINS, EQUALS,  NOT\$1EQUALS, EXISTS | 
|  value  | 문자열/부울 |  예  | - | 예상 값(EXISTS 연산자의 경우 부울) | 

```
{
  "type": "BODY",
  "target": "JSON",
  "path": "$.users[0].name",
  "operator": "EQUALS",
  "value": "John Doe"
}
```

### DNS 어설션
<a name="dns-assertions"></a>

 **레코드 값 어설션** 


| 속성 | Type | 필수 | Range | 설명 | 
| --- | --- | --- | --- | --- | 
|  type  | 문자열 |  예  | - | "RECORD\$1VALUE"이어야 합니다. | 
|  operator  | 문자열 |  예  | - | EQUALS, NOT\$1EQUALS, CONTAINS,  NOT\$1CONTAINS, REGEX\$1MATCH | 
|  value  | 문자열 |  예  | - | 예상 레코드 값 | 

 **레코드 수 어설션** 


| 속성 | Type | 필수 | Range | 설명 | 
| --- | --- | --- | --- | --- | 
|  type  | 문자열 |  예  | - | "RECORD\$1COUNT"이어야 합니다. | 
|  operator  | 문자열 |  예  | - | EQUALS, GREATER\$1THAN, LESS\$1THAN | 
|  value  | 정수 |  예  | ≥ 0 | 예상 개수(최소 0) | 

 **신뢰할 수 있는 어설션** 


| 속성 | Type | 필수 | Range | 설명 | 
| --- | --- | --- | --- | --- | 
|  type  | 문자열 |  예  | - | "AUTHORITATIVE"이어야 합니다. | 
|  value  | 부울 |  예  | - | 예상되는 신뢰할 수 있는 상태 | 

 **TTL 어설션** 


| 속성 | Type | 필수 | Range | 설명 | 
| --- | --- | --- | --- | --- | 
|  type  | 문자열 |  예  | - | "TTL"이어야 합니다. | 
|  operator  | 문자열 |  예  | - | EQUALS, GREATER\$1THAN, LESS\$1THAN | 
|  value  | 정수 |  예  | ≥ 0 | 예상 TTL(최소 0) | 

### SSL 어설션
<a name="ssl-assertions"></a>

 **인증서 만료 어설션** 


| 속성 | Type | 필수 | 기본값 | 설명 | 
| --- | --- | --- | --- | --- | 
|  type  | 문자열 |  예  | - | "CERTIFICATE\$1EXPIRY"이어야 합니다. | 
|  operator  | 문자열 |  예  | - | GREATER\$1THAN, LESS\$1THAN | 
|  value  | 정수 |  예  | - | 시간 값(최소 0) | 
|  unit  | 문자열 | No | "DAYS" | DAYS, HOURS | 

 **인증서 제목 어설션** 


| 속성 | Type | 필수 | 기본값 | 설명 | 
| --- | --- | --- | --- | --- | 
|  type  | 문자열 |  예  | - | "CERTIFICATE\$1SUBJECT"이어야 합니다. | 
|  field  | 문자열 |  예  | - | 제목 필드: CN, O, OU, C, ST, L  | 
|  operator  | 문자열 |  예  | - | CONTAINS, EQUALS, REGEX\$1MATCH | 
|  value  | 문자열 |  예  | - | 예상 필드 값 | 

 **인증서 발급자 어설션** 


| 속성 | Type | 필수 | 기본값 | 설명 | 
| --- | --- | --- | --- | --- | 
|  type  | 문자열 |  예  | - | "CERTIFICATE\$1ISSUER"이어야 합니다. | 
|  field  | 문자열 |  예  | - | 발급자 필드: CN, O  | 
|  operator  | 문자열 |  예  | - | CONTAINS, EQUALS | 
|  value  | 문자열 |  예  | - | 예상 필드 값 | 

### TCP 어설션
<a name="tcp-assertions"></a>

 **연결 성공 어설션** 


| 속성 | Type | 필수 | 기본값 | 설명 | 
| --- | --- | --- | --- | --- | 
|  type  | 문자열 |  예  | - | "CONNECTION\$1SUCCESSFUL"이어야 합니다. | 
|  value  | 부울 |  예  | - | 예상 연결 상태 | 

 **응답 데이터 어설션** 


| 속성 | Type | 필수 | 기본값 | 설명 | 
| --- | --- | --- | --- | --- | 
|  type  | 문자열 |  예  | - | "RESPONSE\$1DATA"이어야 합니다. | 
|  operator  | 문자열 |  예  | - | CONTAINS, EQUALS, NOT\$1CONTAINS,  REGEX\$1MATCH, STARTS\$1WITH, ENDS\$1WITH | 
|  value  | 문자열 |  예  | - | 예상 응답 데이터 | 
|  encoding  | 문자열 | No | "UTF-8" | UTF-8, ASCII, HEX | 

## 데이터 추출
<a name="data-extraction"></a>

추출기를 사용하면 응답에서 데이터를 캡처하여 후속 단계에서 사용하거나, 보고 목적으로 사용할 수 있습니다.

 **추출 속성** 


| 속성 | Type | 필수 | 기본값 | 설명 | 
| --- | --- | --- | --- | --- | 
|  name  | 문자열 |  예  | - | 추출된 데이터의 변수 이름 | 
|  type  | 문자열 |  예  | - | 추출 유형: BODY | 
|  path  | 문자열 | No | - | 본문 추출을 위한 JSONPath  | 
|  regex  | 문자열 | No | - | 정규식 패턴 | 
|  regexGroup  | 정수 | 아니요 | 0 | 정규식 캡처 그룹(최소 0) | 

 **추출 이름 검증** 
+ 패턴: `^[a-zA-Z][a-zA-Z0-9_]*$`
+ 문자로 시작해야 함
+ 이름에 문자, 숫자, 밑줄을 포함할 수 있음

**제한 사항** - 특정 ENUM 값이 있는 스키마의 필드에는 대체가 적용되지 않습니다.

 **추출 유형** 

```
{
  "name": "userId",
  "type": "BODY",
  "path": "$.user.id"
}
```

```
{
  "stepName": "loginAndExtract",
  "checkerType": "HTTP",
  "url": "https://api.example.com/login",
  "httpMethod": "POST",
  "body": "{\"username\":\"test\",\"password\":\"pass\"}",
  "extractors": [
    {
      "name": "textVariable",
      "type": "BODY",
      "path": "$.myvalue"
    }
  ]
},
{
  "stepName": "substituteVariable",
  "checkerType": "HTTP",
  "url": "https://api.example.com/get/${textVariable}",
  "httpMethod": "GET",
  "assertions": [
    {
    "type": "BODY",
    "target": "JSON",
    "path": "$.users[0].name",
    "operator": "EQUALS",
    "value": "${textVariable}"
    }
  ]
}
```