CDK를 사용하여 CloudWatch Synthetics 관리

이 문장은 고급 캘린더 2020의 첫날의 문장이다.
첫 지각입니다. 실례합니다.

입문


올해 4월 AWS CloudWatch Synthetics 출시
https://aws.amazon.com/jp/about-aws/whats-new/2020/04/amazon-cloudwatch-synthetics-generally-available/
서비스를 대충 설명하면 REST API와 웹의 동작을 생생하게 감시하고 CI/CD 등 놓치기 쉬운 특정 조건에서 발생할 수 있는 지연의 큰 시기와 예상치 못한 행동을 검사하며 한도값을 초과하면 경보를 울리는 것이 좋다.
이번에는 웹 비헤이비어 모니터링을 진행하여 설정부터 Node를 시작합니다.js 스크립트의 코드를 관리할 수 있도록 CDK로 구현해 보았습니다.
CDK와 AWS 계정 등에 대한 환경 구축은 설명을 생략하고 순서를 고통스럽게 쓴다.
CDK는 필자의 취향에 따라 TypeScript로 작성합니다.

프로젝트 준비

$ mkdir sample-cloudwatch-synthetics
$ cd sample-cloudwatch-synthetics
$ cdk init --language typescript
$ npm install @aws-cdk/aws-synthetics @aws-cdk/aws-cloudwatch 

모니터링 스크립트 만들기


스크립트를 만드는 공식 문서가 여기 있습니다.
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_WritingCanary.html

폴더 계층 설정


여러 개만약 js 파일이나 스크립트 의존성이 존재한다면, 이 모든 파일을 하나의 ZIP 파일로 연결할 수 있습니다. (폴더 구조는 nodejs/node_modules/myCanaryFilename.js file and other folders and files)
위에서 말한 바와 같이 감시용 Canary 스크립트의 폴더 구조는 nodejs/node_modules/myCanaryFilename.js 이어야 하기 때문에 이번에는 감시 대상마다 스크립트를 관리할 수 있도록 다음과 같이 하겠습니다.
src
└── sample-synthetics
    └── nodejs
        └── node_modules
            └── index.js

스크립트 만들기


Canary 스크립트의 라이브러리 함수 공식입니다.
문서에서 보듯이 Canary 스크립트는 Puppeter 패키지 라이브러리Synthetics 패키지와 Synthetics 로그 전용 SyntheticsLogger 패키지를 사용하지만 AWS에 배치할 때 자동으로 사용할 수 있기 때문에 준비할 필요가 없습니다.(로컬 실행 방법에 대한 조사가 없음)
이번 구글 검색에서 검색package.json을 통해 검색 결과의 맨 위에 Qiita 페이지가 표시되는지 감시한다.
src/nodejs/node_modules/index.js
const synthetics = require('Synthetics');
const log = require('SyntheticsLogger');

const pageLoadBlueprint = async function () {
    try {
        // Googleのページにアクセス
        const page = await synthetics.getPage();
        await page.goto('https://www.google.com/', { waitUntil: 'domcontentloaded', timeout: 10000 });

        // 検索バーに'Qiita'と入力し検索
        await page.type('input[name="q"]', 'Qiita');
        await page.keyboard.press('Enter');
        await page.waitFor(5000);

        // 検索結果の1番上をクリック
        page.click('div#search a');
        await page.waitForNavigation({ waitUntil: "domcontentloaded", timeout: 60000 });

        // 'Qiita'のページにアクセスできていることを確認
        const pageTitle = await page.title();
        if (pageTitle === 'Qiita') {
            log.info('Success')
        } else {
            throw new Error('Not Qiita Page!!');
        }
    } catch (e) {
        console.log(e);
        throw e;
    }
};

exports.handler = async () => {
    return await pageLoadBlueprint();
};

CDK를 사용하여 리소스 생성


30분마다synthetics가 한 번씩 실행되며, 30분 안에 측정을 한 번 확인할 수 없으면 알람을 설정합니다.
lib/sample-cloud-watch-synthetics-stack.ts
import * as path from 'path';
import * as cdk from '@aws-cdk/core';
import { Duration } from '@aws-cdk/core';
import { Alarm, ComparisonOperator } from '@aws-cdk/aws-cloudwatch';
import { Canary, Code, Runtime, Schedule, Test } from '@aws-cdk/aws-synthetics';
import { TreatMissingData } from '@aws-cdk/aws-cloudwatch/lib/alarm';

export class SampleCloudwatchSyntheticsStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const APP_NAME = 'SampleCloudwatchSynthetics';
    const SRC_DIR = '../src'

    const canary = new Canary(this, `${APP_NAME}-canary`, {
      canaryName: 'sample-canary',
      schedule: Schedule.rate(Duration.minutes(30)),
      runtime: Runtime.SYNTHETICS_1_0,
      test: Test.custom({
        code: Code.fromAsset(path.join(__dirname, `${SRC_DIR}/sample-synthetics`)),
        handler: 'index.handler',
      }),
    });

    new Alarm(this, `${APP_NAME}-alarm`, {
      alarmName: `${APP_NAME}-Alarm`,
      alarmDescription: 'Qiitaのページにたどり着けるか',
      metric: canary.metricSuccessPercent(),
      threshold: 1,
      comparisonOperator: ComparisonOperator.LESS_THAN_THRESHOLD,
      period: cdk.Duration.minutes(30),
      evaluationPeriods: 1,
      treatMissingData: TreatMissingData.MISSING
    });
  }
}
QiitacanaryName, 다음 오류로 인해 차단할 수 없음
Canary name is too large, must be between 1 and 21 characters, but is 33 (got "SampleCloudwatchSynthetics-Canary")

Canary name must be lowercase, numbers, hyphens, or underscores (got "SampleCanary")

배치

$ npx cdk deploy

AWC 콘솔에서 확인



자원이 생성되고 성공했는지 확인할 수 있습니다.
이로써 구글 검색sample-canary에서 감시Qiita가 가능한 홈페이지가 정상에서 인기를 끌고 있다.
감시할 수 있으니 다음에는 경찰에 신고할 때 Slack에게 알릴 수 있도록 CDK로 설정해 보려고 합니다.

겸사겸사 말씀드리다


생성된 자원을 삭제할 때, 즉시destroy로 삭제할 수 있습니다.
$ npx cdk destroy

좋은 웹페이지 즐겨찾기