This template creates an AWS CodePipeline that includes stages for source control, building the project using AWS CodeBuild, and deploying using AWS CloudFormation.

Terraform Template

data "aws_iam_policy_document" "assume_role" {

  statement {
    actions = ["sts:AssumeRole"]
    effect = "Allow"

    principals {
      identifiers = ["codepipeline.amazonaws.com"]
      type = "Service"
    }
  }
}

data "aws_iam_policy_document" "codepipeline_policy" {

  statement {
    actions = ["s3:GetObject", "s3:GetObjectVersion", "s3:GetBucketVersioning", "s3:PutObjectAcl", "s3:PutObject"]
    effect = "Allow"
    resources = [aws_s3_bucket.codepipeline_bucket.arn, "${aws_s3_bucket.codepipeline_bucket.arn}/*"]
  }

  statement {
    actions = ["codestar-connections:UseConnection"]
    effect = "Allow"
    resources = [aws_codestarconnections_connection.example.arn]
  }

  statement {
    actions = ["codebuild:BatchGetBuilds", "codebuild:StartBuild"]
    effect = "Allow"
    resources = [*]
  }
}

data "aws_kms_alias" "s3kmskey" {
  name = "alias/myKmsKey"
}

resource "aws_codepipeline" "codepipeline" {

  artifact_store {

    encryption_key {
      id = data.aws_kms_alias.s3kmskey.arn
      type = "KMS"
    }
    location = aws_s3_bucket.codepipeline_bucket.bucket
    type = "S3"
  }
  name = "tf-test-pipeline"
  role_arn = aws_iam_role.codepipeline_role.arn

  stage {

    action {
      category = "Source"

      configuration = {
        BranchName = "main"
        ConnectionArn = aws_codestarconnections_connection.example.arn
        FullRepositoryId = "my-organization/example"
      }
      name = "Source"
      output_artifacts = ["source_output"]
      owner = "AWS"
      provider = "CodeStarSourceConnection"
      version = "1"
    }
    name = "Source"
  }

  stage {

    action {
      category = "Build"

      configuration = {
        ProjectName = "test"
      }
      input_artifacts = ["source_output"]
      name = "Build"
      output_artifacts = ["build_output"]
      owner = "AWS"
      provider = "CodeBuild"
      version = "1"
    }
    name = "Build"
  }

  stage {

    action {
      category = "Deploy"

      configuration = {
        ActionMode = "REPLACE_ON_FAILURE"
        Capabilities = "CAPABILITY_AUTO_EXPAND,CAPABILITY_IAM"
        OutputFileName = "CreateStackOutput.json"
        StackName = "MyStack"
        TemplatePath = "build_output::sam-templated.yaml"
      }
      input_artifacts = ["build_output"]
      name = "Deploy"
      owner = "AWS"
      provider = "CloudFormation"
      version = "1"
    }
    name = "Deploy"
  }
}

resource "aws_codestarconnections_connection" "example" {
  name = "example-connection"
  provider_type = "GitHub"
  provider = ""
}

resource "aws_iam_role" "codepipeline_role" {
  assume_role_policy = data.aws_iam_policy_document.assume_role.json
  name = "test-role"
}

resource "aws_iam_role_policy" "codepipeline_policy" {
  name = "codepipeline_policy"
  policy = data.aws_iam_policy_document.codepipeline_policy.json
  role = aws_iam_role.codepipeline_role.id
}

resource "aws_s3_bucket" "codepipeline_bucket" {
  bucket = "test-bucket"
}

resource "aws_s3_bucket_public_access_block" "codepipeline_bucket_pab" {
  block_public_acls = true
  block_public_policy = true
  bucket = aws_s3_bucket.codepipeline_bucket.id
  ignore_public_acls = true
  restrict_public_buckets = true
}