Skip to content

Instantly share code, notes, and snippets.

@joestump
Last active February 21, 2024 11:40
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save joestump/cac3abb94050186fcba1c57c8a880a71 to your computer and use it in GitHub Desktop.
Save joestump/cac3abb94050186fcba1c57c8a880a71 to your computer and use it in GitHub Desktop.
Trigger AWS CodePipeline with a GitHub webhook using Terraform
provider "aws" {}
provider "github" {}
resource "github_repository" "test" {
name = "joestump-test"
description = "Terraform test repository"
private = true
}
resource "aws_s3_bucket" "test" {
bucket = "joestump-test-bucket"
acl = "private"
}
data "aws_iam_policy_document" "assume_role" {
statement {
effect = "Allow"
principals {
type = "Service"
identifiers = [
"codebuild.amazonaws.com",
"codepipeline.amazonaws.com",
]
}
actions = ["sts:AssumeRole"]
}
}
resource "aws_iam_role" "test" {
name = "joestump-test-role"
assume_role_policy = "${data.aws_iam_policy_document.assume_role.json}"
}
data "aws_iam_policy_document" "test" {
# CodePipeline and CodeBuild use CloudWatch logs for managing their console output.
# This statement gives them them appropriate access according to the docs.
statement {
sid = "AllowLogging"
effect = "Allow"
resources = ["*"]
actions = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
]
}
statement {
sid = "AllowAccessToTheKMSKey"
effect = "Allow"
resources = [
"${aws_kms_key.test.arn}",
]
actions = [
"kms:DescribeKey",
"kms:ListKeyPolicies",
"kms:GetKeyPolicy",
"kms:GetKeyRotationStatus",
"kms:Encrypt",
"kms:Decrypt",
"kms:GenerateDataKey*",
"kms:ReEncrypt*",
]
}
statement {
sid = "AllowAccessToArtifactsInS3"
resources = [
"${aws_s3_bucket.test.arn}/*",
]
actions = [
"s3:DeleteObject",
"s3:GetObject*",
"s3:ListBucket",
"s3:PutObject*",
]
}
statement {
sid = "AllowAccessToArtifactsBucketInS3"
resources = [
"${aws_s3_bucket.test.arn}",
]
actions = [
"s3:GetBucketVersioning",
"s3:GetObject",
"s3:GetObjectVersion",
"s3:ListBucket",
"s3:ListObjects",
]
}
statement {
sid = "AllowCodePipelineToManageResourcesItCreates"
effect = "Allow"
resources = [
"arn:aws:s3:::codepipeline*",
"arn:aws:s3:::elasticbeanstalk*",
]
actions = [
"s3:PutObject",
]
}
statement {
sid = "AllowCodePipelinToRunCodeDeploy"
effect = "Allow"
resources = [
"*",
]
actions = [
"codedeploy:CreateDeployment",
"codedeploy:GetApplicationRevision",
"codedeploy:GetDeployment",
"codedeploy:GetDeploymentConfig",
"codedeploy:RegisterApplicationRevision",
]
}
statement {
sid = "AllowCodePipelineToSeeResources"
effect = "Allow"
resources = [
"*",
]
actions = [
"elasticbeanstalk:CreateApplicationVersion",
"elasticbeanstalk:DescribeApplicationVersions",
"elasticbeanstalk:DescribeEnvironments",
"elasticbeanstalk:DescribeEvents",
"elasticbeanstalk:UpdateEnvironment",
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeLaunchConfigurations",
"autoscaling:DescribeScalingActivities",
"autoscaling:ResumeProcesses",
"autoscaling:SuspendProcesses",
"cloudformation:GetTemplate",
"cloudformation:DescribeStackResource",
"cloudformation:DescribeStackResources",
"cloudformation:DescribeStackEvents",
"cloudformation:DescribeStacks",
"cloudformation:UpdateStack",
"ec2:DescribeInstances",
"ec2:DescribeImages",
"ec2:DescribeAddresses",
"ec2:DescribeSubnets",
"ec2:DescribeVpcs",
"ec2:DescribeSecurityGroups",
"ec2:DescribeKeyPairs",
"elasticloadbalancing:DescribeLoadBalancers",
"rds:DescribeDBInstances",
"rds:DescribeOrderableDBInstanceOptions",
"sns:ListSubscriptionsByTopic",
]
}
statement {
sid = "AllowCodePipelineToInvokeLambdaFunctions"
effect = "Allow"
resources = [
"*",
]
actions = [
"lambda:invokefunction",
"lambda:listfunctions",
]
}
statement {
sid = "AllowCodePipelineToManageBeanstalkS3Artifacts"
effect = "Allow"
resources = [
"arn:aws:s3:::elasticbeanstalk*",
]
actions = [
"s3:ListBucket",
"s3:GetBucketPolicy",
"s3:GetObjectAcl",
"s3:PutObjectAcl",
"s3:DeleteObject",
]
}
statement {
sid = "AllowCodePipelineToManageCodeBuildJobs"
effect = "Allow"
resources = [
"*",
]
actions = [
"codebuild:StartBuild",
"codebuild:StopBuild",
"codebuild:BatchGetBuilds",
"codebuild:BatchGetProjects",
"codebuild:ListBuilds",
"codebuild:ListBuildsForProject",
"codebuild:ListProjects",
]
}
}
resource "aws_iam_role_policy" "test" {
name = "joestump_codepipeline_policy"
role = "${aws_iam_role.test.id}"
policy = "${data.aws_iam_policy_document.test.json}"
}
resource "aws_kms_key" "test" {
description = "joestump-test-key"
}
resource "aws_kms_alias" "test" {
name = "alias/joestump-test"
target_key_id = "${aws_kms_key.test.key_id}"
}
resource "aws_codebuild_project" "test" {
name = "joestump-test-project"
description = "Joe Stump testing GitHub and CodePipeline"
build_timeout = "5"
service_role = "${aws_iam_role.test.arn}"
artifacts {
type = "CODEPIPELINE"
}
cache {
type = "S3"
location = "${aws_s3_bucket.test.bucket}"
}
environment {
compute_type = "BUILD_GENERAL1_SMALL"
image = "sfdcpcg/ci-tools"
type = "LINUX_CONTAINER"
}
source {
type = "CODEPIPELINE"
}
tags {
"Joe_Stump" = "Test"
}
}
resource "aws_codepipeline" "test" {
name = "joestump-test-pipeline"
role_arn = "${aws_iam_role.test.arn}"
artifact_store {
location = "${aws_s3_bucket.test.bucket}"
type = "S3"
encryption_key {
id = "${aws_kms_key.test.arn}"
type = "KMS"
}
}
stage {
name = "Source"
action {
name = "Source"
category = "Source"
owner = "ThirdParty"
provider = "GitHub"
version = "1"
output_artifacts = ["test"]
configuration {
Owner = "sfdc-pcg"
Repo = "${github_repository.test.name}"
Branch = "master"
}
}
}
stage {
name = "Build"
action {
name = "Build"
category = "Build"
owner = "AWS"
provider = "CodeBuild"
input_artifacts = ["test"]
version = "1"
configuration {
ProjectName = "${aws_codebuild_project.test.name}"
}
}
}
}
locals {
webhook_secret = "super-secret"
}
resource "aws_codepipeline_webhook" "bar" {
name = "test-webhook-github-bar"
authentication = "GITHUB_HMAC"
target_action = "Source"
target_pipeline = "${aws_codepipeline.test.name}"
authentication_configuration {
secret_token = "${local.webhook_secret}"
}
filter {
json_path = "$.ref"
match_equals = "refs/heads/{Branch}"
}
}
resource "github_repository_webhook" "test" {
repository = "${github_repository.test.name}"
name = "web"
configuration {
url = "${aws_codepipeline_webhook.test.url}"
content_type = "form"
insecure_ssl = true
secret = "${local.webhook_secret}"
}
events = ["push"]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment