我创建了这个堆栈:
export class InfrastructureStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const bucket = new s3.Bucket(this, "My Hello Website", {
websiteIndexDocument: 'index.html',
websiteErrorDocument: 'error.html',
publicReadAccess: true,
removalPolicy: cdk.RemovalPolicy.DESTROY
});
const api = new apigateway.RestApi(this, "My Endpoint", {
restApiName: "My rest API name",
description: "Some cool description"
});
const myLambda = new lambda.Function(this, 'My Backend', {
runtime: lambda.Runtime.NODEJS_8_10,
handler: 'index.handler',
code: lambda.Code.fromAsset(path.join(__dirname, 'code'))
});
const apiToLambda = new apigateway.LambdaIntegration(myLambda)
api.root.addMethod('GET', apiToLambda);
updateWebsiteUrl.newUrl(api.url);
}
}
最后一行代码是我的函数,用于更新将作为网站部署在 S3 上的 Assets ,并带有将在部署期间创建的 API URL。这只是一个普通的 Node.js 脚本,它将文件 PLACEHOLDER
替换为 api.url
。
当然,在编译期间,CDK 不知道 REST 端点的最终地址是什么,因为这是在部署期间发生的,并且它会使用以下内容更新我的 url:
'https://${Token[TOKEN.26]}.execute-api.${Token[AWS::Region.4]}.${Token[AWS::URLSuffix.1]}/${ token [TOKEN.32]}/;'
部署完 lambda 与 API 端点集成后,有什么方法可以更新它吗?
我想使用 @aws-cdk/aws-s3-deployment
模块将代码部署到新创建的存储桶。所有这些都在同一个堆栈中,因此一个 cdk 部署
将更新我需要的所有内容。
为了避免混淆。我的 updateWebsiteUrl 是:
export function newUrl(newUrl: string): void {
const scriptPath = path.join(__dirname, '/../../front/');
const scriptName = 'script.js';
fs.readFile(scriptPath + scriptName, (err, buf) => {
let scriptContent : string = buf.toString();
let newScript = scriptContent.replace('URL_PLACEHOLDER', newUrl);
fs.writeFile(scriptPath + 'newScript.js', newScript, () => {
console.log('done writing');
});
});
}
我的脚本很简单:
const url = URL_PLACEHOLDER;
function foo() {
let req = new XMLHttpRequest();
req.open('GET', url , false);
req.send(null);
if (req.status == 200) {
replaceContent(req.response);
}
}
function replaceContent(content) {
document.getElementById('content').innerHTML = content;
}
最佳答案
我今天遇到了同样的问题,并设法找到了解决方案。
我在 CDK 程序中使用的 C# 代码如下:
// This will at runtime be just a token which refers to the actual JSON in the format {'api':{'baseUrl':'https://your-url'}}
var configJson = stack.ToJsonString(new Dictionary<string, object>
{
["api"] = new Dictionary<string, object>
{
["baseUrl"] = api.Url
}
});
var configFile = new AwsCustomResource(this, "config-file", new AwsCustomResourceProps
{
OnUpdate = new AwsSdkCall
{
Service = "S3",
Action = "putObject",
Parameters = new Dictionary<string, string>
{
["Bucket"] = bucket.BucketName,
["Key"] = "config.json",
["Body"] = configJson,
["ContentType"] = "application /json",
["CacheControl"] = "max -age=0, no-cache, no-store, must-revalidate"
},
PhysicalResourceId = PhysicalResourceId.Of("config"),
},
Policy = AwsCustomResourcePolicy.FromStatements(
new[]
{
new PolicyStatement(new PolicyStatementProps
{
Actions = new[] { "s3:PutObject" },
Resources= new [] { bucket.ArnForObjects("config.json") }
})
})
});
}
您需要安装以下软件包才能使用可用类型:https://docs.aws.amazon.com/cdk/api/latest/docs/custom-resources-readme.html
它基本上是您可以找到的解决方案的一部分,作为此问题的答案 AWS CDK passing API Gateway URL to static site in same Stack ,或在此 GitHub 存储库:https://github.com/jogold/cloudstructs/blob/master/src/static-website/index.ts#L134
关于amazon-web-services - 使用 aws-cdk 的 token 更新 Assets 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59022931/