diff --git a/CHANGELOG.md b/CHANGELOG.md index c1b8dfb..1a267ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,6 @@ -## Unreleased +## 2.15.7 (2023-11-08) +### Features +✨ Add custom tags (cost allocation tags) to S3 buckets and CloudFront distribution. This will allow us to see cost per bucket and distributions. ## 2.15.6 (2023-10-30) diff --git a/index.js b/index.js index 5bc1912..e88721b 100755 --- a/index.js +++ b/index.js @@ -26,7 +26,7 @@ import { set } from "./lib/store.js" import { checkLisaVersion } from "./lib/versions.js" export const program = new Command() -export const LISA_VERSION = "2.15.6" +export const LISA_VERSION = "2.15.7" resetConf() checkNodeVersion() diff --git a/package.json b/package.json index 4456487..4709e05 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@triggerfishab/lisa-cli", - "version": "2.15.6", + "version": "2.15.7", "description": "CLI commands to generate a new project based on Lisa", "main": "./index.js", "bin": { diff --git a/tasks/services/aws.js b/tasks/services/aws.js index fcc08ed..02cc253 100644 --- a/tasks/services/aws.js +++ b/tasks/services/aws.js @@ -1,6 +1,6 @@ import { CloudFrontClient, - CreateDistributionCommand, + CreateDistributionWithTagsCommand, GetDistributionConfigCommand, ListDistributionsCommand, UpdateCloudFrontOriginAccessIdentityCommand, @@ -18,6 +18,7 @@ import { GetBucketLocationCommand, PutBucketLifecycleConfigurationCommand, PutBucketPolicyCommand, + PutBucketTaggingCommand, PutBucketVersioningCommand, PutPublicAccessBlockCommand, S3Client, @@ -63,6 +64,7 @@ export async function setupAWS(environment = "production") { await putBucketPublicAccessBlock(bucketName) await putBucketLifeCycleRule(bucketName) + await putBucketTags(bucketName) writeSuccess(`S3 bucket for ${environment} created.`) @@ -118,8 +120,13 @@ export async function setupAWS(environment = "production") { }, } - const command = new CreateDistributionCommand({ - DistributionConfig: distributionConfig, + const command = new CreateDistributionWithTagsCommand({ + DistributionConfigWithTags: { + DistributionConfig: distributionConfig, + Tags: { + Items: getTags(bucketName), + }, + }, }) const distribution = await cloudFrontClient.send(command) @@ -149,7 +156,7 @@ async function putBucketPolicy(bucketName) { try { const [accessKeyId, secretAccessKey, canonicalUserId] = await getAWSKeys() - const bucketRegion = await GetBucketRegion(bucketName) + const bucketRegion = await getBucketRegion(bucketName) // Update bucket policy const bucketPolicy = { Version: "2008-10-17", @@ -262,7 +269,7 @@ async function putBucketLifeCycleRule(bucketName) { const [accessKeyId, secretAccessKey, canonicalUserId, accountId] = await getAWSKeys() - const bucketRegion = await GetBucketRegion(bucketName) + const bucketRegion = await getBucketRegion(bucketName) const s3Client = new S3Client({ region: bucketRegion, @@ -296,12 +303,21 @@ async function putBucketLifeCycleRule(bucketName) { } } +function getTags(bucketName) { + return [ + { + Key: "cdn.triggerfish.cloud", + Value: bucketName.replace(".cdn.triggerfish.cloud", ""), + }, + ] +} + async function putBucketPublicAccessBlock(bucketName) { try { const [accessKeyId, secretAccessKey, canonicalUserId, accountId] = await getAWSKeys() - const bucketRegion = await GetBucketRegion(bucketName) + const bucketRegion = await getBucketRegion(bucketName) const s3Client = new S3Client({ region: bucketRegion, @@ -326,7 +342,34 @@ async function putBucketPublicAccessBlock(bucketName) { } } -async function GetBucketRegion(bucketName) { +async function putBucketTags(bucketName) { + try { + const [accessKeyId, secretAccessKey, canonicalUserId, accountId] = + await getAWSKeys() + + const bucketRegion = await getBucketRegion(bucketName) + + const s3Client = new S3Client({ + region: bucketRegion, + credentials: { accessKeyId, secretAccessKey }, + canonicalUserId, + }) + + await s3Client.send( + new PutBucketTaggingCommand({ + Bucket: bucketName, + ExpectedBucketOwner: accountId, + Tagging: { + TagSet: getTags(bucketName), + }, + }), + ) + } catch (error) { + writeError(`${bucketName}: ${error}`) + } +} + +async function getBucketRegion(bucketName) { try { const [accessKeyId, secretAccessKey, canonicalUserId, accountId] = await getAWSKeys()