View a markdown version of this page

일반적인 카나리 기능 - Amazon CloudWatch

일반적인 카나리 기능

모든 카나리 런타임에서 다음 기능을 사용할 수 있습니다.

환경 변수

카나리를 생성할 때 환경 변수를 사용할 수 있습니다. 단일 카나리 스크립트를 작성하고 다른 값으로 사용하여 유사한 태스크에 대해 여러 카나리를 빠르게 생성할 수 있습니다.

예를 들어 조직에 다양한 소프트웨어 개발 단계에 대한 prod, devpre-release와 같은 엔드포인트가 있다고 가정해 보겠습니다. 각 엔드포인트를 테스트하려면 카나리를 생성해야 합니다. 소프트웨어를 테스트하는 단일 카나리 스크립트를 작성할 수 있습니다. 그런 다음 3개의 카나리를 각각 생성할 때 서로 다른 엔드포인트 환경 변수 값을 지정합니다. 카나리를 생성할 때 스크립트 및 환경 변수 값을 지정합니다.

환경 변수의 이름에는 문자, 숫자, 밑줄 문자가 포함될 수 있습니다. 이름은 문자로 시작해야 하며 2자 이상이어야 합니다. 환경 변수의 총 크기는 4KB를 초과할 수 없습니다. Lambda 예약 환경 변수를 환경 변수의 이름으로 지정할 수 없습니다. 예약된 환경 변수에 대한 자세한 내용은 런타임 환경 변수 단원을 참조하세요.

환경 변수는 클라이언트 측에서 암호화되지 않음

기본적으로 AWS는 AWS 소유 키를 사용하여 저장 시 환경 변수 키와 값을 암호화합니다. 그러나 CloudWatch Synthetics는 클라이언트 측 암호화를 적용하지 않습니다. 민감한 정보는 전송 중 암호화한 후에만 저장합니다. 자세한 내용은 전송 중 환경 변수 암호화 섹션을 참조하세요. 고객 관리형 AWS KMS 키를 사용하여 카나리의 유휴 환경 변수를 암호화할 수도 있습니다. 자세한 내용은 고객 관리형 키로 저장 시 환경 변수 암호화 섹션을 참조하세요.

다음 스크립트 예에서는 두 개의 환경 변수를 사용합니다. 이 스크립트는 웹 페이지를 사용할 수 있는지 여부를 확인하는 canary용입니다. 환경 변수를 사용하여 확인하는 URL과 사용하는 CloudWatch Synthetics 로그 수준을 모두 파라미터화합니다.

다음 코드 스니펫은 아래 표시된 전체 스크립트의 일부입니다.

다음 함수는 LogLevelLOG_LEVEL 환경 변수의 값으로 설정합니다.

synthetics.setLogLevel(process.env.LOG_LEVEL);

다음 함수는 URLURL 환경 변수의 값으로 설정합니다.

const URL = process.env.URL;

다음 전체 스크립트는 두 환경 변수를 모두 보여줍니다. 이 스크립트를 사용하여 canary를 생성할 때 LOG_LEVELURL 환경 변수의 값을 지정합니다.

var synthetics = require('@aws/synthetics-puppeteer'); const log = require('@aws/synthetics-logger'); const pageLoadEnvironmentVariable = async function () { // Setting the log level (0-3) synthetics.setLogLevel(process.env.LOG_LEVEL); // INSERT URL here const URL = process.env.URL; let page = await synthetics.getPage(); //You can customize the wait condition here. For instance, //using 'networkidle2' may be less restrictive. const response = await page.goto(URL, {waitUntil: 'domcontentloaded', timeout: 30000}); if (!response) { throw "Failed to load page!"; } //Wait for page to render. //Increase or decrease wait time based on endpoint being monitored. await page.waitFor(15000); await synthetics.takeScreenshot('loaded', 'loaded'); let pageTitle = await page.title(); log.info('Page title: ' + pageTitle); log.debug('Environment variable:' + process.env.URL); //If the response status code is not a 2xx success code if (response.status() < 200 || response.status() > 299) { throw "Failed to load page!"; } }; exports.handler = async () => { return await pageLoadEnvironmentVariable(); };

스크립트에 환경 변수 전달

콘솔에서 canary를 생성할 때 스크립트에 환경 변수를 전달하려면 콘솔의 [환경 변수(Environment variables)] 섹션에서 환경 변수의 키 및 값을 지정합니다. 자세한 내용은 canary 생성 단원을 참조하세요.

API 또는 AWS CLI를 통해 환경 변수를 전달하려면 RunConfig 섹션에서 EnvironmentVariables 파라미터를 사용합니다. 다음은 EnvironmentRegion 키가 있는 두 개의 환경 변수를 사용하는 canary를 생성하는 AWS CLI 명령의 예입니다.

aws synthetics create-canary --cli-input-json '{ "Name":"nameofCanary", "ExecutionRoleArn":"roleArn", "ArtifactS3Location":"s3://amzn-s3-demo-bucket-123456789012-us-west-2", "Schedule":{ "Expression":"rate(0 minute)", "DurationInSeconds":604800 }, "Code":{ "S3Bucket": "canarycreation", "S3Key": "cwsyn-mycanaryheartbeat-12345678-d1bd-1234-abcd-123456789012-12345678-6a1f-47c3-b291-123456789012.zip", "Handler":"pageLoadBlueprint.handler" }, "RunConfig": { "TimeoutInSeconds":60, "EnvironmentVariables": { "Environment":"Production", "Region": "us-west-1" } }, "SuccessRetentionPeriodInDays":13, "FailureRetentionPeriodInDays":13, "RuntimeVersion":"syn-nodejs-2.0" }'

고객 관리형 키로 저장 시 환경 변수 암호화

기본적으로 AWS 소유 키는 유휴 시 카나리 환경 변수를 암호화합니다. 고객 관리형 AWS KMS 키를 지정하여 유휴 시 카나리 환경 변수를 암호화할 수 있습니다. 고객 관리형 키를 사용하면 민감한 구성 데이터의 암호화를 완벽하게 제어할 수 있습니다. 다음 섹션에서는 고객 관리형 키를 사용하기 위한 요구 사항, 구성 단계 및 권한을 설명합니다.

요구 사항

고객 관리형 키를 구성하기 전에 다음 요구 사항을 충족하는지 확인합니다.

  • AWS KMS 키는 대칭 암호화 키여야 합니다.

  • 키 정책은 호출자(Synthetics API를 직접적으로 호출하는 IAM 위탁자)에게 kms:CreateGrant를 부여해야 합니다.

  • AWS Lambda는 권한 부여를 사용하여 유휴 환경 변수를 암호화하고 복호화합니다.

  • AWS KMS 키는 카나리와 동일한 AWS 리전에 있어야 합니다.

고객 관리형 키 구성

카나리를 생성하거나 업데이트할 때 고객 관리형 키를 구성할 수 있습니다. 다음 절차에서는 Amazon CloudWatch 콘솔과 Synthetics API를 사용하여 암호화를 구성하는 방법을 보여줍니다.

콘솔에서 암호화 구성

Amazon CloudWatch 콘솔에서 카나리를 생성하거나 편집하려면 환경 변수 섹션을 확장합니다. 저장 시 암호화 구성에서 고객 관리형 키 사용을 선택한 다음 AWS KMS 키의 ARN을 선택하거나 지정합니다.

API를 사용하여 암호화 구성

CreateCanary 또는 UpdateCanary를 직접적으로 호출할 때 고객 관리형 키의 ARN으로 KmsKeyArn 파라미터를 지정합니다. AWS 관리형 키로 되돌리려면 KmsKeyArn을 빈 문자열로 설정합니다.

예: 고객 관리형 키를 사용한 CreateCanary 요청

{ "Name": "my-canary-EXAMPLE", "KmsKeyArn": "arn:aws:kms:us-east-1:111122223333:key/a1b2c3d4-e5f6-7890-abcd-EXAMPLE11111", "RunConfig": { "EnvironmentVariables": { "SECRET_KEY": "my-secret-value-EXAMPLE" } } }

저장 시 암호화에 필요한 권한

카나리를 생성하거나 업데이트하는 경우 AWS KMS 키에 대해 다음 권한이 있어야 합니다.

  • kms:CreateGrant, kms:Encrypt- 카나리에 대한 고객 관리형 키를 구성하는 데 필요합니다.

  • kms:Decrypt – 고객 관리형 키로 암호화된 환경 변수를 보고 관리하는 데 필요합니다.

  • kms:DescribeKey- 키를 검증하는 데 필요합니다.

카나리 실행 역할에는 저장 시 암호화를 위한 AWS KMS 권한이 필요하지 않습니다. Lambda는 권한 부여를 사용하여 암호화와 복호화를 처리합니다.

다중 위치 카나리

다중 위치 카나리의 경우 각 복제본 위치에 자체 AWS KMS 키가 있을 수 있습니다. 카나리를 생성하거나 업데이트할 때 AddReplicaLocations 파라미터에서 KmsKeyArn을 지정합니다. 키가 복제본과 동일한 리전에 있어야 합니다.

전송 중 환경 변수 암호화

저장 시 암호화 외에도 CloudWatch Synthetics가 저장하기 전에 개별 환경 변수 값을 암호화할 수 있습니다. CloudWatch Synthetics는 이를 전송 중 암호화라고 합니다. 전송 중 값을 암호화하면 콘솔은 일반 텍스트 값을 카나리만 런타임에 복호화할 수 있는 base64로 인코딩된 사이퍼텍스트로 바꿉니다.

전송 중 암호화 작동 방식

전송 중 환경 변수 값을 암호화하도록 선택하는 경우

  1. 콘솔은 선택한 AWS KMS 키로 kms:Encrypt를 직접적으로 호출하여 일반 텍스트 값을 암호화합니다.

  2. 암호화된 사이퍼텍스트(base64 인코딩)는 환경 변수 구성의 일반 텍스트 값을 대체합니다.

  3. 런타임 시 카나리 스크립트는 kms:Decrypt를 직접적으로 호출하여 값을 복호화합니다.

전송 중 암호화에 필요한 권한

전송 중 암호화에는 다음 권한이 필요합니다.

  • 콘솔 사용자 또는 API 호출자 - AWS KMS 키에 대한 kms:Encrypt입니다. 값을 저장하기 전에 암호화하려면 이 권한이 필요합니다.

  • 카나리아 실행 역할 - AWS KMS 키에 대한 kms:Decrypt입니다. 카나리의 Lambda 함수는 런타임 시 값을 복호화하려면 이 권한이 필요합니다.

다음은 카나리 실행 역할에 연결할 예제 IAM 정책입니다.

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "kms:Decrypt", "Resource": "arn:aws:kms:us-east-1:111122223333:key/a1b2c3d4-e5f6-7890-abcd-EXAMPLE11111" } ] }

