<p>Your default security groups and newly created security groups include default rules that <strong>do not enable you to access your instance from the Internet</strong>.
Add this:</p>

<pre><code>
resource "aws_security_group" "allow-ssh" {
  vpc_id = "${aws_vpc.vpc.id}"

  ingress {
    from_port = 0
    to_port = 22
    protocol = "tcp"
  }
}
</code></pre>

<p>Then add the line <code>vpc_security_group_ids = [aws_security_group.allow-ssh.id]</code> to the instance definitions.</p>

CC BY-SA 4.0
2019-09-27T10:57:58.580Z
2019-09-27T10:57:58.580Z
aries1980
<p>As stated in the title of the question, I have a Terraform file (attached below), but the infrastructure it builds doesn't allow me to connect by SSH (I get "Connection timed out"). So either the packets aren't getting to the EC2 instances or the responses aren't getting out. Any ideas? For the purposes of this question the DNS and ALB can be ignored (the former works fine, the latter almost certainly doesn't yet).</p>

<pre><code>provider "aws" {
  region = "us-west-2"
}

resource "aws_vpc" "vpc" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_internet_gateway" "gw" {
  vpc_id = "${aws_vpc.vpc.id}"
}

resource "aws_subnet" "subnet_a" {
  vpc_id = "${aws_vpc.vpc.id}"
  cidr_block = "10.0.1.0/24"
  availability_zone = "us-west-2a"
}

resource "aws_subnet" "subnet_b" {
  vpc_id = "${aws_vpc.vpc.id}"
  cidr_block = "10.0.2.0/24"
  availability_zone = "us-west-2b"
}

resource "aws_route_table" "rt" {
  vpc_id = "${aws_vpc.vpc.id}"

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = "${aws_internet_gateway.gw.id}"
  }
}

resource "aws_route_table_association" "rt_a" {
  subnet_id = "${aws_subnet.subnet_a.id}"
  route_table_id = "${aws_route_table.rt.id}"
}

resource "aws_route_table_association" "rt_b" {
  subnet_id = "${aws_subnet.subnet_b.id}"
  route_table_id = "${aws_route_table.rt.id}"
}

resource "aws_security_group" "alb_sg" {
  vpc_id = "${aws_vpc.vpc.id}"

  ingress {
    from_port = 0
    to_port = 80
    protocol = "tcp"
  }

  ingress {
    from_port = 0
    to_port = 443
    protocol = "tcp"
  }
}

resource "aws_alb" "alb" {
  internal = false
  load_balancer_type = "application"
  security_groups = ["${aws_security_group.alb_sg.id}"]
  subnets = ["${aws_subnet.subnet_a.id}","${aws_subnet.subnet_b.id}"]
}

resource "aws_route53_zone" "primary" {
  name = "REDACTED.REDACTED"
}

resource "aws_route53_record" "alias_route53_record" {
  zone_id = "${aws_route53_zone.primary.zone_id}"
  name    = "REDACTED.REDACTED"
  type    = "A"

  alias {
    name                   = "${aws_alb.alb.dns_name}"
    zone_id                = "${aws_alb.alb.zone_id}"
    evaluate_target_health = true
  }
}

resource "aws_key_pair" "kp" {
  key_name = "kp2019y09m25d001i"
  public_key = "ssh-rsa REDACTED"
}

resource "aws_instance" "instance_a" {
  ami = "ami-08ba47c10a42c61be"
  instance_type = "t2.micro"
  availability_zone = "us-west-2a"
  subnet_id = "${aws_subnet.subnet_a.id}"
  associate_public_ip_address = true
  key_name = "${aws_key_pair.kp.key_name}"
}

resource "aws_instance" "instance_b" {
  ami = "ami-08ba47c10a42c61be"
  instance_type = "t2.micro"
  availability_zone = "us-west-2b"
  subnet_id = "${aws_subnet.subnet_b.id}"
  associate_public_ip_address = true
  key_name = "${aws_key_pair.kp.key_name}"
}

output "instance_a_ip" {
  value = "${aws_instance.instance_a.public_ip}"
}

output "instance_b_ip" {
  value = "${aws_instance.instance_b.public_ip}"
}
</code></pre>

CC BY-SA 4.0
2019-09-25T15:30:44.940Z
There's no security group specified on your instances, I think they take the default security group of the VPC in this case. This security group by default only allow traffic within the VPC and not from anywhere else.
Tensibai
CC BY-SA 4.0
2019-09-25T16:14:14.960Z
@Tensibai Ah indeed that might be the problem. Will add security groups and try again. It looked like the default group allows all traffic but now I see there is a "source" security group on that rule.
Hypertable
CC BY-SA 4.0
2019-09-25T16:24:47.890Z
Indeed it works now. Thanks @Tensibai
Hypertable
CC BY-SA 4.0
2019-09-25T20:24:46.160Z
Feel free to self answer then, you'll be able to accept the answer after 48h and it may be useful to future people hitting the same problem :)
Tensibai
<amazon-ec2><terraform><aws-vpc>
can't access my instances by public IP in a VPC (aka: what is wrong with my terraform)?
Hypertable
# can't access my instances by public IP in a VPC (aka: what is wrong with my terraform)?

(Asked by: username_0 on 2019-09-25)

As stated in the title of the question, I have a Terraform file (attached below), but the infrastructure it builds doesn't allow me to connect by SSH (I get "Connection timed out"). So either the packets aren't getting to the EC2 instances or the responses aren't getting out. Any ideas? For the purposes of this question the DNS and ALB can be ignored (the former works fine, the latter almost certainly doesn't yet).
provider "aws" {
  region = "us-west-2"
}

resource "aws_vpc" "vpc" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_internet_gateway" "gw" {
  vpc_id = "${aws_vpc.vpc.id}"
}

resource "aws_subnet" "subnet_a" {
  vpc_id = "${aws_vpc.vpc.id}"
  cidr_block = "10.0.1.0/24"
  availability_zone = "us-west-2a"
}

resource "aws_subnet" "subnet_b" {
  vpc_id = "${aws_vpc.vpc.id}"
  cidr_block = "10.0.2.0/24"
  availability_zone = "us-west-2b"
}

resource "aws_route_table" "rt" {
  vpc_id = "${aws_vpc.vpc.id}"

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = "${aws_internet_gateway.gw.id}"
  }
}

resource "aws_route_table_association" "rt_a" {
  subnet_id = "${aws_subnet.subnet_a.id}"
  route_table_id = "${aws_route_table.rt.id}"
}

resource "aws_route_table_association" "rt_b" {
  subnet_id = "${aws_subnet.subnet_b.id}"
  route_table_id = "${aws_route_table.rt.id}"
}

resource "aws_security_group" "alb_sg" {
  vpc_id = "${aws_vpc.vpc.id}"

  ingress {
    from_port = 0
    to_port = 80
    protocol = "tcp"
  }

  ingress {
    from_port = 0
    to_port = 443
    protocol = "tcp"
  }
}

resource "aws_alb" "alb" {
  internal = false
  load_balancer_type = "application"
  security_groups = ["${aws_security_group.alb_sg.id}"]
  subnets = ["${aws_subnet.subnet_a.id}","${aws_subnet.subnet_b.id}"]
}

resource "aws_route53_zone" "primary" {
  name = "REDACTED.REDACTED"
}

resource "aws_route53_record" "alias_route53_record" {
  zone_id = "${aws_route53_zone.primary.zone_id}"
  name    = "REDACTED.REDACTED"
  type    = "A"

  alias {
    name                   = "${aws_alb.alb.dns_name}"
    zone_id                = "${aws_alb.alb.zone_id}"
    evaluate_target_health = true
  }
}

resource "aws_key_pair" "kp" {
  key_name = "kp2019y09m25d001i"
  public_key = "ssh-rsa REDACTED"
}

resource "aws_instance" "instance_a" {
  ami = "ami-08ba47c10a42c61be"
  instance_type = "t2.micro"
  availability_zone = "us-west-2a"
  subnet_id = "${aws_subnet.subnet_a.id}"
  associate_public_ip_address = true
  key_name = "${aws_key_pair.kp.key_name}"
}

resource "aws_instance" "instance_b" {
  ami = "ami-08ba47c10a42c61be"
  instance_type = "t2.micro"
  availability_zone = "us-west-2b"
  subnet_id = "${aws_subnet.subnet_b.id}"
  associate_public_ip_address = true
  key_name = "${aws_key_pair.kp.key_name}"
}

output "instance_a_ip" {
  value = "${aws_instance.instance_a.public_ip}"
}

output "instance_b_ip" {
  value = "${aws_instance.instance_b.public_ip}"
}

**Tags:** amazon-ec2, terraform, aws-vpc

> **Comments:**
> **username_1**: There's no security group specified on your instances, I think they take the default security group of the VPC in this case. This security group by default only allow traffic within the VPC and not from anywhere else.  
> **username_0**: @username_1 Ah indeed that might be the problem. Will add security groups and try again. It looked like the default group allows all traffic but now I see there is a "source" security group on that rule.  
> **username_0**: Indeed it works now. Thanks @username_1  
> **username_1**: Feel free to self answer then, you'll be able to accept the answer after 48h and it may be useful to future people hitting the same problem :)  

---

## 1 answers

### Answer by username_2 on 2019-09-27. Score: 1 | Accepted answer

Your default security groups and newly created security groups include default rules that do not enable you to access your instance from the Internet.
Add this:

resource "aws_security_group" "allow-ssh" {
  vpc_id = "${aws_vpc.vpc.id}"

  ingress {
    from_port = 0
    to_port = 22
    protocol = "tcp"
  }
}

Then add the line vpc_security_group_ids = [aws_security_group.allow-ssh.id] to the instance definitions.


---

