DIY for discrimiNAT on AWS

Key information on discrimiNAT for integration in your Infrastructure-as-Code

Table of Contents
Ensure you’ve visited our marketplace page and accepted the terms & conditions, and any custom offers you may have been extended for your AWS account, first.

IMAGE IDENTIFIERS

keyvalue
owner-id679593333241
product-codea83las5cq95zkg3x8i17x6wyy
architecturex86_64

These filters will result in all the historic versions too. The latest among these is recommended.

Contact our DevSecOps at [email protected] for queries at any stage of your journey. Alternatively, just reach out in the live chat.

DEPLOYMENT ESSENTIALS

For effective functioning, the discrimiNAT will need:

  1. A machine type with at least 2 vCPU and 2 GiB RAM. A t3.small should suffice where throughput requirements are basic and allowlists small. Otherwise a c5.large makes a good choice for constant throughput. Talk to our DevSecOps to get the sizing right!
  2. An IAM policy that can read some EC2 metadata, write logs and set instance health (of itself):
    {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Effect": "Allow",
              "Action": [
                  "logs:CreateLogGroup",
                  "logs:CreateLogStream",
                  "logs:PutLogEvents",
                  "logs:DescribeLogStreams"
              ],
              "Resource": [
                  "arn:aws:logs:*:*:log-group:discrimiNAT:log-stream:*"
              ]
          },
          {
              "Effect": "Allow",
              "Action": "autoscaling:SetInstanceHealth",
              "Resource": {
                  "Fn::Sub": "arn:aws:autoscaling:*:*:autoScalingGroup:*:autoScalingGroupName/${AWS::StackName}-AutoScalingGroup*"
              }
          },
          {
              "Effect": "Allow",
              "Action": [
                  "ec2:DescribeNetworkInterfaces",
                  "ec2:DescribeSecurityGroups"
              ],
              "Resource": "*"
          }
      ]
    }
    
  3. Ability to forward IP packets with the SourceDestCheck property of the network interface turned off.
  4. A public IP with routing to the Internet via the AWS supplied Internet Gateway.

When deploying the instance(s), you may configure high-availability through an Auto Scaling Group (see reference implementation here) and routing as per your desired architecture. For example, the route to the Internet will be for destination 0.0.0.0/0 for instances without a public IP and should pass through the discrimiNAT instance.

For monitoring the logs and configuring the FQDN-based firewall egress rules, see the logs and config references.

TERRAFORM MODULE

Before you dive into the DIY code that follows, you may want to consider our fully-working module at the Terraform Registry, which includes preconfigured high-availability and further examples. In fact, one of the examples extends from the canonical terraform-aws-modules/vpc/aws module at the registry.

Contact our DevSecOps at [email protected] for queries at any stage of your journey. Alternatively, just reach out in the live chat.

TERRAFORM EXAMPLE

Lookup

provider "aws" {}

data "aws_ami" "discriminat" {
  owners      = ["aws-marketplace"]
  most_recent = true

  filter {
    name   = "architecture"
    values = ["x86_64"]
  }

  filter {
    name   = "product-code"
    values = ["a83las5cq95zkg3x8i17x6wyy"]
  }
}

output "discriminat_ami_id" {
  value = data.aws_ami.discriminat.id
}

Deploy

This example deployment code is to be considered a starting point for your own architecture and requirements.

provider "aws" {}

data "aws_ami" "discriminat" {
  owners      = ["aws-marketplace"]
  most_recent = true

  filter {
    name   = "architecture"
    values = ["x86_64"]
  }

  filter {
    name   = "product-code"
    values = ["a83las5cq95zkg3x8i17x6wyy"]
  }
}

resource "aws_instance" "discriminat" {
  ami = data.aws_ami.discriminat.id

  instance_type = "t3.small"

  associate_public_ip_address = true
  source_dest_check           = false

  metadata_options {
    http_endpoint = "enabled"
    http_tokens   = "required"
  }

  iam_instance_profile = aws_iam_instance_profile.discriminat.name

  tags = {
    Name = "discrimiNAT-example"
  }
}

resource "aws_iam_policy" "discriminat" {
  name_prefix = "discriminat-"
  policy      = <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "logs:DescribeLogStreams"
            ],
            "Resource": [
                "arn:aws:logs:*:*:log-group:discrimiNAT:log-stream:*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": "autoscaling:SetInstanceHealth",
            "Resource": "arn:aws:autoscaling:*:*:autoScalingGroup:*:autoScalingGroupName/discriminat-*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeNetworkInterfaces",
                "ec2:DescribeSecurityGroups"
            ],
            "Resource": "*"
        }
    ]
}
EOF
}

resource "aws_iam_role" "discriminat" {
  name_prefix        = "discriminat-"
  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Effect": "Allow"
    }
  ]
}
EOF
}

resource "aws_iam_role_policy_attachment" "discriminat" {
  role       = aws_iam_role.discriminat.name
  policy_arn = aws_iam_policy.discriminat.arn
}

resource "aws_iam_instance_profile" "discriminat" {
  role = aws_iam_role.discriminat.name
}
Contact our DevSecOps at [email protected] for queries at any stage of your journey. Alternatively, just reach out in the live chat.

aws CLI EXAMPLE

Lookup

aws ec2 describe-images                                \
  --query                                              \
  'sort_by(Images, &CreationDate)[-1].ImageId'         \
  --filters                                            \
  "Name=owner-id,Values=679593333241"                  \
  "Name=product-code,Values=a83las5cq95zkg3x8i17x6wyy" \
  "Name=architecture,Values=x86_64"                    \
  --no-cli-pager --output text