v AWS CDK 2 개발자 안내서입니다. 이전 CDK v1은 2022년 6월 1일에 유지 관리에 들어갔으며 2023년 6월 1일에 지원이 종료되었습니다.
기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
에서 AWS Cloud Development Kit (AWS CDK)토큰은 구문을 정의하거나 스택을 합성할 때 알려지지 않은 값의 자리 표시자입니다. 이러한 값은 실제 인프라가 생성될 때 배포 시 완전히 해결됩니다. AWS CDK 애플리케이션을 개발할 때 토큰을 사용하여 애플리케이션 전체에서 이러한 값을 관리합니다.
토큰 예
다음은 Amazon Simple Storage Service(Amazon S3) 버킷의 구문을 정의하는 CDK 스택의 예입니다. 버킷의 이름은 아직 알 수 없으므로 bucketName
의 값은 토큰으로 저장됩니다.
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
export class CdkDemoAppStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Define an S3 bucket
const myBucket = new s3.Bucket(this, 'myBucket');
// Store value of the S3 bucket name
const myBucketName = myBucket.bucketName;
// Print the current value for the S3 bucket name at synthesis
console.log("myBucketName: " + bucketName);
}
}
스택을 합성하기 위해 cdk synth
를 실행하면 myBucketName
의 값이 ${Token[TOKEN.
토큰 형식으로 표시됩니다. 이 토큰 형식은가 토큰을 AWS CDK 인코딩하는 방식의 결과입니다. 이 예에서는 토큰이 문자열로 인코딩됩니다.1234
]}
$
cdk synth --quiet
myBucketName: ${Token[TOKEN.21
]}
합성 시 버킷 이름의 값을 알 수 없으므로 토큰은 myBucket
로 렌더링됩니다. AWS CloudFormation 템플릿은 <unique-hash>
Ref
내장 함수를 사용하여 배포 시 알려진 값을 참조합니다.
Resources:
myBucket5AF9C99B
:
# ...
Outputs:
bucketNameOutput:
Description: The name of the S3 bucket
Value:
Ref: myBucket5AF9C99B
고유한 해시가 생성되는 방법에 대한 자세한 내용은 AWS CloudFormation 템플릿에서 생성된 논리적 IDs 섹션을 참조하세요.
토큰 전달
토큰은 마치 토큰이 나타내는 실제 값인 것처럼 전달될 수 있습니다. 다음은 버킷 이름의 토큰을 AWS Lambda 함수의 구문에 전달하는 예제입니다.
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as lambda from 'aws-cdk-lib/aws-lambda';
export class CdkDemoAppStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Define an S3 bucket
const myBucket = new s3.Bucket(this, 'myBucket');
// ...
// Define a Lambda function
const myFunction = new lambda.Function(this, "myFunction", {
runtime: lambda.Runtime.NODEJS_20_X,
handler: "index.handler",
code: lambda.Code.fromInline(`
exports.handler = async function(event) {
return {
statusCode: 200,
body: JSON.stringify('Hello World!'),
};
};
`),
functionName: myBucketName + "Function", // Pass token for the S3 bucket name
environment: {
BUCKET_NAME: myBucketName, // Pass token for the S3 bucket name
}
});
}
}
템플릿을 합성할 때 Ref
및 Fn::Join
내장 함수를 사용하여 배포 시 알려진 값을 지정합니다.
Resources:
myBucket5AF9C99B
:
Type: AWS::S3::Bucket
# ...
myFunction884E1557
:
Type: AWS::Lambda::Function
Properties:
# ...
Environment:
Variables:
BUCKET_NAME:
Ref: myBucket5AF9C99B
FunctionName:
Fn::Join:
- ""
- - Ref: myBucket5AF9C99B
- Function
# ...
토큰 인코딩 작동 방식
토큰은 단일 resolve
메서드를 포함하는 IResolvable
인터페이스를 구현하는 객체입니다. 합성 중에는이 메서드를 AWS CDK 호출하여 CloudFormation 템플릿에서 토큰의 최종 값을 생성합니다.
참고
IResolvable
인터페이스로 직접 작업하는 경우는 거의 없습니다. 문자열로 인코딩된 버전의 토큰만 표시될 가능성이 높습니다.
토큰 인코딩 유형
토큰은 합성 프로세스에 참여하여 모든 유형의 임의 값을 생성합니다. 다른 함수는 일반적으로 string
또는 number
와 같은 기본 유형의 인수만 수락합니다. 이러한 경우 토큰을 사용하려면 cdk.Token
클래스에서 정적 메서드를 사용하여 토큰을 세 가지 유형 중 하나로 인코딩할 수 있습니다.
-
Token.asString
- 문자열 인코딩을 생성하거나 토큰 객체에서.toString()
을 직접적으로 호출합니다. -
Token.asList
- 목록 인코딩을 생성합니다. -
Token.asNumber
- 숫자 인코딩을 생성합니다.
이들은 임의의 값을 가져와 IResolvable
이 될 수 있으며, 표시된 유형의 기본 값으로 인코딩합니다.
중요
이전 유형 중 하나가 인코딩된 토큰일 가능성이 있으므로 콘텐츠를 구문 분석하거나 읽으려고 할 때 주의해야 합니다. 예를 들어 문자열에서 값을 추출하기 위해 문자열을 구문 분석하려고 하는데 문자열이 인코딩된 토큰인 경우 구문 분석이 실패합니다. 마찬가지로 배열 길이를 쿼리하거나 숫자를 사용하여 수학 작업을 수행하려는 경우 먼저 해당 배열이 인코딩된 토큰이 아닌지 확인해야 합니다.
앱에서 토큰을 확인하는 방법
값에 해결되지 않은 토큰이 있는지 확인하려면 Token.isUnresolved
(Python: is_unresolved
) 메서드를 직접적으로 호출합니다. 다음은 Amazon S3 버킷 이름의 값이 토큰인지 확인하는 예입니다. 토큰이 아닌 경우 버킷 이름의 길이를 확인합니다.
// ...
export class CdkDemoAppStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Define an S3 bucket
const myBucket = new s3.Bucket(this, 'myBucket');
// ...
// Check if bucket name is a token. If not, check if length is less than 10 characters
if (cdk.Token.isUnresolved(myBucketName)) {
console.log("Token identified.");
} else if (!cdk.Token.isUnresolved(myBucketName) && myBucketName.length > 10) {
throw new Error('Maximum length for name is 10 characters.');
};
// ...
cdk synth
를 실행하면 myBucketName
이 토큰으로 식별됩니다.
$
cdk synth --quiet
Token identified.
참고
토큰 인코딩을 사용하여 유형 시스템을 이스케이프할 수 있습니다. 예를 들어 합성 시 숫자 값을 생성하는 토큰을 문자열로 인코딩할 수 있습니다. 이러한 함수를 사용하는 경우 합성 후 템플릿이 사용 가능한 상태로 확인되는지 확인하는 것은 사용자의 책임입니다.
문자열 인코딩 토큰 작업
문자열로 인코딩된 토큰은 다음과 같습니다.
${TOKEN[Bucket.Name.1234]}
다음 예와 같이 일반 문자열처럼 전달하고 연결할 수 있습니다.
const functionName = bucket.bucketName + 'Function';
다음 예와 같이 언어에서 지원하는 경우 문자열 보간을 사용할 수도 있습니다.
const functionName = `${bucket.bucketName}Function`;
다른 방식으로 문자열을 조작하지 마세요. 예를 들어 문자열의 하위 문자열을 사용하면 문자열 토큰이 파손될 수 있습니다.
목록 인코딩 토큰 작업
목록 인코딩 토큰은 다음과 같습니다.
["#{TOKEN[Stack.NotificationArns.1234]}"]
이러한 목록을 안전하게 사용할 수 있는 유일한 방법은 다른 구문에 직접 전달하는 것입니다. 문자열 목록 형식의 토큰은 연결할 수 없으며 토큰에서 요소를 가져올 수도 없습니다. 이를 처리하는 유일한 안전한 방법은 Fn.select와 같은 AWS CloudFormation 내장 함수를 사용하는 것입니다.
숫자로 인코딩된 토큰 작업
숫자로 인코딩된 토큰은 다음과 같은 작은 음의 부동 소수점 숫자 집합입니다.
-1.8881545897087626e+289
목록 토큰과 마찬가지로 숫자 값을 수정할 수 없습니다. 이렇게 하면 숫자 토큰이 손상될 수 있습니다.
다음은 숫자로 인코딩된 토큰이 포함된 구문의 예입니다.
import { Stack, Duration, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as rds from 'aws-cdk-lib/aws-rds';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
export class CdkDemoAppStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// Define a new VPC
const vpc = new ec2.Vpc(this, 'MyVpc', {
maxAzs: 3, // Maximum number of availability zones to use
});
// Define an RDS database cluster
const dbCluster = new rds.DatabaseCluster(this, 'MyRDSCluster', {
engine: rds.DatabaseClusterEngine.AURORA,
instanceProps: {
vpc,
},
});
// Get the port token (this is a token encoded as a number)
const portToken = dbCluster.clusterEndpoint.port;
// Print the value for our token at synthesis
console.log("portToken: " + portToken);
}
}
cdk synth
를 실행하면 portToken
의 값이 숫자로 인코딩된 토큰으로 표시됩니다.
$
cdk synth --quiet
portToken: -1.8881545897087968e+289
패스 번호 인코딩 토큰
숫자로 인코딩된 토큰을 다른 구문에 전달할 때는 먼저 문자열로 변환하는 것이 좋습니다. 예를 들어 숫자로 인코딩된 문자열의 값을 연결 문자열의 일부로 사용하려는 경우 변환하면 가독성을 높이는 데 도움이 됩니다.
다음 예에서 portToken
은 connectionString
의 일부로 Lambda 함수에 전달하려는 숫자로 인코딩된 토큰입니다.
import { Stack, Duration, CfnOutput, StackProps } from 'aws-cdk-lib';
// ...
import * as lambda from 'aws-cdk-lib/aws-lambda';
export class CdkDemoAppStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// Define a new VPC
// ...
// Define an RDS database cluster
// ...
// Get the port token (this is a token encoded as a number)
const portToken = dbCluster.clusterEndpoint.port;
// ...
// Example connection string with the port token as a number
const connectionString = `jdbc:mysql://mydb.cluster.amazonaws.com:${portToken}/mydatabase`;
// Use the connection string as an environment variable in a Lambda function
const myFunction = new lambda.Function(this, 'MyLambdaFunction', {
runtime: lambda.Runtime.NODEJS_20_X,
handler: 'index.handler',
code: lambda.Code.fromInline(`
exports.handler = async function(event) {
return {
statusCode: 200,
body: JSON.stringify('Hello World!'),
};
};
`),
environment: {
DATABASE_CONNECTION_STRING: connectionString, // Using the port token as part of the string
},
});
// Output the value of our connection string at synthesis
console.log("connectionString: " + connectionString);
// Output the connection string
new CfnOutput(this, 'ConnectionString', {
value: connectionString,
});
}
}
이 값을 connectionString
에 전달하면 cdk synth
실행 시 출력 값이 숫자로 인코딩된 문자열로 인해 혼동될 수 있습니다.
$
cdk synth --quiet
connectionString: jdbc:mysql://mydb.cluster.amazonaws.com:-1.888154589708796e+289/mydatabase
숫자로 인코딩된 토큰을 문자열로 변환하려면 cdk.Tokenization.stringifyNumber(
를 사용합니다. 다음 예에서는 연결 문자열을 정의하기 전에 숫자로 인코딩된 토큰을 문자열로 변환합니다.token
)
import { Stack, Duration, Tokenization, CfnOutput, StackProps } from 'aws-cdk-lib';
// ...
export class CdkDemoAppStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// Define a new VPC
// ...
// Define an RDS database cluster
// ...
// Get the port token (this is a token encoded as a number)
const portToken = dbCluster.clusterEndpoint.port;
// ...
// Convert the encoded number to an encoded string for use in the connection string
const portAsString = Tokenization.stringifyNumber(portToken);
// Example connection string with the port token as a string
const connectionString = `jdbc:mysql://mydb.cluster.amazonaws.com:${portAsString}/mydatabase`;
// Use the connection string as an environment variable in a Lambda function
const myFunction = new lambda.Function(this, 'MyLambdaFunction', {
// ...
environment: {
DATABASE_CONNECTION_STRING: connectionString, // Using the port token as part of the string
},
});
// Output the value of our connection string at synthesis
console.log("connectionString: " + connectionString);
// Output the connection string
new CfnOutput(this, 'ConnectionString', {
value: connectionString,
});
}
}
cdk synth
를 실행하면 연결 문자열의 값이 더 깨끗하고 명확한 형식으로 표시됩니다.
$
cdk synth --quiet
connectionString: jdbc:mysql://mydb.cluster.amazonaws.com:${Token[TOKEN.242]}/mydatabase
지연 값
AWS CloudFormation 토큰은 파라미터와 같은 배포 시간 값을 나타내는 것 외에도 합성 시간 지연 값을 나타내는 데도 일반적으로 사용됩니다. 이는 값이 생성되는 시점에 결정되지 않고 합성이 완료되기 전에 최종 값이 결정되는 값입니다. 토큰을 사용하여 리터럴 문자열이나 숫자 값을 다른 구문에 전달하는데, 합성 시점의 실제 값은 아직 발생하지 않은 계산에 따라 달라질 수 있습니다.
Lazy.string
및 Lazy.number
와 같은 Lazy
클래스의 정적 메서드를 사용하여 합성 시간 지연 값을 나타내는 토큰을 작성할 수 있습니다. 이러한 메서드는 produce
속성이 컨텍스트 인수를 수락하고 직접 호출 시 최종 값을 반환하는 함수인 객체를 수락합니다.
다음 예에서는 용량이 생성된 후 결정되는 Auto Scaling 그룹을 생성합니다.
let actualValue: number;
new AutoScalingGroup(this, 'Group', {
desiredCapacity: Lazy.numberValue({
produce(context) {
return actualValue;
}
})
});
// At some later point
actualValue = 10;
JSON으로 변환
임의 데이터의 JSON 문자열을 생성하려고 하는데 데이터에 토큰이 포함되어 있는지 모를 수도 있습니다. 토큰이 포함되어 있는지 여부에 관계없이 모든 데이터 구문을 적절하게 JSON 인코딩하려면 다음 예와 같이 메서드 stack.toJsonString
을 사용합니다.
const stack = Stack.of(this);
const str = stack.toJsonString({
value: bucket.bucketName
});