diff --git a/4-gitlab-ci/README.md b/4-gitlab-ci/README.md index e168721..fbda237 100644 --- a/4-gitlab-ci/README.md +++ b/4-gitlab-ci/README.md @@ -1 +1,53 @@ +## Introduction + +First off this lab is entirely optional and also not for the faint hearted. Gitlab CI is currently introducing components to replace the current templates and openTofu will be updated to that as soon as they are supported in self managed runners. If you're not comfortable experimenting and cleaning things up in AWS manually **don't do this lab** + +### Get AWS Credentials for Gitlab + +Log into the AWS console and head to the IAM service. In here you need to create a new user called gitlab. + + + + + + + +```yaml +# This template is a port of the OpenTofu CI/CD component at +# https://gitlab.com/components/opentofu +# It is generated with the `make backports` command from that project. +# +# Please make sure to use the component when your project is hosted on GitLab.com +# or when you are willing to mirror the component project into your self-managed +# instance and use it from there. +# +# Attention: This template will be removed in favor of the OpenTofu CI/CD component as soon as components +# are available for self-managed instances. +# +# This specific template is located at: +# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/OpenTofu.latest.gitlab-ci.yml + +include: + - template: OpenTofu/Base.latest.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/OpenTofu/Base.latest.gitlab-ci.yml + +stages: [validate, build, deploy, cleanup] + +fmt: + extends: .opentofu:fmt + +validate: + extends: .opentofu:validate + +plan: + extends: .opentofu:plan + +apply: + extends: .opentofu:apply + +cleanup: + extends: .opentofu:destroy +``` + + + https://kodekloud.com/blog/understanding-terraform-modules/ diff --git a/4-gitlab-ci/code/data.tf b/4-gitlab-ci/code/data.tf new file mode 100644 index 0000000..b134b52 --- /dev/null +++ b/4-gitlab-ci/code/data.tf @@ -0,0 +1,7 @@ +data "aws_availability_zones" "available" {} + +data "aws_security_group" "default" { + name = "default" + vpc_id = module.vpc.vpc_id +} + diff --git a/4-gitlab-ci/code/env/dev.tfvars b/4-gitlab-ci/code/env/dev.tfvars new file mode 100644 index 0000000..3d610f5 --- /dev/null +++ b/4-gitlab-ci/code/env/dev.tfvars @@ -0,0 +1,2 @@ +ami_id = "ami-029b91ed285a24a90" +instance_size = t4g.nano diff --git a/4-gitlab-ci/code/locals.tf b/4-gitlab-ci/code/locals.tf new file mode 100644 index 0000000..b54693c --- /dev/null +++ b/4-gitlab-ci/code/locals.tf @@ -0,0 +1,9 @@ +locals { + default_tags = merge( + var.additional_tags, + { + Owner = var.name + Environment = var.environment + ManagedBy = "tofu/terraform" + }) +} diff --git a/4-gitlab-ci/code/main.tf b/4-gitlab-ci/code/main.tf new file mode 100644 index 0000000..82b9b44 --- /dev/null +++ b/4-gitlab-ci/code/main.tf @@ -0,0 +1,55 @@ +provider "aws" { + region = "eu-west-1" +} + +resource "aws_security_group" "web_server_sg_tf" { + name = "web-server-sg-tf" + description = "Allow HTTP to web server" + vpc_id = module.vpc.vpc_id + +ingress { + description = "SSH ingress" + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + +ingress { + description = "HTTP ingress" + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + +ingress { + description = "HTTPS ingress" + from_port = 443 + to_port = 443 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + +egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + +resource "aws_instance" "test_ami" { + ami = var.ami_id + instance_type = var.instance_size + associate_public_ip_address = true + subnet_id = module.vpc.public_subnets[0] + vpc_security_group_ids = [aws_security_group.web_server_sg_tf.id] + + user_data = <<-EOF + #!/bin/bash + sudo dnf install -y nginx + sudo systemctl enable nginx + sudo systemctl start nginx + EOF +} diff --git a/4-gitlab-ci/code/outputs.tf b/4-gitlab-ci/code/outputs.tf new file mode 100644 index 0000000..61cacf6 --- /dev/null +++ b/4-gitlab-ci/code/outputs.tf @@ -0,0 +1,33 @@ +# VPC +output "vpc_id" { + description = "The ID of the VPC" + value = module.vpc.vpc_id +} + +# Subnets +output "private_subnets" { + description = "List of IDs of private subnets" + value = module.vpc.private_subnets +} + +output "public_subnets" { + description = "List of IDs of public subnets" + value = module.vpc.public_subnets +} + +output "database_subnets" { + description = "List of IDs of database subnets" + value = module.vpc.database_subnets +} + +# NAT gateways +output "nat_public_ips" { + description = "List of public Elastic IPs created for AWS NAT Gateway" + value = module.vpc.nat_public_ips +} + +# Public IP of instance +output "instance_public_ip" { + description = "Show the public IP of the instance deployed" + value = aws_instance.test_ami.public_ip +} diff --git a/4-gitlab-ci/code/variables.tf b/4-gitlab-ci/code/variables.tf new file mode 100644 index 0000000..d62c799 --- /dev/null +++ b/4-gitlab-ci/code/variables.tf @@ -0,0 +1,48 @@ +variable "name" { + description = "Name of our Application" + type = string + default = "lab-1-app" +} + +variable "environment" { + description = "The deployment environment" + type = string + default = "dev" +} + +variable "private_subnet_suffix" { + description = "Suffix to append to private subnets name" + type = string + default = "private-" +} + +variable "public_subnet_suffix" { + description = "Suffix to append to public subnets name" + type = string + default = "public-" +} + +variable "database_subnet_suffix" { + description = "Suffix to append to database subnets name" + type = string + default = "rds-" +} + +variable "additional_tags" { + description = "Additional default resource tags" + type = map(string) + default = {} +} + +variable "instance_size" { + description = "Size of the instance to run" + type = string + default = "t4g.nano" +} + +variable "ami_id" { + description = "Instance Amazon Machine Image to run" + type = string + default = "ami-029b91ed285a24a90" +} + diff --git a/4-gitlab-ci/code/versions.tf b/4-gitlab-ci/code/versions.tf new file mode 100644 index 0000000..80d48bf --- /dev/null +++ b/4-gitlab-ci/code/versions.tf @@ -0,0 +1,19 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.66.1" + } + } + + backend "s3" { + bucket = "demo-tofu-bucket" + key = "terraform-tofu-lab/terraform.state" + region = "eu-west-1" + acl = "bucket-owner-full-control" + dynamodb_table = "demo-tofu-table" + } + +} diff --git a/4-gitlab-ci/code/vpc.tf b/4-gitlab-ci/code/vpc.tf new file mode 100644 index 0000000..1562f3c --- /dev/null +++ b/4-gitlab-ci/code/vpc.tf @@ -0,0 +1,36 @@ +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 3" + + name = "${var.name}-${var.environment}" + cidr = "20.10.0.0/16" # 10.0.0.0/8 is reserved for EC2-Classic + + azs = data.aws_availability_zones.available.names + private_subnets = ["20.10.1.0/24", "20.10.2.0/24", "20.10.3.0/24"] + public_subnets = ["20.10.11.0/24", "20.10.12.0/24", "20.10.13.0/24"] + database_subnets = ["20.10.21.0/24", "20.10.22.0/24", "20.10.23.0/24"] + + private_subnet_tags = { "name": "${var.private_subnet_suffix}-${var.name}-${var.environment}" } + public_subnet_tags = { "name": "${var.public_subnet_suffix}-${var.name}-${var.environment}" } + database_subnet_tags = { "name": "${var.database_subnet_suffix}-${var.name}-${var.environment}" } + + create_database_subnet_group = true + + enable_nat_gateway = true + single_nat_gateway = true + + enable_dhcp_options = false + + # Default security group - ingress/egress rules cleared to deny all + manage_default_security_group = true + default_security_group_ingress = [] + default_security_group_egress = [] + + # VPC Flow Logs (Cloudwatch log group and IAM role will be created) + enable_flow_log = true + create_flow_log_cloudwatch_log_group = true + create_flow_log_cloudwatch_iam_role = true + flow_log_max_aggregation_interval = 60 + + tags = local.default_tags +} diff --git a/4-gitlab-ci/img/aws-1.png b/4-gitlab-ci/img/aws-1.png new file mode 100644 index 0000000..ccb0f99 Binary files /dev/null and b/4-gitlab-ci/img/aws-1.png differ diff --git a/4-gitlab-ci/img/aws-2.png b/4-gitlab-ci/img/aws-2.png new file mode 100644 index 0000000..409b312 Binary files /dev/null and b/4-gitlab-ci/img/aws-2.png differ diff --git a/4-gitlab-ci/img/aws-3.png b/4-gitlab-ci/img/aws-3.png new file mode 100644 index 0000000..b518f86 Binary files /dev/null and b/4-gitlab-ci/img/aws-3.png differ diff --git a/4-gitlab-ci/img/aws-4.png b/4-gitlab-ci/img/aws-4.png new file mode 100644 index 0000000..34024a3 Binary files /dev/null and b/4-gitlab-ci/img/aws-4.png differ diff --git a/4-gitlab-ci/img/aws-5.png b/4-gitlab-ci/img/aws-5.png new file mode 100644 index 0000000..f226872 Binary files /dev/null and b/4-gitlab-ci/img/aws-5.png differ diff --git a/4-gitlab-ci/img/aws-6.png b/4-gitlab-ci/img/aws-6.png new file mode 100644 index 0000000..e8cc3bf Binary files /dev/null and b/4-gitlab-ci/img/aws-6.png differ diff --git a/4-gitlab-ci/img/build.png b/4-gitlab-ci/img/build.png new file mode 100644 index 0000000..e9cf584 Binary files /dev/null and b/4-gitlab-ci/img/build.png differ diff --git a/4-gitlab-ci/img/gitlab-vars-1.png b/4-gitlab-ci/img/gitlab-vars-1.png new file mode 100644 index 0000000..a9912b7 Binary files /dev/null and b/4-gitlab-ci/img/gitlab-vars-1.png differ diff --git a/4-gitlab-ci/img/pipeline.png b/4-gitlab-ci/img/pipeline.png new file mode 100644 index 0000000..d655eab Binary files /dev/null and b/4-gitlab-ci/img/pipeline.png differ diff --git a/4-gitlab-ci/img/variable-full.png b/4-gitlab-ci/img/variable-full.png new file mode 100644 index 0000000..aa1bb6a Binary files /dev/null and b/4-gitlab-ci/img/variable-full.png differ diff --git a/demo/iac/route53.bak b/demo/iac/route53.bak new file mode 100644 index 0000000..bce61da --- /dev/null +++ b/demo/iac/route53.bak @@ -0,0 +1,11 @@ +resource "aws_route53_record" "chat" { + zone_id = "Z2TWGHEC8YQMWW" + name = "chat.ngd.io" + type = "A" + + alias { + name = module.alb.dns_name + zone_id = module.alb.zone_id + evaluate_target_health = true + } +}