在Pulumi栈中向两个S3桶写入同名文件时出现重复资源URN错误
如何解决Pulumi中同名S3 BucketObject的URN重复问题?
我在一个Pulumi栈里创建了两个独立的S3桶,但是当我尝试给第二个桶上传和第一个桶里同名的文件(比如index.html)时,收到了这个错误:
error: Duplicate resource URN 'urn:pulumi:dev::quickstart::aws:s3/bucketObject:BucketObject::index.html'; try giving it a unique name
以下是重现问题的代码:
using Pulumi; using Pulumi.Aws.S3; class MyStack : Stack { public MyStack() { // Create an AWS resource (S3 Bucket) var bucket1 = new Bucket("my-bucket"); var bucketObject1 = new BucketObject("index.html", new BucketObjectArgs { Bucket = bucket1.BucketName, Content = "HTML in 1" }); var bucket2 = new Bucket("my-bucket2"); var bucketObject2 = new BucketObject("index.html", new BucketObjectArgs { Bucket = bucket2.BucketName, Content = "HTML in 2" }); } }
从AWS的角度来看,这两个文件分别在不同的桶里,完全没有冲突,但我是不是需要给Pulumi里的资源定义另一个“名称”来避免生成重复的URN?
解决办法
别担心,这个问题是Pulumi的资源标识逻辑和AWS实际资源命名逻辑的差异导致的,我给你两种简单的解决方式:
1. 手动设置唯一的逻辑名称,用Key指定S3文件名
Pulumi里创建BucketObject时的第一个参数是逻辑名称,它是Pulumi内部用来标识资源的核心,同一个栈里必须唯一;而S3桶里实际的文件名是由Key参数控制的,两者可以完全不一样。
修改代码如下:
using Pulumi; using Pulumi.Aws.S3; class MyStack : Stack { public MyStack() { var bucket1 = new Bucket("my-bucket"); var bucketObject1 = new BucketObject("bucket1-index.html", new BucketObjectArgs { Bucket = bucket1.BucketName, Content = "HTML in 1", Key = "index.html" // 这里指定S3中实际的文件名 }); var bucket2 = new Bucket("my-bucket2"); var bucketObject2 = new BucketObject("bucket2-index.html", new BucketObjectArgs { Bucket = bucket2.BucketName, Content = "HTML in 2", Key = "index.html" }); } }
这样既保证了两个桶里的文件都是index.html,又让Pulumi的资源逻辑名称唯一,不会再出现URN重复的错误。
2. 用关联桶的标识自动生成唯一逻辑名称
如果需要创建大量类似的资源,手动想唯一名称太麻烦,可以用桶的Id或者BucketName来拼接逻辑名称,让它自动唯一:
using Pulumi; using Pulumi.Aws.S3; class MyStack : Stack { public MyStack() { var bucket1 = new Bucket("my-bucket"); var bucketObject1 = new BucketObject($"{bucket1.Id}-index.html", new BucketObjectArgs { Bucket = bucket1.BucketName, Content = "HTML in 1", Key = "index.html" }); var bucket2 = new Bucket("my-bucket2"); var bucketObject2 = new BucketObject($"{bucket2.Id}-index.html", new BucketObjectArgs { Bucket = bucket2.BucketName, Content = "HTML in 2", Key = "index.html" }); } }
这种方式会自动基于桶的唯一ID生成逻辑名称,彻底避免重复问题,适合批量创建资源的场景。
内容的提问来源于stack exchange,提问作者JSobell
相关产品推荐
相关产品推荐

