How to publish VPC Flow logs to a different account
Tags: aws, s3, cloud, beginners
Published: 2022-02-02 11:39:01

A few AWS users have raised a question on [repost.aws](https://repost.aws/) on the following:

- [save flow log to a different account](https://repost.aws/questions/QUNQddt0bBQK6dfVpnb3Dm4w/save-flow-log-to-a-different-account#ANLOR0nNKDQa-Zg3lUW8ly4g)
- [AWS: s3 bucket policy does not give IAM user access to upload to bucket, throws 403 error](https://repost.aws/questions/QUYZc5X8Y3TLKSGZjzWVgBQQ/aws-s-3-bucket-policy-does-not-give-iam-user-access-to-upload-to-bucket-throws-403-error#AN0la-i4z3RCqbtgFmGDLDtQ)

This post is to help other users who are facing the same issue.

* The first step: create a bucket with a unique name.

As per AWS's documentation [IAM policy for IAM principals that publish flow logs to Amazon S3] (https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs-s3.html#flow-logs-s3-permissions)

> We will be using the following substitutions in the following bucket policies:

| Parameter     | Example       |
| ------------- |:-------------:|
| [BucketName]  | flowlogstest`randomnumber` |
| [Region]      | ap-southeast-2 |
| [AccountB]    | 123456789101 |

- _Policy from the documentation_
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AWSLogDeliveryWrite",
            "Effect": "Allow",
            "Principal": {"Service": "delivery.logs.amazonaws.com"},
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::[BucketName]",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control",
                    "aws:SourceAccount": "[AccountB]"
                },
                "ArnLike": {
                    "aws:SourceArn": "arn:aws:logs:[Region]:[AccountB]:*"
                }
            }
        },
        {
            "Sid": "AWSLogDeliveryCheck",
            "Effect": "Allow",
            "Principal": {"Service": "delivery.logs.amazonaws.com"},
            "Action": ["s3:GetBucketAcl", "s3:ListBucket"],
            "Resource": "arn:aws:s3:::[BucketName]",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "[AccountB]"
                },
                "ArnLike": {
                    "aws:SourceArn": "arn:aws:logs:[Region]:[AccountB]:*"
                }
            }
        }
    ]
}
```

* When we add a bucket policy to send VPC flow logs from AccountA to a S3 bucket in AccountB (different account), we notice the following error:

![Bucket  Policy Error](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/43k0rd8ph081sa2e05zd.png)

* The error is caused due to: 
```json
"Resource": "arn:aws:s3:::[BucketName]",
```
* We need to update the bucket policy to allow access to the bucket and the objects within the bucket by updating it as follows:

```json
"Resource": [
                "arn:aws:s3:::[BucketName]",
                "arn:aws:s3:::[BucketName]/*"
            ],
```

* _The final policy_
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AWSLogDeliveryWrite",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": [
                "arn:aws:s3:::[BucketName]",
                "arn:aws:s3:::[BucketName]/*"
            ],
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control",
                    "aws:SourceAccount": "[AccountB]"
                },
                "ArnLike": {
                    "aws:SourceArn": "arn:aws:logs:[Region]:[AccountB]:*"
                }
            }
        },
        {
            "Sid": "AWSLogDeliveryCheck",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": [
                "s3:GetBucketAcl",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::[BucketName]",
                "arn:aws:s3:::[BucketName]/*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "[AccountB]"
                },
                "ArnLike": {
                    "aws:SourceArn": "arn:aws:logs:[Region]:[AccountB]:*"
                }
            }
        }
    ]
}
```

* Create a flow log for a subnet in a VPC and take note of the subnet zone as we are going to launch an EC2 instance in the same subnet to create some traffic.

> Note: For a quicker demonstration, let's choose 1 min interval (default is 10 mins)

![Create a Flow Log](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cdxdc18rjw0kcwjek0eo.png)

* The flow Log is created:
   ![Flow Log](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mgxk5le64yvaa29d67ac.png)

* Launch an EC2 instance in the same subnet as the flow log.

* After a few minutes, the flow logs are stored in AccountA's S3 bucket and they are prefixed with AccountB's account number.

![Flow Logs from AccountB in AccountA](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uwci0q6tfeokcpklihms.png)

* **Clean Up**
   - Terminate EC2 instance
   - Delete the flow log from the subnet
   - Empty the bucket
   - Delete the bucket

* **Summary**
  - Remember to add both the bucket and the objects within the bucket as resources within the policy.

```json
"Resource": [
                "arn:aws:s3:::[BucketName]",
                "arn:aws:s3:::[BucketName]/*"
            ],
```

* **References**
    - [Using bucket policies](https://docs.aws.amazon.com/AmazonS3/latest/userguide//bucket-policies.html)