Skip to content

Instantly share code, notes, and snippets.

@AlainODea
Last active September 26, 2018 12:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AlainODea/896d54cb43d7a55af9f475e817914d6a to your computer and use it in GitHub Desktop.
Save AlainODea/896d54cb43d7a55af9f475e817914d6a to your computer and use it in GitHub Desktop.
Terraform: Codacy Enterprise infrastructure bootstrap
output "primary_vpc_id" {
value = "${data.aws_vpc.primary.id}"
}
output "private_a_subnet_id" {
value = "${data.aws_subnet.private_a.id}"
}
output "web_proxy_sg_id" {
value = "${data.aws_security_group.web_proxy.id}"
}
output "encrypted_ami_id" {
value = "${data.aws_ami.encrypted.id}"
}
output "shared_alb_id" {
value = "${data.aws_lb.shared.id}"
}
output "codacy_app_private_ip" {
value = "${aws_instance.codacy.private_ip}"
}
provider "aws" {
region = "${var.region}"
}
data "aws_ami" "encrypted" {
most_recent = true
owners = ["self"]
filter {
name = "tag:ImageType"
values = ["${var.codacy_ami_type}"]
}
}
data "aws_vpc" "primary" {
tags {
Name = "${var.primary_vpc_name}"
}
}
data "aws_subnet" "private_a" {
vpc_id = "${data.aws_vpc.primary.id}"
tags {
Name = "${var.private_subnet_a_name}"
}
}
data "aws_security_group" "web_proxy" {
vpc_id = "${data.aws_vpc.primary.id}"
name = "${var.web_proxy_sg_name}"
}
data "aws_security_group" "splunk" {
vpc_id = "${data.aws_vpc.primary.id}"
name = "${var.splunk_sg_name}"
}
data "aws_security_group" "github" {
vpc_id = "${data.aws_vpc.primary.id}"
name = "${var.github_sg_name}"
}
data "aws_security_group" "shared_alb" {
vpc_id = "${data.aws_vpc.primary.id}"
name = "${var.shared_alb_name}"
}
data "aws_security_group" "bastion" {
vpc_id = "${data.aws_vpc.primary.id}"
name = "${var.bastion_sg_name}"
}
data "aws_lb_listener" "shared" {
load_balancer_arn = "${data.aws_lb.shared.arn}"
port = 443
}
resource "aws_lb_listener" "shared_plain" {
load_balancer_arn = "${data.aws_lb.shared.arn}"
port = 80
protocol = "HTTP"
"default_action" {
type = "forward"
target_group_arn = "${aws_lb_target_group.codacy_plain.arn}"
}
}
resource "aws_lb_listener" "shared_admin_plain" {
load_balancer_arn = "${data.aws_lb.shared.arn}"
port = 9000
protocol = "HTTP"
"default_action" {
type = "forward"
target_group_arn = "${aws_lb_target_group.codacy_admin_plain.arn}"
}
}
resource "aws_lb_listener" "shared_admin" {
load_balancer_arn = "${data.aws_lb.shared.arn}"
port = 9443
protocol = "HTTPS"
certificate_arn = "${var.shared_alb_cert_arn}"
ssl_policy = "ELBSecurityPolicy-TLS-1-2-Ext-2018-06"
"default_action" {
type = "forward"
target_group_arn = "${aws_lb_target_group.codacy_admin.arn}"
}
}
resource "aws_lb_listener" "monitoring" {
load_balancer_arn = "${data.aws_lb.shared.arn}"
port = 16005
protocol = "HTTPS"
certificate_arn = "${var.shared_alb_cert_arn}"
ssl_policy = "ELBSecurityPolicy-TLS-1-2-Ext-2018-06"
"default_action" {
type = "forward"
target_group_arn = "${aws_lb_target_group.codacy_monitoring.arn}"
}
}
resource "aws_lb_listener" "api" {
load_balancer_arn = "${data.aws_lb.shared.arn}"
port = 16006
protocol = "HTTPS"
certificate_arn = "${var.shared_alb_cert_arn}"
ssl_policy = "ELBSecurityPolicy-TLS-1-2-Ext-2018-06"
"default_action" {
type = "forward"
target_group_arn = "${aws_lb_target_group.codacy_api.arn}"
}
}
data "aws_lb" "shared" {
name = "${var.shared_alb_name}"
}
resource "aws_lb_listener_rule" "codacy" {
listener_arn = "${data.aws_lb_listener.shared.arn}"
action {
type = "forward"
target_group_arn = "${aws_lb_target_group.codacy.id}"
}
condition {
field = "host-header"
values = ["${var.codacy_fqdn}"]
}
}
resource "aws_lb_listener_rule" "codacy_plain" {
listener_arn = "${aws_lb_listener.shared_plain.arn}"
action {
type = "forward"
target_group_arn = "${aws_lb_target_group.codacy_plain.id}"
}
condition {
field = "host-header"
values = ["${var.codacy_fqdn}"]
}
}
resource "aws_lb_target_group" "codacy" {
name = "${var.codacy_instance_name}"
port = 443
protocol = "HTTPS"
vpc_id = "${data.aws_vpc.primary.id}"
}
resource "aws_lb_target_group" "codacy_plain" {
name = "${var.codacy_instance_name}-plain"
port = 80
protocol = "HTTP"
vpc_id = "${data.aws_vpc.primary.id}"
}
resource "aws_lb_target_group" "codacy_admin_plain" {
name = "${var.codacy_instance_name}-admin-plain"
port = 9000
protocol = "HTTP"
vpc_id = "${data.aws_vpc.primary.id}"
health_check {
path = "/login"
protocol = "HTTP"
}
}
resource "aws_lb_target_group" "codacy_admin" {
name = "${var.codacy_instance_name}-admin"
port = 9443
protocol = "HTTPS"
vpc_id = "${data.aws_vpc.primary.id}"
health_check {
path = "/login"
protocol = "HTTPS"
}
}
resource "aws_lb_target_group" "codacy_monitoring" {
name = "${var.codacy_instance_name}-monitoring"
port = 16005
protocol = "HTTPS"
vpc_id = "${data.aws_vpc.primary.id}"
}
resource "aws_lb_target_group" "codacy_api" {
name = "${var.codacy_instance_name}-api"
port = 16006
protocol = "HTTPS"
vpc_id = "${data.aws_vpc.primary.id}"
}
resource "aws_lb_target_group_attachment" "codacy" {
target_group_arn = "${aws_lb_target_group.codacy.arn}"
target_id = "${aws_instance.codacy.id}"
}
resource "aws_lb_target_group_attachment" "codacy_plain" {
target_group_arn = "${aws_lb_target_group.codacy_plain.arn}"
target_id = "${aws_instance.codacy.id}"
}
resource "aws_lb_target_group_attachment" "codacy_admin_plain" {
target_group_arn = "${aws_lb_target_group.codacy_admin_plain.arn}"
target_id = "${aws_instance.codacy.id}"
}
resource "aws_lb_target_group_attachment" "codacy_admin" {
target_group_arn = "${aws_lb_target_group.codacy_admin.arn}"
target_id = "${aws_instance.codacy.id}"
}
resource "aws_lb_target_group_attachment" "codacy_monitoring" {
target_group_arn = "${aws_lb_target_group.codacy_monitoring.arn}"
target_id = "${aws_instance.codacy.id}"
}
resource "aws_lb_target_group_attachment" "codacy_api" {
target_group_arn = "${aws_lb_target_group.codacy_api.arn}"
target_id = "${aws_instance.codacy.id}"
}
resource "aws_instance" "codacy" {
ami = "${data.aws_ami.encrypted.id}"
instance_type = "${var.codacy_instance_type}"
subnet_id = "${data.aws_subnet.private_a.id}"
vpc_security_group_ids = ["${aws_security_group.codacy_app.id}"]
key_name = "${var.ec2_keypair_name}"
user_data = "${data.template_file.user_data_empty.rendered}"
root_block_device {
volume_type = "gp2"
volume_size = "${var.codacy_app_disk_gb}"
}
tags {
Environment = "${var.environment_tag}"
GL-purpose = "${var.gl_purpose_tag}"
GL-sub-purpose = "${var.gl_sub_purpose_tag}"
Name = "${var.codacy_instance_name}"
Role = "${var.role_tag}"
Team = "${var.team_tag}"
}
}
data "template_file" "user_data_empty" {
template = "${file("${path.module}/user_data_empty.sh")}"
vars {
web_proxy_fqdn = "${var.web_proxy_fqdn}"
}
}
resource "aws_db_instance" "codacy" {
allocated_storage = "${var.codacy_db_disk_gb}"
storage_type = "gp2"
storage_encrypted = true
engine = "postgres"
engine_version = "9.4.18"
db_subnet_group_name = "${aws_db_subnet_group.db.name}"
vpc_security_group_ids = ["${aws_security_group.codacy_db.id}"]
availability_zone = "${data.aws_subnet.private_a.availability_zone}"
instance_class = "${var.codacy_db_instance_type}"
name = "codacy"
username = "${var.codacy_db_username}"
password = "${var.codacy_db_password}"
# parameter group doesn't exist (write more Terraform or create it manually)
parameter_group_name = "codacy-postgres94"
}
resource "aws_db_subnet_group" "db" {
name = "dev_db"
subnet_ids = ["${aws_subnet.db_a.id}", "${aws_subnet.db_b.id}", "${aws_subnet.db_c.id}"]
tags {
Environment = "${var.environment_tag}"
GL-purpose = "${var.gl_purpose_tag}"
GL-sub-purpose = "${var.gl_sub_purpose_tag}"
Name = "dev_db"
Role = "${var.role_tag}"
Team = "${var.team_tag}"
}
}
resource "aws_subnet" "db_a" {
cidr_block = "10.0.12.0/24"
vpc_id = "${data.aws_vpc.primary.id}"
availability_zone = "${var.region}a"
tags {
Environment = "${var.environment_tag}"
GL-purpose = "${var.gl_purpose_tag}"
GL-sub-purpose = "${var.gl_sub_purpose_tag}"
Name = "dev_db_a"
Role = "${var.role_tag}"
Team = "${var.team_tag}"
}
}
resource "aws_subnet" "db_b" {
cidr_block = "10.0.22.0/24"
vpc_id = "${data.aws_vpc.primary.id}"
availability_zone = "${var.region}b"
tags {
Environment = "${var.environment_tag}"
GL-purpose = "${var.gl_purpose_tag}"
GL-sub-purpose = "${var.gl_sub_purpose_tag}"
Name = "dev_db_b"
Role = "${var.role_tag}"
Team = "${var.team_tag}"
}
}
resource "aws_subnet" "db_c" {
cidr_block = "10.0.32.0/24"
vpc_id = "${data.aws_vpc.primary.id}"
availability_zone = "${var.region}c"
tags {
Environment = "${var.environment_tag}"
GL-purpose = "${var.gl_purpose_tag}"
GL-sub-purpose = "${var.gl_sub_purpose_tag}"
Name = "dev_db_c"
Role = "${var.role_tag}"
Team = "${var.team_tag}"
}
}
resource "aws_security_group" "codacy_app" {
name = "${var.codacy_instance_name}-app"
description = "${var.codacy_instance_name}-app"
vpc_id = "${data.aws_vpc.primary.id}"
tags {
Environment = "${var.environment_tag}"
GL-purpose = "${var.gl_purpose_tag}"
GL-sub-purpose = "${var.gl_sub_purpose_tag}"
Name = "${var.codacy_instance_name}"
Role = "${var.role_tag}"
Team = "${var.team_tag}"
}
}
resource "aws_security_group" "codacy_db" {
name = "${var.codacy_instance_name}-db"
description = "${var.codacy_instance_name}-db"
vpc_id = "${data.aws_vpc.primary.id}"
tags {
Environment = "${var.environment_tag}"
GL-purpose = "${var.gl_purpose_tag}"
GL-sub-purpose = "${var.gl_sub_purpose_tag}"
Name = "${var.codacy_instance_name}-db"
Role = "${var.role_tag}"
Team = "${var.team_tag}"
}
}
resource "aws_security_group_rule" "dev_alb_plain_from_staff" {
description = "HTTP"
type = "ingress"
from_port = 80
to_port = 80
protocol = "tcp"
security_group_id = "${data.aws_security_group.shared_alb.id}"
cidr_blocks = ["${var.client_ip_whitelist}"]
}
resource "aws_security_group_rule" "dev_alb_admin_plain_from_staff" {
description = "HTTP"
type = "ingress"
from_port = 9000
to_port = 9000
protocol = "tcp"
security_group_id = "${data.aws_security_group.shared_alb.id}"
cidr_blocks = ["${var.client_ip_whitelist}"]
}
resource "aws_security_group_rule" "dev_alb_admin_from_staff" {
description = "HTTP"
type = "ingress"
from_port = 9443
to_port = 9443
protocol = "tcp"
security_group_id = "${data.aws_security_group.shared_alb.id}"
cidr_blocks = ["${var.client_ip_whitelist}"]
}
resource "aws_security_group_rule" "dev_alb_monitoring_from_staff" {
description = "HTTP"
type = "ingress"
from_port = 16005
to_port = 16005
protocol = "tcp"
security_group_id = "${data.aws_security_group.shared_alb.id}"
cidr_blocks = ["${var.client_ip_whitelist}"]
}
resource "aws_security_group_rule" "dev_alb_api_from_staff" {
description = "HTTP"
type = "ingress"
from_port = 16006
to_port = 16006
protocol = "tcp"
security_group_id = "${data.aws_security_group.shared_alb.id}"
cidr_blocks = ["${var.client_ip_whitelist}"]
}
resource "aws_security_group_rule" "shared_alb_to_codacy_app" {
description = "Codacy listener"
type = "egress"
from_port = 443
to_port = 443
protocol = "tcp"
security_group_id = "${data.aws_security_group.shared_alb.id}"
source_security_group_id = "${aws_security_group.codacy_app.id}"
}
resource "aws_security_group_rule" "codacy_app_from_shared_alb" {
description = "Shared ALB"
type = "ingress"
from_port = 443
to_port = 443
protocol = "tcp"
source_security_group_id = "${data.aws_security_group.shared_alb.id}"
security_group_id = "${aws_security_group.codacy_app.id}"
}
resource "aws_security_group_rule" "shared_alb_to_codacy_app_plain" {
description = "Codacy listener"
type = "egress"
from_port = 80
to_port = 80
protocol = "tcp"
security_group_id = "${data.aws_security_group.shared_alb.id}"
source_security_group_id = "${aws_security_group.codacy_app.id}"
}
resource "aws_security_group_rule" "codacy_app_plain_from_shared_alb" {
description = "Shared ALB"
type = "ingress"
from_port = 80
to_port = 80
protocol = "tcp"
source_security_group_id = "${data.aws_security_group.shared_alb.id}"
security_group_id = "${aws_security_group.codacy_app.id}"
}
resource "aws_security_group_rule" "shared_alb_to_codacy_app_admin_plain" {
description = "Codacy listener"
type = "egress"
from_port = 9000
to_port = 9000
protocol = "tcp"
security_group_id = "${data.aws_security_group.shared_alb.id}"
source_security_group_id = "${aws_security_group.codacy_app.id}"
}
resource "aws_security_group_rule" "codacy_app_admin_plain_from_shared_alb" {
description = "Shared ALB"
type = "ingress"
from_port = 9000
to_port = 9000
protocol = "tcp"
source_security_group_id = "${data.aws_security_group.shared_alb.id}"
security_group_id = "${aws_security_group.codacy_app.id}"
}
resource "aws_security_group_rule" "shared_alb_to_codacy_app_admin" {
description = "Codacy listener"
type = "egress"
from_port = 9443
to_port = 9443
protocol = "tcp"
security_group_id = "${data.aws_security_group.shared_alb.id}"
source_security_group_id = "${aws_security_group.codacy_app.id}"
}
resource "aws_security_group_rule" "codacy_app_admin_from_shared_alb" {
description = "Shared ALB"
type = "ingress"
from_port = 9443
to_port = 9443
protocol = "tcp"
source_security_group_id = "${data.aws_security_group.shared_alb.id}"
security_group_id = "${aws_security_group.codacy_app.id}"
}
resource "aws_security_group_rule" "shared_alb_to_codacy_app_monitoring" {
description = "Codacy listener"
type = "egress"
from_port = 16005
to_port = 16005
protocol = "tcp"
security_group_id = "${data.aws_security_group.shared_alb.id}"
source_security_group_id = "${aws_security_group.codacy_app.id}"
}
resource "aws_security_group_rule" "codacy_app_monitoring_from_shared_alb" {
description = "Shared ALB"
type = "ingress"
from_port = 16005
to_port = 16005
protocol = "tcp"
source_security_group_id = "${data.aws_security_group.shared_alb.id}"
security_group_id = "${aws_security_group.codacy_app.id}"
}
resource "aws_security_group_rule" "shared_alb_to_codacy_app_api" {
description = "Codacy listener"
type = "egress"
from_port = 16006
to_port = 16006
protocol = "tcp"
security_group_id = "${data.aws_security_group.shared_alb.id}"
source_security_group_id = "${aws_security_group.codacy_app.id}"
}
resource "aws_security_group_rule" "codacy_app_api_from_shared_alb" {
description = "Shared ALB"
type = "ingress"
from_port = 16006
to_port = 16006
protocol = "tcp"
source_security_group_id = "${data.aws_security_group.shared_alb.id}"
security_group_id = "${aws_security_group.codacy_app.id}"
}
resource "aws_security_group_rule" "codacy_app_to_web_proxy" {
description = "Web proxy"
type = "egress"
from_port = 3128
to_port = 3128
protocol = "tcp"
security_group_id = "${aws_security_group.codacy_app.id}"
source_security_group_id = "${data.aws_security_group.web_proxy.id}"
}
# web_proxy_from_codacy_app is not required as web_proxy SG allows entire VPC
resource "aws_security_group_rule" "codacy_app_to_codacy_db" {
description = "Codacy RDS"
type = "egress"
from_port = 5432
to_port = 5432
protocol = "tcp"
security_group_id = "${aws_security_group.codacy_app.id}"
source_security_group_id = "${aws_security_group.codacy_db.id}"
}
resource "aws_security_group_rule" "codacy_db_from_codacy_app" {
description = "Codacy App"
type = "ingress"
from_port = 5432
to_port = 5432
protocol = "tcp"
source_security_group_id = "${aws_security_group.codacy_app.id}"
security_group_id = "${aws_security_group.codacy_db.id}"
}
resource "aws_security_group_rule" "codacy_app_to_splunk" {
description = "Splunk logging"
type = "egress"
from_port = 9997
to_port = 9997
protocol = "tcp"
source_security_group_id = "${data.aws_security_group.splunk.id}"
security_group_id = "${aws_security_group.codacy_app.id}"
}
# splunk_from_codacy_app is not required as splunk SG allows entire VPC
resource "aws_security_group_rule" "codacy_app_ssh_from_bastion" {
description = "SSH from Bastion"
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
source_security_group_id = "${data.aws_security_group.bastion.id}"
security_group_id = "${aws_security_group.codacy_app.id}"
}
resource "aws_security_group_rule" "codacy_app_control_from_github" {
description = "Codacy Control Panel from Github"
type = "ingress"
from_port = 9443
to_port = 9443
protocol = "tcp"
source_security_group_id = "${data.aws_security_group.github.id}"
security_group_id = "${aws_security_group.codacy_app.id}"
}
resource "aws_security_group_rule" "codacy_app_monitor_from_github" {
description = "Codacy Monitor from Github"
type = "ingress"
from_port = 16005
to_port = 16005
protocol = "tcp"
source_security_group_id = "${data.aws_security_group.github.id}"
security_group_id = "${aws_security_group.codacy_app.id}"
}
resource "aws_security_group_rule" "codacy_app_api_from_github" {
description = "Codacy App API from Github"
type = "ingress"
from_port = 16006
to_port = 16006
protocol = "tcp"
source_security_group_id = "${data.aws_security_group.github.id}"
security_group_id = "${aws_security_group.codacy_app.id}"
}
resource "aws_security_group_rule" "codacy_to_github_ssh" {
description = "SSH to Github"
type = "egress"
from_port = 22
to_port = 22
protocol = "tcp"
security_group_id = "${aws_security_group.codacy_app.id}"
source_security_group_id = "${data.aws_security_group.github_internal_elb.id}"
}
resource "aws_security_group_rule" "github_ssh_from_codacy" {
description = "SSH from Codacy"
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
source_security_group_id = "${aws_security_group.codacy_app.id}"
security_group_id = "${data.aws_security_group.github_internal_elb.id}"
}
Content-Type: multipart/mixed; boundary="==BOUNDARY=="
MIME-Version: 1.0
--==BOUNDARY==
Content-Type: text/x-shellscript; charset="us-ascii"
# Find logs in /var/log/cloud-init-output.log
set -Eeuxo pipefail
PROXY_HOST=${web_proxy_fqdn}
PROXY_PORT=3128
# Set APT HTTP proxy
cat > /etc/apt/apt.conf.d/80proxy <<'EOF'
Acquire::http::proxy "http://$PROXY_HOST:$PROXY_PORT /";
Acquire::ftp::proxy "ftp://$PROXY_HOST:$PROXY_PORT /";
Acquire::https::proxy "https://$PROXY_HOST:$PROXY_PORT /";
EOF
cat >> /etc/environment <<'EOF'
http_proxy="http://$PROXY_HOST:$PROXY_PORT /"
https_proxy="http://$PROXY_HOST:$PROXY_PORT /"
ftp_proxy="http://$PROXY_HOST:$PROXY_PORT /"
no_proxy="169.254.169.254,localhost,127.0.0.1,localaddress,.example.local"
HTTP_PROXY="http://$PROXY_HOST:$PROXY_PORT /"
HTTPS_PROXY="http://$PROXY_HOST:$PROXY_PORT /"
FTP_PROXY="http://$PROXY_HOST:$PROXY_PORT /"
NO_PROXY="169.254.169.254,localhost,127.0.0.1,localaddress,.example.local"
EOF
# Refresh packages
apt-get --assume-yes update
apt-get --assume-yes upgrade
# Install Amazon RDS Root CA as a trusted root certificate
rds_root_ca=$(mktemp)
mkdir /usr/share/ca-certificates/extra
env https_proxy=http://$PROXY_HOST:$PROXY_PORT curl https://s3.amazonaws.com/rds-downloads/rds-ca-2015-root.pem \
--output /usr/share/ca-certificates/extra/rds-ca-2015-root.crt
dpkg-reconfigure ca-certificates
--==BOUNDARY==
variable "codacy_db_username" {
}
variable "codacy_db_password" {
}
variable "ec2_keypair_name" {
default = "your-ec2-keypair-name"
}
variable "codacy_fqdn" {
default = "codacy.example.com"
}
variable "client_ip_whitelist" {
type = "list"
default = [
"your-office-cidr-1/32",
"your-vpn-cidr-1/32",
"your-other-office-cidr-1/32",
"your-backup-vpn-cidr-1/32"
]
}
variable "codacy_instance_name" {
default = "codacy"
}
variable "codacy_instance_type" {
default = "c5.4xlarge"
}
variable "codacy_ami_type" {
default = "encrypted-ubuntu-16_04"
}
variable "codacy_app_disk_gb" {
default = 500
}
variable "codacy_db_disk_gb" {
default = 500
}
variable "codacy_db_instance_type" {
default = "db.m3.xlarge"
}
variable "web_proxy_fqdn" {
default = "squid.example.com"
}
variable "packages_bucket" {
default = "replace-me"
}
variable "kms_key_id" {
default = "some-kms-key-id"
}
variable "ubuntu_account_number" {
default = "099720109477"
}
variable "region" {
default = "us-west-2"
}
variable "primary_vpc_name" {
default = "ci-cd"
}
variable "private_subnet_a_name" {
default = "private_a"
}
variable "shared_alb_name" {
default = "shared-alb"
}
variable "shared_alb_cert_arn" {
default = "arn:aws:acm:us-west-2:your-account:certificate/your-acm-uuid"
}
variable "web_proxy_sg_name" {
default = "squid"
}
variable "splunk_sg_name" {
default = "splunk"
}
variable "github_sg_name" {
default = "github"
}
variable "github_internal_elb_sg_name" {
default = "github-internal-elb"
}
variable "bastion_sg_name" {
default = "bastion"
}
variable "environment_tag" {
default = "Dev"
}
variable "gl_purpose_tag" {
default = "Dev"
}
variable "gl_sub_purpose_tag" {
default = "CI"
}
variable "role_tag" {
default = "Continuous Integration"
}
variable "team_tag" {
default = "releases@example.com"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment