Terraform Examples

terraform {
  required_version = "~> 1.9"

  # choose one
  backend "s3" {
    bucket         = "s3-bucket-terraform-state"
    key            = "my-project/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "terraform-state-lock"
  }

  # choose one
  backend "remote" {
    organization = "-- terraform.io organization --"
    token = "-- add here your terraform.io token --"
    workspaces {
      name = "-- terraform.io workspace name (directory/path, this is not the terraform workspace from code) --"
    }
  }

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 5.0"
    }

    gitlab = {
      source = "gitlabhq/gitlab"
      version = "~> 3.5"
    }

    github = {
      source  = "integrations/github"
      version = "~> 4.0"
    }
  }
}

provider "aws" {
  region              = "us-east-1"
  allowed_account_ids = [">>aws-account-id<<"]

  default_tags {
    tags = {
      service = ""
      environment = ""
      repo_url = ""
      repo_path = ""
    }
  }
}

provider "gitlab" {
  token = var.gitlab_token
}
locals {
  repositories = [
    {
      name = "newsletter"
      description = "Newsletter simple system"
      archive_on_destroy = false
      is_private = false
    },
  ]
}

module "repositories" {
  source = "../_modules/github-repository" // custom, not shown here

  for_each = { for item in local.repositories: item.name => item }

  description = each.value.description
  name        = each.value.name

  is_private = try(each.value.is_private, true)
  has_issues = try(each.value.has_issues, false)
  has_downloads = try(each.value.has_downloads, false)
  has_projects = try(each.value.has_projects, false)
  has_wiki = try(each.value.has_wiki, false)
  delete_branch_on_merge = try(each.value.delete_branch_on_merge, true)
  archive_on_destroy = try(each.value.archive_on_destroy, true)

  topics = try(each.value.topics, [])
  archived = try(each.value.archived, false)
}

resource "github_repository" "this" {
  name        = var.name
  description = var.description

  visibility = var.is_private ? "private" : "public"

  has_issues    = var.has_issues
  has_downloads = var.has_downloads
  has_projects  = var.has_projects
  has_wiki      = var.has_wiki

  delete_branch_on_merge = var.delete_branch_on_merge

  archive_on_destroy = var.archive_on_destroy

  archived = var.archived

  topics = var.topics
}
# Get current aws account id
data "aws_caller_identity" "current" {}

# Create key pair for your ec2 instance
#
# Run: `ssh-keygen -f ec2` # it will generate private and public key in the current directory
#
resource "aws_key_pair" "key" {
  public_key = file("/path/to/ec2.pub")
  key_name = "my-ec2"
}

# Create security group on the default VPC
resource "aws_security_group" "ec2" {
  name = "my-ec2"
  vpc_id = data.aws_vpc.default.id

  ingress {
    from_port = 0
    protocol = "-1"
    to_port = 0

    description = "Open all port to everyone"

    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port = 22
    protocol = "tcp"
    to_port = 22

    description = "Allow ssh from the same SG"

    self = true
  }

  egress {
    from_port = 0
    protocol = "-1"
    to_port = 0

    description = "Allow output no restriction"

    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "my-ec2"
  }
}

resource "aws_iam_role" "ec2" {
  name = "ec2-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Sid    = ""
        Principal = {
          Service = "ec2.amazonaws.com"
        }
      },
    ]
  })
}

data "aws_iam_policy_document" "role-permissions" {
  statement {
    effect = "Allow"
    actions = [
      "ecr:GetAuthorizationToken" // allow ECR login
    ]
    resources = [
      "*"
    ]
  }
}

resource "aws_iam_role_policy" "ec2" {
  role   = aws_iam_role.ec2.id
  policy = data.aws_iam_policy_document.role-permissions.json
}

resource "aws_iam_instance_profile" "ec2-profile" {
  name = "ec2-profile"
  role = aws_iam_role.ec2.id
}

# Create EC2 Instance
resource "aws_instance" "my-ec2" {
  ami = data.aws_ami.ubuntu_20.id
  instance_type = "t3.small"

  subnet_id = sort(data.aws_subnets.default.ids)[0]

  associate_public_ip_address = true

  vpc_security_group_ids = [
    aws_security_group.ec2.id
  ]

  root_block_device {
    delete_on_termination = true
    volume_size = 50
  }

  key_name = aws_key_pair.key.key_name

  # Enable EC2 termination protection
//  disable_api_termination = true

  # Assign a role to the ec2 instance
  iam_instance_profile = aws_iam_instance_profile.ec2-profile.id

  tags = {
    Name = "my-ec2"
  }
}
# Get Default VPC
data "aws_vpc" "default" {
  default = true
}

# Get all subnets allocated to default VPC
data "aws_subnets" "default" {
  filter {
    name   = "vpc-id"
    values = [data.aws_vpc.default.id]
  }
}

locals {
  vpc_name = "my-vpc"
}

# Get VPC
data "aws_vpc" "vpc" {
  filter {
    name   = "tag:Name"
    values = [local.vpc_name]
  }
}

# Get VPC public subnets
data "aws_subnets" "public" {
  filter {
    name   = "vpc-id"
    values = [data.aws_vpc.vpc.id]
  }

  filter {
    name   = "tag:Name"
    values = ["${local.vpc_name}-public-*"]
  }
}

# Get VPC private subnets
data "aws_subnets" "private" {
  filter {
    name   = "vpc-id"
    values = [data.aws_vpc.vpc.id]
  }

  filter {
    name   = "tag:Name"
    values = ["${local.vpc_name}-private-*"]
  }
}

# Get Ubuntu 22.04 AMI
data "aws_ami" "ubuntu_22" {
  most_recent = true

  filter {
    name   = "name"
    values = [
      "ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-20240927"
    ]
  }

  filter {
    name = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["099720109477"]
}

# Get Ubuntu 24.04 AMI
data "aws_ami" "ubuntu_24" {
  most_recent = true

  filter {
    name   = "name"
    values = [
      "ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-20240927"
    ]
  }

  filter {
    name = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["099720109477"]
}