Skip to content

Instantly share code, notes, and snippets.

@tamsky
Forked from Jamie-BitFlight/buildspec.yml
Created August 28, 2018 15:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tamsky/4b7300e0131ad90fb1eb86c3b522477e to your computer and use it in GitHub Desktop.
Save tamsky/4b7300e0131ad90fb1eb86c3b522477e to your computer and use it in GitHub Desktop.
Terraform module that causes aws_codebuild_project to fail
version: 0.2
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws --version
- eval $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)
- REPOSITORY_URI=${ecr_address}
- GITHUB_TOKEN=${gh_token}
- IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
- git config --global credential.helper store
- printf "https://$GITHUB_TOKEN:x-oauth-basic@github.com\n" >> /root/.git-credentials
- git config --global user.email "builder@example.com"
- git config --global user.name "AWS CICD"
build:
commands:
- echo Build started on `date`
- echo Building the Docker image...
# - git init
# - git submodule update --recursive --remote
- git clone https://github.com/somecompany/erlangservice.git
- docker pull $IMAGE_REPO_NAME:latest || true
- docker build --build-arg POSTGRES_USERNAME=${db_user} --build-arg POSTGRES_HOST=${db_host} --build-arg POSTGRES_PASSWORD=${db_pass} --build-arg POSTGRES_DB=${db_name} --cache-from $CONTAINER_REPOSITORY_URL:latest -t $IMAGE_REPO_NAME:latest .
- docker tag $IMAGE_REPO_NAME:latest $IMAGE_REPO_NAME:$IMAGE_TAG
post_build:
commands:
- echo Build completed on `date`
- echo Pushing the Docker images...
- docker push $IMAGE_REPO_NAME:latest
- docker push $IMAGE_REPO_NAME:$IMAGE_TAG
- echo Writing image definitions file...
- printf '[{"name":"${task_name}","imageUri":"%s"}]' $IMAGE_REPO_NAME:$IMAGE_TAG > imagedefinitions.json
artifacts:
files: imagedefinitions.json
terraform {
backend "s3" { }
}
### For connecting and provisioning
variable "region" { }
variable "aws_access_key" { default = ""}
variable "aws_secret_key" { default = ""}
### For looking up info from the other Terraform States
variable "state_bucket" { description = "The bucket name where the chared Terraform state is kept" }
variable "state_region" { description = "The region for the Terraform state bucket"}
variable "env" { description = "The terraform workspace name." }
variable "name" { description = "The project name" }
### Local Variables
#Github Variables
variable "gh_owner" { }
variable "gh_repo" { }
variable "gh_branch" { }
variable "app_name" { }
variable "gh_token" { }
variable "environment" { default = "staging"}
variable "cluster_name" {}
variable "service_name" {}
variable "family_name" {}
variable "namespace" {
default = "global"
}
variable "stage" {
default = "default"
}
variable "privileged_mode" {
default = "true"
description = "(Optional) If set to true, enables running the Docker daemon inside a Docker container on the CodeBuild instance. Used when building Docker images"
}
variable "build_image" {
default = "aws/codebuild/docker:17.09.0"
description = "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"
}
variable "build_compute_type" {
default = "BUILD_GENERAL1_SMALL"
}
variable "buildspec" {
default = ""
description = "Optional buildspec declaration to use for building the project"
}
variable "aws_region" {
type = "string"
default = ""
description = "(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"
}
variable "aws_account_id" {
type = "string"
default = ""
description = "(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"
}
variable "image_repo_name" {
type = "string"
default = "UNSET"
description = "(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"
}
variable "image_tag" {
type = "string"
default = "latest"
description = "(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"
}
provider "aws" {
region = "${var.region}"
access_key = "${var.aws_access_key}"
secret_key = "${var.aws_secret_key}"
version = "~> 1.8"
}
resource "aws_s3_bucket" "cp_bucket" {
bucket_prefix = "codepipeline-${var.app_name}-${var.environment}"
acl = "private"
force_destroy = true
}
resource "aws_codepipeline" "pipeline" {
name = "${var.app_name}-${var.environment}-pipeline"
role_arn = "${aws_iam_role.codepipeline.arn}"
artifact_store {
location = "${aws_s3_bucket.cp_bucket.bucket}"
type = "S3"
}
stage {
name = "Source"
action {
name = "Source"
category = "Source"
owner = "ThirdParty"
provider = "GitHub"
version = "1"
output_artifacts = ["app_artifacts"]
configuration {
OAuthToken = "${var.gh_token}"
Owner = "${var.gh_owner}"
Repo = "${var.gh_repo}"
Branch = "${var.gh_branch}"
PollForSourceChanges = "true"
}
}
}
stage {
name = "Build"
action {
name = "Build"
category = "Build"
owner = "AWS"
provider = "CodeBuild"
input_artifacts = ["app_artifacts"]
output_artifacts = ["task_artifacts"]
version = "1"
configuration {
ProjectName = "${aws_codebuild_project.project.name}"
}
}
}
stage {
name = "Deploy"
action {
name = "Deploy"
version = "1"
category = "Deploy"
owner = "AWS"
provider = "ECS"
input_artifacts = ["task_artifacts"]
configuration {
ClusterName = "${var.cluster_name}"
ServiceName = "${var.service_name}"
# FileName = "task_definition.json"
}
}
}
}
data "aws_caller_identity" "default" {}
data "aws_region" "default" {
current = true
}
data "template_file" "build" {
template = "${file("${path.module}/buildspec.yml")}"
vars {
ecr_address = "${data.terraform_remote_state.ecr.repository_url}"
task_name = "${var.family_name}"
gh_token = "${var.gh_token}"
db_user = "${data.terraform_remote_state.rds.db_user}"
db_host = "${data.terraform_remote_state.rds.db_host}"
db_pass = "${data.terraform_remote_state.rds.db_pass}"
db_name = "${data.terraform_remote_state.rds.db_name}"
}
}
resource "aws_codebuild_project" "project" {
name = "${lower("${var.app_name}-${var.environment}-project")}"
description = "${var.app_name} build environment for ${var.gh_repo} branch ${var.gh_branch}"
build_timeout = "15"
service_role = "${aws_iam_role.codebuild_role.arn}"
artifacts {
type = "CODEPIPELINE"
}
environment {
compute_type = "${var.build_compute_type}"
image = "${var.build_image}"
type = "LINUX_CONTAINER"
privileged_mode = "${var.privileged_mode}"
environment_variable {
"name" = "GITHUB_TOKEN"
"value" = "${var.gh_token}"
}
environment_variable {
"name" = "AWS_DEFAULT_REGION"
"value" = "${signum(length(var.aws_region)) == 1 ? var.aws_region : data.aws_region.default.name}"
}
environment_variable {
"name" = "AWS_ACCOUNT_ID"
"value" = "${signum(length(var.aws_account_id)) == 1 ? var.aws_account_id : data.aws_caller_identity.default.account_id}"
}
environment_variable {
"name" = "IMAGE_REPO_NAME"
"value" = "${data.terraform_remote_state.ecr.repository_url}"
}
environment_variable {
"name" = "IMAGE_TAG"
"value" = "${signum(length(var.image_tag)) == 1 ? var.image_tag : "latest"}"
}
}
source {
buildspec = "${data.template_file.build.rendered}"
type = "CODEPIPELINE"
# auth {
# type = "OAUTH"
# resource = ""
# }
}
tags {
"Environment" = "Builder"
}
}
resource "aws_iam_role" "codepipeline" {
name = "codepipeline-role-${var.app_name}-${var.environment}"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "codepipeline.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_role_policy" "codepipeline_policy" {
name = "codepipeline_policy_${var.app_name}-${var.environment}"
role = "${aws_iam_role.codepipeline.id}"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect":"Allow",
"Action": [
"s3:GetObject",
"s3:*",
"s3:GetObjectVersion",
"s3:GetBucketVersioning"
],
"Resource": [
"${aws_s3_bucket.cp_bucket.arn}",
"${aws_s3_bucket.cp_bucket.arn}/*"
]
},
{
"Effect": "Allow",
"Action": [
"codebuild:BatchGetBuilds",
"codebuild:StartBuild"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "*"
}
]
}
EOF
}
resource "aws_iam_role" "codebuild_role" {
name = "codebuild-role-${var.app_name}-${var.environment}"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "codebuild.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_role_policy" "codebuild_policy" {
name = "codebuild-policy-${var.app_name}-${var.environment}"
# path = "/service-role/"
# description = "Policy used in trust relationship with CodeBuild"
role = "${aws_iam_role.codebuild_role.id}"
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Resource": [
"*"
],
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"s3:GetObject",
"s3:GetObjectVersion",
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"ecr:BatchCheckLayerAvailability",
"ecr:CompleteLayerUpload",
"ecr:GetAuthorizationToken",
"ecr:InitiateLayerUpload",
"ecr:PutImage",
"ecr:UploadLayerPart",
"s3:*"
]
}
]
}
POLICY
}
resource "aws_iam_role_policy_attachment" "codepipeline_policy_attachment_ECR" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerServiceFullAccess"
role = "${aws_iam_role.codepipeline.id}"
}
# resource "aws_iam_role_policy_attachment" "codebuild_policy_attachment" {
# policy_arn = "${aws_iam_policy.codebuild_policy.arn}"
# role = "${aws_iam_role.codebuild_role.id}"
# }
resource "aws_iam_role_policy_attachment" "codebuild_policy_attachment_ECR" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryPowerUser"
role = "${aws_iam_role.codebuild_role.id}"
}
locals {
state_path = "${var.env == "default" ? "" : "env:/${var.env}/" }"
}
### Look up remote state info
data "terraform_remote_state" "cluster" {
backend = "s3"
config {
bucket = "${var.state_bucket}"
key = "${local.state_path}cluster/state.tfstate"
region = "${var.state_region}"
}
}
data "terraform_remote_state" "rds" {
backend = "s3"
config {
bucket = "${var.state_bucket}"
key = "${local.state_path}rds/state.tfstate"
region = "${var.state_region}"
}
}
data "terraform_remote_state" "vpc" {
backend = "s3"
config {
bucket = "${var.state_bucket}"
key = "${local.state_path}vpc/state.tfstate"
region = "${var.state_region}"
}
}
data "terraform_remote_state" "ecr" {
backend = "s3"
config {
bucket = "${var.state_bucket}"
key = "${local.state_path}ecr/state.tfstate"
region = "${var.state_region}"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment