Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 11 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ module "vpc" {
}
```

> [!WARNING]
> v6.x of the module still supports creating a VPC Flow Log within the root (VPC) module. However, this is deprecated behavior and will be removed in v7.0.0. Please use the [standalone flow log](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/modules/flow-log) module instead.

## External NAT Gateway IPs

By default this module will provision new Elastic IPs for the VPC's NAT Gateways.
Expand Down Expand Up @@ -116,24 +119,6 @@ If you need private subnets that should have no Internet routing (in the sense o

Since AWS Lambda functions allocate Elastic Network Interfaces in proportion to the traffic received ([read more](https://docs.aws.amazon.com/lambda/latest/dg/vpc.html)), it can be useful to allocate a large private subnet for such allocations, while keeping the traffic they generate entirely internal to the VPC.

You can add additional tags with `intra_subnet_tags` as with other subnet types.

## VPC Flow Log

VPC Flow Log allows to capture IP traffic for a specific network interface (ENI), subnet, or entire VPC. This module supports enabling or disabling VPC Flow Logs for entire VPC. If you need to have VPC Flow Logs for subnet or ENI, you have to manage it outside of this module with [aws_flow_log resource](https://www.terraform.io/docs/providers/aws/r/flow_log.html).

### VPC Flow Log Examples

By default `file_format` is `plain-text`. You can also specify `parquet` to have logs written in Apache Parquet format.

```
flow_log_file_format = "parquet"
```

### Permissions Boundary

If your organization requires a permissions boundary to be attached to the VPC Flow Log role, make sure that you specify an ARN of the permissions boundary policy as `vpc_flow_log_permissions_boundary` argument. Read more about required [IAM policy for publishing flow logs](https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs-cwl.html#flow-logs-iam).

## Conditional creation

Prior to Terraform 0.13, you were unable to specify `count` in a module block. If you wish to toggle the creation of the module's resources in an older (pre 0.13) version of Terraform, you can use the `create_vpc` argument.
Expand Down Expand Up @@ -231,19 +216,18 @@ module "vpc_cidr_from_ipam" {

## Examples

- [Complete VPC](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/complete) with VPC Endpoints.
- [Block Public Access](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/block-public-access)
- [Complete VPC](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/complete) w/ VPC Endpoints
- [VPC w/ Flow Log](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/flow-log)
- [VPC using IPAM](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/ipam)
- [Dualstack IPv4/IPv6 VPC](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/ipv6-dualstack)
- [IPv6 only subnets/VPC](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/ipv6-only)
- [IPv6 only subnets VPC](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/ipv6-only)
- [Manage Default VPC](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/manage-default-vpc)
- [Network ACL](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/network-acls)
- [VPC with Outpost](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/outpost)
- [VPC with secondary CIDR blocks](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/secondary-cidr-blocks)
- [VPC with unique route tables](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/separate-route-tables)
- [VPC w/ Network ACL](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/network-acls)
- [VPC w/ Outpost](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/outpost)
- [VPC w/ secondary CIDR blocks](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/secondary-cidr-blocks)
- [VPC w/ unique route tables](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/separate-route-tables)
- [Simple VPC](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/simple)
- [VPC Flow Logs](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/vpc-flow-logs)
- [VPC Block Public Access](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/block-public-access)
- [Few tests and edge case examples](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples/issues)

## Contributing

Expand Down
5 changes: 5 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Examples

The examples provided demonstrate different cluster configurations that users can create with the modules provided.

Please do not mistake the examples provided as "best practices". It is up to users to consult the AWS service documentation for best practices, usage recommendations, etc.
4 changes: 0 additions & 4 deletions examples/complete/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,6 @@ No inputs.
| <a name="output_vpc_endpoints"></a> [vpc\_endpoints](#output\_vpc\_endpoints) | Array containing the full resource object and attributes for all endpoints created |
| <a name="output_vpc_endpoints_security_group_arn"></a> [vpc\_endpoints\_security\_group\_arn](#output\_vpc\_endpoints\_security\_group\_arn) | Amazon Resource Name (ARN) of the security group |
| <a name="output_vpc_endpoints_security_group_id"></a> [vpc\_endpoints\_security\_group\_id](#output\_vpc\_endpoints\_security\_group\_id) | ID of the security group |
| <a name="output_vpc_flow_log_cloudwatch_iam_role_arn"></a> [vpc\_flow\_log\_cloudwatch\_iam\_role\_arn](#output\_vpc\_flow\_log\_cloudwatch\_iam\_role\_arn) | The ARN of the IAM role used when pushing logs to Cloudwatch log group |
| <a name="output_vpc_flow_log_destination_arn"></a> [vpc\_flow\_log\_destination\_arn](#output\_vpc\_flow\_log\_destination\_arn) | The ARN of the destination for VPC Flow Logs |
| <a name="output_vpc_flow_log_destination_type"></a> [vpc\_flow\_log\_destination\_type](#output\_vpc\_flow\_log\_destination\_type) | The type of the destination for VPC Flow Logs |
| <a name="output_vpc_flow_log_id"></a> [vpc\_flow\_log\_id](#output\_vpc\_flow\_log\_id) | The ID of the Flow Log resource |
| <a name="output_vpc_id"></a> [vpc\_id](#output\_vpc\_id) | The ID of the VPC |
| <a name="output_vpc_instance_tenancy"></a> [vpc\_instance\_tenancy](#output\_vpc\_instance\_tenancy) | Tenancy of instances spin up within VPC |
| <a name="output_vpc_ipv6_association_id"></a> [vpc\_ipv6\_association\_id](#output\_vpc\_ipv6\_association\_id) | The association ID for the IPv6 CIDR block |
Expand Down
8 changes: 0 additions & 8 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,6 @@ module "vpc" {
dhcp_options_domain_name = "service.consul"
dhcp_options_domain_name_servers = ["127.0.0.1", "10.10.0.2"]

# VPC Flow Logs (Cloudwatch log group and IAM role will be created)
vpc_flow_log_iam_role_name = "vpc-complete-example-role"
vpc_flow_log_iam_role_use_name_prefix = false
enable_flow_log = true
create_flow_log_cloudwatch_log_group = true
create_flow_log_cloudwatch_iam_role = true
flow_log_max_aggregation_interval = 60

tags = local.tags
}

Expand Down
21 changes: 0 additions & 21 deletions examples/complete/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -513,27 +513,6 @@ output "elasticache_network_acl_arn" {
value = module.vpc.elasticache_network_acl_arn
}

# VPC flow log
output "vpc_flow_log_id" {
description = "The ID of the Flow Log resource"
value = module.vpc.vpc_flow_log_id
}

output "vpc_flow_log_destination_arn" {
description = "The ARN of the destination for VPC Flow Logs"
value = module.vpc.vpc_flow_log_destination_arn
}

output "vpc_flow_log_destination_type" {
description = "The type of the destination for VPC Flow Logs"
value = module.vpc.vpc_flow_log_destination_type
}

output "vpc_flow_log_cloudwatch_iam_role_arn" {
description = "The ARN of the IAM role used when pushing logs to Cloudwatch log group"
value = module.vpc.vpc_flow_log_cloudwatch_iam_role_arn
}

# VPC endpoints
output "vpc_endpoints" {
description = "Array containing the full resource object and attributes for all endpoints created"
Expand Down
72 changes: 72 additions & 0 deletions examples/flow-log/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# AWS Flow Logs to S3 and CloudWatch logs

Configuration in this directory creates a set of VPC resources with VPC Flow Logs enabled in different configurations:

- Flow log to CloudWatch logs using module created CloudWatch log group and IAM role
- Flow log to CloudWatch logs using external CloudWatch log group and IAM role
- Flow log to S3 bucket in text format
- Flow log to S3 bucket in Parquet format

## Usage

To run this example you need to execute:

```bash
$ terraform init
$ terraform plan
$ terraform apply
```

Note that this example may create resources which can cost money (AWS Elastic IP, for example). Run `terraform destroy` when you don't need these resources.

<!-- BEGIN_TF_DOCS -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.5 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.5 |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_disabled"></a> [disabled](#module\_disabled) | ../../modules/flow-log | n/a |
| <a name="module_flow_log"></a> [flow\_log](#module\_flow\_log) | ../../modules/flow-log | n/a |
| <a name="module_flow_log_cloudwatch_external"></a> [flow\_log\_cloudwatch\_external](#module\_flow\_log\_cloudwatch\_external) | ../../modules/flow-log | n/a |
| <a name="module_flow_log_s3"></a> [flow\_log\_s3](#module\_flow\_log\_s3) | ../../modules/flow-log | n/a |
| <a name="module_flow_log_s3_parquet"></a> [flow\_log\_s3\_parquet](#module\_flow\_log\_s3\_parquet) | ../../modules/flow-log | n/a |
| <a name="module_s3_bucket"></a> [s3\_bucket](#module\_s3\_bucket) | terraform-aws-modules/s3-bucket/aws | ~> 5.0 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | ../../ | n/a |

## Resources

| Name | Type |
|------|------|
| [aws_cloudwatch_log_group.flow_log](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource |
| [aws_iam_role.flow_log_cloudwatch](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy.flow_log_cloudwatch](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source |

## Inputs

No inputs.

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_arn"></a> [arn](#output\_arn) | The ARN of the Flow Log |
| <a name="output_cloudwatch_log_group_arn"></a> [cloudwatch\_log\_group\_arn](#output\_cloudwatch\_log\_group\_arn) | ARN of CloudWatch log group created |
| <a name="output_cloudwatch_log_group_name"></a> [cloudwatch\_log\_group\_name](#output\_cloudwatch\_log\_group\_name) | Name of CloudWatch log group created |
| <a name="output_iam_role_arn"></a> [iam\_role\_arn](#output\_iam\_role\_arn) | The Amazon Resource Name (ARN) specifying the IAM role |
| <a name="output_iam_role_name"></a> [iam\_role\_name](#output\_iam\_role\_name) | The name of the IAM role |
| <a name="output_iam_role_unique_id"></a> [iam\_role\_unique\_id](#output\_iam\_role\_unique\_id) | Stable and unique string identifying the IAM role |
| <a name="output_id"></a> [id](#output\_id) | The ID of the Flow Log |
<!-- END_TF_DOCS -->
162 changes: 162 additions & 0 deletions examples/flow-log/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
provider "aws" {
region = local.region
}

data "aws_availability_zones" "available" {}

locals {
name = "ex-${basename(path.cwd)}"
region = "eu-west-1"

vpc_cidr = "10.0.0.0/16"
azs = slice(data.aws_availability_zones.available.names, 0, 3)

tags = {
Example = local.name
GithubRepo = "terraform-aws-vpc"
GithubOrg = "terraform-aws-modules"
}
}

################################################################################
# Flow Log
################################################################################

module "flow_log" {
source = "../../modules/flow-log"

name = local.name
vpc_id = module.vpc.vpc_id

tags = local.tags
}

module "flow_log_cloudwatch_external" {
source = "../../modules/flow-log"

name = "${local.name}-cloudwatch-external"
vpc_id = module.vpc.vpc_id

create_cloudwatch_log_group = false
log_destination = aws_cloudwatch_log_group.flow_log.arn

create_iam_role = false
iam_role_arn = aws_iam_role.flow_log_cloudwatch.arn

tags = local.tags
}

module "flow_log_s3" {
source = "../../modules/flow-log"

name = "${local.name}-s3"
vpc_id = module.vpc.vpc_id

log_destination_type = "s3"
log_destination = module.s3_bucket.s3_bucket_arn

tags = local.tags
}

module "flow_log_s3_parquet" {
source = "../../modules/flow-log"

name = "${local.name}-s3-parquet"
vpc_id = module.vpc.vpc_id

log_destination_type = "s3"
log_destination = module.s3_bucket.s3_bucket_arn
destination_options = {
file_format = "parquet"
hive_compatible_partitions = true
per_hour_partition = true
}

tags = local.tags
}

module "disabled" {
source = "../../modules/flow-log"

create = false
}

################################################################################
# Supporting Resources
################################################################################

module "vpc" {
source = "../../"

name = local.name
cidr = local.vpc_cidr

azs = local.azs
private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)]
public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 4)]

tags = local.tags
}

module "s3_bucket" {
source = "terraform-aws-modules/s3-bucket/aws"
version = "~> 5.0"

bucket_prefix = "${local.name}-"
force_destroy = true

# Policy works for flow logs as well
attach_waf_log_delivery_policy = true

tags = local.tags
}

resource "aws_cloudwatch_log_group" "flow_log" {
name_prefix = "/aws/flow-log/vpc/${module.vpc.vpc_id}/${local.name}-external-"

retention_in_days = 7

tags = local.tags
}

resource "aws_iam_role" "flow_log_cloudwatch" {
name_prefix = "${local.name}-external-"

assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Sid = "VPCFlowLogsAssume"
Principal = {
Service = "vpc-flow-logs.amazonaws.com"
}
},
]
})

tags = local.tags
}

resource "aws_iam_role_policy" "flow_log_cloudwatch" {
name_prefix = "${local.name}-external-"
role = aws_iam_role.flow_log_cloudwatch.id

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams",
]
Effect = "Allow"
Resource = aws_cloudwatch_log_group.flow_log.arn
},
]
})
}
Loading