繁体   English   中英

AWS CDK:按 CDK 顺序运行外部构建命令?

[英]AWS CDK: run external build command in CDK sequence?

是否可以将外部构建命令作为 CDK 堆栈序列的一部分运行? 意图:1) 创建一个 rest API,2) 将 rest URL 写入配置文件,3) 构建和部署 React 应用程序:

import apigateway = require('@aws-cdk/aws-apigateway');
import cdk = require('@aws-cdk/core');
import fs = require('fs')
import s3deployment = require('@aws-cdk/aws-s3-deployment');

export class MyStack extends cdk.Stack {

  const restApi = new apigateway.RestApi(this, ..);
  fs.writeFile('src/app-config.json', 
    JSON.stringify({ "api": restApi.deploymentStage.urlForPath('/myResource') }))

  // TODO locally run 'npm run build', create 'build' folder incl rest api config

  const websiteBucket = new s3.Bucket(this, ..)
  new s3deployment.BucketDeployment(this, .. {
      sources: [s3deployment.Source.asset('build')],
      destinationBucket: websiteBucket
  }) 
}

不幸的是,这是不可能的,因为必要的引用仅在部署之后可用,因此在您尝试写入文件之后(该文件将包含cdk 令牌)。

我个人通过告诉 cdk 到 output apigateway URL 到一个文件,然后在部署对其进行解析以将其上传为 S3 存储桶,从而解决了这个问题,你需要这样做:

  • 使用 output 文件选项进行部署,例如: cdk deploy -O./cdk.out/deploy-output.json
  • In ./cdk.out/deploy-output.json you will find a JSON object with a key for each stack that produced an output (eg your stack that contains an API gateway)
  • 手动解析 JSON 以获取您的 apigateway url
  • 创建您的配置文件并将其上传到 S3(您可以通过 aws-sdk 完成)

当然,您有自定义脚本中的最后一步,这意味着您必须包装您的cdk deploy 我建议使用 nodejs 脚本执行此操作,以便您可以利用 aws-sdk 轻松将文件上传到 S3。

Accepting that cdk doesn't support this, I split logic into two cdk scripts, accessed API gateway URL as cdk output via the cli, then wrapped everything in a bash script.

AWS CDK:

// API gateway
const api = new apigateway.RestApi(this, 'my-api', ..)

// output url
const myResourceURL = api.deploymentStage.urlForPath('/myResource');
new cdk.CfnOutput(this, 'MyRestURL', { value: myResourceURL });

Bash:

# deploy api gw
cdk deploy --app (..)  

# read url via cli with --query
export rest_url=`aws cloudformation describe-stacks --stack-name (..) --query "Stacks[0].Outputs[?OutputKey=='MyRestURL'].OutputValue" --output text`

# configure React app
echo "{ \"api\" : { \"invokeUrl\" : \"$rest_url\" } }" > src/app-config.json

# build React app with url
npm run build

# run second cdk app to deploy React built output folder
cdk deploy --app (..)  

有没有更好的办法?

我解决了一个类似的问题:

  • 还需要构建和上传 react-app
  • 支持从 react-app 读取动态配置 - 看这里
  • 发布了我的特定版本的 react-app(在单独的流程中)
  • 然后,在我的应用程序的 CDK 部署期间,它采用了我的 react-app 的特定版本(从本地配置中检索的版本)并使用 CDK BucketDeployment 将其 zip 文件上传到 S3 存储桶
  • 然后,我使用 AwsCustomResource 生成了一个配置文件,其中包含对 Cognito 和 API-GW 的引用,并将该文件也上传到 S3:

 // create s3 bucket for react-app const uiBucket = new Bucket(this, "ui", { bucketName: this.stackName + "-s3-react-app", blockPublicAccess: BlockPublicAccess.BLOCK_ALL }); let confObj = { "myjsonobj": { "region": `${this.region}`, "identity_pool_id": `${props.CognitoIdentityPool.ref}`, "myBackend": `${apiGw.deploymentStage.urlForPath("/")}` } }; const dataString = JSON.stringify(confObj, null, 4); const bucketDeployment = new BucketDeployment(this, this.stackName + "-app", { destinationBucket: uiBucket, sources: [Source.asset(`reactapp-v1.zip`)] }); bucketDeployment.node.addDependency(uiBucket) const s3Upload = new custom.AwsCustomResource(this, 'config-json', { policy: custom.AwsCustomResourcePolicy.fromSdkCalls({resources: custom.AwsCustomResourcePolicy.ANY_RESOURCE}), onCreate: { service: "S3", action: "putObject", parameters: { Body: dataString, Bucket: `${uiBucket.bucketName}`, Key: "app-config.json", }, physicalResourceId: PhysicalResourceId.of(`${uiBucket.bucketName}`) } }); s3Upload.node.addDependency(bucketDeployment);

正如其他人所提到的,这在 CDK 中不受支持。 所以这就是我们在 SST 中解决它的方法: https://github.com/serverless-stack/serverless-stack

  1. 在 CDK 方面,允许使用其他构造的输出定义 React 环境变量。

     // Create a React.js app const site = new sst.ReactStaticSite(this, "Site", { path: "frontend", environment: { // Pass in the API endpoint to our app REACT_APP_API_URL: api.url, }, });
  2. 在启动后端的本地环境时吐出一个配置文件。

  3. 然后使用sst-env -- react-scripts start启动 React,我们有一个简单的 CLI ,它从配置文件中读取并将它们作为构建时环境变量加载到 React 中。

  4. 部署时,根据输出替换自定义资源中的这些环境变量。

我们在这里写过: https://serverless-stack.com/chapters/setting-serverless-environments-variables-in-a-react-app.html

这里是ReactStaticSiteStaticSite结构的来源供参考。

就我而言,我使用 CDK 的 Python 语言。 我有一个 Makefile,我可以像这样直接从我的 app.py 调用它: os.system("make") 我使用 make 根据AWS Docs构建一个层 zip 文件。 从技术上讲,您可以调用任何您想要的。 当然,您必须导入 os 包。 希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM