Parcourir la source

Merge pull request #253 from mdr-engineering/feature/ftd_MSOCI-1274_VMRay_Modernization

Modernization of the VMRay instance state
Frederick Damstra il y a 4 ans
Parent
commit
72e6d07a69

+ 19 - 0
base/vmray_instances/ami.tf

@@ -0,0 +1,19 @@
+data "aws_ami" "ubuntu2004" {
+  most_recent = true
+  owners = [ var.common_services_account ]
+
+  filter {
+    name   = "virtualization-type"
+    values = ["hvm"]
+  }
+
+  filter {
+    name = "root-device-type"
+    values = ["ebs"]
+  }
+
+  filter {
+    name = "name"
+    values = [ "MSOC_Ubuntu_2004_Minion*" ]
+  }
+}

+ 61 - 9
base/vmray_instances/cloud-init/cloud-init.tpl

@@ -1,21 +1,73 @@
 #cloud-config
-# TODO: This needs to be customized/fixed
 preserve_hostname: false
 hostname: ${hostname}
+salt-master: ${salt_master}
 fqdn: ${fqdn}
 
+# Write files happens early
+write_files:
+#- content: |
+#    proxy=http://${proxy}:80
+#  path: /etc/yum.conf
+#  append: true
+- content: |
+    [global]
+    proxy=${proxy}:80
+  path: /etc/pip.conf
+- content: |
+    export HTTPS_PROXY=http://${proxy}:80
+    export HTTP_PROXY=http://${proxy}:80
+    export NO_PROXY=localhost,127.0.0.1,169.254.169.254,pvt.xdrtest.accenturefederalcyber.com,pvt.xdr.accenturefederalcyber.com,reposerver.msoc.defpoint.local,jenkins.msoc.defpoint.local,pod1search-splunk-sh.msoc.defpoint.local,s3.amazonaws.com,ssm.${ aws_region }.amazonaws.com,ec2messages.${ aws_region }.amazonaws.com,ec2.${ aws_region }.amazonaws.com,ssmmessages.${ aws_region }.amazonaws.com,iratemoses.mdr.defpoint.com,jira.mdr.defpoint.com,reposerver.pvt.xdr.accenturefederalcyber.com,jenkins.pvt.xdr.accenturefederalcyber.com,pod1search-splunk-sh.pvt.xdr.accenturefederalcyber.com,reposerver.pvt.xdrtest.accenturefederalcyber.com,jenkins.pvt.xdrtest.accenturefederalcyber.com,pod1search-splunk-sh.pvt.xdrtest.accenturefederalcyber.com,iratemoses.xdr.accenturefederalcyber.com,jira.xdr.accenturefederalcyber.com,iratemoses.xdrtest.accenturefederalcyber.com,jira.xdrtest.accenturefederalcyber.com
+    export https_proxy=$HTTPS_PROXY
+    export http_proxy=$HTTP_PROXY
+    export no_proxy=$NO_PROXY
+  path: /etc/profile.d/proxy.sh
+- content: |
+    ${fqdn}
+  path: /etc/salt/minion_id
+- content: |
+    master: ${salt_master}
+  path: /etc/salt/minion
+- content: |
+    grains:
+      environment: ${ environment }
+      aws_partition: ${ aws_partition }
+      aws_partition_alias: ${ aws_partition_alias }
+      aws_region: ${ aws_region }
+  path: /etc/salt/minion.d/cloud_init_grains.conf
+
+#yum_repos:
+#  epel-release:
+#    baseurl: http://download.fedoraproject.org/pub/epel/7/$basearch
+#    enabled: false
+#    failovermethod: priority
+#    gpgcheck: true
+#    gpgkey: http://download.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7
+#    name: Extra Packages for Enterprise Linux 7 - Release
+
+packages:
+ - vim
+
+package_update: true # Always patch
+
+growpart:
+  mode: auto
+  devices: [ '/', '/var', '/var/log', '/var/log/audit', '/var/tmp', '/tmp', '/home' ]
+  ignore_growroot_disabled: false
+
 runcmd:
- - echo "${fqdn}" > /etc/salt/minion_id
- - /bin/systemctl restart salt-minion 
+ - /bin/systemctl restart salt-minion
  - /bin/systemctl enable salt-minion
  - /bin/systemctl start amazon-ssm-agent
  - /bin/systemctl enable amazon-ssm-agent
  - /usr/sbin/aide --update --verbose=0
  - /bin/cp /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz
 
-# httpd here to avoid a chicken and egg for repo server
-# installing it via salt state won't work because by then
-# the salt states could have us pointed to ourselves as the repo server
-packages:
- - httpd
-
+# Either final message or power state, but probably not both
+final_message: "The system is up after $UPTIME seconds"
+#power_state:
+#  delay: "+30"
+#  mode: reboot
+#  message: "System configured after $UPTIME seconds"
+#  timeout: 300
+#  condition: true

+ 92 - 65
base/vmray_instances/main.tf

@@ -1,84 +1,98 @@
-data "aws_ami" "ubuntu_pro" {
-  # Ubuntu Pro 18.04 Product ID: fc15dd7b-2aa0-47e5-bb05-94c75950b5de
-
-  most_recent = true
-  owners = [ var.aws_marketplace_ubuntu_owner_id ]
-
-  # sadly, it looks like the image isn't named correctly in govcloud. I've given
-  # canonical feedback on this, but for now we'll use the ami id directly.
-  #filter {
-  #  name   = "name"
-  #  values = ["ubuntu-pro/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*", ]
-  #}
-
-  filter {
-    name   = "image-id"
-    values = [ "ami-0a4050943619c0460" ]
-  }
-
-  filter {
-    name   = "root-device-type"
-    values = ["ebs"]
-  }
-
-  filter {
-    name   = "virtualization-type"
-    values = ["hvm"]
-  }
+# Handy tool to find AMIs:
+#   https://cloud-images.ubuntu.com/locator/ec2/
+#data "aws_ami" "ubuntu_pro" {
+#  # Ubuntu Pro 18.04 Product ID: fc15dd7b-2aa0-47e5-bb05-94c75950b5de
+#
+#  most_recent = true
+#  owners = [ "513442679011" ] # This seems like it might change sometimes?
+#
+#  # sadly, it looks like the image isn't named correctly in govcloud. I've given
+#  # canonical feedback on this, but for now we'll use the ami id directly.
+#  #filter {
+#  #  name   = "name"
+#  #  values = ["ubuntu-pro/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*", ]
+#  #}
+#
+#  filter {
+#    name   = "image-id"
+#    values = [ "ami-0fe6338c47e61cd5d" ]
+#  }
+#
+#  filter {
+#    name   = "root-device-type"
+#    values = ["ebs"]
+#  }
+#
+#  filter {
+#    name   = "virtualization-type"
+#    values = ["hvm"]
+#  }
+#}
+
+data "aws_security_group" "typical-host" {
+  name   = "typical-host"
+  vpc_id = var.vpc_id
 }
 
-module "vmray-server" {
-  source                 = "terraform-aws-modules/ec2-instance/aws"
-  version                = "~> 2.0"
-
-  name                   = "vmray-server"
-  instance_count         = 1
-  disable_api_termination = var.instance_termination_protection
-
-  ami                    = data.aws_ami.ubuntu_pro.image_id
-  instance_type          = var.vmray_server_instance_type
-  key_name               = var.vmray_key_name
-  vpc_security_group_ids = [ aws_security_group.vmray_sg.id ]
-  subnet_id              = data.terraform_remote_state.standard_vpc.outputs.public_subnets[0]
-  tags = merge(var.standard_tags, var.tags)
-
-  ebs_optimized          = true
-  monitoring             = false # Do we use this?
-
-  user_data_base64 = data.template_cloudinit_config.cloud-init-vmray-server.rendered
+# Use the default EBS key
+data "aws_kms_key" "ebs-key" {
+  key_id = "alias/ebs_root_encrypt_decrypt"
 }
 
-#
-module "vmray-worker" {
-  source                 = "terraform-aws-modules/ec2-instance/aws"
-  version                = "~> 2.0"
+resource "aws_network_interface" "vmray-server-interface" {
+  subnet_id = var.private_subnets[0]
+  security_groups = [ data.aws_security_group.typical-host.id, aws_security_group.vmray_sg.id ]
+  description = "vmray-server"
+  tags = merge(var.standard_tags, var.tags, { Name = "vmray-server" })
+}
 
-  name                   = "vmray-worker"
-  instance_count         = var.vmray_worker_instance_count
+resource "aws_instance" "vmray-server-instance" {
+  tenancy = "default"
+  ebs_optimized = true
   disable_api_termination = var.instance_termination_protection
+  instance_initiated_shutdown_behavior = "stop"
+  instance_type          = var.instance_types["vmray-server"]
+  key_name = "msoc-build"
+  monitoring = false
+  iam_instance_profile = "msoc-default-instance-profile"
+
+  ami = data.aws_ami.ubuntu2004.image_id
+  # We need to ignore ebs_block_device changes, because if the AMI changes, so does the snapshot_id.
+  # If they add a feature to block more specific changes (eg `ebs_block_devices[*].snapshot_id`), then
+  # that could be removed.
+  lifecycle { ignore_changes = [ ami, key_name, user_data, ebs_block_device ] }
+
+  root_block_device {
+      volume_type = "gp3"
+      volume_size = "60"
+      delete_on_termination = true
+      encrypted = true
+      kms_key_id = data.aws_kms_key.ebs-key.arn
+  }
 
-  ami                    = data.aws_ami.ubuntu_pro.image_id
-  instance_type          = var.vmray_worker_instance_type
-  key_name               = var.vmray_key_name
-  vpc_security_group_ids = [ aws_security_group.vmray_sg.id ]
-  subnet_ids             = data.terraform_remote_state.standard_vpc.outputs.public_subnets
-  tags = merge(var.standard_tags, var.tags)
-
-  ebs_optimized          = true
-  monitoring             = false
+  network_interface {
+    device_index = 0
+    network_interface_id = aws_network_interface.vmray-server-interface.id
+  }
 
-  #user_data_base64 = data.template_cloudinit_config.vmray-worker.*.rendered
+  user_data = data.template_cloudinit_config.cloud-init-vmray-server.rendered
+  tags = merge( var.standard_tags, var.tags, { Name = "vmray-server" })
+  volume_tags = merge( var.standard_tags, var.tags, { Name = "vmray-server" })
 }
 
-
 data "template_file" "cloud-init-vmray-server" {
   # Should these be in a common directory? I suspect they'd be reusable
   template = file("${path.module}/cloud-init/cloud-init.tpl")
 
   vars = {
-    hostname = "vmray_server"
-    fqdn = "vmrayserver.TODO.makemeavariable"
+    hostname = "vmray-server"
+    fqdn = "vmray-server.${var.dns_info["private"]["zone"]}"
     environment = var.environment
+    salt_master  = var.salt_master
+    proxy = var.proxy
+    aws_partition = var.aws_partition
+    aws_partition_alias = var.aws_partition_alias
+    aws_region = var.aws_region
   }
 }
 
@@ -101,3 +115,16 @@ data "template_cloudinit_config" "cloud-init-vmray-server" {
   #  content      = "ffbaz"
   #}
 }
+
+module "private_dns_record_vmray_server" {
+  source = "../../submodules/dns/private_A_record"
+
+  name = "vmray-server"
+  ip_addresses = [ aws_instance.vmray-server-instance.private_ip ]
+  dns_info = var.dns_info
+  reverse_enabled = true
+
+  providers = {
+    aws.c2 = aws.c2
+  }
+}

+ 2 - 22
base/vmray_instances/outputs.tf

@@ -1,23 +1,3 @@
-output vmray_server_arn {
-  value = module.vmray-server.arn
-}
-
-output vmray_server_public_ip {
-  value = module.vmray-server.public_ip
-}
-
-output vmray_server_private_ip {
-  value = module.vmray-server.private_ip
-}
-
-output vmray_worker_arn {
-  value = module.vmray-worker.arn
-}
-
-output vmray_worker_public_ip {
-  value = module.vmray-worker.public_ip
-}
-
-output vmray_worker_private_ip {
-  value = module.vmray-worker.private_ip
+output "vmray-server-private-ip" {
+  value = aws_instance.vmray-server-instance.private_ip
 }

+ 0 - 11
base/vmray_instances/remote_state.tf

@@ -1,11 +0,0 @@
-data "terraform_remote_state" "standard_vpc" {
-  backend = "s3"
-  config = {
-    bucket = var.remote_state_bucket
-    region = var.aws_region
-    encrypt = true
-    key = "aws/test/aws-us-gov/mdr-test-malware/010-standard-vpc/terraform.tfstate" # TODO
-    profile = var.common_profile
-    role_arn = "arn:${var.aws_partition}:iam::${var.common_services_account}:role/user/mdr_terraformer"
-  }
-}

+ 1 - 1
base/vmray_instances/security-groups.tf

@@ -1,7 +1,7 @@
 resource "aws_security_group" "vmray_sg" {
   name        = "vmray_sg"
   description = "Security Rules Specific to VMRay"
-  vpc_id      = data.terraform_remote_state.standard_vpc.outputs.vpc_id
+  vpc_id      = var.vpc_id
 
   tags        = merge(var.standard_tags, var.tags)
 }

+ 11 - 26
base/vmray_instances/vars.tf

@@ -1,45 +1,30 @@
-variable "vmray_server_instance_type" {
-  description = "Instance type for the controlling server."
-  type        = string
-}
-
-variable "vmray_worker_instance_type" {
-  description = "Instance type for the worker(s). Must be a bare metal instance type."
-  type        = string
-}
-
 variable "vmray_worker_instance_count" {
   description = "How many workers to build. These are expensive."
   type        = number
 }
 
-variable "vmray_key_name" {
-  description = "Provisioning key for new instance. Will be cleaned up via salt. Do not change after initial provisioning."
-  type = string
-}
-
 variable "tags" {
   description = "Tags to add to the resource (in addition to global standard tags)"
   type        = map
   default     = { }
 }
 
-# ----------------------------------
-# Below this line are variables inherited from higher levels, so they
-# do not need to be explicitly passed to this module.
+variable "instance_types" { type = map }
 variable "instance_termination_protection" { type = bool }
 variable "standard_tags" { type = map }
 variable "dns_info" { type = map }
-variable "aws_marketplace_ubuntu_owner_id" { type = string }
 variable "environment" { type = string }
 variable "portal_test_whitelist" { type = list }
-
-# ----------------------------------
-# Required for remote state, though they can be used elsewhere
-
-# TODO: Use terragrunt dependencies instead
-variable "remote_state_bucket" { type = string }
+variable "trusted_ips" { type = list(string) }
+variable "proxy" { type = string }
+variable "salt_master" { type = string }
+variable "cidr_map" { type = map }
 variable "aws_region" { type = string }
 variable "aws_partition" { type = string }
+variable "aws_partition_alias" { type = string }
+variable "aws_account_id" { type = string }
+variable "vpc_id" { type = string }
+variable "azs" { type = list(string) }
+variable "public_subnets" { type = list(string) }
+variable "private_subnets" { type = list(string) }
 variable "common_services_account" { type = string }
-variable "common_profile" { type = string }