Skip to content

Commit

Permalink
feat: add support for optional S3 secondary artifact (#78)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
jhosteny authored Mar 16, 2021
1 parent 1c61c19 commit 3c23c4e
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 1 deletion.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ Available targets:
| [aws_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) |
| [aws_iam_role_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) |
| [aws_region](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) |
| [aws_s3_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/s3_bucket) |
| [aws_s3_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) |
| [random_string](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) |

Expand Down Expand Up @@ -236,6 +237,9 @@ Available targets:
| 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 |
| 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 |
| 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 |
| secondary\_artifact\_encryption\_enabled | Set to true to enable encryption on the secondary artifact bucket | `bool` | `false` | no |
| secondary\_artifact\_identifier | Secondary artifact identifier. Must match the identifier in the build spec | `string` | `null` | no |
| secondary\_artifact\_location | Location of secondary artifact. Must be an S3 reference | `string` | `null` | no |
| 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 |
| source\_credential\_auth\_type | The type of authentication used to connect to a GitHub, GitHub Enterprise, or Bitbucket repository. | `string` | `"PERSONAL_ACCESS_TOKEN"` | no |
| source\_credential\_server\_type | The source provider used for this project. | `string` | `"GITHUB"` | no |
Expand Down
4 changes: 4 additions & 0 deletions docs/terraform.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
| [aws_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) |
| [aws_iam_role_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) |
| [aws_region](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) |
| [aws_s3_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/s3_bucket) |
| [aws_s3_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) |
| [random_string](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) |

Expand Down Expand Up @@ -79,6 +80,9 @@
| 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 |
| 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 |
| 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 |
| secondary\_artifact\_encryption\_enabled | Set to true to enable encryption on the secondary artifact bucket | `bool` | `false` | no |
| secondary\_artifact\_identifier | Secondary artifact identifier. Must match the identifier in the build spec | `string` | `null` | no |
| secondary\_artifact\_location | Location of secondary artifact. Must be an S3 reference | `string` | `null` | no |
| 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 |
| source\_credential\_auth\_type | The type of authentication used to connect to a GitHub, GitHub Enterprise, or Bitbucket repository. | `string` | `"PERSONAL_ACCESS_TOKEN"` | no |
| source\_credential\_server\_type | The source provider used for this project. | `string` | `"GITHUB"` | no |
Expand Down
53 changes: 52 additions & 1 deletion main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,14 @@ resource "aws_iam_policy" "default_cache_bucket" {
policy = join("", data.aws_iam_policy_document.permissions_cache_bucket.*.json)
}

data "aws_s3_bucket" "secondary_artifact" {
count = module.this.enabled ? (var.secondary_artifact_location != null ? 1 : 0) : 0
bucket = var.secondary_artifact_location
}

data "aws_iam_policy_document" "permissions" {
count = module.this.enabled ? 1 : 0

statement {
sid = ""

Expand All @@ -163,6 +170,26 @@ data "aws_iam_policy_document" "permissions" {
"*",
]
}

dynamic "statement" {
for_each = var.secondary_artifact_location != null ? [1] : []
content {
sid = ""

actions = [
"s3:PutObject",
"s3:GetBucketAcl",
"s3:GetBucketLocation"
]

effect = "Allow"

resources = [
join("", data.aws_s3_bucket.secondary_artifact.*.arn),
"${join("", data.aws_s3_bucket.secondary_artifact.*.arn)}/*",
]
}
}
}

data "aws_iam_policy_document" "vpc_permissions" {
Expand Down Expand Up @@ -219,7 +246,7 @@ data "aws_iam_policy_document" "vpc_permissions" {

data "aws_iam_policy_document" "combined_permissions" {
override_policy_documents = compact([
data.aws_iam_policy_document.permissions.json,
join("", data.aws_iam_policy_document.permissions.*.json),
var.vpc_config != {} ? join("", data.aws_iam_policy_document.vpc_permissions.*.json) : null
])
}
Expand Down Expand Up @@ -280,6 +307,30 @@ resource "aws_codebuild_project" "default" {
location = var.artifact_location
}

# Since the output type is restricted to S3 by the provider (this appears to
# be an bug in AWS, rather than an architectural decision; see this issue for
# discussion: https://github.com/hashicorp/terraform-provider-aws/pull/9652),
# this cannot be a CodePipeline output. Otherwise, _all_ of the artifacts
# would need to be secondary if there were more than one. For reference, see
# https://docs.aws.amazon.com/codepipeline/latest/userguide/action-reference-CodeBuild.html#action-reference-CodeBuild-config.
dynamic "secondary_artifacts" {
for_each = var.secondary_artifact_location != null ? [1] : []
content {
type = "S3"
location = var.secondary_artifact_location
artifact_identifier = var.secondary_artifact_identifier
encryption_disabled = ! var.secondary_artifact_encryption_enabled
# According to AWS documention, in order to have the artifacts written
# to the root of the bucket, the 'namespace_type' should be 'NONE'
# (which is the default), 'name' should be '/', and 'path' should be
# empty. For reference, see https://docs.aws.amazon.com/codebuild/latest/APIReference/API_ProjectArtifacts.html.
# However, I was unable to get this to deploy to the root of the bucket
# unless path was also set to '/'.
path = "/"
name = "/"
}
}

cache {
type = lookup(local.cache, "type", null)
location = lookup(local.cache, "location", null)
Expand Down
18 changes: 18 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,24 @@ variable "artifact_location" {
description = "Location of artifact. Applies only for artifact of type S3"
}

variable "secondary_artifact_location" {
type = string
default = null
description = "Location of secondary artifact. Must be an S3 reference"
}

variable "secondary_artifact_identifier" {
type = string
default = null
description = "Secondary artifact identifier. Must match the identifier in the build spec"
}

variable "secondary_artifact_encryption_enabled" {
type = bool
default = false
description = "Set to true to enable encryption on the secondary artifact bucket"
}

variable "report_build_status" {
type = bool
default = false
Expand Down

0 comments on commit 3c23c4e

Please sign in to comment.