diff --git a/backup.tf b/backup.tf new file mode 100644 index 0000000..83ce09e --- /dev/null +++ b/backup.tf @@ -0,0 +1,98 @@ +/* Resources for setting up Gitlab remote backup on Amazon S3 */ +locals { + gitlab_backup_iam_policy_name = "${local.environment_prefix}-gitlab-backup" + gitlab_backup_iam_role_name = "${local.environment_prefix}-gitlab-backup" +} +resource "aws_s3_bucket" "gitlab_backup" { + count = var.enable_gitlab_backup_to_s3 ? 1 : 0 + bucket = var.gitlab_backup_bucket_name + + tags = merge(local.default_tags, var.additional_tags) + + lifecycle { + precondition { + condition = anytrue([ + (var.enable_gitlab_backup_to_s3 == false), + (var.enable_gitlab_backup_to_s3 == true && var.gitlab_backup_bucket_name != null) + ]) + error_message = "Gitlab backup to S3 is set to ${var.enable_gitlab_backup_to_s3}. gitlab_backup_bucket_name is mandatory to create S3 bucket." + } + } +} + +resource "aws_s3_bucket_acl" "gitlab_backup" { + count = var.enable_gitlab_backup_to_s3 ? 1 : 0 + bucket = aws_s3_bucket.gitlab_backup[0].id + acl = "private" +} + +data "aws_iam_policy_document" "gitlab_s3_backup" { + count = var.enable_gitlab_backup_to_s3 ? 1 : 0 + statement { + effect = "Allow" + actions = [ + "s3:AbortMultipartUpload", + "s3:GetBucketAcl", + "s3:GetBucketLocation", + "s3:GetObject", + "s3:GetObjectAcl", + "s3:ListBucketMultipartUploads", + "s3:PutObject", + "s3:PutObjectAcl" + ] + resources = [ + "arn:aws:s3:::${aws_s3_bucket.gitlab_backup[0].bucket}/*" + ] + } + statement { + effect = "Allow" + actions = [ + "s3:GetBucketLocation", + "s3:ListAllMyBuckets" + ] + resources = [ + "*" + ] + } + statement { + effect = "Allow" + actions = [ + "s3:ListBucket" + ] + resources = [ + "arn:aws:s3:::${aws_s3_bucket.gitlab_backup[0].bucket}" + ] + } +} + +resource "aws_iam_policy" "gitlab_backup" { + count = var.enable_gitlab_backup_to_s3 ? 1 : 0 + name = local.gitlab_backup_iam_policy_name + policy = data.aws_iam_policy_document.gitlab_s3_backup[0].json + tags = merge({ + Name = local.gitlab_backup_iam_policy_name + }, local.default_tags, var.additional_tags) +} + +resource "aws_iam_role" "gitlab_backup" { + name = local.gitlab_backup_iam_role_name + assume_role_policy = < 'AWS', - 'region' => '${aws_region}', - 'use_iam_profile' => true -} -gitlab_rails['backup_upload_remote_directory'] = '${gitlab_backup_s3_bucket_name}' diff --git a/gitlab_config_templates/gitlab-redis.tftpl b/gitlab_config_templates/gitlab-redis.tftpl deleted file mode 100644 index ed60013..0000000 --- a/gitlab_config_templates/gitlab-redis.tftpl +++ /dev/null @@ -1 +0,0 @@ -redis['enable'] = false diff --git a/load_balancers.tf b/load_balancers.tf new file mode 100644 index 0000000..20857c8 --- /dev/null +++ b/load_balancers.tf @@ -0,0 +1,103 @@ +/* Resources for Gitlab classic load balancer */ +locals { + gitlab_lb_sg_name = "${local.environment_prefix}-gitlab-lb" + gitlab_lb_name = "${local.environment_prefix}-gitlab" +} +resource "aws_security_group" "gitlab_lb" { + name = local.gitlab_lb_sg_name + vpc_id = data.aws_vpc.vpc.id + description = "Security group for Gitlab load balancer" + ingress = [ + { + from_port = 80 + protocol = "tcp" + to_port = 80 + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + prefix_list_ids = [] + security_groups = [] + self = false + description = "allow http ingress from anywhere" + }, + { + from_port = 443 + protocol = "tcp" + to_port = 443 + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + prefix_list_ids = [] + security_groups = [] + self = false + description = "allow https ingress from anywhere" + }, + { + from_port = 22 + protocol = "tcp" + to_port = 22 + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + prefix_list_ids = [] + security_groups = [] + self = false + description = "allow SSH ingress from anywhere" + } + ] + egress = [ + { + from_port = 0 + protocol = "-1" + to_port = 0 + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + prefix_list_ids = [] + security_groups = [] + self = false + description = "allow all egress" + } + ] + tags = merge({ + Name = local.gitlab_lb_sg_name + }, local.default_tags, var.additional_tags) +} + +module "elb" { + source = "terraform-aws-modules/elb/aws" + version = "~> 2.0" + name = local.gitlab_lb_name + subnets = var.public_subnet_ids + security_groups = [aws_security_group.gitlab_lb.id] + internal = false + listener = [ + { + instance_port = 80 + instance_protocol = "HTTP" + lb_port = 80 + lb_protocol = "HTTP" + }, + { + instance_port = 80 + instance_protocol = "HTTP" + lb_port = 443 + lb_protocol = "HTTPS" + ssl_certificate_id = var.create_acm_certificate ? module.acm.acm_certificate_arn : var.acm_certificate_arn + }, + { + instance_port = 22 + instance_protocol = "TCP" + lb_port = 22 + lb_protocol = "TCP" + }, + ] + health_check = { + target = "${var.healthcheck_protocol}:${var.healthcheck_port}${var.healthcheck_path}" + interval = var.healthcheck_interval + healthy_threshold = var.healthcheck_healthy_threshold + unhealthy_threshold = var.healthcheck_unhealthy_threshold + timeout = var.healthcheck_timeout + } + number_of_instances = 1 + instances = tolist([aws_instance.gitlab.id]) + tags = merge({ + Name = local.gitlab_lb_name + }, local.default_tags, var.additional_tags) +} diff --git a/main.tf b/main.tf index 826aa7e..55a551f 100644 --- a/main.tf +++ b/main.tf @@ -1,17 +1,16 @@ locals { - managed_by = "Terraform" - gitlab_config_file_name = "gitlab.rb" - rendered_gitlab_config_file_name = "gitlab_rendered.rb" - gitlab_additional_config_file_name = "gitlab_additional.rb" - gitlab_config_tmp_path = "/tmp/gitlab/gitlab_config" - gitlab_config_template_file_path = "${path.module}/gitlab_config_templates" - gitlab_config_file_path = "${path.cwd}/gitlab_config" - gitlab_config_playbook_file = "${path.module}/playbooks/gitlab_setup.yaml" - gitlab_complete_url = join("", tolist(["https://", values(module.records.route53_record_name)[0]])) + default_tags = { + ManagedBy = "Terraform" + Environment = var.environment + } + environment_prefix = substr(var.environment, 0, 1) + gitlab_instance_name = "${local.environment_prefix}-gitlab" + gitlab_ssh_key_name = "${local.environment_prefix}-gitlab-key-pair" + gitlab_instance_sg_name = "${local.environment_prefix}-gitlab" + gitlab_instance_profile_name = "${local.environment_prefix}-gitlab" } resource "aws_instance" "gitlab" { - count = 1 ami = var.ami_id instance_type = var.instance_type subnet_id = var.private_subnet_id @@ -22,21 +21,23 @@ resource "aws_instance" "gitlab" { root_block_device { volume_type = var.volume_type volume_size = var.volume_size + iops = var.volume_iops delete_on_termination = false } - tags = { - Name = "${var.environment_prefix}-gitlab" - Environment = var.environment_prefix - ManagedBy = local.managed_by - } + tags = merge({ + Name = local.gitlab_instance_name + }, local.default_tags, var.additional_tags) } resource "aws_key_pair" "gitlab_ssh" { count = var.gitlab_ssh_public_key != null ? 1 : 0 - key_name = "${var.environment_prefix}-gitlab-key-pair" + key_name = local.gitlab_ssh_key_name public_key = var.gitlab_ssh_public_key + tags = merge({ + Name = local.gitlab_ssh_key_name + }, local.default_tags, var.additional_tags) } data "aws_vpc" "vpc" { @@ -48,7 +49,7 @@ data "aws_route53_zone" "zone" { } resource "aws_security_group" "gitlab" { - name = "${var.environment_prefix}-gitlab" + name = local.gitlab_instance_sg_name vpc_id = data.aws_vpc.vpc.id description = "Security group for Gitlab instance" ingress = [ @@ -99,68 +100,9 @@ resource "aws_security_group" "gitlab" { description = "allow all egress" } ] - tags = { - Environment = var.environment_prefix - ManagedBy = local.managed_by - } -} - -resource "aws_security_group" "gitlab_lb" { - name = "${var.environment_prefix}-gitlab-lb" - vpc_id = data.aws_vpc.vpc.id - description = "Security group for Gitlab load balancer" - ingress = [ - { - from_port = 80 - protocol = "tcp" - to_port = 80 - cidr_blocks = ["0.0.0.0/0"] - ipv6_cidr_blocks = ["::/0"] - prefix_list_ids = [] - security_groups = [] - self = false - description = "allow http ingress from anywhere" - }, - { - from_port = 443 - protocol = "tcp" - to_port = 443 - cidr_blocks = ["0.0.0.0/0"] - ipv6_cidr_blocks = ["::/0"] - prefix_list_ids = [] - security_groups = [] - self = false - description = "allow https ingress from anywhere" - }, - { - from_port = 22 - protocol = "tcp" - to_port = 22 - cidr_blocks = ["0.0.0.0/0"] - ipv6_cidr_blocks = ["::/0"] - prefix_list_ids = [] - security_groups = [] - self = false - description = "allow SSH ingress from anywhere" - } - ] - egress = [ - { - from_port = 0 - protocol = "-1" - to_port = 0 - cidr_blocks = ["0.0.0.0/0"] - ipv6_cidr_blocks = ["::/0"] - prefix_list_ids = [] - security_groups = [] - self = false - description = "allow all egress" - } - ] - tags = { - Environment = var.environment_prefix - ManagedBy = local.managed_by - } + tags = merge({ + Name = local.gitlab_instance_sg_name + }, local.default_tags, var.additional_tags) } module "records" { @@ -190,375 +132,15 @@ module "acm" { wait_for_validation = true - tags = { + tags = merge({ Name = var.gitlab_domain - } -} - -module "elb" { - source = "terraform-aws-modules/elb/aws" - version = "~> 2.0" - - name = "${var.environment_prefix}-gitlab" - - subnets = var.public_subnet_ids - security_groups = [aws_security_group.gitlab_lb.id] - internal = false - - listener = [ - { - instance_port = 80 - instance_protocol = "HTTP" - lb_port = 80 - lb_protocol = "HTTP" - }, - { - instance_port = 80 - instance_protocol = "HTTP" - lb_port = 443 - lb_protocol = "HTTPS" - ssl_certificate_id = var.create_acm_certificate ? module.acm.acm_certificate_arn : var.acm_certificate_arn - }, - { - instance_port = 22 - instance_protocol = "TCP" - lb_port = 22 - lb_protocol = "TCP" - }, - ] - - health_check = { - target = "${var.healthcheck_protocol}:${var.healthcheck_port}${var.healthcheck_path}" - interval = var.healthcheck_interval - healthy_threshold = var.healthcheck_healthy_threshold - unhealthy_threshold = var.healthcheck_unhealthy_threshold - timeout = var.healthcheck_timeout - } - number_of_instances = length(aws_instance.gitlab) - instances = aws_instance.gitlab[*].id - - tags = { - Environment = var.environment_prefix - } -} - -module "gitlab_pg" { - source = "terraform-aws-modules/rds/aws" - identifier = "${var.environment_prefix}-gitlab-pg" - create_db_instance = true - create_db_subnet_group = true - create_db_parameter_group = var.gitlab_pg_create_db_parameter_group - parameter_group_name = var.gitlab_pg_parameter_group_name - parameters = var.gitlab_pg_parameters - db_subnet_group_name = "${var.environment_prefix}-gitlab-pg" - subnet_ids = var.gitlab_pg_subnet_ids - allocated_storage = var.gitlab_pg_allocated_storage - storage_type = var.gitlab_pg_storage_type - db_name = var.gitlab_pg_db_name - port = tostring(var.gitlab_pg_port) - engine = "postgres" - engine_version = var.gitlab_pg_engine_version - instance_class = var.gitlab_pg_db_instance_class - username = var.gitlab_pg_username - password = var.gitlab_pg_password - create_random_password = false - publicly_accessible = var.gitlab_pg_publicly_accessible - vpc_security_group_ids = [aws_security_group.gitlab_rds.id] -} - -resource "aws_security_group" "gitlab_rds" { - name = "${var.environment_prefix}-gitlab-rds" - vpc_id = data.aws_vpc.vpc.id - description = "Security group for Gitlab RDS" - ingress = [ - { - from_port = var.gitlab_pg_port - protocol = "tcp" - to_port = var.gitlab_pg_port - cidr_blocks = [] - ipv6_cidr_blocks = [] - prefix_list_ids = [] - security_groups = [aws_security_group.gitlab.id] - self = false - description = "allow TCP access from Gitlab instance" - } - ] - tags = { - Environment = var.environment_prefix - ManagedBy = local.managed_by - } -} - -resource "aws_elasticache_cluster" "gitlab_redis" { - cluster_id = "${var.environment_prefix}-gitlab-redis" - engine = "redis" - node_type = var.gitlab_redis_node_type - num_cache_nodes = var.gitlab_redis_num_cache_nodes - parameter_group_name = var.gitlab_redis_create_parameter_group == true ? aws_elasticache_parameter_group.gitlab_redis[0].name : var.gitlab_redis_parameter_group_name - engine_version = var.gitlab_redis_engine_version - port = var.gitlab_redis_port - security_group_ids = [aws_security_group.gitlab_redis.id] - subnet_group_name = var.gitlab_redis_create_subnet_group == true ? aws_elasticache_subnet_group.gitlab_redis[0].name : var.gitlab_redis_subnet_group_name - - lifecycle { - precondition { - condition = anytrue([ - (var.gitlab_redis_create_parameter_group == false && var.gitlab_redis_parameter_group_name != null), - (var.gitlab_redis_create_parameter_group) - ]) - error_message = "Parameter Group creation for Gitlab Redis is set to ${var.gitlab_redis_create_parameter_group}. Provide a pre-existing Parameter Group name." - } - } -} - -resource "aws_elasticache_parameter_group" "gitlab_redis" { - count = var.gitlab_redis_create_parameter_group == true ? 1 : 0 - family = var.gitlab_redis_parameter_group.family - name = var.gitlab_redis_parameter_group.name - - lifecycle { - precondition { - condition = var.gitlab_redis_parameter_group.name != null && var.gitlab_redis_parameter_group.family != null - error_message = "Provide name and family in gitlab_redis_parameter_group for Parameter Group creation" - } - } -} - -resource "aws_elasticache_subnet_group" "gitlab_redis" { - count = var.gitlab_redis_create_subnet_group == true ? 1 : 0 - name = "${var.environment_prefix}-gitlab-redis" - subnet_ids = var.gitlab_redis_subnet_ids - tags = { - Name = "${var.environment_prefix}-gitlab-redis" - ManagedBy = local.managed_by - } - lifecycle { - precondition { - condition = var.gitlab_redis_create_subnet_group && length(var.gitlab_redis_subnet_ids) != 0 - error_message = "Subnet Group creation needs subnet-ids. Add subnet-ids to gitlab_redis_subnet_ids" - } - } -} - -resource "aws_security_group" "gitlab_redis" { - name = "${var.environment_prefix}-gitlab-redis" - vpc_id = data.aws_vpc.vpc.id - description = "Security group for Gitlab Redis" - ingress = [ - { - from_port = var.gitlab_redis_port - protocol = "tcp" - to_port = var.gitlab_redis_port - cidr_blocks = [] - ipv6_cidr_blocks = [] - prefix_list_ids = [] - security_groups = [aws_security_group.gitlab.id] - self = false - description = "allow TCP access from Gitlab instance" - } - ] - tags = { - Environment = var.environment_prefix - ManagedBy = local.managed_by - } -} - -resource "aws_s3_bucket" "gitlab_backup" { - count = var.enable_gitlab_backup_to_s3 ? 1 : 0 - bucket = var.gitlab_backup_bucket_name - lifecycle { - precondition { - condition = anytrue([ - (var.enable_gitlab_backup_to_s3 == false), - (var.enable_gitlab_backup_to_s3 == true && var.gitlab_backup_bucket_name != null) - ]) - error_message = "Gitlab backup to S3 is set to ${var.enable_gitlab_backup_to_s3}. gitlab_backup_bucket_name is mandatory to create S3 bucket." - } - - } -} - -resource "aws_s3_bucket_acl" "gitlab_backup" { - count = var.enable_gitlab_backup_to_s3 ? 1 : 0 - bucket = aws_s3_bucket.gitlab_backup[0].id - acl = "private" -} - -data "aws_iam_policy_document" "gitlab_s3_backup" { - count = var.enable_gitlab_backup_to_s3 ? 1 : 0 - statement { - effect = "Allow" - actions = [ - "s3:AbortMultipartUpload", - "s3:GetBucketAcl", - "s3:GetBucketLocation", - "s3:GetObject", - "s3:GetObjectAcl", - "s3:ListBucketMultipartUploads", - "s3:PutObject", - "s3:PutObjectAcl" - ] - resources = [ - "arn:aws:s3:::${aws_s3_bucket.gitlab_backup[0].bucket}/*" - ] - } - statement { - effect = "Allow" - actions = [ - "s3:GetBucketLocation", - "s3:ListAllMyBuckets" - ] - resources = [ - "*" - ] - } - statement { - effect = "Allow" - actions = [ - "s3:ListBucket" - ] - resources = [ - "arn:aws:s3:::${aws_s3_bucket.gitlab_backup[0].bucket}" - ] - } -} - -resource "aws_iam_policy" "gitlab_backup" { - count = var.enable_gitlab_backup_to_s3 ? 1 : 0 - name = "gitlab-backup" - policy = data.aws_iam_policy_document.gitlab_s3_backup[0].json -} - -resource "aws_iam_role" "gitlab_backup" { - name = "gitlab-backup" - assume_role_policy = <