Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manual ec2 example fails #51

Open
tbenst opened this issue Nov 22, 2019 · 1 comment
Open

Manual ec2 example fails #51

tbenst opened this issue Nov 22, 2019 · 1 comment

Comments

@tbenst
Copy link

tbenst commented Nov 22, 2019

I copied the files from https://nixos.org/nixops/manual/#sec-deploying-to-ec2, and only changed the accessKeyId. Unfortunately I get this error:

> nixops create ./load-balancer.nix ./load-balancer-ec2.nix -d load-balancer-ec2
created deployment ‘7d8239f3-0d5b-11ea-89e6-02428c63fe0c’
7d8239f3-0d5b-11ea-89e6-02428c63fe0c
> nixops deploy -d load-balancer-ec2
error: I don't know an AMI for virtualisation type pv-ebs with instance type m1.small
(use '--show-trace' to show detailed location information)
error: evaluation of the deployment specification failed

Next I tried switching to region = "us-west-2" and deployment.ec2.instanceType = "t2.micro";. Now I get the same error for each instance:

error: Multiple exceptions (3): 
  * backend1: EC2ResponseError: 400 Bad Request
<?xml version="1.0" encoding="UTF-8"?>
<Response><Errors><Error><Code>VPCResourceNotSpecified</Code><Message>The specified instance type can only be used in a VPC. A subnet ID or network interface ID is required to carry out the request.</Message></Error></Errors><RequestID>8f4346fb-3a7e-4263-b0d1-17acd0a0d446</RequestID></Response>

Anyone know what tweaks need to be made so the manual example works? Thanks!

Edit: after some googling, it appears this may be because newer AWS accounts have a default VPC but older ones do not. hashicorp/terraform#4367. That said, it would be nice if the example was "more" declarative

Edit2: I just made a new AWS account and this did not resolve the issue. Appears the basic example needs to show configuring a VPC

@tbenst
Copy link
Author

tbenst commented Nov 24, 2019

For anyone that gets stuck, here's a configuration for AWS now that VPC must be specified. Hope it saves someone a few hours :). Would be great to update the manual with a working example. I based this off of https://github.com/nh2/nixops-tutorial and https://github.com/NixOS/nixops-aws/blob/master/examples/vpc.nix.

nginx-server-ec2.nix:

let
  region = "us-west-2";
  accessKeyId = "my-access-key"; # symbolic name looked up in ~/.ec2-keys or a ~/.aws/credentials profile name
  # We must declare an AWS Subnet for each Availability Zone
  # because Subnets cannot span AZs.
  subnets = [
    { name = "nixops-vpc-subnet-a"; cidr = "10.0.0.0/19"; zone = "${region}a"; }
    { name = "nixops-vpc-subnet-b"; cidr = "10.0.32.0/19"; zone = "${region}b"; }
    { name = "nixops-vpc-subnet-c"; cidr = "10.0.64.0/19"; zone = "${region}c"; }
    { name = "nixops-vpc-subnet-d"; cidr = "10.0.96.0/19"; zone = "${region}d"; }
  ];
  domain = "example.com";
  ec2 = { resources, ... }: {
    deployment.targetEnv = "ec2";
    deployment.ec2.accessKeyId = accessKeyId;
    deployment.ec2.region = region;
    deployment.ec2.subnetId = resources.vpcSubnets.nixops-vpc-subnet-c;
    deployment.ec2.instanceType = "t2.micro";
    deployment.ec2.keyPair = resources.ec2KeyPairs.my-key-pair;
    deployment.ec2.associatePublicIpAddress = true;
    deployment.ec2.elasticIPv4 = resources.elasticIPs.eip;
    deployment.ec2.ebsBoot = true;
    deployment.ec2.ebsInitialRootDiskSize = 20;
    deployment.ec2.securityGroupIds = [ "allow-ssh" "allow-http" ];
  };
  lib = (import <nixpkgs> {}).lib;
in
{
  nginx-server = ec2;

  resources = {
    # Provision an EC2 key pair.
    ec2KeyPairs.my-key-pair =
      { inherit region accessKeyId; };

    # create security groups
    ec2SecurityGroups.allow-ssh = { resources, ... }: {
      inherit region accessKeyId;
      name = "allow-ssh";
      description = "allow-ssh";
      vpcId = resources.vpc.nixops-vpc;
      rules = [
        { fromPort = 22; toPort = 22; sourceIp = "0.0.0.0/0"; }
      ];
    };

    ec2SecurityGroups.allow-http = { resources, ... }: {
      inherit region accessKeyId;
      name = "allow-http";
      description = "allow-http";
      vpcId = resources.vpc.nixops-vpc;
      rules = [
        { fromPort = 80; toPort = 80; sourceIp = "0.0.0.0/0"; }
        { fromPort = 443; toPort = 443; sourceIp = "0.0.0.0/0"; }
      ];
    };

    # configure VPC
    vpc.nixops-vpc = {
      inherit region accessKeyId;
      instanceTenancy = "default";
      enableDnsSupport = true;
      enableDnsHostnames = true;
      cidrBlock = "10.0.0.0/16";
      tags.Source = "NixOps";
    };

    vpcSubnets =
      let
        makeSubnet = {cidr, zone}:
          { resources, ... }: {
            inherit region zone accessKeyId;
            vpcId = resources.vpc.nixops-vpc;
            cidrBlock = cidr;
            mapPublicIpOnLaunch = true;
            tags.Source = "NixOps";
        };
      in
        builtins.listToAttrs
          (map
            ({ name, cidr, zone }: lib.nameValuePair name (makeSubnet { inherit cidr zone; }) )
            subnets
          );

    vpcRouteTables = {
      route-table = { resources, ... }: {
        inherit accessKeyId region;
        vpcId = resources.vpc.nixops-vpc;
      };
    };

    vpcRoutes = {
      igw-route = { resources, ... }: {
        inherit region accessKeyId;
        routeTableId = resources.vpcRouteTables.route-table;
        destinationCidrBlock = "0.0.0.0/0";
        gatewayId = resources.vpcInternetGateways.nixops-igw;
      };
    };

    vpcRouteTableAssociations =
      let
        association = subnetName: { resources, ... }: {
          inherit accessKeyId region;
          subnetId = resources.vpcSubnets."${subnetName}";
          routeTableId = resources.vpcRouteTables.route-table;
        };
      in
        builtins.listToAttrs
          (map
            ({ name, ... }: lib.nameValuePair "association-${name}" (association name) )
            subnets
          );
    vpcInternetGateways.nixops-igw = { resources, ... }: {
      inherit accessKeyId region;
      vpcId = resources.vpc.nixops-vpc;
    };

    # Optional: static IP address
    elasticIPs.eip = {
      inherit region accessKeyId;
      vpc = true;
    };
  };
}

nginx-server.nix:

{
  # special NixOps config
  network = {
    description = "Nginx server";
    enableRollback = true;
  };
  # end special NixOps config

  # from https://gist.github.com/nh2/28bce850755cf14bd7749ea78e4238ab
  /* boot.kernelModules = [ "tcp_bbr" ]; # faster tcp kernel support
  # Enable BBR congestion control
  boot.kernel.sysctl."net.ipv4.tcp_congestion_control" = "bbr"; */

  nginx-server = { config, pkgs, ... }: {
    networking.firewall.enable = true;
      # Reject instead of drop.
      networking.firewall.rejectPackets = true;
      networking.firewall.allowedTCPPorts = [
        22
        80 # nginx
        443 # nginx
      ];

    services.nginx = {
      enable = true;
      /* virtualHosts."${domain}" = {
        enableACME = true;
      }; */
    };
  };
}

Then:

> nixops create ./nginx-server.nix ./nginx-server-ec2.nix -d nginx-server-ec2
> nixops deploy -d nginx-server-ec2

@grahamc grahamc transferred this issue from NixOS/nixops Apr 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant