2016-07-07 1 views
1

2 개의 VPC 보안 그룹을 만들고 싶습니다.Terraform을 사용하여 AWS VPC 보안 그룹을 만들 때 순환 오류가 발생했습니다.

VPC의 요새 호스트 용이고 개인 서브넷 용입니다.

# 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

,이 오류가 반환됩니다 : 나는 PrivateSG에서 BastionSG의 진입 규칙을 주석 경우

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

는 계획이 잘 실행됩니다.

또한 BastionSG에서 PrivateSG에 대한 출력 규칙을 주석 처리하면 정상적으로 실행됩니다.

AWS Scenario 2 for building a VPC with Public/Private subnets and Bastion host에는 설정하려는 아키텍처가 나와 있습니다.

AWS 콘솔을 통해 정확히 동일한 설정이 구성되었으며 정상적으로 작동합니다.

왜 Terraform은 그것을 받아들이지 않습니까? Bastion 보안 그룹을 개인 보안 그룹에 연결하는 다른 방법이 있습니까?

어떻게 든 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)의 두포 (Hood) 아래에서 나에게 한 번 봤다고 말할 수있다. 의존성 체인을 이해하면 미래에 반드시 도움이 될 것입니다. –

+0

좋은 대답은 왜 내가 aws_security_group_rule을 사용하고자하는지 분명하게 알려주기 때문입니다. 내가 생각하기에는 문서에서 명확하지 않은 것이 있습니다. –

+1

또한 보는 방법에 따라 좋거나 나쁠 수있는보다 세부적인 제어 기능을 제공합니다. 별도의 규칙 리소스를 사용하면 원할 경우 Terraform 외부 그룹에 추가 규칙을 자유롭게 추가 할 수 있으며 Terraform은 다음에 실행할 때 해당 규칙을 제거하지 않습니다. 물론 Terraform에서 특정 보안 프로필을 적용하기를 원할 수도 있기 때문에 나쁜 것으로 생각할 수도 있습니다. – ydaetskcoR

관련 문제