Skip to content

Commit 7425c45

Browse files
committed
initial commit
0 parents  commit 7425c45

16 files changed

+554
-0
lines changed

.circleci/config.yml

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
---
2+
version: 2.1
3+
4+
orbs:
5+
terraform: circleci/[email protected]
6+
7+
workflows:
8+
validate-and-security-scan:
9+
jobs:
10+
- checkout-code:
11+
filters:
12+
branches:
13+
only:
14+
- /.*/
15+
tags:
16+
ignore:
17+
- /.*/
18+
- validate:
19+
requires:
20+
- checkout-code
21+
filters:
22+
branches:
23+
only:
24+
- /.*/
25+
tags:
26+
ignore:
27+
- /.*/
28+
- security-scan:
29+
requires:
30+
- validate
31+
filters:
32+
branches:
33+
only:
34+
- /.*/
35+
tags:
36+
ignore:
37+
- /.*/
38+
39+
jobs:
40+
checkout-code:
41+
docker:
42+
- image: cimg/base:2022.02
43+
steps:
44+
- checkout
45+
- persist_to_workspace:
46+
root: .
47+
paths:
48+
- "./*"
49+
validate:
50+
executor:
51+
name: terraform/default
52+
tag: "1.1.3"
53+
steps:
54+
- attach_workspace:
55+
at: .
56+
- terraform/fmt
57+
- terraform/validate
58+
security-scan:
59+
docker:
60+
- image: aquasec/tfsec-ci:v1.0
61+
user: root
62+
steps:
63+
- attach_workspace:
64+
at: .
65+
- run:
66+
name: perform security scan
67+
command: tfsec .

