Compare commits
2 Commits
f992fc540e
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11c5aee0f1 | ||
|
|
1b706fe858 |
@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
### Added
|
||||
- Added S3 bucket provisioning terraform configuration (#59)
|
||||
- Creates an S3 bucket to be used for anything Orchard
|
||||
- Creates a log bucket for any logs tracking the S3 bucket
|
||||
- Added transparent PyPI proxy implementing PEP 503 Simple API (#108)
|
||||
- `GET /pypi/simple/` - package index (proxied from upstream)
|
||||
- `GET /pypi/simple/{package}/` - version list with rewritten download links
|
||||
|
||||
19
provisioners/modules/aws-s3/.devcontainer/devcontainer.json
Normal file
19
provisioners/modules/aws-s3/.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "EC2 Provisioner Dev Container",
|
||||
"image": "registry.global.bsf.tools/esv/bsf/bsf-integration/dev-env-setup/provisioner_image:v0.18.1",
|
||||
"mounts": [
|
||||
"source=${localEnv:HOME}/.ssh,target=/home/user/.ssh,type=bind,consistency=cached",
|
||||
"source=${localEnv:HOME}/.okta,target=/home/user/.okta,type=bind,consistency=cached",
|
||||
"source=${localEnv:HOME}/.netrc,target=/home/user/.netrc,type=bind,consistency=cached"
|
||||
],
|
||||
"forwardPorts": [
|
||||
8000
|
||||
],
|
||||
"runArgs": [
|
||||
"--network=host"
|
||||
],
|
||||
"containerUser": "ubuntu",
|
||||
"remoteUser": "ubuntu",
|
||||
"updateRemoteUserUID": true,
|
||||
"onCreateCommand": "sudo usermod -s /bin/bash ubuntu"
|
||||
}
|
||||
70
provisioners/modules/aws-s3/data.tf
Normal file
70
provisioners/modules/aws-s3/data.tf
Normal file
@@ -0,0 +1,70 @@
|
||||
data "aws_caller_identity" "current" {}
|
||||
|
||||
# Main S3 bucket policy to reject HTTPS requests
|
||||
data "aws_iam_policy_document" "s3_reject_https_policy" {
|
||||
statement {
|
||||
sid = "s3RejectHTTPS"
|
||||
effect = "Deny"
|
||||
|
||||
principals {
|
||||
type = "*"
|
||||
identifiers = ["*"]
|
||||
}
|
||||
|
||||
actions = ["s3:*"]
|
||||
|
||||
resources = [
|
||||
aws_s3_bucket.s3_bucket.arn,
|
||||
"${aws_s3_bucket.s3_bucket.arn}/*",
|
||||
]
|
||||
|
||||
condition {
|
||||
test = "Bool"
|
||||
variable = "aws:SecureTransport"
|
||||
values = ["false"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Logging bucket policy to reject HTTPS requests and take logs
|
||||
data "aws_iam_policy_document" "logging_bucket_policy" {
|
||||
statement {
|
||||
principals {
|
||||
identifiers = ["logging.s3.amazonaws.com"]
|
||||
type = "Service"
|
||||
}
|
||||
|
||||
actions = ["s3:PutObject"]
|
||||
|
||||
resources = ["${aws_s3_bucket.logging.arn}/*"]
|
||||
|
||||
condition {
|
||||
test = "StringEquals"
|
||||
variable = "aws:SourceAccount"
|
||||
values = [data.aws_caller_identity.current.account_id]
|
||||
}
|
||||
}
|
||||
|
||||
statement {
|
||||
sid = "loggingRejectHTTPS"
|
||||
effect = "Deny"
|
||||
|
||||
principals {
|
||||
type = "*"
|
||||
identifiers = ["*"]
|
||||
}
|
||||
|
||||
actions = ["s3:*"]
|
||||
|
||||
resources = [
|
||||
aws_s3_bucket.logging.arn,
|
||||
"${aws_s3_bucket.logging.arn}/*"
|
||||
]
|
||||
|
||||
condition {
|
||||
test = "Bool"
|
||||
variable = "aws:SecureTransport"
|
||||
values = ["false"]
|
||||
}
|
||||
}
|
||||
}
|
||||
12
provisioners/modules/aws-s3/main.tf
Normal file
12
provisioners/modules/aws-s3/main.tf
Normal file
@@ -0,0 +1,12 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = ">= 6.28"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "aws" {
|
||||
region = "us-gov-west-1"
|
||||
}
|
||||
137
provisioners/modules/aws-s3/s3.tf
Normal file
137
provisioners/modules/aws-s3/s3.tf
Normal file
@@ -0,0 +1,137 @@
|
||||
# Disable warnings about MFA delete and IAM access analyzer (currently cannot support them)
|
||||
# kics-scan disable=c5b31ab9-0f26-4a49-b8aa-4cc064392f4d,e592a0c5-5bdb-414c-9066-5dba7cdea370
|
||||
|
||||
# Bucket to actually store artifacts
|
||||
resource "aws_s3_bucket" "s3_bucket" {
|
||||
bucket = var.bucket
|
||||
|
||||
tags = {
|
||||
Name = "Orchard S3 Provisioning Bucket"
|
||||
Environment = var.environment
|
||||
}
|
||||
}
|
||||
|
||||
# Control public access
|
||||
resource "aws_s3_bucket_public_access_block" "s3_bucket_public_access_block" {
|
||||
bucket = aws_s3_bucket.s3_bucket.id
|
||||
|
||||
block_public_acls = true
|
||||
block_public_policy = true
|
||||
ignore_public_acls = true
|
||||
restrict_public_buckets = true
|
||||
}
|
||||
|
||||
/*
|
||||
Our lifecycle rule is as follows:
|
||||
- Standard storage
|
||||
-> OneZone IA storage after 30 days
|
||||
-> Glacier storage after 180 days
|
||||
*/
|
||||
resource "aws_s3_bucket_lifecycle_configuration" "s3_bucket_lifecycle_configuration" {
|
||||
bucket = aws_s3_bucket.s3_bucket.id
|
||||
|
||||
rule {
|
||||
id = "Standard to OneZone"
|
||||
|
||||
filter {}
|
||||
|
||||
status = "Enabled"
|
||||
|
||||
transition {
|
||||
days = 30
|
||||
storage_class = "ONEZONE_IA"
|
||||
}
|
||||
}
|
||||
|
||||
rule {
|
||||
id = "OneZone to Glacier"
|
||||
|
||||
filter {}
|
||||
|
||||
status = "Enabled"
|
||||
|
||||
transition {
|
||||
days = 180
|
||||
storage_class = "GLACIER"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Enable versioning but without MFA delete enabled
|
||||
resource "aws_s3_bucket_versioning" "s3_bucket_versioning" {
|
||||
bucket = aws_s3_bucket.s3_bucket.id
|
||||
|
||||
versioning_configuration {
|
||||
status = "Enabled"
|
||||
}
|
||||
}
|
||||
|
||||
# Give preference to the bucket owner
|
||||
resource "aws_s3_bucket_ownership_controls" "s3_bucket_ownership_controls" {
|
||||
bucket = aws_s3_bucket.s3_bucket.id
|
||||
|
||||
rule {
|
||||
object_ownership = "BucketOwnerPreferred"
|
||||
}
|
||||
}
|
||||
|
||||
# Set access control list to private
|
||||
resource "aws_s3_bucket_acl" "s3_bucket_acl" {
|
||||
depends_on = [aws_s3_bucket_ownership_controls.s3_bucket_ownership_controls]
|
||||
|
||||
bucket = aws_s3_bucket.s3_bucket.id
|
||||
acl = var.acl
|
||||
}
|
||||
|
||||
# Bucket for logging
|
||||
resource "aws_s3_bucket" "logging" {
|
||||
bucket = "orchard-logging-bucket"
|
||||
|
||||
tags = {
|
||||
Name = "Orchard S3 Logging Bucket"
|
||||
Environment = var.environment
|
||||
}
|
||||
}
|
||||
|
||||
# Versioning for the logging bucket
|
||||
resource "aws_s3_bucket_versioning" "orchard_logging_bucket_versioning" {
|
||||
bucket = aws_s3_bucket.logging.id
|
||||
|
||||
versioning_configuration {
|
||||
status = "Enabled"
|
||||
}
|
||||
}
|
||||
|
||||
# Policies for the main s3 bucket and the logging bucket
|
||||
resource "aws_s3_bucket_policy" "s3_bucket_https_policy" {
|
||||
bucket = aws_s3_bucket.s3_bucket.id
|
||||
policy = data.aws_iam_policy_document.s3_reject_https_policy.json
|
||||
}
|
||||
resource "aws_s3_bucket_policy" "logging_policy" {
|
||||
bucket = aws_s3_bucket.logging.bucket
|
||||
policy = data.aws_iam_policy_document.logging_bucket_policy.json
|
||||
}
|
||||
|
||||
# Set up the logging bucket with folders with logs for both buckets
|
||||
resource "aws_s3_bucket_logging" "s3_bucket_logging" {
|
||||
bucket = aws_s3_bucket.s3_bucket.bucket
|
||||
|
||||
target_bucket = aws_s3_bucket.logging.bucket
|
||||
target_prefix = "s3_log/"
|
||||
target_object_key_format {
|
||||
partitioned_prefix {
|
||||
partition_date_source = "EventTime"
|
||||
}
|
||||
}
|
||||
}
|
||||
resource "aws_s3_bucket_logging" "logging_bucket_logging" {
|
||||
bucket = aws_s3_bucket.logging.bucket
|
||||
|
||||
target_bucket = aws_s3_bucket.logging.bucket
|
||||
target_prefix = "log/"
|
||||
target_object_key_format {
|
||||
partitioned_prefix {
|
||||
partition_date_source = "EventTime"
|
||||
}
|
||||
}
|
||||
}
|
||||
17
provisioners/modules/aws-s3/variables.tf
Normal file
17
provisioners/modules/aws-s3/variables.tf
Normal file
@@ -0,0 +1,17 @@
|
||||
variable "bucket" {
|
||||
description = "Name of the S3 bucket"
|
||||
type = string
|
||||
default = "orchard-provisioning-bucket"
|
||||
}
|
||||
|
||||
variable "acl" {
|
||||
description = "Access control list for the bucket"
|
||||
type = string
|
||||
default = "private"
|
||||
}
|
||||
|
||||
variable "environment" {
|
||||
description = "Environment of the bucket"
|
||||
type = string
|
||||
default = "Development"
|
||||
}
|
||||
Reference in New Issue
Block a user