amazon-web-services - 如何将配置传递给 AWS-CDK 堆栈中使用的 Web 应用程序
问题描述
假设您有一个 AWS CDK 堆栈创建一些资源
- Cognito 用户池
- AppSync 端点
您要部署到 S3 的 Web 应用程序会使用它。
您将如何以编程方式将 appsync 端点的端点 url 等配置传递给您要部署的应用程序?
AWS Amplify 创建aws-exports.js
应用程序使用的文件。该文件由一些放大命令创建并放入应用程序目录以从应用程序访问。
有没有关于如何在不使用放大的情况下解决这个问题的工具或建议?如果有人对此有一些示例或想法,那就太好了。
我正在使用使用生成器创建的标准 React 应用程序。
解决方案
我知道几个月前有人问过这个问题,但我来到这里时试图自己解决这个问题。
挑战在于配置值在 CDK 部署之后才可用,因此您不能只添加脚本来编写堆栈输出。我的解决方案是添加我自己的部署脚本,它首先部署后端堆栈,然后构建配置,然后部署 Web 堆栈。
调用脚本npm run deploy
:
cdk/package.json
"deploy": "node deploy"
cdk/deploy.js
const execSync = require('child_process').execSync
const exec = command => {
execSync(command, {
stdio: [0, 1, 2]
})
}
console.log('- Deploying backend.')
exec(`cdk deploy --all --require-approval never -c deploy=backend`)
console.log('- Generating frontend config.')
exec(`npm run build-config --prefix ../web`) // "node scripts/buildConfig.js"
console.log('- Building frontend.')
exec(`npm run build --prefix ../web`) // "react-scripts build"
console.log('- Deploying frontend.')
exec(`cdk deploy --all --require-approval never -c deploy=frontend`)
条件堆栈部署:
cdk/cdk.ts
const deploy = app.node.tryGetContext('deploy')
if (deploy === 'backend') {
new AuthStack(...)
new ApiStack(...)
}
if (deploy === 'frontend') {
new WebStack(...)
}
输出配置所需的值:
cdk/lib/auth-stack.ts
...
const userPool = new cognito.UserPool(...)
this.exportValue(userPool.userPoolId, {
name: 'UserPoolId',
})
...
读取输出并构建配置:
web/scripts/buildConfig.js
const fs = require('fs')
const path = require('path')
const { CloudFormation } = require('aws-sdk')
const region = 'us-west-2'
const cloudformation = new CloudFormation({ region })
const outputs = {}
// get stack info
const apiStack = await cloudformation.describeStacks({ StackName: 'ApiStack' }).promise()
const authStack = await cloudformation.describeStacks({ StackName: 'AuthStack' }).promise()
// build the outputs into a simple object
apiStack.Stacks[0].Outputs.forEach(({ ExportName, OutputValue }) => { outputs[ExportName] = OutputValue })
authStack.Stacks[0].Outputs.forEach(({ ExportName, OutputValue }) => { outputs[ExportName] = OutputValue })
// read existing config (this is our version of aws-exports)
const configFilePath = path.join(__dirname, '..', 'src', 'config.json')
const config = JSON.parse(fs.readFileSync(configFilePath))
// build config:
config.Auth = {
region,
userPoolId: outputs.UserPoolId,
userPoolWebClientId: outputs.WebUserPoolClientId,
}
config.API = {
aws_appsync_graphqlEndpoint: outputs.AppSyncURL,
aws_appsync_region: region,
aws_appsync_authenticationType: 'AMAZON_COGNITO_USER_POOLS',
aws_project_region: region,
aws_cognito_region: region,
aws_user_pools_id: outputs.UserPoolId,
aws_user_pools_web_client_id: outputs.WebUserPoolClientId,
}
// update the file
fs.writeFileSync(configFilePath, JSON.stringify(config, null, 2))
在 React 中:
web/src/App.tsx
import * as config from './config.json'
Amplify.configure({
Auth: config.Auth,
API: config.API,
})
推荐阅读
- vb.net - 使用 Backgroundworker 从 MSAccess 数据库中的 Datagridview.rows.add 出错
- database - 添加回软删除数据,创建新条目或恢复已删除数据的更好方法是什么
- python - AttributeError:模块“geopandas”没有属性“GeoDataFrame”
- firebase - 我在vs控制台中安装firebase时遇到问题,请帮帮我
- excel - Excel - 如何使用电源查询 M 组合多个文件并保留文件名
- python - 如何在不使用数组的情况下在循环中向字典添加值
- ios - 如何从 RTMP url 播放实时视频?
- android - 使用 Dagger Hilt 启动片段时,片段的属性未初始化
- openshift-3 - 为什么 openshift 在我创建服务帐户时会创建两个秘密
- reactjs - 如何防止组件在 QR 扫描后重新渲染?