terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 4.0" } } } provider "aws" { region = "us-east-1" } # ECR Repository resource "aws_ecr_repository" "ecr_repository" { name = var.ecr_repository_name force_delete = true image_tag_mutability = "IMMUTABLE" image_scanning_configuration { scan_on_push = true } encryption_configuration { encryption_type = "KMS" } } # Build project resource "aws_iam_role" "codebuild_role" { name = "codebuild-role" assume_role_policy = jsonencode({ "Version" : "2012-10-17", "Statement" : [ { "Effect" : "Allow", "Principal" : { "Service" : "codebuild.amazonaws.com" }, "Action" : "sts:AssumeRole" } ] }) } resource "aws_iam_role_policy" "codebuild_role_policy" { role = aws_iam_role.codebuild_role.name policy = jsonencode({ "Version" : "2012-10-17", "Statement" : [ { "Effect" : "Allow", "Resource" : [ "*" ], "Action" : [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents", "ecr:GetAuthorizationToken", "ecr:CreateRepository", "ecr:InitiateLayerUpload", "ecr:UploadLayerPart", "ecr:CompleteLayerUpload", "ecr:BatchCheckLayerAvailability", "ecr:PutImage", "ecs:UpdateService", "s3:GetObject", "s3:GetObjectVersion", "s3:GetBucketVersioning", "s3:PutObjectAcl", "s3:PutObject" ] } ] }) } resource "aws_codebuild_project" "codebuild_project" { name = var.codebuild_project_name description = "Builds the .NET application image and pushes it to the ECR repository" service_role = aws_iam_role.codebuild_role.arn artifacts { type = "NO_ARTIFACTS" } environment { compute_type = "BUILD_GENERAL1_2XLARGE" image = "aws/codebuild/amazonlinux2-x86_64-standard:4.0" type = "LINUX_CONTAINER" image_pull_credentials_type = "CODEBUILD" privileged_mode = "true" } source { type = "GITHUB" location = var.github_url git_clone_depth = 1 git_submodules_config { fetch_submodules = true } buildspec = replace(file(var.buildspec_path), "ECR_REPO_URL", aws_ecr_repository.ecr_repository.repository_url) } source_version = "main" } # Pipeline resource "aws_iam_role" "codepipeline_role" { name = "codepipeline-role" assume_role_policy = jsonencode({ "Version" : "2012-10-17", "Statement" : [ { "Effect" : "Allow", "Principal" : { "Service" : "codepipeline.amazonaws.com" }, "Action" : "sts:AssumeRole" } ] }) } resource "aws_iam_role_policy" "codepipeline_role_policy" { name = "codepipeline-role-policy" role = aws_iam_role.codepipeline_role.id policy = jsonencode({ "Version" : "2012-10-17", "Statement" : [ { "Effect" : "Allow", "Action" : [ "s3:GetObject", "s3:GetObjectVersion", "s3:GetBucketVersioning", "s3:PutObjectAcl", "s3:PutObject" ], "Resource" : [ "${aws_s3_bucket.codepipeline_bucket.arn}", "${aws_s3_bucket.codepipeline_bucket.arn}/*" ] }, { "Effect" : "Allow", "Action" : [ "codestar-connections:UseConnection" ], "Resource" : "${aws_codestarconnections_connection.github_connection.arn}" }, { "Effect" : "Allow", "Action" : [ "codebuild:BatchGetBuilds", "codebuild:StartBuild" ], "Resource" : "*" } ] }) } resource "aws_codestarconnections_connection" "github_connection" { name = "codestar-github-connection" provider_type = "GitHub" } # S3 bucket and structure resource "aws_s3_bucket" "codepipeline_bucket" { bucket_prefix = "codepipeline-tfmsdemo" force_destroy = true } resource "aws_s3_bucket_acl" "codepipeline_bucket" { bucket = aws_s3_bucket.codepipeline_bucket.id acl = "private" } resource "aws_s3_bucket_versioning" "codepipeline_bucket" { bucket = aws_s3_bucket.codepipeline_bucket.id versioning_configuration { status = "Enabled" } } resource "aws_s3_bucket_public_access_block" "codepipeline_bucket" { bucket = aws_s3_bucket.codepipeline_bucket.id block_public_acls = true block_public_policy = true ignore_public_acls = true restrict_public_buckets = true } resource "aws_s3_bucket_server_side_encryption_configuration" "codepipeline_bucket" { bucket = aws_s3_bucket.codepipeline_bucket.bucket rule { apply_server_side_encryption_by_default { sse_algorithm = "aws:kms" } } } resource "aws_s3_bucket_logging" "example" { bucket = aws_s3_bucket.codepipeline_bucket.id target_bucket = aws_s3_bucket.codepipeline_bucket.id target_prefix = "logs/" } data "aws_kms_alias" "s3kmskey" { name = "alias/aws/s3" } # CodePipeline resource "aws_codepipeline" "build_pipeline" { name = var.pipeline_name role_arn = aws_iam_role.codepipeline_role.arn artifact_store { location = aws_s3_bucket.codepipeline_bucket.bucket type = "S3" encryption_key { id = data.aws_kms_alias.s3kmskey.arn type = "KMS" } } stage { name = "Source" action { name = "Source" category = "Source" owner = "AWS" provider = "CodeStarSourceConnection" version = "1" output_artifacts = ["source_output"] configuration = { ConnectionArn = aws_codestarconnections_connection.github_connection.arn FullRepositoryId = var.github_path BranchName = "main" } } } stage { name = "Build" action { name = "Build" category = "Build" owner = "AWS" provider = "CodeBuild" input_artifacts = ["source_output"] output_artifacts = ["build_output"] version = "1" configuration = { ProjectName = var.codebuild_project_name } } } }