How to create bastion host in my public vcp using terraform? - amazon-web-services

I have vpc with public and private.
How do I create bastion host on the public?
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 2.0"
name = "${local.name}-vpc"
cidr = "10.1.0.0/16"
azs = ["us-east-2a", "us-east-2b", "us-east-2c"]
private_subnets = ["10.1.1.0/24", "10.1.2.0/24", "10.1.3.0/24"]
public_subnets = ["10.1.101.0/24", "10.1.102.0/24", "10.1.103.0/24"]
single_nat_gateway = true
enable_nat_gateway = true
enable_vpn_gateway = false
enable_dns_hostnames = true
public_subnet_tags = {
Name = "public"
}
private_subnet_tags = {
Name = "private"
}
public_route_table_tags = {
Name = "public-RT"
}
private_route_table_tags = {
Name = "private-RT"
}
tags = {
Environment = local.environment
Name = local.name
}
}
Edit
I add this to the code above:
resource "aws_security_group" "bastion-sg" {
name = "bastion-security-group"
vpc_id = "${module.vpc.vpc_id}"
ingress {
protocol = "tcp"
from_port = 22
to_port = 22
cidr_blocks = ["0.0.0.0/0"]
}
egress {
protocol = -1
from_port = 0
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "bastion" {
ami = "ami-0d5d9d301c853a04a"
key_name = "key"
instance_type = "t2.micro"
vpc_security_group_ids = ["${aws_security_group.bastion-sg.id}"]
associate_public_ip_address = true
}
But when I run terraform apply I get error:
Error: Error launching source instance: InvalidParameter: Security group sg-0e3d05f76119af726 and subnet subnet-4b0c1123 belong to different networks.
status code: 400, request id: ddce7fc3-3ef9-407d-b0cd-0dda640bb3a9
on vpc.tf line 108, in resource "aws_instance" "bastion":
108: resource "aws_instance" "bastion" {

resource "aws_security_group" "bastion-sg" {
name = "bastion-security-group"
vpc_id = "aws_vpc.My_VPC.id"
ingress {
protocol = var.bastion_ingress_protocol
from_port = var.bastion_ingress_from_port
to_port = var.bastion_ingress_to_port
cidr_blocks = var.bastion_ingress_cidr
}
egress {
protocol = var.bastion_egress_protocol
from_port = var.bastion_egress_from_port
to_port = var.bastion_egress_to_port
cidr_blocks = var.bastion_egress_cidr
}
}
resource "aws_instance" "bastion" {
ami = var.bastion_ami
key_name = var.key
instance_type = var.bastion_instance_type
security_groups = [aws_security_group.bastion-sg.id]
associate_public_ip_address = true
}

Related

User_data not working in Launch configuration. Is it a problem with my security group or my Launch configuration?

I am currently learning Terraform and I need help with regard to the below code. I want to create a simple architecture of an autoscaling group of EC2 instances behind an Application load balancer. The setup gets completed but when I try to access the application endpoint, it gets timed out. When I tried to access the EC2 instances, I was unable to (because EC2 instances were in a security group allowing access from the ALB security group only). I changed the instance security group ingress values and ran the user_data script manually following which I reverted the changes to the instance security group to complete my setup.
My question is why is my setup not working via the below code? Is it because the access is being restricted by the load balancer security group or is my launch configuration block incorrect?
data "aws_ami" "amazon-linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-kernel-5.10-hvm-2.0.20220426.0-x86_64-gp2"]
}
}
data "aws_availability_zones" "available" {
state = "available"
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "3.14.0"
name = "main-vpc"
cidr = "10.0.0.0/16"
azs = data.aws_availability_zones.available.names
public_subnets = ["10.0.4.0/24","10.0.5.0/24","10.0.6.0/24"]
enable_dns_hostnames = true
enable_dns_support = true
}
resource "aws_launch_configuration" "TestLC" {
name_prefix = "Lab-Instance-"
image_id = data.aws_ami.amazon-linux.id
instance_type = "t2.nano"
key_name = "CloudformationKeyPair"
user_data = file("./user_data.sh")
security_groups = [aws_security_group.TestInstanceSG.id]
lifecycle {
create_before_destroy = true
}
}
resource "aws_autoscaling_group" "TestASG" {
min_size = 1
max_size = 3
desired_capacity = 2
launch_configuration = aws_launch_configuration.TestLC.name
vpc_zone_identifier = module.vpc.public_subnets
}
resource "aws_lb_listener" "TestListener"{
load_balancer_arn = aws_lb.TestLB.arn
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.TestTG.arn
}
}
resource "aws_lb" "TestLB" {
name = "Lab-App-Load-Balancer"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.TestLoadBalanceSG.id]
subnets = module.vpc.public_subnets
}
resource "aws_lb_target_group" "TestTG" {
name = "LabTargetGroup"
port = "80"
protocol = "HTTP"
vpc_id = module.vpc.vpc_id
}
resource "aws_autoscaling_attachment" "TestAutoScalingAttachment" {
autoscaling_group_name = aws_autoscaling_group.TestASG.id
lb_target_group_arn = aws_lb_target_group.TestTG.arn
}
resource "aws_security_group" "TestInstanceSG" {
name = "LAB-Instance-SecurityGroup"
ingress{
from_port = 80
to_port = 80
protocol = "tcp"
security_groups = [aws_security_group.TestLoadBalanceSG.id]
}
ingress{
from_port = 22
to_port = 22
protocol = "tcp"
security_groups = [aws_security_group.TestLoadBalanceSG.id]
}
egress{
from_port = 0
to_port = 0
protocol = "-1"
security_groups = [aws_security_group.TestLoadBalanceSG.id]
}
vpc_id = module.vpc.vpc_id
}
resource "aws_security_group" "TestLoadBalanceSG" {
name = "LAB-LoadBalancer-SecurityGroup"
ingress{
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress{
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress{
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
vpc_id = module.vpc.vpc_id
}

Allowing load-balanced autoscaled instances to connect to the internet - AWS / Terraform

I'm using Terraform and I'm having a tricky time with connecting my autoscaled AWS EC2 instances to the internet. I can launch a standalone EC2 that connects with no difficulty, but when I visit the public IP addresses of my instances created with an autoscaling group I get "This site can’t be reached xxx.xx.xxx.xxx unexpectedly closed the connection."
The main difference I'm seeing is that I can specify a network interface with an EC2, but I'm not sure how this would work with my launch template. My instances launch into different subnets in different availability zones, and the template is as follows:
provider "aws" {
region = "us-east-1"
access_key = "xxxxx"
secret_key = "xxxxx"
}
data "template_file" "testfile" {
template = <<EOF
#!/bin/bash
sudo apt update -y
sudo apt install apache2 -y
sudo systemct1 start apache2
sudo bash -c 'echo hello, world! > var/www/html/index.html'
EOF
}
resource "aws_vpc" "first_vpc" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "prod-vpc"
}
}
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.first_vpc.id
tags = {
Name = "prod-igw"
}
}
resource "aws_route_table" "prod_route_table" {
vpc_id = aws_vpc.first_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.gw.id
}
route {
ipv6_cidr_block = "::/0"
gateway_id = aws_internet_gateway.gw.id
}
tags = {
Name = "prod-rt"
}
}
resource "aws_subnet" "subnet_1" {
vpc_id = aws_vpc.first_vpc.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
map_public_ip_on_launch = true
tags = {
Name = "prod-subnet-1"
Tier = "public"
}
}
resource "aws_subnet" "subnet_2" {
vpc_id = aws_vpc.first_vpc.id
cidr_block = "10.0.2.0/24"
availability_zone = "us-east-1b"
map_public_ip_on_launch = true
tags = {
Name = "prod-subnet-2"
Tier = "public"
}
}
resource "aws_subnet" "subnet_3" {
vpc_id = aws_vpc.first_vpc.id
cidr_block = "10.0.3.0/24"
availability_zone = "us-east-1c"
map_public_ip_on_launch = true
tags = {
Name = "prod-subnet-3"
Tier = "public"
}
}
resource "aws_route_table_association" "a" {
subnet_id = aws_subnet.subnet_1.id
route_table_id = aws_route_table.prod_route_table.id
}
resource "aws_route_table_association" "b" {
subnet_id = aws_subnet.subnet_2.id
route_table_id = aws_route_table.prod_route_table.id
}
resource "aws_route_table_association" "c" {
subnet_id = aws_subnet.subnet_3.id
route_table_id = aws_route_table.prod_route_table.id
}
resource "aws_security_group" "allow_web" {
name = "allow_web"
description = "Allow web inbound traffic"
vpc_id = aws_vpc.first_vpc.id
ingress {
description = "HTTPS from VPC"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "HTTP from VPC"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = "allow_tls"
}
}
resource "aws_launch_template" "frontend" {
name = "frontend"
image_id = "ami-0ee02acd56a52998e"
instance_type = "t2.micro"
vpc_security_group_ids = [aws_security_group.allow_web.id]
network_interfaces {
device_index = 0
associate_public_ip_address = true
}
user_data = base64encode(data.template_file.testfile.rendered)
}
resource "aws_lb" "loadbalancer" {
name = "loadbalancer"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.allow_web.id]
subnets = [aws_subnet.subnet_1.id, aws_subnet.subnet_2.id, aws_subnet.subnet_3.id]
tags = {
Environment = "production"
}
}
resource "aws_autoscaling_group" "as_group_1" {
vpc_zone_identifier = [aws_subnet.subnet_1.id, aws_subnet.subnet_2.id, aws_subnet.subnet_3.id]
desired_capacity = 3
max_size = 5
min_size = 2
target_group_arns = [aws_lb_target_group.frontendhttp.arn]
launch_template {
id = aws_launch_template.frontend.id
version = "$Latest"
}
}
resource "aws_lb_target_group" "frontendhttp" {
name = "frontendhttp"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.first_vpc.id
}
resource "aws_lb_listener" "frontendhttp" {
load_balancer_arn = aws_lb.loadbalancer.arn
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.frontendhttp.arn
}
}
#Test standalone instance
resource "aws_network_interface" "web_server_1" {
subnet_id = aws_subnet.subnet_1.id
private_ips = ["10.0.1.50"]
security_groups = [aws_security_group.allow_web.id]
}
resource "aws_instance" "ubuntu-1" {
ami = "ami-0ee02acd56a52998e"
instance_type = "t2.micro"
availability_zone = "us-east-1a" #hardcoded to ensure that subnet and instance are in same availability availability zone
network_interface {
device_index = 0
network_interface_id = aws_network_interface.web_server_1.id
}
user_data = <<-EOF
#!/bin/bash
sudo apt update -y
sudo apt install apache2 -y
sudo systemct1 start apache2
sudo bash -c 'echo hello! > var/www/html/index.html'
EOF
tags = {
Name = "web-server"
}
}
I modified a bit your template (user data, its indentation and aws_launch_template), and now it works now. It will work only over HTTP, as you don't have HTTPS setup, so don't need SG rules for HTTPS.
data "template_file" "testfile" {
template = <<EOF
#!/bin/bash
apt update -y
apt install apache2 -y
systemct1 start apache2
echo "hello, world!" > var/www/html/index.html
EOF
}
resource "aws_vpc" "first_vpc" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "prod-vpc"
}
}
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.first_vpc.id
tags = {
Name = "prod-igw"
}
}
resource "aws_route_table" "prod_route_table" {
vpc_id = aws_vpc.first_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.gw.id
}
route {
ipv6_cidr_block = "::/0"
gateway_id = aws_internet_gateway.gw.id
}
tags = {
Name = "prod-rt"
}
}
resource "aws_subnet" "subnet_1" {
vpc_id = aws_vpc.first_vpc.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
map_public_ip_on_launch = true
tags = {
Name = "prod-subnet-1"
Tier = "public"
}
}
resource "aws_subnet" "subnet_2" {
vpc_id = aws_vpc.first_vpc.id
cidr_block = "10.0.2.0/24"
availability_zone = "us-east-1b"
map_public_ip_on_launch = true
tags = {
Name = "prod-subnet-2"
Tier = "public"
}
}
resource "aws_subnet" "subnet_3" {
vpc_id = aws_vpc.first_vpc.id
cidr_block = "10.0.3.0/24"
availability_zone = "us-east-1c"
map_public_ip_on_launch = true
tags = {
Name = "prod-subnet-3"
Tier = "public"
}
}
resource "aws_route_table_association" "a" {
subnet_id = aws_subnet.subnet_1.id
route_table_id = aws_route_table.prod_route_table.id
}
resource "aws_route_table_association" "b" {
subnet_id = aws_subnet.subnet_2.id
route_table_id = aws_route_table.prod_route_table.id
}
resource "aws_route_table_association" "c" {
subnet_id = aws_subnet.subnet_3.id
route_table_id = aws_route_table.prod_route_table.id
}
resource "aws_security_group" "allow_web" {
name = "allow_web"
description = "Allow web inbound traffic"
vpc_id = aws_vpc.first_vpc.id
ingress {
description = "HTTP from VPC"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = "allow_http"
}
}
resource "aws_launch_template" "frontend" {
name = "frontend"
image_id = "ami-0ee02acd56a52998e"
instance_type = "t2.micro"
vpc_security_group_ids = [aws_security_group.allow_web.id]
# DONT NEED THIS
# network_interfaces {
# device_index = 0
# associate_public_ip_address = true
# }
user_data = base64encode(data.template_file.testfile.rendered)
}
resource "aws_lb" "loadbalancer" {
name = "loadbalancer"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.allow_web.id]
subnets = [aws_subnet.subnet_1.id, aws_subnet.subnet_2.id, aws_subnet.subnet_3.id]
tags = {
Environment = "production"
}
}
resource "aws_autoscaling_group" "as_group_1" {
vpc_zone_identifier = [aws_subnet.subnet_1.id, aws_subnet.subnet_2.id, aws_subnet.subnet_3.id]
desired_capacity = 3
max_size = 5
min_size = 2
target_group_arns = [aws_lb_target_group.frontendhttp.arn]
launch_template {
id = aws_launch_template.frontend.id
version = "$Latest"
}
}
resource "aws_lb_target_group" "frontendhttp" {
name = "frontendhttp"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.first_vpc.id
}
resource "aws_lb_listener" "frontendhttp" {
load_balancer_arn = aws_lb.loadbalancer.arn
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.frontendhttp.arn
}
}

