Skip to content

Commit 1c203d3

Browse files
authored
Merge pull request #2 from huksley/cloudposse-master
Cloudposse master
2 parents 9d153df + 1f2553c commit 1c203d3

File tree

9 files changed

+577
-52
lines changed

9 files changed

+577
-52
lines changed

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
# Compiled files
22
*.tfstate
33
*.tfstate.backup
4+
.terraform.tfstate.lock.info
45

56
# Module directory
67
.terraform/
7-
88
.idea
99
*.iml
10+
11+
# Build Harness
12+
.build-harness
13+
build-harness/

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
SHELL := /bin/bash
22

3+
# List of targets the `readme` target should call before generating the readme
4+
export README_DEPS ?= docs/targets.md docs/terraform.md
5+
36
-include $(shell curl -sSL -o .build-harness "https://git.io/build-harness"; echo .build-harness)
47

8+
## Lint terraform code
59
lint:
610
$(SELF) terraform:install terraform:get-modules terraform:get-plugins terraform:lint terraform:validate

README.md

Lines changed: 240 additions & 30 deletions
Large diffs are not rendered by default.

README.yaml

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
---
2+
#
3+
# This is the canonical configuration for the `README.md`
4+
# Run `make readme` to rebuild the `README.md`
5+
#
6+
7+
# Name of this project
8+
name: terraform-aws-codebuild
9+
10+
# Logo for this project
11+
#logo: docs/logo.png
12+
13+
# License of this project
14+
license: "APACHE2"
15+
16+
# Canonical GitHub repo
17+
github_repo: cloudposse/terraform-aws-codebuild
18+
19+
# Badges to display
20+
badges:
21+
- name: "Build Status"
22+
image: "https://travis-ci.org/cloudposse/terraform-aws-codebuild.svg?branch=master"
23+
url: "https://travis-ci.org/cloudposse/terraform-aws-codebuild"
24+
- name: "Latest Release"
25+
image: "https://img.shields.io/github/release/cloudposse/terraform-aws-codebuild.svg"
26+
url: "https://github.com/cloudposse/terraform-aws-codebuild/releases"
27+
- name: "Slack Community"
28+
image: "https://slack.cloudposse.com/badge.svg"
29+
url: "https://slack.cloudposse.com"
30+
31+
related:
32+
- name: "terraform-aws-ecs-codepipeline"
33+
description: "Terraform Module for CI/CD with AWS Code Pipeline and Code Build for ECS"
34+
url: "https://github.com/cloudposse/terraform-aws-ecs-codepipeline"
35+
36+
# Short description of this project
37+
description: |-
38+
Terraform module to create AWS CodeBuild project for AWS CodePipeline.
39+
40+
# How to use this project
41+
usage: |-
42+
Include this module in your existing terraform code:
43+
44+
```hcl
45+
module "build" {
46+
source = "git::https://github.com/cloudposse/terraform-aws-codebuild.git?ref=master"
47+
namespace = "general"
48+
name = "ci"
49+
stage = "staging"
50+
51+
# https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-available.html
52+
build_image = "aws/codebuild/docker:1.12.1"
53+
build_compute_type = "BUILD_GENERAL1_SMALL"
54+
55+
# These attributes are optional, used as ENV variables when building Docker images and pushing them to ECR
56+
# For more info:
57+
# http://docs.aws.amazon.com/codebuild/latest/userguide/sample-docker.html
58+
# https://www.terraform.io/docs/providers/aws/r/codebuild_project.html
59+
60+
privileged_mode = "true"
61+
aws_region = "us-east-1"
62+
aws_account_id = "xxxxxxxxxx"
63+
image_repo_name = "ecr-repo-name"
64+
image_tag = "latest"
65+
66+
# Optional extra environment variables
67+
environment_variables = [{
68+
name = "JENKINS_URL"
69+
value = "https://jenkins.example.com"
70+
},
71+
{
72+
name = "COMPANY_NAME"
73+
value = "Amazon"
74+
},
75+
{
76+
name = "TIME_ZONE"
77+
value = "Pacific/Auckland"
78+
79+
}]
80+
}
81+
```
82+
83+
### To hide warnings about unset versions in providers
84+
85+
Add this to your .tf files
86+
```hcl
87+
provider "random" {
88+
version = "~> 1.0"
89+
}
90+
91+
provider "null" {
92+
version = "~> 1.0"
93+
}
94+
```
95+
96+
# Other files to include in this README from the project folder
97+
include:
98+
- "docs/targets.md"
99+
- "docs/terraform.md"
100+
101+
# Contributors to this project
102+
contributors:
103+
- name: "Erik Osterman"
104+
github: "osterman"
105+
- name: "Igor Rodionov"
106+
github: "goruha"
107+
- name: "Andriy Knysh"
108+
github: "aknysh"
109+
- name: "Jamie Nelson"
110+
github: "Jamie-BitfFlight"
111+
- name: "Sarkis Varozian"
112+
github: "sarkis"

