codepipeline-demo

This commit is contained in:
Edward Viaene
2020-02-18 18:14:40 +01:00
parent aa4e3dbb7b
commit cc37d59c87
15 changed files with 646 additions and 0 deletions
+47
View File
@@ -0,0 +1,47 @@
# code build
resource "aws_codebuild_project" "demo" {
name = "demo-docker-build"
description = "demo docker build"
build_timeout = "30"
service_role = aws_iam_role.demo-codebuild.arn
encryption_key = aws_kms_alias.demo-artifacts.arn
artifacts {
type = "CODEPIPELINE"
}
cache {
type = "S3"
location = aws_s3_bucket.codebuild-cache.bucket
}
environment {
compute_type = "BUILD_GENERAL1_SMALL"
image = "aws/codebuild/docker:18.09.0"
type = "LINUX_CONTAINER"
privileged_mode = true
environment_variable {
name = "AWS_DEFAULT_REGION"
value = var.AWS_REGION
}
environment_variable {
name = "AWS_ACCOUNT_ID"
value = data.aws_caller_identity.current.account_id
}
environment_variable {
name = "IMAGE_REPO_NAME"
value = aws_ecr_repository.demo.name
}
environment_variable {
name = "IMAGE_TAG"
value = "latest"
}
}
source {
type = "CODEPIPELINE"
buildspec = "buildspec.yml"
}
}
+4
View File
@@ -0,0 +1,4 @@
resource "aws_codecommit_repository" "demo" {
repository_name = "demo"
description = "This is the demo repository"
}
+74
View File
@@ -0,0 +1,74 @@
#
# codepipeline - demo
#
resource "aws_codepipeline" "demo" {
name = "demo-docker-pipeline"
role_arn = aws_iam_role.demo-codepipeline.arn
artifact_store {
location = aws_s3_bucket.demo-artifacts.bucket
type = "S3"
encryption_key {
id = aws_kms_alias.demo-artifacts.arn
type = "KMS"
}
}
stage {
name = "Source"
action {
name = "Source"
category = "Source"
owner = "AWS"
provider = "CodeCommit"
version = "1"
output_artifacts = ["demo-docker-source"]
configuration = {
RepositoryName = aws_codecommit_repository.demo.repository_name
BranchName = "master"
}
}
}
stage {
name = "Build"
action {
name = "Build"
category = "Build"
owner = "AWS"
provider = "CodeBuild"
input_artifacts = ["demo-docker-source"]
output_artifacts = ["demo-docker-build"]
version = "1"
configuration = {
ProjectName = aws_codebuild_project.demo.name
}
}
}
stage {
name = "Deploy"
action {
name = "Deploy"
category = "Deploy"
owner = "AWS"
provider = "ECS"
input_artifacts = ["demo-docker-build"]
version = "1"
configuration = {
ClusterName = "demo" # name of cluster
ServiceName = "demo" # name of service
}
role_arn = aws_iam_role.demo-codepipeline.arn
}
}
}
+4
View File
@@ -0,0 +1,4 @@
resource "aws_ecr_repository" "demo" {
name = "demo"
}
+4
View File
@@ -0,0 +1,4 @@
resource "aws_ecs_cluster" "demo" {
name = "demo"
}
+80
View File
@@ -0,0 +1,80 @@
resource "aws_ecs_task_definition" "demo" {
family = "demo"
execution_role_arn = aws_iam_role.ecs-task-execution-role.arn
task_role_arn = aws_iam_role.ecs-demo-task-role.arn
cpu = 256
memory = 512
network_mode = "awsvpc"
requires_compatibilities = [
"FARGATE"
]
container_definitions = <<DEFINITION
[
{
"essential": true,
"image": "${aws_ecr_repository.demo.repository_url}",
"name": "demo",
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group" : "demo",
"awslogs-region": "${var.AWS_REGION}",
"awslogs-stream-prefix": "ecs"
}
},
"secrets": [],
"environment": [],
"portMappings": [
{
"containerPort": 3000,
"hostPort": 3000,
"protocol": "tcp"
}
]
}
]
DEFINITION
}
resource "aws_ecs_service" "demo" {
name = "demo"
cluster = aws_ecs_cluster.demo.id
desired_count = 1
task_definition = aws_ecs_task_definition.demo.arn
launch_type = "FARGATE"
network_configuration {
subnets = slice(module.vpc.public_subnets, 1, 2)
security_groups = [aws_security_group.ecs-demo.id]
assign_public_ip = true
}
load_balancer {
target_group_arn = aws_lb_target_group.demo.id
container_name = "demo"
container_port = "3000"
}
lifecycle {
ignore_changes = [
task_definition
]
}
}
# security group
resource "aws_security_group" "ecs-demo" {
name = "ECS demo"
vpc_id = module.vpc.vpc_id
description = "ECS demo"
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = [
"0.0.0.0/0"
]
}
}
+135
View File
@@ -0,0 +1,135 @@
#
# iam roles
#
resource "aws_iam_role" "demo-codebuild" {
name = "demo-codebuild"
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" "demo-codebuild" {
role = aws_iam_role.demo-codebuild.name
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Resource": [
"*"
],
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
},
{
"Sid": "CodeCommitPolicy",
"Effect": "Allow",
"Action": [
"codecommit:GitPull"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"ec2:CreateNetworkInterface",
"ec2:DescribeDhcpOptions",
"ec2:DescribeNetworkInterfaces",
"ec2:DeleteNetworkInterface",
"ec2:DescribeSubnets",
"ec2:DescribeSecurityGroups",
"ec2:DescribeVpcs"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"${aws_s3_bucket.codebuild-cache.arn}",
"${aws_s3_bucket.codebuild-cache.arn}/*"
]
},
{
"Effect":"Allow",
"Action": [
"s3:List*",
"s3:Put*",
"s3:Get*"
],
"Resource": [
"${aws_s3_bucket.demo-artifacts.arn}",
"${aws_s3_bucket.demo-artifacts.arn}/*"
]
},
{
"Sid": "ECRPushPolicy",
"Effect": "Allow",
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:DescribeImages",
"ecr:BatchGetImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:PutImage"
],
"Resource": [
"*"
]
},
{
"Sid": "ECRAuthPolicy",
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"kms:DescribeKey",
"kms:GenerateDataKey*",
"kms:Encrypt",
"kms:ReEncrypt*",
"kms:Decrypt"
],
"Resource": [
"${aws_kms_key.demo-artifacts.arn}"
]
}
]
}
POLICY
}
+106
View File
@@ -0,0 +1,106 @@
resource "aws_iam_role" "demo-codepipeline" {
name = "demo-codepipeline"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "codepipeline.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
data "aws_iam_policy_document" "demo-codepipeline-role-policy" {
statement {
effect = "Allow"
actions = [
"s3:*",
]
resources = [
aws_s3_bucket.demo-artifacts.arn,
"${aws_s3_bucket.demo-artifacts.arn}/*",
]
}
statement {
effect = "Allow"
actions = [
"codebuild:BatchGetBuilds",
"codebuild:StartBuild",
]
resources = [
"*",
]
}
statement {
effect = "Allow"
actions = [
"sts:AssumeRole",
]
resources = [
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/demo-codepipeline",
]
}
statement {
effect = "Allow"
actions = [
"kms:DescribeKey",
"kms:GenerateDataKey*",
"kms:Encrypt",
"kms:ReEncrypt*",
"kms:Decrypt",
]
resources = [
aws_kms_key.demo-artifacts.arn,
]
}
statement {
effect = "Allow"
actions = [
"codecommit:UploadArchive",
"codecommit:Get*",
"codecommit:BatchGet*",
"codecommit:Describe*",
"codecommit:BatchDescribe*",
"codecommit:GitPull",
]
resources = [
aws_codecommit_repository.demo.arn,
]
}
statement {
effect = "Allow"
actions = [
"ecs:*",
]
resources = [
"*",
]
}
statement {
effect = "Allow"
actions = [
"iam:PassRole",
]
resources = [
aws_iam_role.ecs-task-execution-role.arn,
aws_iam_role.ecs-demo-task-role.arn,
]
}
}
resource "aws_iam_role_policy" "demo-codepipeline" {
name = "codepipeline-policy"
role = aws_iam_role.demo-codepipeline.id
policy = data.aws_iam_policy_document.demo-codepipeline-role-policy.json
}
+70
View File
@@ -0,0 +1,70 @@
resource "aws_iam_role" "ecs-task-execution-role" {
name = "ecs-task-execution-role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_role_policy" "ecs-task-execution-role" {
name = "ecs-task-execution-role"
role = aws_iam_role.ecs-task-execution-role.id
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"logs:CreateLogStream",
"logs:PutLogEvents",
"ssm:GetParameters",
"ssm:GetParameter"
],
"Resource": "*"
}
]
}
EOF
}
resource "aws_iam_role" "ecs-demo-task-role" {
name = "ecs-demo-task-role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
+32
View File
@@ -0,0 +1,32 @@
#
# kms
#
data "aws_iam_policy_document" "demo-artifacts-kms-policy" {
policy_id = "key-default-1"
statement {
sid = "Enable IAM User Permissions"
effect = "Allow"
principals {
type = "AWS"
identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"]
}
actions = [
"kms:*",
]
resources = [
"*",
]
}
}
resource "aws_kms_key" "demo-artifacts" {
description = "kms key for demo artifacts"
policy = data.aws_iam_policy_document.demo-artifacts-kms-policy.json
}
resource "aws_kms_alias" "demo-artifacts" {
name = "alias/demo-artifacts"
target_key_id = aws_kms_key.demo-artifacts.key_id
}
+32
View File
@@ -0,0 +1,32 @@
resource "aws_lb" "demo" {
name = "demo"
subnets = module.vpc.public_subnets
load_balancer_type = "network"
}
resource "aws_lb_listener" "demo" {
load_balancer_arn = aws_lb.demo.arn
port = "80"
protocol = "TCP"
default_action {
target_group_arn = aws_lb_target_group.demo.id
type = "forward"
}
}
resource "aws_lb_target_group" "demo" {
name = "demo-http"
port = "3000"
protocol = "TCP"
target_type = "ip"
vpc_id = module.vpc.vpc_id
deregistration_delay = "30"
health_check {
healthy_threshold = 2
unhealthy_threshold = 2
protocol = "TCP"
interval = 30
}
}
+9
View File
@@ -0,0 +1,9 @@
provider "aws" {
region = var.AWS_REGION
}
data "aws_availability_zones" "available" {
}
data "aws_caller_identity" "current" {
}
+28
View File
@@ -0,0 +1,28 @@
#
# cache s3 bucket
#
resource "aws_s3_bucket" "codebuild-cache" {
bucket = "demo-codebuild-cache-${random_string.random.result}"
acl = "private"
}
resource "aws_s3_bucket" "demo-artifacts" {
bucket = "demo-artifacts-${random_string.random.result}"
acl = "private"
lifecycle_rule {
id = "clean-up"
enabled = "true"
expiration {
days = 30
}
}
}
resource "random_string" "random" {
length = 8
special = false
upper = false
}
+3
View File
@@ -0,0 +1,3 @@
variable "AWS_REGION" {
default = "eu-west-1"
}
+18
View File
@@ -0,0 +1,18 @@
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "2.24.0"
name = "vpc-module-demo"
cidr = "10.0.0.0/16"
azs = slice(data.aws_availability_zones.available.names, 0, 3)
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
enable_nat_gateway = false
enable_vpn_gateway = false
tags = {
"Name" = "terraform-cloudpipeline-demo"
}
}