2016-07-07 71 views
1

我想創建2個VPC安全組。嘗試使用Terraform創建AWS VPC安全組時出現循環錯誤

一個用於VPC的Bastion主機,另一個用於Private子網。

# BASTION # 
resource "aws_security_group" "VPC-BastionSG" { 
    name  = "VPC-BastionSG" 
    description = "The sec group for the Bastion instance" 
    vpc_id  = "aws_vpc.VPC.id" 

    ingress { 
     from_port = 22 
     to_port = 22 
     protocol = "tcp" 
     cidr_blocks = ["my.super.ip/32"] 
    } 

    egress { 
     # Access to the Private subnet from the bastion host[ssh] 
     from_port = 22 
     to_port = 22 
     protocol = "tcp" 
     security_groups = ["${aws_security_group.VPC-PrivateSG.id}"] 
    } 
    egress { 
     # Access to the Private subnet from the bastion host[jenkins] 
     from_port = 8686 
     to_port = 8686 
     protocol = "tcp" 
     security_groups = ["${aws_security_group.VPC-PrivateSG.id}"] 
    } 

    tags = { 
    Name = "VPC-BastionSG" 
    } 
} 

# PRIVATE # 
resource "aws_security_group" "VPC-PrivateSG" { 
    name  = "VPC-PrivateSG" 
    description = "The sec group for the private subnet" 
    vpc_id  = "aws_vpc.VPC.id" 

    ingress { 
     from_port = 22 
     to_port = 22 
     protocol = "tcp" 
     security_groups = ["${aws_security_group.VPC-BastionSG.id}"] 
    } 
    ingress { 
     from_port = 80 
     to_port = 80 
     protocol = "tcp" 
     security_groups = ["${aws_security_group.VPC-PublicSG.id}"] 
    } 
    ingress { 
     from_port = 443 
     to_port = 443 
     protocol = "tcp" 
     security_groups = ["${aws_security_group.VPC-PublicSG.id}"] 
    } 
    ingress { 
     from_port = 3306 
     to_port = 3306 
     protocol = "tcp" 
     security_groups = ["${aws_security_group.VPC-PublicSG.id}"] 
    } 
    ingress { 
     from_port = 8686 
     to_port = 8686 
     protocol = "tcp" 
     security_groups = ["${aws_security_group.VPC-BastionSG.id}"] 
    } 
    ingress { 
     # ALL TRAFFIC from the same subnet 
     from_port = 0 
     to_port = 0 
     protocol = "-1" 
     self  = true 
    } 
    egress { 
     # ALL TRAFFIC to outside world 
     from_port = 0 
     to_port = 0 
     protocol = "-1" 
     cidr_blocks = ["0.0.0.0/0"] 
    } 
    tags = { 
    Name = "VPC-PrivateSG" 
    } 
} 

當我terraform plan它,返回此錯誤:

**`Error configuring: 1 error(s) occurred: 
* Cycle: aws_security_group.VPC-BastionSG, aws_security_group.VPC-PrivateSG`** 

如果我註釋掉入口規則從PrivateSG的BastionSG計劃執行罰款。

此外,如果我從BastionSG註釋出PrivateSG的出口規則,它也會執行正常。

AWS Scenario 2 for building a VPC with Public/Private subnets and Bastion host描述了我嘗試設置的體系結構。

我有通過AWS控制檯配置的完全相同的設置,它播放良好。

爲什麼Terraform不接受它? 是否有另一種方法將Bastion安全組與私人安全組連接?

EDIT

據我所知有不知何故需要打破即使在AWS它是有效的兩個秒組之間的循環引用。

所以,我想允許來自Bastion sec組的所有出站流量(0.0.0.0/0),而不是將它指定給單個安全組。

它會對安全造成不良影響嗎?

+0

terraform GitHub存在一個問題,它描述了相互依賴的安全組。線程末端的推薦解決方案是否適用於您的案例? https://github.com/hashicorp/terraform/issues/539 – jbird

+1

謝謝你指出@jbird。我用CIDR塊代替它,它不再抱怨。但我更喜歡ydaetskcoR的答案,因爲我想要有清晰的描述性代碼。 –

回答

6

Terraform嘗試爲其所處的文件夾中定義的所有資源構建依賴關係鏈。這樣做可以解決它是否需要按照特定順序構建事物,並且它是如何工作的關鍵。

顯然,您的示例將失敗,因爲您有一個循環依賴項(如Terraform指出的那樣),其中每個安全組都依賴於已創建的另一個安全組。

有時候這些可能會很難解決,也許意味着你需要重新考慮你想要做的事情(正如你所提到的,一種選擇是簡單地允許所有出口流量從堡壘主機出來並且僅限制入口流量),但在這種情況下,您可以選擇使用aws_security_group_rule資源和aws_security_group資源。

這意味着我們可以首先定義空白的安全組,其中沒有任何規則,然後我們可以將它們用作我們爲組創建的安全組規則的目標。

一個簡單的例子可能是這個樣子:

resource "aws_security_group" "bastion" { 
    name = "bastion" 
    description = "Bastion security group" 
} 

resource "aws_security_group_rule" "bastion-to-private-ssh-egress" { 
    type = "egress" 
    from_port = 22 
    to_port = 22 
    protocol = "tcp" 
    security_group_id = "${aws_security_group.bastion.id}" 
    source_security_group_id = "${aws_security_group.private.id}" 
} 

resource "aws_security_group" "private" { 
    name = "private" 
    description = "Private security group" 
} 

resource "aws_security_group_rule" "private-from-bastion-ssh-ingress" { 
    type = "ingress" 
    from_port = 22 
    to_port = 22 
    protocol = "tcp" 
    security_group_id = "${aws_security_group.private.id}" 
    source_security_group_id = "${aws_security_group.bastion.id}" 
} 

現在,Terraform可以看到依存關係鏈說,這兩個安全組必須要麼這些安全組規則之前,作爲兩者都依賴創建關於已經創建的組。

+0

謝謝,這是一個非常明確和有用的答案。我可以說你在Terraform的引擎下看了我一眼。瞭解依賴關係鏈將來肯定會對我有所幫助。 –

+0

好的答案,因爲它讓我很清楚爲什麼你會想要使用aws_security_group_rule;我認爲這在文檔中是不清楚的。 –

+1

它也給你更細粒度的控制,這可能是一個好的或壞的事情,這取決於你如何看待它。使用單獨的規則資源意味着您可以自由地將額外的規則添加到Terraform之外的組,如果您願意,Terraform下次運行時不會刪除它們。當然,您可能會認爲這是一件壞事,因爲您可能希望Terraform強制執行特定的安全配置文件。 – ydaetskcoR

相關問題