

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# Amazon Virtual Private Cloud AWS CodeBuild 와 함께 사용
<a name="vpc-support"></a>

일반적으로 AWS CodeBuild 는 VPC의 리소스에 액세스할 수 없습니다. 액세스를 활성화하려면 CodeBuild 프로젝트 구성에 추가적인 VPC별 구성 정보를 제공해야 합니다. 여기에는 VPC ID, VPC 서브넷 ID 및 VPC 보안 그룹 ID가 포함됩니다. 그러면 VPC 활성화 빌드가 VPC 내부의 리소스에 액세스할 수 있습니다. Amazon VPC의 VPC 설정에 대한 자세한 내용은 [Amazon VPC 사용 설명서](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Introduction.html)를 참조하세요.

**Topics**
+ [사용 사례](#use-cases)
+ [VPC 모범 사례](#best-practices-for-vpcs)
+ [VPC의 제한 사항](#vpc-limitations)
+ [CodeBuild 프로젝트에서 Amazon VPC 액세스 허용](enabling-vpc-access-in-projects.md)
+ [VPC 설정 문제 해결](troubleshooting-vpc.md)
+ [VPC 엔드포인트 사용](use-vpc-endpoints-with-codebuild.md)
+ [관리형 프록시 서버와 AWS CodeBuild 함께 사용](run-codebuild-in-managed-proxy-server.md)
+ [프록시 서버와 AWS CodeBuild 함께 사용](use-proxy-server.md)
+ [CloudFormation VPC 템플릿](cloudformation-vpc-template.md)

## 사용 사례
<a name="use-cases"></a>

 AWS CodeBuild 빌드의 VPC 연결을 통해 다음을 수행할 수 있습니다.
+ 프라이빗 서브넷에서 격리된 Amazon RDS 데이터베이스의 데이터에 대해 빌드에서 통합 테스트를 실행합니다.
+ 테스트에서 Amazon ElastiCache 클러스터의 데이터를 직접 쿼리합니다.
+ Amazon EC2, Amazon ECS에서 호스팅되는 내부 웹 서비스 또는 내부 Elastic Load Balancing을 사용하는 서비스와 상호 작용합니다.
+ Python용 PyPI, Java용 Maven 및 Node.js용 npm과 같은 자체 호스팅된 내부 결과물 리포지토리의 종속성을 검색합니다.
+ Amazon VPC 엔드포인트를 통해서만 액세스할 수 있도록 구성된 S3 버킷의 객체에 액세스합니다.
+ 서브넷과 연결된 NAT 게이트웨이 또는 NAT 인스턴스의 탄력적 IP 주소를 통해 고정 IP 주소가 필요한 외부 웹 서비스를 쿼리합니다.

빌드는 VPC에서 호스팅되는 모든 리소스에 액세스할 수 있습니다.

## VPC 모범 사례
<a name="best-practices-for-vpcs"></a>

CodeBuild에서 작동하도록 VPC를 설정할 때 이 체크리스트를 사용합니다.
+ 퍼블릭 및 프라이빗 서브넷과 NAT 게이트웨이가 있는 VPC를 설정합니다. NAT 게이트웨이는 퍼블릭 서브넷에 상주해야 합니다. 자세한 내용은 Amazon VPC 사용 설명서의 [퍼블릭 및 프라이빗 서브넷이 있는 VPC(NAT)](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Scenario2.html)를 참조하세요.**
**중요**  
CodeBuild와 VPC를 함께 사용하여 CodeBuild가 퍼블릭 엔드포인트에 도달할 수 있게 하려면 NAT 게이트웨이 또는 NAT 인스턴스가 필요합니다(예: 빌드 실행 중 CLI 명령을 실행하는 경우). CodeBuild는 생성하는 네트워크 인터페이스에 탄력적 IP 주소를 할당하는 것을 지원하지 않기 때문에 NAT 게이트웨이 또는 NAT 인스턴스 대신 인터넷 게이트웨이를 사용할 수 없습니다. 또한 Amazon EC2 인스턴스를 시작하지 않고 생성된 네트워크 인터페이스의 경우 Amazon EC2는 퍼블릭 IP 주소 자동 할당을 지원하지 않습니다.
+ VPC에 여러 가용 영역을 포함합니다.
+ 보안 그룹에 빌드에 허용된 인바운드(수신) 트래픽이 없는지 확인합니다. CodeBuild에는 아웃바운드 트래픽에 대한 특정 요구 사항이 없지만 GitHub 또는 Amazon S3와 같이 빌드에 필요한 모든 인터넷 리소스에 대한 액세스를 허용해야 합니다.

  자세한 내용은 Amazon VPC 사용 설명서의 [보안 그룹 규칙](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html#SecurityGroupRules)을 참조하세요.**
+ 빌드에 대해 별도의 서브넷을 설정합니다.
+ VPC에 액세스하기 위해 CodeBuild 프로젝트를 설정할 때 프라이빗 서브넷만 포함합니다.

Amazon VPC의 VPC 설정에 대한 자세한 내용은 [Amazon VPC 사용 설명서](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Introduction.html)를 참조하세요.

 CloudFormation 를 사용하여 CodeBuild VPC 기능을 사용하도록 VPC를 구성하는 방법에 대한 자세한 내용은 섹션을 참조하세요[CloudFormation VPC 템플릿](cloudformation-vpc-template.md).

## VPC의 제한 사항
<a name="vpc-limitations"></a>
+ CodeBuild에서 VPC로의 연결은 공유 VPC에 대해 지원되지 않습니다.

# CodeBuild 프로젝트에서 Amazon VPC 액세스 허용
<a name="enabling-vpc-access-in-projects"></a>

VPC 구성에 다음 설정을 포함합니다.
+ **VPC ID**에서 CodeBuild가 사용하는 VPC ID를 선택합니다.
+ **서브넷**에서 CodeBuild가 사용하는 리소스를 포함하거나 해당 리소스에 라우팅되는 NAT 변환을 통해 프라이빗 서브넷을 선택합니다.
+ **보안 그룹**에서 CodeBuild가 VPC의 리소스에 대한 액세스를 허용하기 위해 사용하는 보안 그룹을 선택합니다.



콘솔을 사용하여 빌드 프로젝트를 생성하려면 [빌드 프로젝트 만들기(콘솔)](create-project.md#create-project-console) 단원을 참조하십시오. CodeBuild 프로젝트를 생성하거나 변경할 때 **VPC**에서 VPC ID, 서브넷 및 보안 그룹을 선택합니다.



 AWS CLI 를 사용하여 빌드 프로젝트를 생성하려면 섹션을 참조하세요[빌드 프로젝트 생성(AWS CLI)](create-project.md#create-project-cli). CodeBuild와 AWS CLI 함께를 사용하는 경우 CodeBuild가 IAM 사용자를 대신하여 서비스와 상호 작용하는 데 사용하는 서비스 역할에 정책이 연결되어 있어야 합니다. 자세한 내용은 [VPC 네트워크 인터페이스를 생성하는 데 필요한 AWS 서비스에 대한 CodeBuild 액세스 허용](auth-and-access-control-iam-identity-based-access-control.md#customer-managed-policies-example-create-vpc-network-interface) 단원을 참조하세요.

*vpcConfig* 객체는 *vpcId*, *securityGroupIds* 및 *subnets*을 포함해야 합니다.
+ *vpcId*: 필수 항목입니다. CodeBuild가 사용하는 VPC ID입니다. 리전의 모든 Amazon VPC ID 목록을 가져오려면 다음 명령을 실행합니다.

  ```
  aws ec2 describe-vpcs
  ```
+ *subnets*: 필수 항목입니다. CodeBuild가 사용하는 리소스가 포함된 서브넷 ID입니다. 이 ID를 얻으려면 다음 명령을 실행합니다.

  ```
  aws ec2 describe-subnets --filters "Name=vpc-id,Values=<vpc-id>" --region us-east-1
  ```
**참고**  
`us-east-1`을 해당 리전으로 바꿉니다.
+ *securityGroupIds*: 필수 항목입니다. CodeBuild가 VPC의 리소스에 대한 액세스를 허용하기 위해 사용하는 보안 그룹 ID입니다. 이 ID를 얻으려면 다음 명령을 실행합니다.

  ```
  aws ec2 describe-security-groups --filters "Name=vpc-id,Values=<vpc-id>" --region us-east-1
  ```
**참고**  
`us-east-1`을 해당 리전으로 바꿉니다.

# VPC 설정 문제 해결
<a name="troubleshooting-vpc"></a>

오류 메시지에 표시되는 정보를 사용하면 해당 문제를 식별, 진단 및 해결하는 데 도움이 됩니다.

다음은 일반적인 CodeBuild VPC 오류인 `Build does not have internet connectivity. Please check subnet network configuration`의 문제를 해결할 때 도움이 되는 몇 가지 지침입니다.

1. [인터넷 게이트웨이가 VPC에 연결되어 있는지 확인합니다](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html#Add_IGW_Attach_Gateway).

1. [퍼블릭 서브넷의 라우팅 테이블이 인터넷 게이트웨이를 가리키는지 확인합니다](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Route_Tables.html#route-tables-internet-gateway).

1. [네트워크 ACL이 트래픽의 흐름을 허용하는지 확인합니다](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html#SecurityGroupRules).

1. [보안 그룹이 트래픽의 흐름을 허용하는지 확인합니다](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html#SecurityGroupRules).

1. [NAT 게이트웨이 문제를 해결합니다](https://docs.aws.amazon.com/vpc/latest/userguide/VPC-nat-gateway.html#nat-gateway-troubleshooting).

1. [프라이빗 서브넷의 라우팅 테이블이 NAT 게이트웨이를 가리키는지 확인합니다](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Route_Tables.html#route-tables-nat).

1. CodeBuild가 IAM 사용자를 대신하여 서비스와 상호 작용할 때 사용하는 서비스 역할이 [이 정책](https://docs.aws.amazon.com/codebuild/latest/userguide/auth-and-access-control-iam-identity-based-access-control.html#customer-managed-policies-example-create-vpc-network-interface)의 권한을 가지고 있어야 합니다. 자세한 내용은 [CodeBuild가 다른 AWS 서비스와 상호 작용하도록 허용](setting-up-service-role.md) 단원을 참조하십시오.

   CodeBuild에 사용 권한이 없는 경우, `Unexpected EC2 error: UnauthorizedOperation` 오류가 표시될 수 있습니다. 이 오류는 VPC 작업에 필요한 Amazon EC2 권한이 CodeBuild에 없을 때 발생할 수 있습니다.

# VPC 엔드포인트 사용
<a name="use-vpc-endpoints-with-codebuild"></a>

인터페이스 VPC 엔드포인트를 사용하도록 AWS CodeBuild 를 구성하여 빌드의 보안을 개선할 수 있습니다. 인터페이스 엔드포인트는 프라이빗 IP 주소를 사용하여 Amazon EC2 및 CodeBuild에 비공개로 액세스할 수 있는 기술인 PrivateLink로 구동됩니다. PrivateLink는 관리형 인스턴스, CodeBuild 및 Amazon EC2 간의 모든 네트워크 트래픽을 Amazon 네트워크로 제한합니다. (관리형 인스턴스는 인터넷에 액세스할 수 없음) 또한 인터넷 게이트웨이, NAT 디바이스 또는 가상 프라이빗 게이트웨이가 필요 없습니다. PrivateLink를 구성하는 것이 필수는 아니지만 구성하는 것이 좋습니다. PrivateLink 및 VPC 엔드포인트에 대한 자세한 내용은 [란 무엇입니까 AWS PrivateLink?](https://docs.aws.amazon.com/vpc/latest/privatelink/what-is-privatelink.html)를 참조하세요.

## VPC 엔드포인트를 생성하기 전에
<a name="vpc-endpoints-before-you-begin"></a>

 에 대한 VPC 엔드포인트를 구성하기 전에 다음 제한 사항에 유의 AWS CodeBuild하세요.

**참고**  
 Amazon VPC PrivateLink 연결을 지원하지 않는 AWS 서비스와 함께 CodeBuild를 사용하려면 [NAT 게이트웨이](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_NAT_Instance.html)를 사용합니다.
+  VPC 엔드포인트는 Amazon Route 53을 통해 Amazon이 제공하는 DNS만 지원합니다. 자체 DNS를 사용하는 경우에는 조건부 DNS 전달을 사용할 수 있습니다. 자세한 정보는 *Amazon VPC 사용 설명서*의 [DHCP 옵션 세트](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_DHCP_Options.html)를 참조하세요.
+  VPC 엔드포인트는 교차 리전 요청을 현재 지원하지 않습니다. 빌드 입력 및 출력을 저장하는 모든 S3 버킷과 동일한 AWS 리전에서 엔드포인트를 생성해야 합니다. Amazon S3 콘솔 또는 [get-bucket-location](https://docs.aws.amazon.com/cli/latest/reference/s3api/get-bucket-location.html) 명령을 사용하여 버킷 위치를 찾을 수 있습니다. 리전별 Amazon S3 엔드포인트를 사용하여 버킷에 액세스하세요(예: `<bucket-name>.s3-us-west-2.amazonaws.com`). Amazon S3의 리전별 엔드포인트에 대한 자세한 내용은 *Amazon Web Services 일반 참조*의 [Amazon Simple Storage Service](https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region)를 참조하세요. AWS CLI 를 사용하여 Amazon S3에 요청하는 경우 기본 리전을 버킷이 생성된 리전과 동일한 리전으로 설정하거나 요청에 `--region` 파라미터를 사용합니다.

## CodeBuild용 VPC 엔드포인트 생성
<a name="creating-vpc-endpoints"></a>

[인터페이스 엔드포인트 생성](https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html#create-interface-endpoint)의 지침에 따라 엔드포인트 `com.amazonaws.region.codebuild`를 만듭니다. 이는에 대한 VPC 엔드포인트입니다 AWS CodeBuild.

![\[VPC 엔드포인트 서비스 구성.\]](http://docs.aws.amazon.com/ko_kr/codebuild/latest/userguide/images/vpc-endpoint.png)


 *region*은 미국 동부(오하이오) AWS 리전과 같이 CodeBuild에서 지원하는 리전`us-east-2`의 리전 식별자를 나타냅니다. 지원되는 AWS 리전 목록은 * AWS 일반* 참조의 [CodeBuild](https://docs.aws.amazon.com/general/latest/gr/rande.html#codebuild_region)를 참조하세요. 엔드포인트는 로그인 시 지정한 리전으로 미리 채워집니다 AWS. 리전을 변경하면 그에 따라 VPC 엔드포인트가 업데이트됩니다.

## CodeBuild에 대한 VPC 엔드포인트 정책 생성
<a name="creating-vpc-endpoint-policy"></a>

 다음을 지정할 수 있는 Amazon VPC 엔드포인트 AWS CodeBuild 에 대한 정책을 생성할 수 있습니다.
+ 작업을 수행할 수 있는 위탁자.
+ 수행할 수 있는 작업.
+ 작업을 수행할 수 있는 리소스.

다음 예제 정책은 모든 보안 주체가 `project-name` 프로젝트에 대한 빌드를 시작하고 볼 수만 있도록 지정합니다.

```
{
    "Statement": [
        {
            "Action": [
                "codebuild:ListBuildsForProject",
                "codebuild:StartBuild",
                "codebuild:BatchGetBuilds"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:codebuild:region-ID:account-ID:project/project-name",
            "Principal": "*"
        }
    ]
}
```

 자세한 내용은 *Amazon VPC 사용 설명서*의 [VPC 엔드포인트를 통해 서비스에 대한 액세스 제어](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-endpoints-access.html)를 참조하세요.

# 관리형 프록시 서버와 AWS CodeBuild 함께 사용
<a name="run-codebuild-in-managed-proxy-server"></a>

 관리형 프록시 서버에서 AWS CodeBuild 예약 용량 플릿을 실행하려면 프록시 규칙을 사용하여 외부 사이트와의 트래픽을 허용하거나 거부하도록 프록시 서버를 구성해야 합니다. 관리형 프록시 서버에서 예약 용량 플릿을 실행하는 것은 VPC, Windows 또는 MacOS에서 지원되지 않습니다.

**중요**  
프록시 구성이 플릿에 존재하는 기간에 따라 추가 비용이 발생합니다. 자세한 내용은 [https://aws.amazon.com/codebuild/pricing/](https://aws.amazon.com/codebuild/pricing/) 참조하십시오.

**Topics**
+ [예약 용량 플릿에 대한 관리형 프록시 구성](#run-codebuild-in-managed-proxy-server-configure)
+ [CodeBuild 예약 용량 플릿 실행](#use-managed-server-run-acb-fleet)

## 예약 용량 플릿에 대한 관리형 프록시 구성
<a name="run-codebuild-in-managed-proxy-server-configure"></a>

 예약 용량 플릿에 대해 관리형 프록시 서버를 구성하려면 콘솔에서 플릿을 생성하거나 AWS CLI를 사용할 때 이 기능을 활성화해야 합니다. 정의해야 할 몇 가지 속성이 있습니다.

**프록시 구성 정의 - 선택 사항**  
예약 용량 인스턴스에 네트워크 액세스 제어를 적용하는 프록시 구성입니다.

**기본 동작**  
발신 트래픽의 동작을 정의합니다.    
**허용**  
기본적으로 모든 대상으로 전송되는 트래픽을 허용합니다.  
**거부**  
기본적으로 모든 대상으로 전송되는 트래픽을 거부합니다.

**프록시 규칙**  
네트워크 액세스 제어를 제한할 대상 도메인을 지정합니다.

콘솔에서 프록시 구성을 정의하려면 [예약 용량 플릿 생성](fleets.md#fleets.how-to)의 지침을 참조하세요. 를 사용하여 프록시 구성을 정의하려면 다음 JSON 구문을 수정하고 결과를 저장 AWS CLI하면 됩니다.

```
"proxyConfiguration": {
    "defaultBehavior": "ALLOW_ALL" | "DENY_ALL",
    "orderedProxyRules": [
        {
            "type": "DOMAIN" | "IP",
            "effect": "ALLOW" | "DENY",
            "entities": [
                "destination"
            ]
        }
    ]
}
```

JSON 파일은 다음과 비슷합니다.

```
"proxyConfiguration": {
    "defaultBehavior": "DENY_ALL",
    "orderedProxyRules": [
        {
            "type": "DOMAIN",
            "effect": "ALLOW",
            "entities": [
                "github.com"
            ]
        }
    ]
}
```

## CodeBuild 예약 용량 플릿 실행
<a name="use-managed-server-run-acb-fleet"></a>

 관리형 프록시 서버에서 AWS CodeBuild 예약 용량 플릿을 실행할 때 CodeBuild는 관리형 프록시 주소로 `HTTP_PROXY` 및 `HTTPS_PROXY` 환경 변수를 자동으로 설정합니다. 종속 항목 소프트웨어에 자체 구성이 있고 환경 변수를 준수하지 않는 경우 이러한 값을 참조하고 빌드 명령에서 소프트웨어 구성을 업데이트하여 관리형 프록시를 통해 빌드 트래픽을 올바르게 라우팅할 수 있습니다. 자세한 내용은 [에서 빌드 프로젝트 생성AWS CodeBuild](create-project.md) 및 [에서 빌드 프로젝트 설정 변경 AWS CodeBuild](change-project.md) 섹션을 참조하세요.

# 프록시 서버와 AWS CodeBuild 함께 사용
<a name="use-proxy-server"></a>

 프록시 서버와 AWS CodeBuild 함께를 사용하여 인터넷과 주고받는 HTTP 및 HTTPS 트래픽을 규제할 수 있습니다. 프록시 서버에서 CodeBuild를 실행하려면 VPC에서 퍼블릭 서브넷에 프록시 서버를 설치하고 가상 서브넷에 CodeBuild를 설치합니다.

프록시 서버에서 CodeBuild를 실행하는 주요 사용 사례는 두 가지입니다.
+  VPC에서 NAT 게이트웨이 또는 NAT 인스턴스를 사용할 필요가 없어집니다.
+  프록시 서버 내 인스턴스가 액세스할 수 있는 URL을 지정하고 프록시 서버가 액세스를 거부하는 URL을 지정할 수 있습니다.

 CodeBuild를 두 가지 유형의 프록시 서버에 사용할 수 있습니다. 두 유형 모두, 프록시 서버는 퍼블릭 서브넷에서 실행되고 CodeBuild는 프라이빗 서브넷에서 실행됩니다.
+  **명시적 프록시**: 명시적 프록시 서버를 사용하는 경우 프로젝트 수준에서 CodeBuild에 `NO_PROXY`, `HTTP_PROXY` 및 `HTTPS_PROXY` 환경 변수를 구성해야 합니다. 자세한 내용은 [에서 빌드 프로젝트 설정 변경 AWS CodeBuild](change-project.md) 및 [에서 빌드 프로젝트 생성AWS CodeBuild](create-project.md) 섹션을 참조하세요.
+  **투명 프록시**: 투명 프록시 서버를 사용하는 경우 특별한 구성이 필요하지 않습니다.

**Topics**
+ [프록시 서버에서 CodeBuild를 실행하기 위해 필요한 구성 요소 설정](use-proxy-server-transparent-components.md)
+ [명시적 프록시 서버에서 CodeBuild 실행](run-codebuild-in-explicit-proxy-server.md)
+ [투명 프록시 서버에서 CodeBuild 실행](run-codebuild-in-transparent-proxy-server.md)
+ [프록시 서버에서 패키지 관리자 및 기타 도구 실행](use-proxy-server-tools.md)

# 프록시 서버에서 CodeBuild를 실행하기 위해 필요한 구성 요소 설정
<a name="use-proxy-server-transparent-components"></a>

 투명 또는 명시적 프록시 서버에서 실행하려면 다음 구성 요소가 필요합니다 AWS CodeBuild .
+  VPC 
+  프록시 서버용 VPC에 퍼블릭 서브넷 1개.
+  CodeBuild용 VPC에 프라이빗 서브넷 1개.
+  VPC와 인터넷 간 통신을 허용하는 인터넷 게이트웨이.

 다음 다이어그램은 구성 요소가 상호 작용하는 방식을 보여 줍니다.

![\[다이어그램에서 구성 요소가 상호 작용하는 방식을 보여 줍니다.\]](http://docs.aws.amazon.com/ko_kr/codebuild/latest/userguide/images/codebuild-proxy-transparent.png)


## VPC, 서브넷 및 네트워크 게이트웨이 설정
<a name="use-proxy-server-transparent-setup"></a>

 투명 또는 명시적 프록시 서버에서 AWS CodeBuild 를 실행하려면 다음 단계가 필요합니다.

1. VPC를 생성합니다. 자세한 내용은 Amazon VPC 사용 설명서의 [VPC 생성](https://docs.aws.amazon.com/vpc/latest/userguide/working-with-vpcs.html#Create-VPC)을 참조하세요.**

1. VPC에서 서브넷 2개를 만듭니다. 하나는 프록시 서버가 실행되는 `Public Subnet`이라는 퍼블릭 서브넷입니다. 다른 하나는 CodeBuild가 실행되는 `Private Subnet`이라는 프라이빗 서브넷입니다.

   자세한 내용은 [VPC에서 서브넷 만들기](https://docs.aws.amazon.com/vpc/latest/userguide/working-with-vpcs.html#AddaSubnet) 단원을 참조하십시오.

1.  인터넷 게이트웨이를 생성하여 VPC에 연결합니다. 자세한 내용은 [인터넷 게이트웨이 생성 및 연결](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html#Add_IGW_Attach_Gateway)을 참조하세요.

1.  기본 라우팅 테이블에 VPC(0.0.0.0/0)에서 인터넷 게이트웨이로 가는 트래픽을 라우팅하는 규칙을 추가합니다. 자세한 내용은 [라우팅 테이블에 경로 추가 및 라우팅 테이블에서 경로 제거](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Route_Tables.html#AddRemoveRoutes) 단원을 참조하십시오.

1.  VPC의 기본 보안 그룹에 VPC(0.0.0.0/0)로부터 들어오는 SSH 트래픽(TCP 22)을 허용하는 규칙을 추가합니다.

1.  Amazon EC2 인스턴스를 시작하려면 Amazon EC2 사용 설명서에서 [인스턴스 시작 마법사를 사용하여 인스턴스 시작](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/launching-instance.html)의 지침을 따르세요.** 마법사를 실행할 때 다음 옵션을 선택합니다.
   +  **인스턴스 유형 선택**에서 Amazon Linux Amazon Machine Image(AMI)를 선택합니다.
   +  **서브넷**에서 이 주제의 앞부분에서 만든 퍼블릭 서브넷을 선택합니다. 제안된 이름을 사용했다면 **퍼블릭 서브넷**입니다.
   +  [**Auto-assign Public IP**]에서 [**Enable**]을 선택합니다.
   +  **보안 그룹 구성** 페이지의 **보안 그룹 할당**에서 **Select an existing security group(기존 보안 그룹 선택)**을 선택합니다. 그런 다음 기본 보안 그룹을 선택합니다.
   +  **시작**을 선택한 후 기존 키 페어를 하나 선택하거나 생성합니다.

    다른 옵션은 모두 기본 설정을 선택합니다.

1.  EC2 인스턴스가 실행되면 원본/대상 확인을 비활성화합니다. 자세한 내용은 Amazon VPC 사용 설명서의 [소스/대상 확인 비활성화](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_NAT_Instance.html#EIP_Disable_SrcDestCheck)를 참조하세요.**

1.  VPC에서 라우팅 테이블을 만듭니다. 라우팅 테이블에 인터넷으로 향하는 트래픽을 프록시 서버로 라우팅하는 규칙을 추가합니다. 이 라우팅 테이블을 프라이빗 서브넷과 연결합니다. 이 단계는 CodeBuild가 실행되는 프라이빗 서브넷 내 인스턴스의 아웃바운드 요청이 항상 프록시 서버를 통해 라우팅되도록 하는 데 필요합니다.

## 프록시 서버 설치 및 구성
<a name="use-proxy-server-squid-install"></a>

 선택할 수 있는 프록시 서버는 많습니다. 오픈 소스 프록시 서버인 Squid는가 프록시 서버에서 어떻게 AWS CodeBuild 실행되는지 보여주는 데 사용됩니다. 동일한 개념을 다른 프록시 서버에도 적용할 수 있습니다.

 Squid를 설치하려면 다음 명령을 실행하여 yum repo를 사용합니다.

```
sudo yum update -y
sudo yum install -y squid
```

 Squid를 설치한 후 이 주제의 뒷부분에 나오는 지침에 따라 `squid.conf` 파일을 편집합니다.

## HTTPS 트래픽에 대해 Squid 구성
<a name="use-proxy-server-squid-configure-https"></a>

 HTTPS의 경우, TLS(전송 계층 보안) 연결에서 HTTP 트래픽이 캡슐화된 것입니다. Squid는 [SslPeekAndSplice](https://wiki.squid-cache.org/Features/SslPeekAndSplice)라는 기능을 사용하여 TLS 초기화에서 요청된 인터넷 호스트를 포함하는 SNI(서버 이름 표시)를 검색합니다. 이는 Squid가 HTTPS 트래픽을 해독할 필요가 없도록 하기 위해 필요합니다. SslPeekAndSplice를 활성화하려면 Squid가 인증서를 요구합니다. OpenSSL을 사용하여 이 인증서를 만듭니다.

```
sudo mkdir /etc/squid/ssl
cd /etc/squid/ssl
sudo openssl genrsa -out squid.key 2048
sudo openssl req -new -key squid.key -out squid.csr -subj "/C=XX/ST=XX/L=squid/O=squid/CN=squid"
sudo openssl x509 -req -days 3650 -in squid.csr -signkey squid.key -out squid.crt
sudo cat squid.key squid.crt | sudo tee squid.pem
```

**참고**  
 HTTP의 경우, Squid를 구성할 필요가 없습니다. 모든 HTTP/1.1 요청 메시지에서 요청되는 인터넷 호스를 지정하는 호스트 헤더 필드를 검색할 수 있습니다.

# 명시적 프록시 서버에서 CodeBuild 실행
<a name="run-codebuild-in-explicit-proxy-server"></a>

 명시적 프록시 서버에서 AWS CodeBuild 를 실행하려면 외부 사이트와의 트래픽을 허용하거나 거부하도록 프록시 서버를 구성한 다음 `HTTP_PROXY` 및 `HTTPS_PROXY` 환경 변수를 구성해야 합니다.

**Topics**
+ [Squid를 명시적 프록시 서버로 구성](#use-proxy-server-explicit-squid-configure)
+ [CodeBuild 프로젝트 생성](#use-proxy-server-explicit-create-acb-project)
+ [명시적 프록시 서버 샘플 `squid.conf` 파일](#use-proxy-server-explicit-sample-squid-conf)

## Squid를 명시적 프록시 서버로 구성
<a name="use-proxy-server-explicit-squid-configure"></a>

 Squid를 명시적 프록시 서버로 구성하려면 다음과 같이 `/etc/squid/squid.conf` 파일을 수정해야 합니다.
+  다음 기본 ACL(액세스 제어 목록) 규칙을 제거합니다.

  ```
  acl localnet src 10.0.0.0/8     
  acl localnet src 172.16.0.0/12  
  acl localnet src 192.168.0.0/16 
  acl localnet src fc00::/7       
  acl localnet src fe80::/10
  ```

   제거한 기본 ACL 규칙 대신 다음 규칙을 추가합니다. 첫 번째 줄은 VPC의 요청을 허용합니다. 다음 두 줄은 프록시 서버에 AWS CodeBuild가 사용할 수 있는 대상 URL에 대한 액세스 권한을 부여합니다. 마지막 줄에서 정규식을 편집하여 AWS 리전에서 S3 버킷 또는 CodeCommit 리포지토리를 지정합니다. 예제:
  + 소스가 Amazon S3일 경우 **acl download\$1src dstdom\$1regex .\$1s3\$1.us-west-1\$1.amazonaws\$1.com** 명령을 사용하여 `us-west-1` 리전 내 S3 버킷에 대한 액세스 권한을 부여합니다.
  +  소스가 인 경우 AWS CodeCommit`git-codecommit.<your-region>.amazonaws.com`를 사용하여 허용 목록에 AWS 리전을 추가합니다.

  ```
  acl localnet src 10.1.0.0/16 #Only allow requests from within the VPC
  acl allowed_sites dstdomain .github.com #Allows to download source from GitHub
  acl allowed_sites dstdomain .bitbucket.com #Allows to download source from Bitbucket
  acl download_src dstdom_regex .*\.amazonaws\.com #Allows to download source from Amazon S3 or CodeCommit
  ```
+  `http_access allow localnet`을 다음으로 바꿉니다.

  ```
  http_access allow localnet allowed_sites
  http_access allow localnet download_src
  ```
+ 빌드가 로그 및 아티팩트를 업로드하도록 하려면 다음 중 하나를 수행하십시오.

  1. `http_access deny all` 문 앞에 다음 문을 삽입합니다. 이를 통해 CodeBuild는 CloudWatch와 Amazon S3에 액세스할 수 있습니다. CodeBuild에서 CloudWatch Logs를 생성하려면 CloudWatch에 대한 액세스 권한이 필요합니다. Amazon S3에 대한 액세스는 아티팩트 및 Amazon S3 캐싱을 업로드하기 위해 필요합니다.
     + 

       ```
       https_port 3130 cert=/etc/squid/ssl/squid.pem ssl-bump intercept
       acl SSL_port port 443
       http_access allow SSL_port
       acl allowed_https_sites ssl::server_name .amazonaws.com
       acl step1 at_step SslBump1
       acl step2 at_step SslBump2
       acl step3 at_step SslBump3
       ssl_bump peek step1 all
       ssl_bump peek step2 allowed_https_sites
       ssl_bump splice step3 allowed_https_sites
       ssl_bump terminate step2 all
       ```
     + `squid.conf`를 저장한 후 다음 명령을 실행합니다.

       ```
       sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 3130
       sudo service squid restart
       ```

  1.  buildspec 파일에 `proxy`를 추가합니다. 자세한 내용은 [buildspec 구문](build-spec-ref.md#build-spec-ref-syntax) 단원을 참조하십시오.

     ```
     version: 0.2
     proxy:
       upload-artifacts: yes
       logs: yes
     phases:
       build:
         commands:
           - command
     ```

**참고**  
RequestError 시간 초과 오류가 발생할 경우 [프록시 서버에서 CodeBuild를 실행할 때 RequestError 시간 초과 오류](troubleshooting.md#code-request-timeout-error) 단원을 참조하십시오.

자세한 내용은 본 주제의 후반부에서 [명시적 프록시 서버 샘플 `squid.conf` 파일](#use-proxy-server-explicit-sample-squid-conf)을 참조하세요.

## CodeBuild 프로젝트 생성
<a name="use-proxy-server-explicit-create-acb-project"></a>

 명시적 프록시 서버 AWS CodeBuild 로를 실행하려면 프로젝트 수준에서 프록시 서버 및 포트 3128에 대해 생성한 EC2 인스턴스의 프라이빗 IP 주소로 `HTTP_PROXY` 및 `HTTPS_PROXY` 환경 변수를 설정합니다. 프라이빗 IP 주소는 `http://your-ec2-private-ip-address:3128`과 비슷합니다. 자세한 내용은 [에서 빌드 프로젝트 생성AWS CodeBuild](create-project.md) 및 [에서 빌드 프로젝트 설정 변경 AWS CodeBuild](change-project.md) 섹션을 참조하세요.

 다음 명령을 사용하여 Squid 프록시 액세스 로그를 확인합니다.

```
sudo tail -f /var/log/squid/access.log
```

## 명시적 프록시 서버 샘플 `squid.conf` 파일
<a name="use-proxy-server-explicit-sample-squid-conf"></a>

 다음은 명시적 프록시 서버용으로 구성된 `squid.conf` 파일의 예입니다.

```
  acl localnet src 10.0.0.0/16 #Only allow requests from within the VPC
  # add all URLS to be whitelisted for download source and commands to be run in build environment
  acl allowed_sites dstdomain .github.com    #Allows to download source from github
  acl allowed_sites dstdomain .bitbucket.com #Allows to download source from bitbucket
  acl allowed_sites dstdomain ppa.launchpad.net #Allows to run apt-get in build environment
  acl download_src dstdom_regex .*\.amazonaws\.com #Allows to download source from S3 or CodeCommit
  acl SSL_ports port 443
  acl Safe_ports port 80		# http
  acl Safe_ports port 21		# ftp
  acl Safe_ports port 443		# https
  acl Safe_ports port 70		# gopher
  acl Safe_ports port 210		# wais
  acl Safe_ports port 1025-65535	# unregistered ports
  acl Safe_ports port 280		# http-mgmt
  acl Safe_ports port 488		# gss-http
  acl Safe_ports port 591		# filemaker
  acl Safe_ports port 777		# multiling http
  acl CONNECT method CONNECT
  #
  # Recommended minimum Access Permission configuration:
  #
  # Deny requests to certain unsafe ports
  http_access deny !Safe_ports
  # Deny CONNECT to other than secure SSL ports
  http_access deny CONNECT !SSL_ports
  # Only allow cachemgr access from localhost
  http_access allow localhost manager
  http_access deny manager
  # We strongly recommend the following be uncommented to protect innocent
  # web applications running on the proxy server who think the only
  # one who can access services on "localhost" is a local user
  #http_access deny to_localhost
  #
  # INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
  #
  # Example rule allowing access from your local networks.
  # Adapt localnet in the ACL section to list your (internal) IP networks
  # from where browsing should be allowed
  http_access allow localnet allowed_sites
  http_access allow localnet download_src
  http_access allow localhost
  # Add this for CodeBuild to access CWL end point, caching and upload artifacts S3 bucket end point
  https_port 3130 cert=/etc/squid/ssl/squid.pem ssl-bump intercept
  acl SSL_port port 443
  http_access allow SSL_port
  acl allowed_https_sites ssl::server_name .amazonaws.com
  acl step1 at_step SslBump1
  acl step2 at_step SslBump2
  acl step3 at_step SslBump3
  ssl_bump peek step1 all
  ssl_bump peek step2 allowed_https_sites
  ssl_bump splice step3 allowed_https_sites
  ssl_bump terminate step2 all
  # And finally deny all other access to this proxy
  http_access deny all
  # Squid normally listens to port 3128
  http_port 3128
  # Uncomment and adjust the following to add a disk cache directory.
  #cache_dir ufs /var/spool/squid 100 16 256
  # Leave coredumps in the first cache dir
  coredump_dir /var/spool/squid
  #
  # Add any of your own refresh_pattern entries above these.
  #
  refresh_pattern ^ftp:		1440	20%	10080
  refresh_pattern ^gopher:	1440	0%	1440
  refresh_pattern -i (/cgi-bin/|\?) 0	0%	0
  refresh_pattern .		0	20%	4320
```

# 투명 프록시 서버에서 CodeBuild 실행
<a name="run-codebuild-in-transparent-proxy-server"></a>

 투명한 프록시 서버에서 AWS CodeBuild 를 실행하려면 상호 작용하는 웹 사이트 및 도메인에 액세스할 수 있도록 프록시 서버를 구성해야 합니다.

**Topics**
+ [Squid를 투명 프록시 서버로 구성](#use-proxy-server-transparent-squid-configure)
+ [CodeBuild 프로젝트 생성](#use-proxy-server-transparent-create-acb-project)

## Squid를 투명 프록시 서버로 구성
<a name="use-proxy-server-transparent-squid-configure"></a>

 프록시 서버를 투명으로 구성하려면 액세스하려는 도메인 및 웹 사이트에 대한 액세스 권한을 부여해야 합니다. 투명한 프록시 서버 AWS CodeBuild 로를 실행하려면에 대한 액세스 권한을 부여해야 합니다`amazonaws.com`. 또한 CodeBuild가 사용하는 다른 웹 사이트에 대해서도 액세스 권한을 부여해야 합니다. 이러한 웹 사이트는 CodeBuild 프로젝트를 생성하는 방식에 따라 달라집니다. 예를 들어 GitHub, Bitbucket, Yum, Maven 같은 리포지토리용 웹 사이트입니다. Squid에 특정 도메인 및 웹 사이트에 대한 액세스 권한을 부여하려면 다음과 같은 명령을 사용하여 `squid.conf` 파일을 업데이트합니다. 이 샘플 명령은 `amazonaws.com`, `github.com` 및 `bitbucket.com`에 대한 액세스 권한을 부여합니다. 이 샘플을 편집하여 다른 웹 사이트에 대한 액세스 권한을 부여할 수 있습니다.

```
cat | sudo tee /etc/squid/squid.conf ≪EOF
visible_hostname squid
#Handling HTTP requests
http_port 3129 intercept
acl allowed_http_sites dstdomain .amazonaws.com
#acl allowed_http_sites dstdomain domain_name [uncomment this line to add another domain]
http_access allow allowed_http_sites
#Handling HTTPS requests
https_port 3130 cert=/etc/squid/ssl/squid.pem ssl-bump intercept
acl SSL_port port 443
http_access allow SSL_port
acl allowed_https_sites ssl::server_name .amazonaws.com
acl allowed_https_sites ssl::server_name .github.com
acl allowed_https_sites ssl::server_name .bitbucket.com
#acl allowed_https_sites ssl::server_name [uncomment this line to add another website]
acl step1 at_step SslBump1
acl step2 at_step SslBump2
acl step3 at_step SslBump3
ssl_bump peek step1 all
ssl_bump peek step2 allowed_https_sites
ssl_bump splice step3 allowed_https_sites
ssl_bump terminate step2 all
http_access deny all
EOF
```

 프라이빗 서브넷에 있는 인스턴스에서 오는 수신 요청은 Squid 포트로 리디렉션해야 합니다. Squid는 HTTP 트래픽의 경우 포트 3129(80이 아님)에서 수신 대기하고, HTTPS 트래픽의 경우 포트 3130(443이 아님)에서 수신 대기합니다. **iptables** 명령을 사용하여 트래픽을 라우팅합니다.

```
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3129
sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 3130
sudo service iptables save
sudo service squid start
```

## CodeBuild 프로젝트 생성
<a name="use-proxy-server-transparent-create-acb-project"></a>

 프록시 서버를 구성한 후에는 추가 구성 없이 프라이빗 서브넷 AWS CodeBuild 에서와 함께 사용할 수 있습니다. 모든 HTTP 및 HTTPS 요청이 퍼블릭 프록시 서버를 통과합니다. 다음 명령을 사용하여 Squid 프록시 액세스 로그를 확인합니다.

```
sudo tail -f /var/log/squid/access.log
```

# 프록시 서버에서 패키지 관리자 및 기타 도구 실행
<a name="use-proxy-server-tools"></a>

다음 절차에 따라 프록시 서버에서 패키지 관리자 및 기타 도구를 실행합니다.

**프록시 서버에서 패키지 관리자와 같은 도구를 실행하려면**

1.  `squid.conf` 파일에 문을 추가하여 프록시 서버의 허용 목록에 도구를 추가합니다.

1.  프록시 서버의 프라이빗 엔드포인트를 가리키는 줄을 buildspec 파일에 추가합니다.

 다음 예제는 `apt-get`, `curl` 및 `maven`에서 이렇게 하는 방법을 보여줍니다. 다른 도구를 사용하는 경우에도 동일한 원칙이 적용됩니다. CodeBuild가 프록시 서버의 엔드포인트를 인식하도록 `squid.conf` 파일의 허용 목록에 추가하고 buildspec 파일에 명령을 추가합니다.

**프록시 서버에서 `apt-get`을 실행하려면**

1. `squid.conf` 파일에 다음 문을 추가하여 프록시 서버의 허용 목록에 `apt-get`을 추가합니다. 처음 세 줄은 빌드 환경에서 `apt-get`을 실행하도록 허용합니다.

   ```
   acl allowed_sites dstdomain ppa.launchpad.net # Required for apt-get to run in the build environment
   acl apt_get dstdom_regex .*\.launchpad.net # Required for CodeBuild to run apt-get in the build environment
   acl apt_get dstdom_regex .*\.ubuntu.com    # Required for CodeBuild to run apt-get in the build environment
   http_access allow localnet allowed_sites
   http_access allow localnet apt_get
   ```

1. `apt-get` 명령이 `/etc/apt/apt.conf.d/00proxy`에서 프록시 구성을 검색하도록 buildspec 파일에 다음 문을 추가합니다.

   ```
   echo 'Acquire::http::Proxy "http://<private-ip-of-proxy-server>:3128"; Acquire::https::Proxy "http://<private-ip-of-proxy-server>:3128"; Acquire::ftp::Proxy "http://<private-ip-of-proxy-server>:3128";' > /etc/apt/apt.conf.d/00proxy
   ```

**프록시 서버에서 `curl`을 실행하려면**

1.  `squid.conf` 파일에 다음을 추가하여 빌드 환경의 허용 목록에 `curl`을 추가합니다.

   ```
   acl allowed_sites dstdomain ppa.launchpad.net # Required to run apt-get in the build environment
   acl allowed_sites dstdomain google.com # Required for access to a webiste. This example uses www.google.com.
   http_access allow localnet allowed_sites
   http_access allow localnet apt_get
   ```

1.  `curl`이 프라이빗 프록시 서버를 사용하여 `squid.conf`에 추가한 웹 사이트에 액세스하도록 buildspec 파일에 다음 문을 추가합니다. 이 예제에서 웹 사이트는 `google.com`입니다.

   ```
   curl -x <private-ip-of-proxy-server>:3128 https://www.google.com
   ```

**프록시 서버에서 `maven`을 실행하려면**

1.  `squid.conf` 파일에 다음을 추가하여 빌드 환경의 허용 목록에 `maven`을 추가합니다.

   ```
   acl allowed_sites dstdomain ppa.launchpad.net # Required to run apt-get in the build environment
   acl maven dstdom_regex .*\.maven.org # Allows access to the maven repository in the build environment
   http_access allow localnet allowed_sites
   http_access allow localnet maven
   ```

1. buildspec 파일에 다음 문을 추가합니다.

   ```
   maven clean install -DproxySet=true -DproxyHost=<private-ip-of-proxy-server> -DproxyPort=3128
   ```

# CloudFormation VPC 템플릿
<a name="cloudformation-vpc-template"></a>

CloudFormation을 사용하면, 템플릿 파일을 사용하여 리소스 모음을 단일 유닛(*스택*)으로 함께 생성하고 삭제함으로써 AWS 인프라 배포를 예측 가능하고 반복적으로 생성하고 프로비저닝할 수 있습니다. 자세한 내용은 [CloudFormation 사용 설명서](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html)를 참조하세요.

다음은 VPC를 구성하여 CloudFormation를 사용하기 위한 AWS CodeBuild YAML 템플릿입니다. 이 파일은 [samples.zip](./samples/samples.zip)에서도 사용할 수 있습니다.

```
Description:  This template deploys a VPC, with a pair of public and private subnets spread
  across two Availability Zones. It deploys an internet gateway, with a default
  route on the public subnets. It deploys a pair of NAT gateways (one in each AZ),
  and default routes for them in the private subnets.

Parameters:
  EnvironmentName:
    Description: An environment name that is prefixed to resource names
    Type: String

  VpcCIDR:
    Description: Please enter the IP range (CIDR notation) for this VPC
    Type: String
    Default: 10.192.0.0/16

  PublicSubnet1CIDR:
    Description: Please enter the IP range (CIDR notation) for the public subnet in the first Availability Zone
    Type: String
    Default: 10.192.10.0/24

  PublicSubnet2CIDR:
    Description: Please enter the IP range (CIDR notation) for the public subnet in the second Availability Zone
    Type: String
    Default: 10.192.11.0/24

  PrivateSubnet1CIDR:
    Description: Please enter the IP range (CIDR notation) for the private subnet in the first Availability Zone
    Type: String
    Default: 10.192.20.0/24

  PrivateSubnet2CIDR:
    Description: Please enter the IP range (CIDR notation) for the private subnet in the second Availability Zone
    Type: String
    Default: 10.192.21.0/24

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCIDR
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Ref EnvironmentName

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Ref EnvironmentName

  InternetGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC

  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [ 0, !GetAZs '' ]
      CidrBlock: !Ref PublicSubnet1CIDR
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName} Public Subnet (AZ1)

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [ 1, !GetAZs  '' ]
      CidrBlock: !Ref PublicSubnet2CIDR
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName} Public Subnet (AZ2)

  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [ 0, !GetAZs  '' ]
      CidrBlock: !Ref PrivateSubnet1CIDR
      MapPublicIpOnLaunch: false
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName} Private Subnet (AZ1)

  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [ 1, !GetAZs  '' ]
      CidrBlock: !Ref PrivateSubnet2CIDR
      MapPublicIpOnLaunch: false
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName} Private Subnet (AZ2)

  NatGateway1EIP:
    Type: AWS::EC2::EIP
    DependsOn: InternetGatewayAttachment
    Properties:
      Domain: vpc

  NatGateway2EIP:
    Type: AWS::EC2::EIP
    DependsOn: InternetGatewayAttachment
    Properties:
      Domain: vpc

  NatGateway1:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatGateway1EIP.AllocationId
      SubnetId: !Ref PublicSubnet1

  NatGateway2:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatGateway2EIP.AllocationId
      SubnetId: !Ref PublicSubnet2

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName} Public Routes

  DefaultPublicRoute:
    Type: AWS::EC2::Route
    DependsOn: InternetGatewayAttachment
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  PublicSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicRouteTable
      SubnetId: !Ref PublicSubnet1

  PublicSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicRouteTable
      SubnetId: !Ref PublicSubnet2


  PrivateRouteTable1:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName} Private Routes (AZ1)

  DefaultPrivateRoute1:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable1
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGateway1

  PrivateSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PrivateRouteTable1
      SubnetId: !Ref PrivateSubnet1

  PrivateRouteTable2:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName} Private Routes (AZ2)

  DefaultPrivateRoute2:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable2
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGateway2

  PrivateSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PrivateRouteTable2
      SubnetId: !Ref PrivateSubnet2

  NoIngressSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: "no-ingress-sg"
      GroupDescription: "Security group with no ingress rule"
      VpcId: !Ref VPC

Outputs:
  VPC:
    Description: A reference to the created VPC
    Value: !Ref VPC

  PublicSubnets:
    Description: A list of the public subnets
    Value: !Join [ ",", [ !Ref PublicSubnet1, !Ref PublicSubnet2 ]]

  PrivateSubnets:
    Description: A list of the private subnets
    Value: !Join [ ",", [ !Ref PrivateSubnet1, !Ref PrivateSubnet2 ]]

  PublicSubnet1:
    Description: A reference to the public subnet in the 1st Availability Zone
    Value: !Ref PublicSubnet1

  PublicSubnet2:
    Description: A reference to the public subnet in the 2nd Availability Zone
    Value: !Ref PublicSubnet2

  PrivateSubnet1:
    Description: A reference to the private subnet in the 1st Availability Zone
    Value: !Ref PrivateSubnet1

  PrivateSubnet2:
    Description: A reference to the private subnet in the 2nd Availability Zone
    Value: !Ref PrivateSubnet2

  NoIngressSecurityGroup:
    Description: Security group with no ingress rule
    Value: !Ref NoIngressSecurityGroup
```