CloudFormation通过AwsCustomResource AWS SDK调用(CodeArtifact get



我发现了一些关于使用AwsCustomResource从AWS CDK构造中进行AWS SDK调用的问题和答案,但在响应可能很大、cfn响应超过4KB左右限制的用例中没有发现。

我的目标是能够从我的CDK堆栈中获取小的代码工件存储资产。最初,我从CDK构造中调用AWS SDK开始,但后来意识到我会有竞争条件,因为CDK构造并不意味着运行异步代码。

然后,我考虑使用AwsCustomResource对CodeArtifact进行getPackageVersionAssetSDK调用,但现在我的问题是响应对于CFN响应来说太大了。

这就是我所拥有的,但它不适用于大于几KB的响应。

const namespace = new AwsCustomResource(this, 'custom-resource', {
onUpdate: {
physicalResourceId: PhysicalResourceId.of('codeartifact-stored-artifact-namespace'),
service: 'CodeArtifact',
action: 'getPackageVersionAsset',
parameters: {
repository: codeartifactCoordinates.repository,
domain: codeartifactCoordinates.domain,
domainOwner: codeartifactCoordinates.domainOwner,
format: codeartifactCoordinates.format,
namespace: codeartifactCoordinates.groupId,
package: codeartifactCoordinates.artifactId,
packageVersion: codeartifactCoordinates.version,
asset: `${codeartifactCoordinates.artifactId}-${codeartifactCoordinates.version}-${codeartifactCoordinates.classifier}.zip`
}
},
policy: AwsCustomResourcePolicy.fromSdkCalls({resources: AwsCustomResourcePolicy.ANY_RESOURCE})
});
const result = namespace.getResponseField('Data');

为了进行比较,这是我在使用客户端从Construct:调用SDK时开始使用的AWS SDK代码

const outputFile = `artifact-${crypto.randomBytes(16).toString("hex")}.yml`;
const file = require('fs').createWriteStream(outputFile);
const params : AWS.CodeArtifact.GetPackageVersionAssetRequest = {
domain: codeartifactCoordinates.domain,
domainOwner: codeartifactCoordinates.domainOwner,
repository: codeartifactCoordinates.repository,
format: codeartifactCoordinates.format,
namespace: codeartifactCoordinates.groupId,
package: codeartifactCoordinates.artifactId,
packageVersion: codeartifactCoordinates.version,
asset: `${codeartifactCoordinates.artifactId}-${codeartifactCoordinates.version}-${codeartifactCoordinates.classifier}.yml`
};
return new Promise((resolve, reject) => {
codeartifact
.getPackageVersionAsset(params)
.createReadStream()
.on('end', () => {
const data = fs.readFileSync(outputFile, "utf-8");
const yamlNs = YAML.parse(data);
return resolve(yamlNs);
})
.on('error', (error) => {
return reject(error);
})
.pipe(file)

});

有更好的模式吗?或者,有没有一种方法可以在我的Construct中进行AWS SDK调用,这样我就可以等待资产响应调用完成并避免竞争条件?

所以我最终使用了nodejschild_processspawnSync()方法。它从运行CDK的节点进程生成一个同步子进程。在此过程中,我运行AWS CLI与AWS CodeArtifact(在我的特定情况下(进行对话,并检索一个大文件资产。

当然,您可以在这里使用任何AWS CLI命令,只需根据需要设置CLI参数即可。

import * as fs from "fs"
import * as path from "path"
import * as crypto from "crypto"
import * as cp from 'child_process';
export interface CodeArtifactCoordinatesType {
readonly repository: string;
readonly domain: string;
readonly domainOwner: string;
readonly format: string;
readonly groupId: string;
readonly artifactId: string;
readonly version: string;
readonly classifier: string;
}
export class YourClassNameHere {
static fromCodeArtifactCoordinates(codeartifactCoordinates: CodeArtifactCoordinatesType) : any {
const outputFile = `${codeartifactCoordinates.artifactId}-${codeartifactCoordinates.version}-${codeartifactCoordinates.classifier}.ext`;
var getPackageVersionAssetProcess = cp.spawnSync('aws', [
'codeartifact',
'get-package-version-asset',
'--domain',
codeartifactCoordinates.domain,
'--domain-owner',
codeartifactCoordinates.domainOwner,
'--repository',
codeartifactCoordinates.repository,
'--format',
codeartifactCoordinates.format,
'--namespace',
codeartifactCoordinates.groupId,
'--package',
codeartifactCoordinates.artifactId,
'--package-version',
codeartifactCoordinates.version,
'--asset',
outputFile,
outputFile
], {stdio: [0, 1, 2]});
if (getPackageVersionAssetProcess.error) {
console.error(getPackageVersionAssetProcess.error.stack);
throw "Error executing 'get-package-version-asset' aws cli command."
} else if (getPackageVersionAssetProcess.stderr) {
console.error(getPackageVersionAssetProcess.stderr);
throw "aws codeartifact get-package-version-asset command parameters caused an error."
} else {
const data = fs.readFileSync(outputFile, "utf-8");
return data;
}
}
}

然后,您可以将其作为一个静态方法进行调用。例如

const data = YourClassNameHere.fromCodeArtifactCoordinates(codeartifactCoordinates);

CCD_ 4当然是包含来自CCD_ 5接口的各种属性的对象。即repositorydomain等。

最新更新