Skip to content

Commit 3c23c4e

Browse files
authored
feat: add support for optional S3 secondary artifact (#78)
* feat: add support for optional S3 secondary artifact Fixes #77. * docs: add regenerated README * fix: address review comments * docs: rebuild README * fix: use positive variable name * docs: update to latest harness and rebuild docs * fix: handle conditionally instantiated permissions data source
1 parent 1c61c19 commit 3c23c4e

File tree

4 files changed

+78
-1
lines changed

4 files changed

+78
-1
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ Available targets:
189189
| [aws_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) |
190190
| [aws_iam_role_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) |
191191
| [aws_region](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) |
192+
| [aws_s3_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/s3_bucket) |
192193
| [aws_s3_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) |
193194
| [random_string](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) |
194195

@@ -236,6 +237,9 @@ Available targets:
236237
| privileged\_mode | (Optional) If set to true, enables running the Docker daemon inside a Docker container on the CodeBuild instance. Used when building Docker images | `bool` | `false` | no |
237238
| regex\_replace\_chars | Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
238239
| report\_build\_status | Set to true to report the status of a build's start and finish to your source provider. This option is only valid when the source\_type is BITBUCKET or GITHUB | `bool` | `false` | no |
240+
| secondary\_artifact\_encryption\_enabled | Set to true to enable encryption on the secondary artifact bucket | `bool` | `false` | no |
241+
| secondary\_artifact\_identifier | Secondary artifact identifier. Must match the identifier in the build spec | `string` | `null` | no |
242+
| secondary\_artifact\_location | Location of secondary artifact. Must be an S3 reference | `string` | `null` | no |
239243
| secondary\_sources | (Optional) secondary source for the codebuild project in addition to the primary location | <pre>list(object(<br> {<br> git_clone_depth = number<br> location = string<br> source_identifier = string<br> type = string<br> fetch_submodules = bool<br> insecure_ssl = bool<br> report_build_status = bool<br> }))</pre> | `[]` | no |
240244
| source\_credential\_auth\_type | The type of authentication used to connect to a GitHub, GitHub Enterprise, or Bitbucket repository. | `string` | `"PERSONAL_ACCESS_TOKEN"` | no |
241245
| source\_credential\_server\_type | The source provider used for this project. | `string` | `"GITHUB"` | no |

docs/terraform.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
| [aws_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) |
3333
| [aws_iam_role_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) |
3434
| [aws_region](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) |
35+
| [aws_s3_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/s3_bucket) |
3536
| [aws_s3_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) |
3637
| [random_string](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) |
3738

@@ -79,6 +80,9 @@
7980
| privileged\_mode | (Optional) If set to true, enables running the Docker daemon inside a Docker container on the CodeBuild instance. Used when building Docker images | `bool` | `false` | no |
8081
| regex\_replace\_chars | Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
8182
| report\_build\_status | Set to true to report the status of a build's start and finish to your source provider. This option is only valid when the source\_type is BITBUCKET or GITHUB | `bool` | `false` | no |
83+
| secondary\_artifact\_encryption\_enabled | Set to true to enable encryption on the secondary artifact bucket | `bool` | `false` | no |
84+
| secondary\_artifact\_identifier | Secondary artifact identifier. Must match the identifier in the build spec | `string` | `null` | no |
85+
| secondary\_artifact\_location | Location of secondary artifact. Must be an S3 reference | `string` | `null` | no |
8286
| secondary\_sources | (Optional) secondary source for the codebuild project in addition to the primary location | <pre>list(object(<br> {<br> git_clone_depth = number<br> location = string<br> source_identifier = string<br> type = string<br> fetch_submodules = bool<br> insecure_ssl = bool<br> report_build_status = bool<br> }))</pre> | `[]` | no |
8387
| source\_credential\_auth\_type | The type of authentication used to connect to a GitHub, GitHub Enterprise, or Bitbucket repository. | `string` | `"PERSONAL_ACCESS_TOKEN"` | no |
8488
| source\_credential\_server\_type | The source provider used for this project. | `string` | `"GITHUB"` | no |

main.tf

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,14 @@ resource "aws_iam_policy" "default_cache_bucket" {
136136
policy = join("", data.aws_iam_policy_document.permissions_cache_bucket.*.json)
137137
}
138138

139+
data "aws_s3_bucket" "secondary_artifact" {
140+
count = module.this.enabled ? (var.secondary_artifact_location != null ? 1 : 0) : 0
141+
bucket = var.secondary_artifact_location
142+
}
143+
139144
data "aws_iam_policy_document" "permissions" {
145+
count = module.this.enabled ? 1 : 0
146+
140147
statement {
141148
sid = ""
142149

@@ -163,6 +170,26 @@ data "aws_iam_policy_document" "permissions" {
163170
"*",
164171
]
165172
}
173+
174+
dynamic "statement" {
175+
for_each = var.secondary_artifact_location != null ? [1] : []
176+
content {
177+
sid = ""
178+
179+
actions = [
180+
"s3:PutObject",
181+
"s3:GetBucketAcl",
182+
"s3:GetBucketLocation"
183+
]
184+
185+
effect = "Allow"
186+
187+
resources = [
188+
join("", data.aws_s3_bucket.secondary_artifact.*.arn),
189+
"${join("", data.aws_s3_bucket.secondary_artifact.*.arn)}/*",
190+
]
191+
}
192+
}
166193
}
167194

168195
data "aws_iam_policy_document" "vpc_permissions" {
@@ -219,7 +246,7 @@ data "aws_iam_policy_document" "vpc_permissions" {
219246

220247
data "aws_iam_policy_document" "combined_permissions" {
221248
override_policy_documents = compact([
222-
data.aws_iam_policy_document.permissions.json,
249+
join("", data.aws_iam_policy_document.permissions.*.json),
223250
var.vpc_config != {} ? join("", data.aws_iam_policy_document.vpc_permissions.*.json) : null
224251
])
225252
}
@@ -280,6 +307,30 @@ resource "aws_codebuild_project" "default" {
280307
location = var.artifact_location
281308
}
282309

310+
# Since the output type is restricted to S3 by the provider (this appears to
311+
# be an bug in AWS, rather than an architectural decision; see this issue for
312+
# discussion: https://github.com/hashicorp/terraform-provider-aws/pull/9652),
313+
# this cannot be a CodePipeline output. Otherwise, _all_ of the artifacts
314+
# would need to be secondary if there were more than one. For reference, see
315+
# https://docs.aws.amazon.com/codepipeline/latest/userguide/action-reference-CodeBuild.html#action-reference-CodeBuild-config.
316+
dynamic "secondary_artifacts" {
317+
for_each = var.secondary_artifact_location != null ? [1] : []
318+
content {
319+
type = "S3"
320+
location = var.secondary_artifact_location
321+
artifact_identifier = var.secondary_artifact_identifier
322+
encryption_disabled = ! var.secondary_artifact_encryption_enabled
323+
# According to AWS documention, in order to have the artifacts written
324+
# to the root of the bucket, the 'namespace_type' should be 'NONE'
325+
# (which is the default), 'name' should be '/', and 'path' should be
326+
# empty. For reference, see https://docs.aws.amazon.com/codebuild/latest/APIReference/API_ProjectArtifacts.html.
327+
# However, I was unable to get this to deploy to the root of the bucket
328+
# unless path was also set to '/'.
329+
path = "/"
330+
name = "/"
331+
}
332+
}
333+
283334
cache {
284335
type = lookup(local.cache, "type", null)
285336
location = lookup(local.cache, "location", null)

variables.tf

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,24 @@ variable "artifact_location" {
147147
description = "Location of artifact. Applies only for artifact of type S3"
148148
}
149149

150+
variable "secondary_artifact_location" {
151+
type = string
152+
default = null
153+
description = "Location of secondary artifact. Must be an S3 reference"
154+
}
155+
156+
variable "secondary_artifact_identifier" {
157+
type = string
158+
default = null
159+
description = "Secondary artifact identifier. Must match the identifier in the build spec"
160+
}
161+
162+
variable "secondary_artifact_encryption_enabled" {
163+
type = bool
164+
default = false
165+
description = "Set to true to enable encryption on the secondary artifact bucket"
166+
}
167+
150168
variable "report_build_status" {
151169
type = bool
152170
default = false

0 commit comments

Comments
 (0)