2016-07-07 7 views
1

2つのVPCセキュリティグループを作成したいとします。Terraformを使用してAWS VPCセキュリティグループを作成するときのサイクルエラー

1つはVPCのBastionホスト用で、もう1つはプライベートサブネット用です。

# 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でそれが有効であるにもかかわらず、壊す必要がある2秒のグループの間の循環参照があることを理解したよう。

私は、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リソースと組み合わせてaws_security_group_ruleリソースを使用するオプションがあります。

これは、最初にルールを持たない空のセキュリティグループを定義して、グループに対して作成するセキュリティグループルールのターゲットとして使用できることを意味します。

簡単な例は次のようになります。今

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}" 
} 

は、テラフォームが依存チェーンは、それらの両方が依存しているとして、両方のセキュリティグループは、これらのセキュリティグループルールのいずれかの前に作成する必要があることを述べていることがわかりますすでに作成されているグループに適用されます。

+0

ありがとう、それは非常に明確で有用な答えです。あなたが私にTerraformのフードの下で一見をくれたと言うことができます。依存関係を理解することは、将来確実に私を助けます。 –

+0

これは、なぜあなたがaws_security_group_ruleを使いたいのかが分かりやすいためです。私はそれがドキュメントではっきりしていないと思います。 –

+1

また、あなたはそれを見ているかどうかによって、良いものか悪いものかを細かく制御できます。別のルールリソースを使用すると、必要に応じてTerraform外のグループに余分なルールを自由に追加することができ、次回Terraformを実行したときに削除されません。もちろん、Terraformに特定のセキュリティプロファイルを適用させたいと思うかもしれないので、悪いことを考えるかもしれません。 – ydaetskcoR

関連する問題