.gitignore

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
**/.terraform/*
2+
3+
# .tfstate files
4+
*.tfstate
5+
*.tfstate.*
6+
*.terraform.lock.*
7+
8+
# Crash log files
9+
crash.log
10+
crash.*.log
11+
12+
# Ignore override files as they are usually used to override resources locally and so
13+
# are not checked in
14+
override.tf
15+
override.tf.json
16+
*_override.tf
17+
*_override.tf.json
18+
19+
# Include override files you do wish to add to version control using negated pattern
20+
# !example_override.tf
21+
22+
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
23+
# example: *tfplan*
24+
25+
# Ignore CLI configuration files
26+
.terraformrc
27+
terraform.rc

.terraform-docs.yaml

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
formatter: "markdown table"
2+
3+
sort:
4+
enabled: true
5+
by: required
6+
7+
content: |-
8+
{{ .Requirements }}
9+
{{ .Providers }}
10+
{{ .Inputs }}
11+
{{ .Outputs }}
12+
{{ .Resources }}
13+
14+
output:
15+
file: README.md
16+
mode: inject
17+
template: |-
18+
<!-- begin-tf-docs -->
19+
{{ .Content }}
20+
<!-- end-tf-docs -->

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 Expel, Inc.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
docs:
2+
terraform-docs ./

README.md

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# terraform-aws-eks
2+
Terraform module for configuring Amazon EKS to integrate with [Expel Workbench](https://workbench.expel.io/).
3+
4+
Configures a CloudWatch subscription filter to send data to a Kinesis data stream that
5+
[Expel Workbench](https://workbench.expel.io/) consumes.
6+
7+
## Usage
8+
```hcl
9+
module "expel_aws_eks" {
10+
source = "expel-io/cloudtrail/eks"
11+
version = "1.1.0"
12+
13+
expel_customer_organization_guid = "Replace with your organization GUID from Expel Workbench"
14+
region = "AWS region in which Kinesis data stream will be created"
15+
}
16+
```
17+
Once you have configured your AWS environment, go to
18+
https://workbench.expel.io/settings/security-devices?setupIntegration=aws and create an AWS EKS
19+
security device to enable Expel to begin monitoring your AWS environment.
20+
21+
## Permissions
22+
The permissions allocated by this module allow Expel Workbench to perform investigations and get a broad understanding of your AWS footprint.
23+
24+
## Limitations
25+
1. Only supports onboarding a single AWS account, not an entire AWS Organization.
26+
2. Will always create a new CloudWatch subscription filter (AWS has a limit of 2 subscription filters per CloudWatch log group)
27+
3. Will always create a new Kinesis data stream.
28+
4. Does not modify cluster configuration to grant Expel's IAM role read-only access (must be done separately)
29+
30+
See Expel's Getting Started Guide for Amazon EKS for options if you
31+
have an AWS Organization or already have a Kinesis data stream you want to re-use.
32+
33+
<!-- begin-tf-docs -->
34+
## Requirements
35+
36+
| Name | Version |
37+
|------|---------|
38+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.1.0 |
39+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.0.0 |
40+
## Providers
41+
42+
| Name | Version |
43+
|------|---------|
44+
| <a name="provider_aws"></a> [aws](#provider\_aws) | 4.9.0 |
45+
## Inputs
46+
47+
| Name | Description | Type | Default | Required |
48+
|------|-------------|------|---------|:--------:|
49+
| <a name="input_eks_log_group_name"></a> [eks\_log\_group\_name](#input\_eks\_log\_group\_name) | The EKS log group name to integrate with Expel Workbench. | `string` | n/a | yes |
50+
| <a name="input_expel_customer_organization_guid"></a> [expel\_customer\_organization\_guid](#input\_expel\_customer\_organization\_guid) | Expel customer's organization GUID assigned to you by Expel. You can find it in your browser URL after navigating to Settings > My Organization in Workbench. | `string` | n/a | yes |
51+
| <a name="input_enable_stream_encryption"></a> [enable\_stream\_encryption](#input\_enable\_stream\_encryption) | Optionally encrypt data in the Kinesis stream with a Kinesis-owned KMS key. | `bool` | `true` | no |
52+
| <a name="input_expel_assume_role_session_name"></a> [expel\_assume\_role\_session\_name](#input\_expel\_assume\_role\_session\_name) | The session name Expel will use when authenticating. | `string` | `"ExpelEKSServiceSession"` | no |
53+
| <a name="input_expel_aws_account_arn"></a> [expel\_aws\_account\_arn](#input\_expel\_aws\_account\_arn) | Expel's AWS Account ARN to allow assuming role to gain EKS access. | `string` | `"arn:aws:iam::012205512454:user/ExpelCloudService"` | no |
54+
| <a name="input_prefix"></a> [prefix](#input\_prefix) | A prefix to group all Expel integration resources. | `string` | `"expel-aws-eks"` | no |
55+
| <a name="input_stream_capacity_mode"></a> [stream\_capacity\_mode](#input\_stream\_capacity\_mode) | The data stream capacity mode: ON\_DEMAND (recommended) or PROVISIONED. See: https://docs.aws.amazon.com/streams/latest/dev/how-do-i-size-a-stream.html | `string` | `"ON_DEMAND"` | no |
56+
| <a name="input_stream_retention_hours"></a> [stream\_retention\_hours](#input\_stream\_retention\_hours) | The number of hours data will be retained in the stream. See: https://docs.aws.amazon.com/streams/latest/dev/kinesis-extended-retention.html | `number` | `1` | no |
57+
| <a name="input_stream_shard_count"></a> [stream\_shard\_count](#input\_stream\_shard\_count) | The number of shards for the Kinesis stream. Only required if `stream_capacity_mode` is `PROVISIONED`. See: https://docs.aws.amazon.com/streams/latest/dev/how-do-i-size-a-stream.html | `number` | `null` | no |
58+
| <a name="input_tags"></a> [tags](#input\_tags) | A set of tags to group resources. | `map` | `{}` | no |
59+
## Outputs
60+
61+
| Name | Description |
62+
|------|-------------|
63+
| <a name="output_aws_region"></a> [aws\_region](#output\_aws\_region) | The AWS Region where the Kinesis resources exist |
64+
| <a name="output_kinesis_stream_name"></a> [kinesis\_stream\_name](#output\_kinesis\_stream\_name) | Name of the Kinesis data stream Expel will consume from |
65+
| <a name="output_role_arn"></a> [role\_arn](#output\_role\_arn) | IAM Role ARN of the role for Expel to assume to access Kinesis data |
66+
| <a name="output_role_session_name"></a> [role\_session\_name](#output\_role\_session\_name) | The session name Expel will use when authenticating |
67+
## Resources
68+
69+
| Name | Type |
70+
|------|------|
71+
| [aws_cloudwatch_log_subscription_filter.eks_subscription_filter](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_subscription_filter) | resource |
72+
| [aws_iam_policy.eks_consumer_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
73+
| [aws_iam_policy.eks_producer_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
74+
| [aws_iam_role.cloudwatch_assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
75+
| [aws_iam_role.expel_assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
76+
| [aws_iam_role_policy_attachment.eks_consumer_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
77+
| [aws_iam_role_policy_attachment.eks_producer_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
78+
| [aws_kinesis_stream.kinesis_data_stream](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kinesis_stream) | resource |
79+
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
80+
| [aws_iam_policy_document.assume_role_iam_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
81+
| [aws_iam_policy_document.cloudwatch_assume_role_iam_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
82+
| [aws_iam_policy_document.eks_consumer_iam_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
83+
| [aws_iam_policy_document.eks_producer_iam_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
84+
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
85+
<!-- end-tf-docs -->

examples/basic/README.md

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Basic
2+
3+
This configuration sets up appropriate AWS resources that are necessary to integrate Expel Workbench with an existing EKS instance.
4+
5+
This `Basic` example is the simplest onboarding experience, as it assumes a single AWS Account is being onboarded with one EKS instance.
6+
7+
## Usage
8+
9+
10+
To run this example you need to execute:
11+
12+
```bash
13+
terraform init
14+
terraform apply -var-file="terraform.tfvars"
15+
```
16+
17+
Note that this example may create resources which can cost money (AWS Kinesis data stream, for example). Run `terraform destroy` when you don't need these resources.
18+
19+
## Requirements
20+
21+
| Name | Version |
22+
|------|---------|
23+
| terraform | = 1.1.3 |
24+
| aws | = 4.0 |

examples/basic/main.tf

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
variable "region" {
2+
type = string
3+
}
4+
5+
variable "expel_customer_organization_guid" {
6+
description = "Use your organization GUID assigned to you by Expel. You can find it in your browser URL after navigating to Settings > My Organization in Workbench"
7+
type = string
8+
}
9+
10+
variable "eks_log_group_name" {
11+
description = "Use the log group name in CloudWatch containing EKS logs."
12+
type = string
13+
}
14+
15+
provider "aws" {
16+
region = var.region
17+
}
18+
19+
module "expel_aws_eks_integration" {
20+
source = "../../"
21+
22+
expel_customer_organization_guid = var.expel_customer_organization_guid
23+
expel_assume_role_session_name = "ExpelServiceAssumeRoleForEKSAccess"
24+
eks_log_group_name = var.eks_log_group_name
25+
stream_capacity_mode = "ON_DEMAND"
26+
stream_retention_hours = 24
27+
enable_stream_encryption = true
28+
29+
prefix = "expel-aws-eks"
30+
tags = {
31+
"is_external" = "true"
32+
}
33+
}
34+
35+
output "expel_aws_eks_integration" {
36+
value = module.expel_aws_eks_integration
37+
}

examples/basic/terraform.tfvars

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# region = "Replace with the AWS region in which you want the Kinesis data stream to be configured for EKS logs"
2+
# expel_customer_organization_guid = "Replace with your organization GUID assigned to you by Expel. You can find it in your browser URL after navigating to Settings > My Organization in Workbench"
3+
# eks_log_group_name = "Replace with your EKS log group name"
4+
5+
6+
region = "us-east-2"
7+
expel_customer_organization_guid = "9a5434c2-66b8-49e3-a544-6e8797f4a1d3"
8+
eks_log_group_name = "/aws/eks/dan-cluster/cluster"

iam.tf

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
2+
data "aws_iam_policy_document" "assume_role_iam_document" {
3+
# Allow Expel to assume the role
4+
statement {
5+
actions = ["sts:AssumeRole"]
6+
effect = "Allow"
7+
principals {
8+
type = "AWS"
9+
identifiers = [var.expel_aws_account_arn]
10+
}
11+
12+
condition {
13+
test = "StringEquals"
14+
variable = "sts:ExternalId"
15+
values = [var.expel_customer_organization_guid]
16+
}
17+
}
18+
}
19+
20+
resource "aws_iam_role" "expel_assume_role" {
21+
name = "ExpelServiceAssumeRole"
22+
assume_role_policy = data.aws_iam_policy_document.assume_role_iam_document.json
23+
tags = local.tags
24+
}
25+
26+
resource "aws_iam_role_policy_attachment" "eks_consumer_policy_attachment" {
27+
role = aws_iam_role.expel_assume_role.name
28+
policy_arn = aws_iam_policy.eks_consumer_policy.arn
29+
}
30+
31+
resource "aws_iam_policy" "eks_consumer_policy" {
32+
name = "${var.prefix}-eks-consumer-policy"
33+
policy = data.aws_iam_policy_document.eks_consumer_iam_document.json
34+
tags = local.tags
35+
}
36+
37+
data "aws_iam_policy_document" "eks_consumer_iam_document" {
38+
39+
# Allow Expel Workbench to retrieve data from Kinesis
40+
statement {
41+
actions = [
42+
"kinesis:DescribeLimits",
43+
"kinesis:DescribeStream",
44+
"kinesis:DescribeStreamSummary",
45+
"kinesis:GetRecords",
46+
"kinesis:GetShardIterator",
47+
"kinesis:ListShards"
48+
]
49+
resources = [aws_kinesis_stream.kinesis_data_stream.arn]
50+
effect = "Allow"
51+
}
52+
53+
# Allow Expel Workbench to gather information about EKS clusters
54+
statement {
55+
actions = [
56+
"eks:AccessKubernetesApi",
57+
"eks:DescribeCluster",
58+
"eks:DescribeNodegroup",
59+
"eks:ListClusters",
60+
"eks:ListNodegroups",
61+
"eks:ListUpdates",
62+
"sts:GetCallerIdentity"
63+
]
64+
resources = ["*"]
65+
effect = "Allow"
66+
}
67+
}

kinesis.tf

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
3+
# If encryption was disabled, create an unencrypted stream
4+
resource "aws_kinesis_stream" "kinesis_data_stream" {
5+
name = "${var.prefix}-kinesis-data-stream"
6+
retention_period = var.stream_retention_hours
7+
8+
shard_level_metrics = [
9+
"IncomingBytes",
10+
"OutgoingBytes",
11+
"IncomingRecords",
12+
"OutgoingRecords",
13+
"IteratorAgeMilliseconds",
14+
]
15+
16+
stream_mode_details {
17+
stream_mode = var.stream_capacity_mode
18+
}
19+
shard_count = var.stream_capacity_mode == "PROVISIONED" ? var.stream_shard_count : null
20+
21+
# Optionally configure stream encryption
22+
encryption_type = var.enable_stream_encryption ? "KMS": "NONE"
23+
kms_key_id = var.enable_stream_encryption ? "alias/aws/kinesis" : null
24+
25+
tags = local.tags
26+
}

0 commit comments

Comments
 (0)