From 5e338eeb6b048d1474cbcfeec83a3ced4bf3298b Mon Sep 17 00:00:00 2001 From: Hugo Shaka Date: Wed, 27 Mar 2024 15:56:57 -0400 Subject: [PATCH] [v15] helm: support Athena backend (#39907) * add aws athena support * update reference * improve test readability * address feedback --- .../helm-reference/teleport-cluster.mdx | 80 +++++++++++ .../templates/auth/_config.aws.tpl | 29 +++- .../__snapshot__/auth_config_test.yaml.snap | 136 ++++++++++++++++++ .../tests/auth_config_test.yaml | 118 +++++++++++++++ examples/chart/teleport-cluster/values.yaml | 29 ++++ 5 files changed, 387 insertions(+), 5 deletions(-) diff --git a/docs/pages/reference/helm-reference/teleport-cluster.mdx b/docs/pages/reference/helm-reference/teleport-cluster.mdx index d9b4955d5b751..781d1a110835d 100644 --- a/docs/pages/reference/helm-reference/teleport-cluster.mdx +++ b/docs/pages/reference/helm-reference/teleport-cluster.mdx @@ -963,6 +963,86 @@ You can set `volumeSize` to request a different size of persistent volume when i `aws` settings are described in the AWS guide: [Running an HA Teleport cluster using an AWS EKS Cluster](../../deploy-a-cluster/helm-deployments/aws.mdx) +### `aws.region` + +`aws.region` is the AWS region where the DynamoDB tables are located. + +### `aws.backendTable` + +`aws.backendTable` is the DynamoDB table name to use for backend storage. +Teleport will attempt to create this table automatically if it does not exist. +The container will need an appropriately-provisioned IAM role with permissions +to create DynamoDB tables. + +### `aws.auditLogTable` + +`aws.auditLogTable` is the DynamoDB table name to use for audit log storage. +Teleport will attempt to create this table automatically if it does not exist. +The container will need an appropriately-provisioned IAM role with permissions +to create DynamoDB tables. This MUST NOT be the same table name as used +for `aws.backendTable` as the schemas are different. + +If you are using the Athena backend, you don't need to set this value. +If you set this value, audit logs will be sent both to the Athena and DynamoDB +backends, this is useful when migrating backends. +If both `aws.athenaURL` and `aws.auditLogTable` (DynamoDB) are set, the +`aws.auditLogPrimaryBackend` value configures which backend is used for querying. +Teleport queries the audit backend to display the audit log in the web UI, +export events using the audit log collector, or perform any action that needs to +inspect past audit events. + +### `aws.auditLogMirrorOnStdout` + +`aws.auditLogMirrorOnStdout` controls whether to mirror audit log entries to +stdout in JSON format (useful for external log collectors). + +Defaults to `false`. + +### `aws.auditLogPrimaryBackend` + +`auditLogPrimaryBackend` controls which backend is used for queries when multiple +audit backends are enabled. This setting has no effect when a single audit log +backend is enabled. + +This setting is used when migrating from DynamoDB to Athena. +Possible values are `dynamo` and `athena`. + +### `aws.athenaURL` + +`athenaURL` contains the Athena audit log backend configuration. +When this value is set, Teleport will export events to the Athena audit backend. + +To use the Athena audit backend, you must set up the required infrastructure +(S3 buckets, SQS queue, AthenaDB, IAM roles and permissions, ...). + +The requirements are described in [the Athena backend documentation](../backends.mdx#athena) + +If both `aws.athenaURL` and `aws.auditLogTable` (DynamoDB) are set, the +`aws.auditLogPrimaryBackend` value configures which backend is used for querying. + +### `aws.sessionRecordingBucket` + +`aws.sessionRecordingBucket` is the S3 bucket name to use for recorded session +storage. Teleport will attempt to create this bucket automatically if it does +not exist. + +The container will need an appropriately-provisioned IAM role with permissions +to create S3 buckets. + +### `aws.backups` + +`aws.backups` controls if DynamoDB backups are enabled when Teleport configures +the Dynamo backend. + +### `aws.dynamoAutoScaling` + +Whether Teleport should configure DynamoDB's autoscaling. Defaults to `false`. + + + DynamoDB autoscaling is no longer recommended. Teleport now defaults to "on + demand" DynamoDB billing, which has more reliable performance. + + ## `gcp` `gcp` settings are described in the GCP guide: [Running an HA Teleport cluster using a Google Cloud GKE cluster](../../deploy-a-cluster/helm-deployments/gcp.mdx) diff --git a/examples/chart/teleport-cluster/templates/auth/_config.aws.tpl b/examples/chart/teleport-cluster/templates/auth/_config.aws.tpl index 9fb0863116957..8a2f6e6896119 100644 --- a/examples/chart/teleport-cluster/templates/auth/_config.aws.tpl +++ b/examples/chart/teleport-cluster/templates/auth/_config.aws.tpl @@ -4,11 +4,7 @@ type: dynamodb region: {{ required "aws.region is required in chart values" .Values.aws.region }} table_name: {{ required "aws.backendTable is required in chart values" .Values.aws.backendTable }} - {{- if .Values.aws.auditLogMirrorOnStdout }} - audit_events_uri: ['dynamodb://{{ required "aws.auditLogTable is required in chart values" .Values.aws.auditLogTable }}', 'stdout://'] - {{- else }} - audit_events_uri: ['dynamodb://{{ required "aws.auditLogTable is required in chart values" .Values.aws.auditLogTable }}'] - {{- end }} + audit_events_uri: {{- include "teleport-cluster.auth.config.aws.audit" . | nindent 4 }} audit_sessions_uri: s3://{{ required "aws.sessionRecordingBucket is required in chart values" .Values.aws.sessionRecordingBucket }} continuous_backups: {{ required "aws.backups is required in chart values" .Values.aws.backups }} {{- if .Values.aws.dynamoAutoScaling }} @@ -24,3 +20,26 @@ auto_scaling: false {{- end }} {{- end -}} + +{{- define "teleport-cluster.auth.config.aws.audit" -}} + {{- if and .Values.aws.auditLogTable (not .Values.aws.athenaURL) -}} +- 'dynamodb://{{.Values.aws.auditLogTable}}' + {{- else if and (not .Values.aws.auditLogTable) .Values.aws.athenaURL -}} +- {{ .Values.aws.athenaURL | quote }} + {{- else if and .Values.aws.auditLogTable .Values.aws.athenaURL -}} + {{- if eq .Values.aws.auditLogPrimaryBackend "dynamo" -}} +- 'dynamodb://{{.Values.aws.auditLogTable}}' +- {{ .Values.aws.athenaURL | quote }} + {{- else if eq .Values.aws.auditLogPrimaryBackend "athena" -}} +- {{ .Values.aws.athenaURL | quote }} +- 'dynamodb://{{.Values.aws.auditLogTable}}' + {{- else -}} + {{- fail "Both Dynamo and Athena audit backends are enabled. You must specify the primary backend by setting `aws.auditLogPrimaryBackend` to either 'dynamo' or 'athena'." -}} + {{- end -}} + {{- else -}} + {{- fail "You need an audit backend. In AWS mode, you must set at least one of `aws.auditLogTable` (Dynamo) and `aws.athenaURL` (Athena)." -}} + {{- end -}} + {{- if .Values.aws.auditLogMirrorOnStdout }} +- 'stdout://' + {{- end -}} +{{- end -}} diff --git a/examples/chart/teleport-cluster/tests/__snapshot__/auth_config_test.yaml.snap b/examples/chart/teleport-cluster/tests/__snapshot__/auth_config_test.yaml.snap index bd5c9956cdc6b..d818940a4ae95 100644 --- a/examples/chart/teleport-cluster/tests/__snapshot__/auth_config_test.yaml.snap +++ b/examples/chart/teleport-cluster/tests/__snapshot__/auth_config_test.yaml.snap @@ -1673,3 +1673,139 @@ matches snapshot for volumes.yaml: output: stderr severity: INFO version: v3 +uses athena as primary backend when configured: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: teleport.example.com + cluster_name: teleport.example.com + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: teleport.example.com + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + storage: + audit_events_uri: + - athena://db.table?topicArn=arn:aws:sns:region:account_id:topic_name + - dynamodb://my-dynamodb-table + audit_sessions_uri: s3://asd + auto_scaling: false + continuous_backups: false + region: asd + table_name: asd + type: dynamodb + version: v3 +uses athena, dynamo, and stdout when everything is on: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: teleport.example.com + cluster_name: teleport.example.com + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: teleport.example.com + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + storage: + audit_events_uri: + - athena://db.table?topicArn=arn:aws:sns:region:account_id:topic_name + - dynamodb://my-dynamodb-table + - stdout:// + audit_sessions_uri: s3://asd + auto_scaling: false + continuous_backups: false + region: asd + table_name: asd + type: dynamodb + version: v3 +uses dynamo as primary backend when configured: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: teleport.example.com + cluster_name: teleport.example.com + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: teleport.example.com + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + storage: + audit_events_uri: + - dynamodb://my-dynamodb-table + - athena://db.table?topicArn=arn:aws:sns:region:account_id:topic_name + audit_sessions_uri: s3://asd + auto_scaling: false + continuous_backups: false + region: asd + table_name: asd + type: dynamodb + version: v3 diff --git a/examples/chart/teleport-cluster/tests/auth_config_test.yaml b/examples/chart/teleport-cluster/tests/auth_config_test.yaml index ea2ed147ccc65..468fdc8f0d8d1 100644 --- a/examples/chart/teleport-cluster/tests/auth_config_test.yaml +++ b/examples/chart/teleport-cluster/tests/auth_config_test.yaml @@ -510,3 +510,121 @@ tests: - matchRegex: path: data.teleport\.yaml pattern: 'billing_mode: provisioned' + + - it: fails when no audit backend is configured + set: + chartMode: aws + clusterName: "teleport.example.com" + aws: + region: asd + backendTable: asd + sessionRecordingBucket: asd + asserts: + - failedTemplate: + errorMessage: "You need an audit backend. In AWS mode, you must set at least one of `aws.auditLogTable` (Dynamo) and `aws.athenaURL` (Athena)." + + - it: configures dynamo when dynamo is set + set: + chartMode: aws + clusterName: "teleport.example.com" + aws: + region: asd + backendTable: asd + sessionRecordingBucket: asd + auditLogTable: my-dynamodb-table + asserts: + - matchRegex: + path: data.teleport\.yaml + pattern: '- dynamodb://my-dynamodb-table' + + - it: configures athena when athenaURL is set + set: + chartMode: aws + clusterName: "teleport.example.com" + aws: + region: asd + backendTable: asd + sessionRecordingBucket: asd + athenaURL: 'athena://db.table?topicArn=arn:aws:sns:region:account_id:topic_name' + asserts: + - matchRegex: + path: data.teleport\.yaml + pattern: '- athena://db.table' + + - it: configures dynamo and stdout when dynamo is set and mirroring is on + set: + chartMode: aws + clusterName: "teleport.example.com" + aws: + region: asd + backendTable: asd + sessionRecordingBucket: asd + auditLogTable: my-dynamodb-table + auditLogMirrorOnStdout: true + asserts: + - matchRegex: + path: data.teleport\.yaml + pattern: '- dynamodb://my-dynamodb-table' + - matchRegex: + path: data.teleport\.yaml + pattern: '- stdout://' + + - it: fails when both athena and dynamo are set but no order is specified + set: + chartMode: aws + clusterName: "teleport.example.com" + aws: + region: asd + backendTable: asd + sessionRecordingBucket: asd + auditLogTable: my-dynamodb-table + athenaURL: 'athena://db.table?topicArn=arn:aws:sns:region:account_id:topic_name' + asserts: + - failedTemplate: + errorMessage: "Both Dynamo and Athena audit backends are enabled. You must specify the primary backend by setting `aws.auditLogPrimaryBackend` to either 'dynamo' or 'athena'." + + - it: uses athena as primary backend when configured + set: + chartMode: aws + clusterName: "teleport.example.com" + aws: + region: asd + backendTable: asd + sessionRecordingBucket: asd + auditLogTable: my-dynamodb-table + athenaURL: 'athena://db.table?topicArn=arn:aws:sns:region:account_id:topic_name' + auditLogPrimaryBackend: "athena" + asserts: + - matchSnapshot: + path: data.teleport\.yaml + + - it: uses dynamo as primary backend when configured + set: + chartMode: aws + clusterName: "teleport.example.com" + aws: + region: asd + backendTable: asd + sessionRecordingBucket: asd + auditLogTable: my-dynamodb-table + athenaURL: 'athena://db.table?topicArn=arn:aws:sns:region:account_id:topic_name' + auditLogPrimaryBackend: "dynamo" + asserts: + - matchSnapshot: + path: data.teleport\.yaml + + - it: uses athena, dynamo, and stdout when everything is on + set: + chartMode: aws + clusterName: "teleport.example.com" + aws: + region: asd + backendTable: asd + sessionRecordingBucket: asd + auditLogTable: my-dynamodb-table + athenaURL: 'athena://db.table?topicArn=arn:aws:sns:region:account_id:topic_name' + auditLogPrimaryBackend: "athena" + auditLogMirrorOnStdout: true + asserts: + - matchSnapshot: + path: data.teleport\.yaml diff --git a/examples/chart/teleport-cluster/values.yaml b/examples/chart/teleport-cluster/values.yaml index e0d234f65ed1c..e84ababd713d2 100644 --- a/examples/chart/teleport-cluster/values.yaml +++ b/examples/chart/teleport-cluster/values.yaml @@ -348,9 +348,34 @@ aws: # The DynamoDB table name to use for audit log storage. Teleport will attempt to create this table automatically if it does not exist. # The container will need an appropriately-provisioned IAM role with permissions to create DynamoDB tables. # This MUST NOT be the same table name as used for 'backendTable' as the schemas are different. + # + # If you are using the Athena backend, you don't need to set this value. + # If you set this value, audit logs will be sent both to the Athena and DynamoDB + # backends, this is useful when migrating backends. + # If both `aws.athenaURL` and `aws.auditLogTable` (DynamoDB) are set, the + # `aws.auditLogPrimaryBackend` value configures which backend is used for querying. + # Teleport queries the audit backend to display the audit log in the web UI, export events + # using the audit log collector, or perform any action that needs to inspect past audit events. auditLogTable: "" # Whether to mirror audit log entries to stdout in JSON format (useful for external log collectors) auditLogMirrorOnStdout: false + # auditLogPrimaryBackend controls which backend is used for queries when multiple + # audit backends are enabled. This setting has no effect when a single audit + # log backend is enabled.This setting is used when migrating from DynamoDB to + # Athena. + # + # Possible values are `dynamo` and `athena`. + auditLogPrimaryBackend: "" + # athenaURL contains the Athena audit log backend configuration + # When this value is set, Teleport will export events to the Athena audit backend. + # + # To use the Athena audit backend, you must set up the required infrastructure + # (S3 buckets, SQS queue, AthenaDB, IAM roles and permissions, ...). + # The requirements are described in the documentation: https://goteleport.com/docs/reference/backends/#athena + # + # If both `aws.athenaURL` and `aws.auditLogTable` (DynamoDB) are set, the + # `aws.auditLogPrimaryBackend` value configures which backend is used for querying. + athenaURL: "" # The S3 bucket name to use for recorded session storage. Teleport will attempt to create this bucket automatically if it does not exist. # The container will need an appropriately-provisioned IAM role with permissions to create S3 buckets. sessionRecordingBucket: "" @@ -358,6 +383,10 @@ aws: backups: false # Whether Teleport should configure DynamoDB's autoscaling. + # + # WARNING: DynamoDB autoscaling is no longer recommended. Teleport now + # defaults to "on demand" DynamoDB billing, which has more reliable performance. + # # Requires additional statements in the IAM Teleport Policy to be allowed to configure the autoscaling. # See https://goteleport.com/docs/setup/reference/backends/#dynamodb-autoscaling dynamoAutoScaling: false