forked from Widen/cloudfront-auth
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WTL-852 Add Terraform configuration (#22)
- Loading branch information
Showing
20 changed files
with
468 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
# Terraform Modules for CloudFront Authentication | ||
|
||
This directory contains the _Terraform_ configuration for adding authentication to a CloudFront distribution. Currently only OKTA Native authentication is supported. | ||
|
||
## Usage | ||
|
||
The Terraform modules for each identity provider are in the [modules](./modules) directory. Refer to the [examples](./examples) directory for Terraform configuration that you can include in your project and adapt. Refer to the `variables.tf` file of the module to see all the available input variables. Below is an example for OKTA Native. | ||
|
||
1. Call the module in your Terraform configuration. CloudFront uses the `us-east-1` region, so you must pass a `us-east-1` provider to the module. | ||
|
||
```hcl | ||
module "cloudfront_auth_okta_native" { | ||
source = "github.com/iress/cloudfront-auth//infra/terraform/modules/okta_native" | ||
# Lambda function version to deploy (see the Releases page of this GitHub repository) | ||
release_version = "v3.0.0" | ||
name = "my-website-auth" | ||
org_url = "https://my-org.okta.com/oauth2/default" | ||
client_id = "Nf2qSD9wXKU9ph8an22T" | ||
domain_name = "my-cloudfront-site.example.com" | ||
# aws.global_services is a us-east-1 provider | ||
providers = { | ||
aws = aws.global_services | ||
} | ||
} | ||
``` | ||
1. Add a [lambda_function_association](https://www.terraform.io/docs/providers/aws/r/cloudfront_distribution.html#lambda_function_association) to your [aws_cloudfront_distribution](https://www.terraform.io/docs/providers/aws/r/cloudfront_distribution.html) resource: | ||
```hcl | ||
resource "aws_cloudfront_distribution" "distribution" { | ||
# ... other configuration ... | ||
# lambda_function_association is also supported by ordered_cache_behavior | ||
default_cache_behavior { | ||
# ... other configuration ... | ||
lambda_function_association { | ||
event_type = "viewer-request" | ||
lambda_arn = module.cloudfront_auth_okta_native.auth_lambda_arn | ||
include_body = false | ||
} | ||
} | ||
} | ||
``` | ||
## Requirements | ||
This module requires [wget](https://www.gnu.org/software/wget/) to be installed on the machine or container that runs Terraform. | ||
## Logs | ||
Logs are written to CloudWatch. The table below shows where the logs can be found, where {name} is the value of the `name` input variable in the Terraform module. | ||
| Function | Log group name | Region | | ||
|----------|----------------|--------| | ||
| Authentication | /aws/lambda/us-east-1.{name} | The region closest to the user who made the request to the website | ||
| Secret rotation | /aws/lambda/{name}-rotation | us-east-1 | ||
## Destroying | ||
The first time you run `terraform destroy` you may receive the following error: | ||
*Lambda was unable to delete arn:aws:lambda:us-east-1:553479592532:function:my-website-auth:1 because it is a replicated function. Please see our [documentation](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-edge-delete-replicas.html) for Deleting Lambda@Edge Functions and Replicas.* | ||
When this occurs, wait (up to a few hours) for CloudFront to delete the Lambda function replicas, then run `terraform destroy` again. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
module "cloudfront_auth_okta_native" { | ||
source = "github.com/iress/cloudfront-auth//infra/terraform/modules/okta_native" | ||
|
||
release_version = "v3.0.0" | ||
name = "my-website-auth" | ||
org_url = "https://my-org.okta.com/oauth2/default" | ||
client_id = "Nf2qSD9wXKU9ph8an22T" | ||
domain_name = "my-cloudfront-site.example.com" | ||
|
||
providers = { | ||
aws = aws.global_services | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
terraform { | ||
required_version = ">= 1.0.0" | ||
} | ||
|
||
provider "aws" { | ||
region = "us-east-1" | ||
alias = "global_services" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
data "aws_caller_identity" "current" {} | ||
|
||
data "aws_region" "current" {} | ||
|
||
data "aws_iam_policy_document" "auth" { | ||
statement { | ||
actions = ["ssm:GetParametersByPath"] | ||
resources = ["arn:aws:ssm:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:parameter/${var.name}"] | ||
} | ||
|
||
statement { | ||
actions = ["secretsmanager:GetSecretValue"] | ||
resources = ["arn:aws:secretsmanager:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:secret:${var.name}/*"] | ||
} | ||
} | ||
|
||
data "aws_iam_policy_document" "rotation" { | ||
statement { | ||
actions = ["secretsmanager:PutSecretValue"] | ||
resources = ["arn:aws:secretsmanager:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:secret:${var.name}/*"] | ||
} | ||
} | ||
|
||
module "auth" { | ||
source = "../_lambda" | ||
|
||
name = var.name | ||
tags = var.tags | ||
package_url = var.package_url | ||
timeout = 5 | ||
iam_policy_override_json = data.aws_iam_policy_document.auth.json | ||
lambda_at_edge = true | ||
} | ||
|
||
module "rotation" { | ||
source = "../_lambda" | ||
|
||
name = "${var.name}-rotation" | ||
tags = var.tags | ||
package_url = "https://github.com/iress/cloudfront-auth/releases/download/${var.release_version}/rotate_key_pair.zip" | ||
timeout = 30 | ||
iam_policy_override_json = data.aws_iam_policy_document.rotation.json | ||
} | ||
|
||
resource "aws_lambda_permission" "allow_secrets_manager" { | ||
statement_id = "AllowExecutionFromSecretsManager" | ||
action = "lambda:InvokeFunction" | ||
function_name = module.rotation.lambda_arn | ||
principal = "secretsmanager.amazonaws.com" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
output "auth_lambda_arn" { | ||
value = module.auth.lambda_arn | ||
description = "The Amazon Resource Name (ARN) identifying the authentication Lambda Function Version" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Provider passed in should always be us-east-1 | ||
|
||
terraform { | ||
required_providers { | ||
aws = { | ||
source = "hashicorp/aws" | ||
version = "~> 3" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
resource "aws_secretsmanager_secret" "key_pair" { | ||
name = "${var.name}/key-pair" | ||
recovery_window_in_days = 0 | ||
tags = var.tags | ||
} | ||
|
||
resource "aws_secretsmanager_secret_rotation" "key_pair" { | ||
secret_id = aws_secretsmanager_secret.key_pair.id | ||
rotation_lambda_arn = module.rotation.lambda_arn | ||
|
||
rotation_rules { | ||
automatically_after_days = var.key_pair_rotation_period_days | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
variable "release_version" { | ||
description = "The name of the GitHub release version to deploy" | ||
type = string | ||
} | ||
|
||
variable "name" { | ||
description = "A name for the AWS resources created by this module" | ||
type = string | ||
} | ||
|
||
variable "tags" { | ||
description = "Tags to add to each resource" | ||
type = map(string) | ||
} | ||
|
||
variable "package_url" { | ||
description = "The URL of the Lambda authentication function package" | ||
type = string | ||
} | ||
|
||
variable "key_pair_rotation_period_days" { | ||
description = "The number of days between automatic scheduled rotations of the key pair" | ||
type = number | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
data "aws_iam_policy_document" "assume_role" { | ||
statement { | ||
actions = ["sts:AssumeRole"] | ||
|
||
principals { | ||
type = "Service" | ||
identifiers = var.lambda_at_edge ? ["lambda.amazonaws.com", "edgelambda.amazonaws.com"] : ["lambda.amazonaws.com"] | ||
} | ||
} | ||
} | ||
|
||
data "aws_iam_policy_document" "execution" { | ||
override_json = var.iam_policy_override_json | ||
|
||
statement { | ||
sid = "logs" | ||
|
||
actions = [ | ||
"logs:CreateLogGroup", | ||
"logs:CreateLogStream", | ||
"logs:PutLogEvents" | ||
] | ||
|
||
resources = ["arn:aws:logs:*:*:*"] | ||
} | ||
} | ||
|
||
resource "aws_iam_role" "lambda" { | ||
name = var.name | ||
assume_role_policy = data.aws_iam_policy_document.assume_role.json | ||
tags = var.tags | ||
} | ||
|
||
resource "aws_iam_role_policy" "execution" { | ||
name = var.name | ||
role = aws_iam_role.lambda.id | ||
policy = data.aws_iam_policy_document.execution.json | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
locals { | ||
package_directory = "${path.module}/packages" | ||
package_filename = basename(var.package_url) | ||
} | ||
|
||
# Always download the lambda package if it does not exist | ||
resource "null_resource" "download" { | ||
triggers = { | ||
always_run = uuid() | ||
} | ||
|
||
provisioner "local-exec" { | ||
command = "test -f ${local.package_directory}/${local.package_filename} || (mkdir -p ${local.package_directory} && wget -P ${local.package_directory} ${var.package_url})" | ||
} | ||
} | ||
|
||
resource "aws_lambda_function" "main" { | ||
filename = "${local.package_directory}/${local.package_filename}" | ||
function_name = var.name | ||
role = aws_iam_role.lambda.arn | ||
handler = "index.handler" | ||
source_code_hash = base64sha256(var.package_url) | ||
runtime = "nodejs14.x" | ||
timeout = var.timeout | ||
publish = var.lambda_at_edge | ||
tags = var.tags | ||
|
||
# Ensure the lambda function is created after the package is downloaded | ||
depends_on = [ | ||
null_resource.download | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
output "lambda_arn" { | ||
value = var.lambda_at_edge ? aws_lambda_function.main.qualified_arn : aws_lambda_function.main.arn | ||
description = "The Amazon Resource Name (ARN) identifying the Lambda Function Version" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Provider passed in should always be us-east-1 | ||
|
||
terraform { | ||
required_providers { | ||
aws = { | ||
source = "hashicorp/aws" | ||
version = "~> 3" | ||
} | ||
} | ||
} |
Oops, something went wrong.