docs/targets.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
## Makefile Targets
2+
```
3+
Available targets:
4+
5+
help Help screen
6+
help/all Display help for all targets
7+
help/short This help short screen
8+
lint Lint terraform code
9+
10+
```

docs/terraform.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
2+
## Inputs
3+
4+
| Name | Description | Type | Default | Required |
5+
|------|-------------|:----:|:-----:|:-----:|
6+
| attributes | Additional attributes (e.g. `policy` or `role`) | list | `<list>` | no |
7+
| aws_account_id | (Optional) AWS Account ID. Used as CodeBuild ENV variable when building Docker images. For more info: http://docs.aws.amazon.com/codebuild/latest/userguide/sample-docker.html | string | `` | no |
8+
| aws_region | (Optional) AWS Region, e.g. us-east-1. Used as CodeBuild ENV variable when building Docker images. For more info: http://docs.aws.amazon.com/codebuild/latest/userguide/sample-docker.html | string | `` | no |
9+
| build_compute_type | Instance type of the build instance | string | `BUILD_GENERAL1_SMALL` | no |
10+
| build_image | Docker image for build environment, e.g. 'aws/codebuild/docker:1.12.1' or 'aws/codebuild/eb-nodejs-6.10.0-amazonlinux-64:4.0.0'. For more info: http://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref.html | string | `aws/codebuild/docker:1.12.1` | no |
11+
| buildspec | Optional buildspec declaration to use for building the project | string | `` | no |
12+
| cache_bucket_suffix_enabled | The cache bucket generates a random 13 character string to generate a unique bucket name. If set to false it uses terraform-null-label's id value | string | `true` | no |
13+
| cache_enabled | If cache_enabled is true, create an S3 bucket for storing codebuild cache inside | string | `true` | no |
14+
| cache_expiration_days | How many days should the build cache be kept | string | `7` | no |
15+
| codebuild_var1 | | string | `var1` | no |
16+
| codebuild_var1_val | | string | `value1` | no |
17+
| codebuild_var2 | | string | `var2` | no |
18+
| codebuild_var2_val | | string | `value2` | no |
19+
| codebuild_var3 | | string | `var3` | no |
20+
| codebuild_var3_val | | string | `value3` | no |
21+
| delimiter | Delimiter to be used between `name`, `namespace`, `stage`, etc. | string | `-` | no |
22+
| enabled | A boolean to enable/disable resource creation | string | `true` | no |
23+
| github_token | (Optional) GitHub auth token environment variable (`GITHUB_TOKEN`) | string | `` | no |
24+
| image_repo_name | (Optional) ECR repository name to store the Docker image built by this module. Used as CodeBuild ENV variable when building Docker images. For more info: http://docs.aws.amazon.com/codebuild/latest/userguide/sample-docker.html | string | `UNSET` | no |
25+
| image_tag | (Optional) Docker image tag in the ECR repository, e.g. 'latest'. Used as CodeBuild ENV variable when building Docker images. For more info: http://docs.aws.amazon.com/codebuild/latest/userguide/sample-docker.html | string | `latest` | no |
26+
| name | Solution name, e.g. 'app' or 'jenkins' | string | `codebuild` | no |
27+
| namespace | Namespace, which could be your organization name, e.g. 'cp' or 'cloudposse' | string | `global` | no |
28+
| 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 | string | `false` | no |
29+
| source_location | The location of the source code from git or s3. | string | `` | no |
30+
| source_type | The type of repository that contains the source code to be built. Valid values for this parameter are: CODECOMMIT, CODEPIPELINE, GITHUB, GITHUB_ENTERPRISE, BITBUCKET or S3. | string | `CODEPIPELINE` | no |
31+
| stage | Stage, e.g. 'prod', 'staging', 'dev', or 'test' | string | `default` | no |
32+
| tags | Additional tags (e.g. `map('BusinessUnit', 'XYZ')` | map | `<map>` | no |
33+
34+
## Outputs
35+
36+
| Name | Description |
37+
|------|-------------|
38+
| cache_bucket_name | Cache S3 bucket name |
39+
| project_id | Project ID |
40+
| project_name | Project name |
41+
| role_arn | IAM Role ARN |
42+

main.tf

Lines changed: 92 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,59 @@ module "label" {
1515
tags = "${var.tags}"
1616
}
1717

18+
resource "aws_s3_bucket" "cache_bucket" {
19+
count = "${var.enabled == "true" && var.cache_enabled == "true" ? 1 : 0}"
20+
bucket = "${local.cache_bucket_name_normalised}"
21+
acl = "private"
22+
force_destroy = true
23+
tags = "${module.label.tags}"
24+
25+
lifecycle_rule {
26+
id = "codebuildcache"
27+
enabled = true
28+
29+
prefix = "/"
30+
tags = "${module.label.tags}"
31+
32+
expiration {
33+
days = "${var.cache_expiration_days}"
34+
}
35+
}
36+
}
37+
38+
resource "random_string" "bucket_prefix" {
39+
length = 12
40+
number = false
41+
upper = false
42+
special = false
43+
lower = true
44+
}
45+
46+
locals {
47+
cache_bucket_name = "${module.label.id}${var.cache_bucket_suffix_enabled == "true" ? "-${random_string.bucket_prefix.result}" : "" }"
48+
49+
## Clean up the bucket name to use only hyphens, and trim its length to 63 characters.
50+
## As per https://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html
51+
cache_bucket_name_normalised = "${substr(join("-", split("_", lower(local.cache_bucket_name))), 0, min(length(local.cache_bucket_name),63))}"
52+
53+
## This is the magic where a map of a list of maps is generated
54+
## and used to conditionally add the cache bucket option to the
55+
## aws_codebuild_project
56+
cache_def = {
57+
"true" = [{
58+
type = "S3"
59+
location = "${var.enabled == "true" && var.cache_enabled == "true" ? join("", aws_s3_bucket.cache_bucket.*.bucket) : "none" }"
60+
}]
61+
62+
"false" = []
63+
}
64+
65+
# Final Map Selected from above
66+
cache = "${local.cache_def[var.cache_enabled]}"
67+
}
68+
1869
resource "aws_iam_role" "default" {
70+
count = "${var.enabled == "true" ? 1 : 0}"
1971
name = "${module.label.id}"
2072
assume_role_policy = "${data.aws_iam_policy_document.role.json}"
2173
}
@@ -38,25 +90,34 @@ data "aws_iam_policy_document" "role" {
3890
}
3991

4092
resource "aws_iam_policy" "default" {
93+
count = "${var.enabled == "true" ? 1 : 0}"
4194
name = "${module.label.id}"
4295
path = "/service-role/"
4396
policy = "${data.aws_iam_policy_document.permissions.json}"
4497
}
4598

99+
resource "aws_iam_policy" "default_cache_bucket" {
100+
count = "${var.enabled == "true" && var.cache_enabled == "true" ? 1 : 0}"
101+
name = "${module.label.id}-cache-bucket"
102+
path = "/service-role/"
103+
policy = "${data.aws_iam_policy_document.permissions_cache_bucket.json}"
104+
}
105+
46106
data "aws_iam_policy_document" "permissions" {
47107
statement {
48108
sid = ""
49109

50110
actions = [
51-
"logs:CreateLogGroup",
52-
"logs:CreateLogStream",
53-
"logs:PutLogEvents",
54111
"ecr:BatchCheckLayerAvailability",
55112
"ecr:CompleteLayerUpload",
56113
"ecr:GetAuthorizationToken",
57114
"ecr:InitiateLayerUpload",
58115
"ecr:PutImage",
59116
"ecr:UploadLayerPart",
117+
"logs:CreateLogGroup",
118+
"logs:CreateLogStream",
119+
"logs:PutLogEvents",
120+
"ssm:GetParameters",
60121
]
61122

62123
effect = "Allow"
@@ -67,17 +128,39 @@ data "aws_iam_policy_document" "permissions" {
67128
}
68129
}
69130

131+
data "aws_iam_policy_document" "permissions_cache_bucket" {
132+
count = "${var.enabled == "true" ? 1 : 0}"
133+
134+
statement {
135+
sid = ""
136+
137+
actions = [
138+
"s3:*",
139+
]
140+
141+
effect = "Allow"
142+
143+
resources = [
144+
"${aws_s3_bucket.cache_bucket.arn}",
145+
"${aws_s3_bucket.cache_bucket.arn}/*",
146+
]
147+
}
148+
}
149+
70150
resource "aws_iam_role_policy_attachment" "default" {
151+
count = "${var.enabled == "true" ? 1 : 0}"
71152
policy_arn = "${aws_iam_policy.default.arn}"
72153
role = "${aws_iam_role.default.id}"
73154
}
74155

75-
#data "aws_ecr_repository" "service" {
76-
# count = "${signum(length(var.image_repo_name)) != 0 ? 1 : 0}"
77-
# name = "${var.image_repo_name}"
78-
#}
156+
resource "aws_iam_role_policy_attachment" "default_cache_bucket" {
157+
count = "${var.enabled == "true" && var.cache_enabled == "true" ? 1 : 0}"
158+
policy_arn = "${element(aws_iam_policy.default_cache_bucket.*.arn, count.index)}"
159+
role = "${aws_iam_role.default.id}"
160+
}
79161

80162
resource "aws_codebuild_project" "default" {
163+
count = "${var.enabled == "true" ? 1 : 0}"
81164
name = "${module.label.id}"
82165
service_role = "${aws_iam_role.default.arn}"
83166

@@ -139,7 +222,8 @@ resource "aws_codebuild_project" "default" {
139222

140223
source {
141224
buildspec = "${var.buildspec}"
142-
type = "CODEPIPELINE"
225+
type = "${var.source_type}"
226+
location = "${var.source_location}"
143227
}
144228

145229
tags = "${module.label.tags}"

outputs.tf

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
output "project_name" {
2-
value = "${aws_codebuild_project.default.name}"
2+
description = "Project name"
3+
value = "${join("", aws_codebuild_project.default.*.name)}"
34
}
45

56
output "project_id" {
6-
value = "${aws_codebuild_project.default.id}"
7+
description = "Project ID"
8+
value = "${join("", aws_codebuild_project.default.*.id)}"
79
}
810

911
output "role_arn" {
10-
value = "${aws_iam_role.default.id}"
12+
description = "IAM Role ARN"
13+
value = "${join("", aws_iam_role.default.*.id)}"
14+
}
15+
16+
output "cache_bucket_name" {
17+
description = "Cache S3 bucket name"
18+
value = "${var.enabled == "true" && var.cache_enabled == "true" ? join("", aws_s3_bucket.cache_bucket.*.bucket) : "UNSET" }"
1119
}

0 commit comments

Comments
 (0)