Created
April 12, 2022 13:50
-
-
Save zimbatm/56e7c6df6cc7902ebaed26989b1e5c69 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Fetch the latest NixOS AMI from 20.03 | |
module "nixos_image" { | |
source = "[email protected]:tweag/terraform-nixos.git//aws_image_nixos?ref=43cbf822c07e705c66fb6d719ab58ed9cb05f87d" | |
release = "20.09" | |
} | |
data "external" "local_info" { | |
program = ["${path.module}/get_local_info.sh"] | |
} | |
# Generate a SSH key-pair | |
resource "tls_private_key" "machine" { | |
algorithm = "RSA" | |
} | |
# Updating key pairs is impossible if they have the same name, so we | |
# need to uniquify the name using the creation time. | |
resource "time_static" "keypair_update" { | |
triggers = { | |
# Save the time when the key pair changes | |
keypair = tls_private_key.machine.public_key_fingerprint_md5 | |
} | |
} | |
# Record the SSH public key into AWS | |
resource "aws_key_pair" "machine" { | |
key_name = "${var.name}-machine-${time_static.keypair_update.unix}" | |
public_key = tls_private_key.machine.public_key_openssh | |
} | |
# This is the security group that will be attached to the instance | |
resource "aws_security_group" "machine" { | |
name = "${var.name}-machine" | |
description = "Machine SG" | |
tags = var.tags | |
vpc_id = var.vpc_id | |
} | |
# A bunch of rules for the group | |
resource "aws_security_group_rule" "machine_ingress_ssh" { | |
description = "Allow SSH from everywhere" | |
type = "ingress" | |
from_port = 22 | |
to_port = 22 | |
protocol = "tcp" | |
cidr_blocks = ["0.0.0.0/0"] | |
security_group_id = aws_security_group.machine.id | |
} | |
# A bunch of rules for the group | |
resource "aws_security_group_rule" "machine_ingress_mosh" { | |
description = "Allow SSH from everywhere" | |
type = "ingress" | |
from_port = 60001 | |
to_port = 60001 | |
protocol = "udp" | |
cidr_blocks = ["0.0.0.0/0"] | |
security_group_id = aws_security_group.machine.id | |
} | |
resource "aws_security_group_rule" "machine_ingress_http" { | |
description = "Allow HTTP from the Load-Balancer only" | |
type = "ingress" | |
from_port = 0 | |
to_port = 0 | |
protocol = "-1" | |
source_security_group_id = aws_security_group.lb.id | |
security_group_id = aws_security_group.machine.id | |
} | |
resource "aws_security_group_rule" "machine_egress_all" { | |
description = "Allow to connect to the whole Internet" | |
type = "egress" | |
from_port = 0 | |
to_port = 0 | |
protocol = "-1" | |
cidr_blocks = ["0.0.0.0/0"] | |
security_group_id = aws_security_group.machine.id | |
} | |
# Permissions for the AWS instance | |
data "aws_iam_policy_document" "machine" { | |
statement { | |
sid = "SecretsAccess" | |
actions = [ | |
"ssm:GetParameterHistory", | |
"ssm:ListTagsForResource", | |
"ssm:GetParametersByPath", | |
"ssm:GetParameters", | |
"ssm:GetParameter", | |
] | |
resources = [ | |
aws_ssm_parameter.brossa_config.arn | |
] | |
} | |
statement { | |
sid = "CognitoIdpPermissions" | |
actions = [ | |
"cognito-idp:*", | |
] | |
resources = [ | |
"arn:aws:cognito-idp:*" | |
] | |
} | |
statement { | |
sid = "SESEmailPermissions" | |
actions = [ | |
"ses:*", | |
] | |
resources = [ | |
"arn:aws:ses:*" | |
] | |
} | |
} | |
# A bunch of IAM resources needed to give permissions to the instance | |
resource "aws_iam_role" "machine" { | |
name = "${var.name}-machine" | |
tags = var.tags | |
assume_role_policy = <<EOF | |
{ | |
"Version": "2012-10-17", | |
"Statement": [ | |
{ | |
"Action": "sts:AssumeRole", | |
"Principal": { | |
"Service": "ec2.amazonaws.com" | |
}, | |
"Effect": "Allow", | |
"Sid": "" | |
} | |
] | |
} | |
EOF | |
} | |
resource "aws_iam_role_policy" "machine" { | |
name = "${var.name}-machine" | |
role = aws_iam_role.machine.name | |
policy = data.aws_iam_policy_document.machine.json | |
} | |
resource "aws_iam_instance_profile" "machine" { | |
name = "${var.name}-machine" | |
role = aws_iam_role.machine.name | |
depends_on = [aws_iam_role_policy.machine] | |
} | |
# The actual AWS instance | |
resource "aws_instance" "machine" { | |
# Base image to start the instance with | |
ami = module.nixos_image.ami | |
iam_instance_profile = aws_iam_instance_profile.machine.name | |
instance_type = var.ec2_instance_type | |
key_name = aws_key_pair.machine.key_name | |
vpc_security_group_ids = [aws_security_group.machine.id] | |
# always deploy in the first subnet | |
subnet_id = var.vpc_subnets[1] | |
tags = merge(var.tags, { "Name" = "${var.name}-machine" }) | |
root_block_device { | |
volume_type = "gp2" | |
volume_size = "50" # GiB | |
} | |
lifecycle { | |
create_before_destroy = true | |
} | |
} | |
# This deploys the NixOS configuration onto the VM | |
module "machine_deploy" { | |
source = "[email protected]:tweag/terraform-nixos.git//deploy_nixos?ref=43cbf822c07e705c66fb6d719ab58ed9cb05f87d" | |
NIX_PATH = data.external.local_info.result.nix_path | |
nixos_config = "${path.module}/configuration.nix" | |
ssh_agent = false | |
ssh_private_key = tls_private_key.machine.private_key_pem | |
target_host = aws_instance.machine.public_ip | |
target_user = "root" | |
keys = { | |
"grafana-agent-loki-url" = var.loki_url | |
"grafana-agent-loki-username" = var.loki_username | |
"grafana-agent-loki-password" = var.loki_password | |
"grafana-agent-prometheus-remote-write-url" = var.prometheus_remote_write_url | |
"grafana-agent-prometheus-remote-write-username" = var.prometheus_remote_write_username | |
"grafana-agent-prometheus-remote-write-password" = var.prometheus_remote_write_password | |
} | |
triggers = { | |
# Force a new deployment if the instance ID has changed. The ID changes if | |
# the instance is re-created for example. | |
machine_id = aws_instance.machine.id | |
} | |
} | |
# Attach a DNS name for accessing the machine directly. Not strictly | |
# necessary. | |
resource "aws_route53_record" "machine" { | |
zone_id = var.zone_id | |
name = "machine.${var.domain}" | |
type = "A" | |
ttl = "300" | |
records = [aws_instance.machine.public_ip] | |
} | |
# LB Target group that holds the machine | |
resource "aws_lb_target_group" "machine" { | |
name = "${var.name}-machine" | |
port = 8000 | |
protocol = "HTTP" | |
vpc_id = var.vpc_id | |
tags = var.tags | |
health_check { | |
enabled = true | |
interval = 5 | |
path = "/health" | |
port = 8000 | |
protocol = "HTTP" | |
timeout = 2 | |
healthy_threshold = 2 | |
unhealthy_threshold = 3 | |
} | |
} | |
resource "aws_lb_target_group_attachment" "machine" { | |
target_group_arn = aws_lb_target_group.machine.arn | |
target_id = aws_instance.machine.id | |
port = 8000 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment