diff --git a/buildspec.yml b/terraform/buildspec.yml similarity index 100% rename from buildspec.yml rename to terraform/buildspec.yml diff --git a/terraform/main.tf b/terraform/main.tf index 17ca2800..68b7db96 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -3,6 +3,15 @@ provider "aws" { region = "eu-west-2" } +# ------------------------------- +# ----------- BUILD ------------- +# ------------------------------- + +module "hc-codebuild" { + source = "./modules/hc-codebuild" + name = "hc-codebuild" +} + # ------------------------------- # ----------- STAGING ----------- # ------------------------------- @@ -36,6 +45,16 @@ module "hc-staging-cluster" { subnets = ["${aws_default_subnet.default_A.id}", "${aws_default_subnet.default_B.id}"] } +module "hc-staging-pipeline" { + source = "./modules/hc-codepipeline" + name = "hc-staging-pipeline" + repository_name = "hackcambridge/hc2020-prototype" + repository_branch = "master" + repository_owner = "hackcambridge" + codebuild = "hc-codebuild" + # TODO: Switch to GitHub version 2 (maybe connect hooks) +} + # ------------------------------- # ------------ PROD ------------- # ------------------------------- @@ -70,6 +89,17 @@ module "hc-prod-cluster" { subnets = ["${aws_default_subnet.default_A.id}", "${aws_default_subnet.default_B.id}"] } +module "hc-prod-pipeline" { + source = "./modules/hc-codepipeline" + name = "hc-prod-pipeline" + repository_name = "hackcambridge/hc2020-prototype" + repository_branch = "deploy" + repository_owner = "hackcambridge" + codebuild = "hc-codebuild" + # TODO: Switch to GitHub version 2 (maybe connect hooks) +} + + # ------------------------------- # ---------- DATABASE ----------- # ------------------------------- @@ -88,3 +118,5 @@ module "hc-rds-cluster" { DB_USERNAME = "${var.DB_USERNAME}" DB_PASSWORD = "${var.DB_PASSWORD}" } + + diff --git a/terraform/modules/hc-codebuild/main.tf b/terraform/modules/hc-codebuild/main.tf new file mode 100644 index 00000000..0e8e0e97 --- /dev/null +++ b/terraform/modules/hc-codebuild/main.tf @@ -0,0 +1,52 @@ +data "template_file" "buildspec" { + template = "${file("buildspec.yml")}" + vars = { + env = var.env + } +} + +resource "aws_codebuild_project" "hc-codebuild" { + badge_enabled = false + build_timeout = 60 + name = var.name + queued_timeout = 480 + service_role = data.aws_iam_role.hc-codebuild.arn + tags = { + Environment = var.env + } + + artifacts { + encryption_disabled = false + name = "hc-codebuild-${var.env}" + override_artifact_name = false + packaging = "NONE" + type = "CODEPIPELINE" + } + + environment { + compute_type = "BUILD_GENERAL1_SMALL" + image = "aws/codebuild/amazonlinux2-x86_64-standard:2.0" + image_pull_credentials_type = "CODEBUILD" + privileged_mode = false + type = "LINUX_CONTAINER" + } + + logs_config { + cloudwatch_logs { + status = "ENABLED" + } + + s3_logs { + encryption_disabled = false + status = "DISABLED" + } + } + + source { + buildspec = data.template_file.buildspec.rendered + git_clone_depth = 0 + insecure_ssl = false + report_build_status = false + type = "CODEPIPELINE" + } +} diff --git a/terraform/modules/hc-codebuild/output.tf b/terraform/modules/hc-codebuild/output.tf new file mode 100644 index 00000000..e69de29b diff --git a/terraform/modules/hc-codebuild/variables.tf b/terraform/modules/hc-codebuild/variables.tf new file mode 100644 index 00000000..8b9e44d1 --- /dev/null +++ b/terraform/modules/hc-codebuild/variables.tf @@ -0,0 +1,9 @@ +variable "env" { + description = "The environment configuration to pass to the CodeBuild instance" + default = "" +} + +variable "name" { + description = "The name to give to the CodeBuild instance" + default = "" +} diff --git a/terraform/modules/hc-codepipeline/main.tf b/terraform/modules/hc-codepipeline/main.tf new file mode 100644 index 00000000..3a2ab580 --- /dev/null +++ b/terraform/modules/hc-codepipeline/main.tf @@ -0,0 +1,85 @@ +resource "aws_codepipeline" "hc-codepipeline" { + name = var.name + role_arn = data.aws_iam_role.pipeline_role.arn + tags = { + Environment = var.env + } + + artifact_store { + location = var.artifacts_bucket_name + type = "S3" + } + + stage { + name = "Source" + + action { + category = "Source" + configuration = { + "Branch" = var.repository_branch + "Owner" = var.repository_owner + "PollForSourceChanges" = "false" + "Repo" = var.repository_name + } + input_artifacts = [] + name = "Source" + output_artifacts = [ + "SourceArtifact", + ] + owner = "ThirdParty" + provider = "GitHub" + run_order = 1 + version = "1" + } + } + stage { + name = "Build" + + action { + category = "Build" + configuration = { + "EnvironmentVariables" = jsonencode( + [ + { + name = "environment" + type = "PLAINTEXT" + value = var.env + }, + ] + ) + "ProjectName" = var.codebuild + } + input_artifacts = [ + "SourceArtifact", + ] + name = "Build" + output_artifacts = [ + "BuildArtifact", + ] + owner = "AWS" + provider = "CodeBuild" + run_order = 1 + version = "1" + } + } + stage { + name = "Deploy" + + action { + category = "Deploy" + configuration = { + "BucketName" = var.static_web_bucket_name + "Extract" = "true" + } + input_artifacts = [ + "BuildArtifact", + ] + name = "Deploy" + output_artifacts = [] + owner = "AWS" + provider = "S3" + run_order = 1 + version = "1" + } + } +} diff --git a/terraform/modules/hc-codepipeline/output.tf b/terraform/modules/hc-codepipeline/output.tf new file mode 100644 index 00000000..e69de29b diff --git a/terraform/modules/hc-codepipeline/variables.tf b/terraform/modules/hc-codepipeline/variables.tf new file mode 100644 index 00000000..16e84c8d --- /dev/null +++ b/terraform/modules/hc-codepipeline/variables.tf @@ -0,0 +1,40 @@ + +variable "artifacts_bucket_name" { + description = "The name of the artifacts bucket for the CodePipeline" + default = "" +} + +variable "codebuild" { + description = "The name of the CodeBuild AWS instance" + default = "" +} + +variable "env" { + description = "The environment configuration to pass to the CodeBuild instance" + default = "" +} + +variable "name" { + description = "The name to give to the CodeBuild instance" + default = "" +} + +variable "static_web_bucket_name" { + description = "The name of the static web bucket where we store previous deployments" + default = "" +} + +variable "repository_branch" { + description = "The branch of the repository where the code is stored" + default = "" +} + +variable "repository_owner" { + description = "The owner of the repository where the code is stored" + default = "" +} + +variable "repository_name" { + description = "The name branch of the repository where the code is stored" + default = "" +} diff --git a/terraform/modules/hc-hooks/main.tf b/terraform/modules/hc-hooks/main.tf new file mode 100644 index 00000000..bc60ef24 --- /dev/null +++ b/terraform/modules/hc-hooks/main.tf @@ -0,0 +1,33 @@ +resource "aws_codepipeline_webhook" "codepipeline_webhook" { + authentication = "GITHUB_HMAC" + name = "codepipeline-webhook" + target_action = "Source" + target_pipeline = aws_codepipeline.static_web_pipeline.name + + authentication_configuration { + secret_token = random_string.github_secret.result + } + + filter { + json_path = "$.ref" + match_equals = "refs/heads/{Branch}" + } + tags = {} +} + +resource "github_repository_webhook" "github_hook" { + repository = var.repository_name + events = ["push"] + + configuration { + url = aws_codepipeline_webhook.codepipeline_webhook.url + insecure_ssl = "0" + content_type = "json" + secret = random_string.github_secret.result + } +} + +resource "random_string" "github_secret" { + length = 99 + special = false +} diff --git a/terraform/modules/hc-hooks/output.tf b/terraform/modules/hc-hooks/output.tf new file mode 100644 index 00000000..e69de29b diff --git a/terraform/modules/hc-hooks/variables.tf b/terraform/modules/hc-hooks/variables.tf new file mode 100644 index 00000000..09e82373 --- /dev/null +++ b/terraform/modules/hc-hooks/variables.tf @@ -0,0 +1,9 @@ +variable "name" { + description = "The name to give to the CodeBuild instance" + default = "" +} + +variable "env" { + description = "The environment configuration to pass to the CodeBuild instance" + default = "" +}