My Lambda can't connect to my RDS instance

I'm trying to create both services within the same VPC and give them appropriate security groups but they I can't make it work.
variable "vpc_cidr_block" {
default = "10.1.0.0/16"
}
variable "cidr_block_subnet_public" {
default = "10.1.1.0/24"
}
variable "cidr_block_subnets_private" {
default = ["10.1.2.0/24", "10.1.3.0/24", "10.1.4.0/24"]
}
data "aws_availability_zones" "available" {
state = "available"
}
resource "aws_vpc" "vpc" {
cidr_block = var.vpc_cidr_block
}
resource "aws_subnet" "private" {
count = length(var.cidr_block_subnets_private)
cidr_block = var.cidr_block_subnets_private[count.index]
vpc_id = aws_vpc.vpc.id
availability_zone = data.aws_availability_zones.available.names[count.index]
}
resource "aws_security_group" "lambda" {
vpc_id = aws_vpc.vpc.id
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_security_group" "rds" {
vpc_id = aws_vpc.vpc.id
ingress {
description = "PostgreSQL"
from_port = 5432
protocol = "tcp"
to_port = 5432
// security_groups = [aws_security_group.lambda.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_lambda_function" "event" {
function_name = "ServerlessExampleEvent"
timeout = 30
s3_bucket = "mn-lambda"
s3_key = "mn/v1.0.0/lambda-1.0.0-all.jar"
handler = "dk.fitfit.handler.EventRequestHandler"
runtime = "java11"
memory_size = 256
role = aws_iam_role.event.arn
vpc_config {
security_group_ids = [aws_security_group.lambda.id]
subnet_ids = [for s in aws_subnet.private: s.id]
}
environment {
variables = {
JDBC_DATABASE_URL = "jdbc:postgresql://${aws_db_instance.rds.address}:${aws_db_instance.rds.port}/${aws_db_instance.rds.identifier}"
DATABASE_USERNAME = aws_db_instance.rds.username
DATABASE_PASSWORD = aws_db_instance.rds.password
}
}
}
resource "aws_db_subnet_group" "db" {
subnet_ids = aws_subnet.private.*.id
}
resource "aws_db_instance" "rds" {
allocated_storage = 10
engine = "postgres"
engine_version = "11.5"
instance_class = "db.t2.micro"
username = "postgres"
password = random_password.password.result
skip_final_snapshot = true
apply_immediately = true
vpc_security_group_ids = [aws_security_group.rds.id]
db_subnet_group_name = aws_db_subnet_group.db.name
}
resource "random_password" "password" {
length = 32
special = false
}
I tried to not clutter the question by only posting the relevant part of my HCL. Please let me know if I missed anything important.
The biggest issue is the commented out security_groups parameter on the ingress block of the rds security group. Uncommenting that should then allow Postgresql traffic from the lambda security group:
resource "aws_security_group" "rds" {
vpc_id = aws_vpc.vpc.id
ingress {
description = "PostgreSQL"
from_port = 5432
protocol = "tcp"
to_port = 5432
security_groups = [aws_security_group.lambda.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
As well as that your JDBC string is basically resolving to something like jdbc:postgresql://terraform-20091110230000000000000001.xxxx.us-east-1.rds.amazonaws.com:5432/terraform-20091110230000000000000001 because you aren't specifying an identifier for the RDS instance and so it defaults to generating an identifier prefixed with terraform- plus the timestamp and a counter. The important part to note here is that your RDS instance doesn't yet include a database of the name terraform-20091110230000000000000001 for your application to connect to because you haven't specified it.
You can have RDS create a database on the RDS instance by using the name parameter. You can then update your JDBC connection string to specify the database name as well:
resource "aws_db_instance" "rds" {
allocated_storage = 10
engine = "postgres"
engine_version = "11.5"
instance_class = "db.t2.micro"
username = "postgres"
password = random_password.password.result
skip_final_snapshot = true
apply_immediately = true
name = "foo"
vpc_security_group_ids = [aws_security_group.rds.id]
db_subnet_group_name = aws_db_subnet_group.db.name
}
resource "aws_lambda_function" "event" {
function_name = "ServerlessExampleEvent"
timeout = 30
s3_bucket = "mn-lambda"
s3_key = "mn/v1.0.0/lambda-1.0.0-all.jar"
handler = "dk.fitfit.handler.EventRequestHandler"
runtime = "java11"
memory_size = 256
role = aws_iam_role.event.arn
vpc_config {
security_group_ids = [aws_security_group.lambda.id]
subnet_ids = [for s in aws_subnet.private : s.id]
}
environment {
variables = {
JDBC_DATABASE_URL = "jdbc:postgresql://${aws_db_instance.rds.address}:${aws_db_instance.rds.port}/${aws_db_instance.rds.name}"
DATABASE_USERNAME = aws_db_instance.rds.username
DATABASE_PASSWORD = aws_db_instance.rds.password
}
}
}

Terraform AWS not able to ping, or ssh just created EC2 instances

I would like to ask for assistance.
I wrote terraform script which is creating 5 EC2 instances but I am not able to ping or SSH them.
Do you see any potential issue with this? I have opened icmp, ssh, not when I checked form other computers/sites I get port is closed.
When I create manually EC2 is working from my computer, I am able to ssh/ping, but not with this terraform script.
provider "aws" {
version = "~> 3.0"
region = "us-east-1"
access_key = "AKxxxxxxxxxxx"
secret_key = "2CLBj/s9dC5r52Y"
}
# Create a VPC
resource "aws_vpc" "BrokenByteVPC" {
cidr_block = "192.168.100.0/28"
tags = {
Name = "BrokenByteVPC"
}
}
resource "aws_subnet" "BrokenbyteLB-subnet" {
vpc_id = aws_vpc.BrokenByteVPC.id
cidr_block = "192.168.100.0/28"
availability_zone = "us-east-1a"
tags = {
Name = "BrokenbyteLB-subnet"
}
}
resource "aws_internet_gateway" "BrokenByte-gateway" {
vpc_id = aws_vpc.BrokenByteVPC.id
tags = {
Name = "BrokenByte-gateway"
}
}
resource "aws_route_table" "BrokenByte-Route-table" {
vpc_id = aws_vpc.BrokenByteVPC.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.BrokenByte-gateway.id
}
}
resource "aws_route_table_association" "a" {
subnet_id = aws_subnet.BrokenbyteLB-subnet.id
route_table_id = aws_route_table.BrokenByte-Route-table.id
}
resource "aws_security_group" "allow_traffic" {
name = "allow_Traffic"
description = "Allow SSH,HTTP and HTTPS inbound traffic"
vpc_id = aws_vpc.BrokenByteVPC.id
ingress {
description = "Dozvoli SVEEEEEEEE"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "SSH traffic"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "HTTP traffic"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "HTTPS traffic"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "Allow_ssh_http_https"
}
}
resource "aws_network_interface" "NginX-public" {
subnet_id = aws_subnet.BrokenbyteLB-subnet.id
#private_ips = ["192.168.100.2"]
security_groups = [aws_security_group.allow_traffic.id]
}
resource "aws_network_interface" "NginX-LB" {
subnet_id = aws_subnet.BrokenbyteLB-subnet.id
private_ips = ["192.168.100.10"]
security_groups = [aws_security_group.allow_traffic.id]
}
resource "aws_network_interface" "www1" {
subnet_id = aws_subnet.BrokenbyteLB-subnet.id
private_ips = ["192.168.100.11"]
security_groups = [aws_security_group.allow_traffic.id]
}
resource "aws_network_interface" "www2" {
subnet_id = aws_subnet.BrokenbyteLB-subnet.id
private_ips = ["192.168.100.12"]
security_groups = [aws_security_group.allow_traffic.id]
}
resource "aws_network_interface" "www3" {
subnet_id = aws_subnet.BrokenbyteLB-subnet.id
private_ips = ["192.168.100.13"]
security_groups = [aws_security_group.allow_traffic.id]
}
resource "aws_eip" "BrokenByte-PublicIP" {
vpc = true
network_interface = aws_network_interface.NginX-public.id
#associate_with_private_ip = "192.168.100.10"
depends_on = [aws_internet_gateway.BrokenByte-gateway, aws_instance.BrokenByteNginX]
}
resource "aws_instance" "BrokenByteNginX" {
ami = "ami-0dba2cb6798deb6d8"
availability_zone = "us-east-1a"
instance_type = "t2.micro"
key_name = "aws_test"
network_interface {
device_index=0
network_interface_id = aws_network_interface.NginX-LB.id
}
network_interface {
device_index=1
network_interface_id = aws_network_interface.NginX-public.id
}
tags = {
Name = "BrokenByteNginXLB"
}
user_data = <<-EOF
#!/bin/bash
sudo apt-get update -y
EOF
}
resource "aws_instance" "BrokenByteWWW1" {
ami = "ami-0dba2cb6798deb6d8"
availability_zone = "us-east-1a"
instance_type = "t2.micro"
key_name = "aws_test"
network_interface {
device_index=0
network_interface_id = aws_network_interface.www1.id
}
tags = {
Name = "BrokenByteWWW1"
}
}
resource "aws_instance" "BrokenByteWWW2" {
ami = "ami-0dba2cb6798deb6d8"
availability_zone = "us-east-1a"
instance_type = "t2.micro"
key_name = "aws_test"
network_interface {
device_index=0
network_interface_id = aws_network_interface.www2.id
}
tags = {
Name = "BrokenByteWWW2"
}
}
resource "aws_instance" "BrokenByteWWW3" {
ami = "ami-0dba2cb6798deb6d8"
availability_zone = "us-east-1a"
instance_type = "t2.micro"
key_name = "aws_test"
network_interface {
device_index=0
network_interface_id = aws_network_interface.www3.id
}
tags = {
Name = "BrokenByteWWW3"
}
}
None of your instances have public IP address (except the one with aws_eip.BrokenByte-PublicIP), since your public subnet is missing map_public_ip_on_launch. You can rectify the issue by:
resource "aws_subnet" "BrokenbyteLB-subnet" {
vpc_id = aws_vpc.BrokenByteVPC.id
cidr_block = "192.168.100.0/28"
availability_zone = "us-east-1a"
map_public_ip_on_launch = true
tags = {
Name = "BrokenbyteLB-subnet"
}
}
I was sure is something related to network card, but wasn't sure what.
Now is fine, I can ping and SSH, just swapped public IP to be network 0, and I removed code for network.
#Marcin, your first reply showed me in which direction to look.
# network_interface {
# device_index=0
# network_interface_id = aws_network_interface.NginX-LB.id
# }
network_interface {
device_index=0
network_interface_id = aws_network_interface.NginX-public.id
}

The subnet ID 'aws_subnet.firstsubnet.id' does not exist status code: 400,

I would like to use AWS Auto Scaling Group (ASG).
How to correct an error?
Error: Error creating AutoScaling Group: ValidationError: The subnet ID 'aws_subnet.firstsubnet.id' does not exist
status code: 400, request id: 06571fdb-585b-486e-ae9c-19d3acb14d9e
...........................................................................
My code below:
resource "aws_vpc" "myvpc"{
cidr_block = "192.168.0.0/16"
instance_tenancy = "default"
enable_dns_hostnames = true
tags = {
Name = "newvpc"
}
}
resource "aws_subnet" "firstsubnet"{
vpc_id = aws_vpc.myvpc.id
cidr_block = "192.168.1.0/24"
availability_zone = "${var.availability_zone1}"
map_public_ip_on_launch = true
tags = {
Name = "public_subnet"
}
}
resource "aws_subnet" "secondsubnet"{
vpc_id = aws_vpc.myvpc.id
cidr_block = "192.168.2.0/24"
availability_zone = "${var.availability_zone2}"
tags = {
Name = "private_subnet"
}
}
resource "aws_internet_gateway" "my_igv" {
vpc_id = aws_vpc.myvpc.id
tags = {
Name = "my_igv"
}
}
resource "aws_route_table" "my_route" {
vpc_id = aws_vpc.myvpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.my_igv.id
}
tags = {
Name = "my_route"
}
}
resource "aws_route_table_association" "subnet_assosiate" {
subnet_id = aws_subnet.firstsubnet.id
route_table_id = aws_route_table.my_route.id
}
resource "aws_security_group" "mysc1" {
name = "mysc1-http"
description = "Allow inbound traffic"
vpc_id = aws_vpc.myvpc.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "allow_http"
}
}
resource "aws_instance" "wp" {
ami = "ami-07d9160fa81ccffb5"
instance_type = "t2.micro"
vpc_security_group_ids = ["${aws_security_group.mysc1.id}"]
subnet_id = aws_subnet.firstsubnet.id
key_name = "MyKey"
tags = {
Name = "wordpress"
}
connection {
type = "ssh"
user = "ec2-user"
private_key = file("./MyKey.pem")
host = aws_instance.wp.public_ip
}
}
resource "aws_security_group" "mysc2" {
name = "mysc2-db"
description = "Allow inbound traffic"
vpc_id = aws_vpc.myvpc.id
ingress {
from_port = 3306
to_port = 3306
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "allow_db"
}
}
resource "aws_instance" "db" {
ami = "ami-07d9160fa81ccffb5"
instance_type = "t2.micro"
vpc_security_group_ids = ["${aws_security_group.mysc2.id}"]
subnet_id = aws_subnet.secondsubnet.id
key_name = "MyKey"
tags = {
Name = "mysql"
}
}
output "instance_ip_addr" {
value = aws_instance.db.private_ip
}
module "asg" {
source = "terraform-aws-modules/autoscaling/aws"
version = "~> 3.0"
name = "service"
# Launch configuration
lc_name = "example-lc"
image_id = "ami-ebd02392"
instance_type = "t2.micro"
security_groups = ["${aws_security_group.mysc1.id}"]
ebs_block_device = [
{
device_name = "/dev/xvdz"
volume_type = "gp2"
volume_size = "50"
delete_on_termination = true
},
]
root_block_device = [
{
volume_size = "50"
volume_type = "gp2"
},
]
# Auto scaling group
asg_name = "example-asg"
vpc_zone_identifier = ["aws_subnet.firstsubnet.id", "aws_subnet.secondsubnet.id"]
health_check_type = "EC2"
min_size = 0
max_size = 4
desired_capacity = 4
wait_for_capacity_timeout = 0
tags = [
{
key = "Environment"
value = "dev"
propagate_at_launch = true
},
{
key = "Project"
value = "megasecret"
propagate_at_launch = true
},
]
tags_as_map = {
extra_tag1 = "extra_value1"
extra_tag2 = "extra_value2"
}
}
module "elb_http" {
source = "terraform-aws-modules/elb/aws"
version = "~> 2.0"
name = "elb-example"
subnets = ["${aws_subnet.firstsubnet.id}", "${aws_subnet.secondsubnet.id}"]
security_groups = ["${aws_security_group.mysc1.id}"]
internal = false
listener = [
{
instance_port = "80"
instance_protocol = "HTTP"
lb_port = "80"
lb_protocol = "HTTP"
},
{
instance_port = "8080"
instance_protocol = "http"
lb_port = "8080"
lb_protocol = "http"
#ssl_certificate_id = "arn:aws:acm:eu-west-1:235367859451:certificate/6c270328-2cd5-4b2d-8dfd-ae8d0004ad31"
},
]
health_check = {
target = "HTTP:80/"
interval = 30
healthy_threshold = 2
unhealthy_threshold = 2
timeout = 5
}
access_logs = {
bucket = "my-access-logs-bucket"
}
// ELB attachments
number_of_instances = 2
instances = ["i-06ff41a77dfb5349d", "i-4906ff41a77dfb53d"]
tags = {
Owner = "user"
Environment = "dev"
}
}
There reason for the error is that you are passing strings instead of actual subnet ids.
Thus, instead of:
vpc_zone_identifier = ["aws_subnet.firstsubnet.id", "aws_subnet.secondsubnet.id"]
there should be:
vpc_zone_identifier = [aws_subnet.firstsubnet.id, aws_subnet.secondsubnet.id]
or
vpc_zone_identifier = ["${aws_subnet.firstsubnet.id}", "${aws_subnet.secondsubnet.id}"]