Terraform Version: v0.11.8
I am trying to update the rule of security group which is in another region (Ireland) after deploying my current security group (Ohio).
Below is my code snippet:
variable "aws_account_id" {}
terraform {
backend "s3" {}
}
provider "aws" {
region = "us-east-2"
allowed_account_ids = ["${var.aws_account_id}"]
}
provider "aws" {
alias = "TestApp"
region = "eu-west-1"
}
data "aws_security_group" "test_sg" {
provider = "aws.TestApp"
name = "test-sg"
}
resource "aws_security_group" "test1_sg" {
name = "Test 1"
vpc_id = "VPC ID"
}
resource "aws_security_group_rule" "allow_test1_access_test_sg" {
provider = "aws.TestApp"
type = "ingress"
from_port = "80"
to_port = "80"
protocol = "tcp"
security_group_id = "${data.aws_security_group.test_sg.id}"
source_security_group_id = "${aws_security_group.test1_sg.id}"
}
I am getting circular dependency like below.
Case 1: Run above code, Getting error that test1_sg security group does not exist.
Case 2: Run above code without provider = "aws.TestApp" in aws_security_group_rule, Getting error that test_sg security group does not exist.
Case 3: Run above code without provider = "aws.TestApp" in data "aws_security_group" "test_sg" , Getting error that test_sg security group does not exist.
I am not sure this is 100% issue of inter-region communication but it seems like this is the case.
Note: The above error is coming while running terraform apply. Plan is showing correct change without any error.
Any help will be highly appreciated.
Thanks!
Ok so finally i found the answer.
As per Amazon documentation...
You cannot reference the security group of a peer VPC that's in a
different region. Instead, use the CIDR block of the peer VPC.
AWS Doc: Updating Your Security Groups to Reference Peer VPC Groups
I need to use cidr block instead of the security group while referencing in cross region.
As far as I can see with your case 1, your source security group should be "test1_sg". There is no security group with the name "test1_access_test2". Use this.
source_security_group_id = "${aws_security_group.test1_sg.id}"
Otherwise, go and check on your console whether that security group exists or not.
Related
When I'm creating a Network ACL for AWS in Terraform I'm not able to configure the field "Type"
However if you configure the ACL via Portal the field type can be configured accordingly.
aws nacl ui
The Type field on the web console is just an easy way to select pre-configured combinations of protocols and ports. This field is not there in terraform templates, and you can simply specify the protocol and port separately as shown in #marcincuber's answer. It's the same in AWS CloudFormation as well.
The type field is "automatically defined" based on the information you use for the port/protocol.
For example, try to create a rule for port 25/tcp.
After you apply and the rule is created, the type will automatically be set to "SMTP(25)".
You are looking for the following terraform resources that support protocol argument:
resource "aws_network_acl" "bar" {
vpc_id = aws_vpc.foo.id
}
resource "aws_network_acl_rule" "bar" {
network_acl_id = aws_network_acl.bar.id
rule_number = 200
egress = false
protocol = "tcp"
rule_action = "allow"
cidr_block = aws_vpc.foo.cidr_block
from_port = 22
to_port = 22
}
The example was takes from https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl_rule
I got a microservice in an ECS instance in AWS behind a WAF, I want to create these rules:
Allow specific IPs (done)
Allow all connections from inside the VPN (done)
Deny all the other requests.
The first two IP set are created, but I can't make the last one to work. I tried creating the IP set with 0.0.0.0/0 and another combinations without success.
This is my code, I removed ipset 1 and 2 (that are working), this is the ipset 3:
resource "aws_wafv2_ip_set" "ipset" {
name = "${var.app_name}-${var.environment_name}-whitelist-ips"
scope = "REGIONAL"
ip_address_version = "IPV4"
addresses = ["0.0.0.0/0"]
}
module "alb_wafv2" {
source = "trussworks/wafv2/aws"
version = "~> 2.0"
name = "${var.app_name}-${var.environment_name}"
scope = "REGIONAL"
alb_arn = aws_lb.app_lb.arn
associate_alb = true
ip_sets_rule = [
{
name = "${var.app_name}-${var.environment_name}-ip-blacklist"
action = "deny"
priority = 1
ip_set_arn = aws_wafv2_ip_set.ipset.arn
}
]
}
{
RespMetadata: {
StatusCode: 400,
RequestID: "c98b2d3a-ebd0-44e0-a80a-702bc698598b"
},
Field: "IP_ADDRESS",
Message_: "Error reason: The parameter contains formatting that is not valid., field: IP_ADDRESS, parameter: 0.0.0.0/0",
Parameter: "0.0.0.0/0",
Reason: "The parameter contains formatting that is not valid."
}
Tried to create an IP Set from the AWS Console with the same error:
So I got two questions, first, how can I do this? And the second one, is this the best approach?
Thanks in advance
You don't need to block 0.0.0.0/0. After you created two IP rules, look "Default web ACL action for requests that don't match any rules" on WAF console and set Action to Block.
Consider using this trick to bypass the 0.0.0.0/0 limitation:
Divide the IPv4 address space into two chunks: 0.0.0.0/1 and 128.0.0.0/1
The following terraform snippet was accepted and the ip set was created by TF (Terraform 0.15.4 and aws provider version 3.42.0):
resource "aws_wafv2_ip_set" "ipset" {
name = "all_internet_kludge"
scope = "REGIONAL"
ip_address_version = "IPV4"
addresses = ["0.0.0.0/1", "128.0.0.0/1"]
}
You can't block all addresses (CIDR /0). It is not supported. From docs:
AWS WAF supports all IPv4 and IPv6 CIDR ranges except for /0.
Instead, you can use network ACL to deny all traffic, or security groups.
I am trying to use terraform to spin up a VPC and single instance and then connect via ssh but I'm unable to. I'm aware I don't have any keys here but I'm trying to simply connect via the web terminal and it still says
There was a problem setting up the instance connection The connection
has been closed because the server is taking too long to respond. This
is usually caused by network problems, such as a spotty wireless
signal, or slow network speeds. Please check your network connection
and try again or contact your system administrator.
Is anyone able to look at my code and see what I'm doing wrong?
provider "aws" {
region = "us-east-2"
}
resource "aws_vpc" "vpc" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "test"
}
}
resource "aws_internet_gateway" "gateway" {
vpc_id = "${aws_vpc.vpc.id}"
tags = {
Name = "test"
}
}
resource "aws_subnet" "subnet" {
vpc_id = "${aws_vpc.vpc.id}"
cidr_block = "${aws_vpc.vpc.cidr_block}"
availability_zone = "us-east-2a"
map_public_ip_on_launch = true
tags = {
Name = "test"
}
}
resource "aws_route_table" "table" {
vpc_id = "${aws_vpc.vpc.id}"
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.gateway.id}"
}
tags = {
Name = "test"
}
}
resource "aws_route_table_association" "public" {
subnet_id = "${aws_subnet.subnet.id}"
route_table_id = "${aws_route_table.table.id}"
}
resource "aws_instance" "node" {
#ami = "ami-0d5d9d301c853a04a" # Ubuntu 18.04
ami = "ami-0d03add87774b12c5" # Ubuntu 16.04
instance_type = "t2.micro"
subnet_id = "${aws_subnet.subnet.id}"
}
UPDATE1: I've added key_name = "mykey" which I have previously created. I am unable to ping the public ip and upon trying to ssh with the key I get the following:
$ ssh -v -i ~/.ssh/mykey ubuntu#1.2.3.4
OpenSSH_7.9p1, LibreSSL 2.7.3
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 48: Applying options for *
debug1: Connecting to 1.2.3.4 [1.2.3.4] port 22.
where mykey and 1.2.3.4 have been changed for posting.
UPDATE2: Looking at the security group I don't see anything which stands out. The ACL for this has the following:
Rule # Type Protocol Port Range Source Allow / Deny
100 ALL Traffic ALL ALL 0.0.0.0/0 ALLOW
* ALL Traffic ALL ALL 0.0.0.0/0 DENY
Is this a problem? It seems that no one sees an issue with the terraform code so if anyone can confirm this is not a problem with the code then I think this can be closed out and moved to a different board since it would not be a code issue, correct?
The web console uses SSH to connect, so you still need to setup an SSH key. The only way to connect without an SSH key configured, and port 22 open in the Security Group, is to use AWS Systems Manager Session Manager, but that requires the SSM agent running on the EC2 instance and appropriate IAM roles assigned to the instance.
You have not supplied a key_name to indicate which SSH keypair to use.
If you don't have an existing aws_key_pair then you will also need to create one.
I am trying to setup AWS SFTP transfer in vpc endpoint mode but there is one think I can't manage with.
The problem I have is how to get target IPs for NLB target group.
The only output I found:
output "vpc_endpoint_transferserver_network_interface_ids" {
description = "One or more network interfaces for the VPC Endpoint for transferserver"
value = flatten(aws_vpc_endpoint.transfer_server.*.network_interface_ids)
}
gives network interface ids which cannot be used as targets:
Outputs:
api_url = https://12345.execute-api.eu-west-1.amazonaws.com/prod
vpc_endpoint_transferserver_network_interface_ids = [
"eni-12345",
"eni-67890",
"eni-abcde",
]
I went through:
terraform get subnet integration ips from vpc endpoint subnets tab
and
Terraform how to get IP address of aws_lb
but none of them seems to be working. The latter says:
on modules/sftp/main.tf line 134, in data "aws_network_interface" "ifs":
134: count = "${length(local.nlb_interface_ids)}"
The "count" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the count depends on.
You can create an Elastic IP
resource "aws_eip" "lb" {
instance = "${aws_instance.web.id}"
vpc = true
}
Then specify the Elastic IPs while creating Network LB
resource "aws_lb" "example" {
name = "example"
load_balancer_type = "network"
subnet_mapping {
subnet_id = "${aws_subnet.example1.id}"
allocation_id = "${aws_eip.example1.id}"
}
subnet_mapping {
subnet_id = "${aws_subnet.example2.id}"
allocation_id = "${aws_eip.example2.id}"
}
}
I need help in writing a terraform script fro AWS as follows:
I have a list of security groups in multiple regions, for example,
- us-east-2
- us-west-1
- etc.
Now when I add a new instance in any of the region, I am applying an EIP.
I need to add that EIP all traffic in every region's security group.
So far what I tried:
Saving the EIP in a file called node_ips.txt
Read that file
Apply it to security group
Here is the script sample:
variable "list_eips" { type=list" }
resource "aws_eip_association" "eip_assoc" {
count = "${local.number_of_instances}"
instance_id = "${element(aws_instance.ec2_instance.*.id, count.index)}"
allocation_id = "${element(data.aws_eip.db_ip.*.id, count.index)}"
provisioner "local-exec" {
command = "echo ${self.public_ip} >> node_ips.txt"
}
}
data "template_file" "read_node_ips" {
template = "${file("${path.cwd}/node_ips.txt")}"
}
resource "aws_security_group_rule" "allow_db_communication" {
type = "ingress"
from_port = 0
to_port = 65535
protocol = "tcp"
cidr_blocks = ["${split(",", "${join("/32,", concat(compact(split("\n",data.template_file.read_node_ips.rendered)),var.list_eips) )}/32")}"]
security_group_id = "${data.aws_security_group.cassandra_sg.id}"
}
This is not working for me. It is adding rules only for list_eips.
Again, when I add a new instance in different region, the secruity group is different. So, I am not able to know what was my security group in previous region.
Please advise any idea.
Thanks.
Terraform has the idea of "Multiple Provider Instances", You can create providers for each region that need to access and manipulate resources.
# West coast region
provider "aws" {
alias = "west"
region = "us-west-2"
}
resource "aws_instance" "foo" {
provider = "aws.west"
# ...
}
https://www.terraform.io/docs/configuration/providers.html