如何在TerraformAsset中排除指定文件夹?求即时解决方案
临时解决CDKTF中TerraformAsset复制冗余目录的问题
我正在用CDKTF(TypeScript)将Docker镜像部署到AWS ECS,参考的构建推送逻辑通过TerraformAsset获取目录哈希作为镜像标签,以此避免无变更时重复构建。但我的目录结构中Dockerfile位于根目录,执行cdktf synth时,TerraformAsset会复制整个根目录(包括infra下生成的cdktf.out)到infra/cdktf.out,最终触发ENAMETOOLONG错误。官方已提议为TerraformAsset添加忽略文件夹功能,但目前尚未实现,且.terraformignore无法解决此问题,以下是几个临时可行的解决方案:
方案1:自定义拷贝逻辑替代TerraformAsset默认行为
绕过TerraformAsset的自动拷贝机制,手动复制仅需要的文件/目录到临时文件夹,并计算该临时目录的哈希值用于镜像标签,避免冗余文件被复制:
import * as fs from 'fs-extra'; import * as crypto from 'crypto'; import * as path from 'path'; // 创建临时构建上下文目录 const tempBuildDir = path.join(__dirname, '../temp-build-context'); fs.emptyDirSync(tempBuildDir); // 仅复制构建Docker镜像需要的内容 fs.copySync(path.join(__dirname, '../Dockerfile'), path.join(tempBuildDir, 'Dockerfile')); fs.copySync(path.join(__dirname, '../backend'), path.join(tempBuildDir, 'backend')); fs.copySync(path.join(__dirname, '../frontend'), path.join(tempBuildDir, 'frontend')); // 计算临时目录的哈希值,替代TerraformAsset的assetHash function getDirHash(dirPath: string): string { const hash = crypto.createHash('sha256'); // 按文件名排序保证哈希计算一致性 const files = fs.readdirSync(dirPath, { withFileTypes: true, recursive: true }) .sort((a, b) => a.name.localeCompare(b.name)); for (const file of files) { const fullPath = path.join(dirPath, file.name); if (file.isFile()) { hash.update(fs.readFileSync(fullPath)); } else if (file.isDirectory()) { hash.update(file.name); } } return hash.digest('hex').slice(0, 8); } const assetHash = getDirHash(tempBuildDir); const version = require(path.join(__dirname, '../package.json')).version; this.tag = `${repo.repositoryUrl}:${version}-${assetHash}`; // 执行镜像构建推送 this.image = new Resource(this, `image`, { provisioners: [ { type: "local-exec", workingDir: tempBuildDir, command: `docker login -u ${auth.userName} -p ${auth.password} ${auth.proxyEndpoint} && docker build -t ${this.tag} . && docker push ${this.tag}`, }, ], }); // 脚本退出时清理临时目录 process.on('exit', () => { fs.removeSync(tempBuildDir); });
方案2:用archive_file数据源打包指定内容
借助Terraform的archive_file数据源,仅打包需要的文件/目录并计算哈希,避免整个目录被复制:
import * as path from 'path'; // 打包需要的构建文件,排除冗余目录 const buildArchive = new DataArchiveFile(this, "build-archive", { type: "zip", sourceDir: path.join(__dirname, "../"), excludes: ["infra/**", "cdktf.out/**"], outputPath: path.join(__dirname, "../build-context.zip"), }); // 使用打包文件的哈希生成镜像标签 const assetHash = buildArchive.outputBase64Sha256.slice(0, 8); const version = require(path.join(__dirname, '../package.json')).version; this.tag = `${repo.repositoryUrl}:${version}-${assetHash}`; // 解压归档文件作为构建上下文,执行镜像推送 this.image = new Resource(this, `image`, { provisioners: [ { type: "local-exec", command: `mkdir -p temp-build && unzip ${buildArchive.outputPath} -d temp-build && docker login -u ${auth.userName} -p ${auth.password} ${auth.proxyEndpoint} && docker build -t ${this.tag} temp-build && docker push ${this.tag} && rm -rf temp-build`, }, ], });
内容的提问来源于stack exchange,提问作者dwjohnston
相关产品推荐
相关产品推荐