카나리 스크립트의 값 복호화

카나리 스크립트에서 암호화된 환경 변수를 사용하려면 런타임에 복호화합니다. 다음 Node.js 예제에서는 환경 변수를 복호화하는 방법을 보여줍니다.

const { KMSClient, DecryptCommand } = require('@aws-sdk/client-kms'); const client = new KMSClient({ region: process.env.AWS_REGION }); async function decryptEnvVar(name) { const encrypted = process.env[name]; const req = { CiphertextBlob: Buffer.from(encrypted, 'base64'), }; const command = new DecryptCommand(req); const response = await client.send(command); return new TextDecoder().decode(response.Plaintext); } // Usage const mySecret = await decryptEnvVar('MY_CONFIG_VAR');

다른 AWS 서비스와 canary 통합

카나리의 AWS SDK 라이브러리를 사용하여 다른 AWS 서비스와 통합할 수 있습니다.

이렇게 하려면 카나리에 다음 코드를 추가합니다. 이 예제에서 카나리는 AWS Secrets Manager와 통합됩니다.

  • AWS SDK를 가져옵니다.

    const AWS = require('aws-sdk');
  • 통합하려는 AWS 서비스에 대한 클라이언트를 생성합니다.

    const secretsManager = new AWS.SecretsManager();
  • 클라이언트를 사용하여 해당 서비스에 대한 API 호출을 수행합니다.

    var params = { SecretId: secretName }; return await secretsManager.getSecretValue(params).promise();

다음 카나리 스크립트 코드 스니펫은 Secrets Manager와 통합하는 방법을 자세히 보여줍니다.

var synthetics = require('@aws/synthetics-puppeteer'); const log = require('@aws/synthetics-logger'); const AWS = require('aws-sdk'); const secretsManager = new AWS.SecretsManager(); const getSecrets = async (secretName) => { var params = { SecretId: secretName }; return await secretsManager.getSecretValue(params).promise(); } const secretsExample = async function () { let URL = "<URL>"; let page = await synthetics.getPage(); log.info(`Navigating to URL: ${URL}`); const response = await page.goto(URL, {waitUntil: 'domcontentloaded', timeout: 30000}); // Fetch secrets let secrets = await getSecrets("secretname") /** * Use secrets to login. * * Assuming secrets are stored in a JSON format like: * { * "username": "<USERNAME>", * "password": "<PASSWORD>" * } **/ let secretsObj = JSON.parse(secrets.SecretString); await synthetics.executeStep('login', async function () { await page.type(">USERNAME-INPUT-SELECTOR<", secretsObj.username); await page.type(">PASSWORD-INPUT-SELECTOR<", secretsObj.password); await Promise.all([ page.waitForNavigation({ timeout: 30000 }), await page.click(">SUBMIT-BUTTON-SELECTOR<") ]); }); // Verify login was successful await synthetics.executeStep('verify', async function () { await page.waitForXPath(">SELECTOR<", { timeout: 30000 }); }); }; exports.handler = async () => { return await secretsExample(); };

canary가 고정 IP 주소를 사용하도록 지정

canary가 고정 IP 주소를 사용하도록 canary를 설정할 수 있습니다.

canary가 고정 IP 주소를 사용하도록 지정하려면
  1. 새 VPC를 생성합니다. 자세한 내용은 VPC에서 DNS 사용하기 섹션을 참조하세요.

  2. 새 인터넷 게이트웨이를 생성합니다. 자세한 내용은 VPC에 인터넷 게이트웨이 추가 단원을 참조하세요.

  3. 새 VPC 내부에 퍼블릭 서브넷을 생성합니다.

  4. VPC에 새 라우팅 테이블을 추가합니다.

  5. 0.0.0.0/0에서 인터넷 게이트웨이로 이동하는 경로를 새 라우팅 테이블에 추가합니다.

  6. 새 라우팅 테이블을 퍼블릭 서브넷과 연결합니다.

  7. 탄력적 IP 주소를 생성합니다. 자세한 내용은 탄력적인 IP 주소 섹션을 참조하십시오.

  8. 새 NAT 게이트웨이를 생성하여 퍼블릭 서브넷 및 탄력적 IP 주소에 할당합니다.

  9. VPC 내부에 프라이빗 서브넷을 생성합니다.

  10. 0.0.0.0/0에서 NAT 게이트웨이로 이동하는 경로를 VPC 기본 라우팅 테이블에 추가합니다.

  11. canary를 생성합니다.