commit 86981a13e305f474aa8fc283289698497ce1c175 Author: Vojtech Mares Date: Wed Oct 16 10:58:42 2024 +0200 feat: initial commit diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..87a0020 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +end_of_line = lf +max_line_length = null + +[Makefile] +indent_style = tab diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2272f6e --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.terraform +*.tfstate* +*.auto.tfvars diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl new file mode 100644 index 0000000..166ac0b --- /dev/null +++ b/.terraform.lock.hcl @@ -0,0 +1,25 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.72.0" + constraints = "~> 5.72" + hashes = [ + "h1:g7DtrWPK6KyZgqy6ZxYsSNhiVu/iPNLWnV7LKsJn/Q8=", + "zh:1a5e979b0c68063e1cdde592864fbfd0566f81c2125f811e96c9d85815d9a5fb", + "zh:2c1cd5f43748ab9cf4127fcc7cb73535b01ebb0408b14edf4f0e9475521ab8ea", + "zh:32749d892279fb14ce2a02ca4f7d25891983464f6696ed62e4a4350ee7931d02", + "zh:32ece5073409de4a25ca7b35e246117da7915683eb6317797b0c98e8b9b4cfbd", + "zh:3b7bb7be87e2ab432c0a30d085ef9a06b87def29f69cf5154bfc07bec7811db4", + "zh:5f986460e947675c9f85cc233c68b9af16385ac2e66c0ae22ed3501cd482abf5", + "zh:6ac164504e04d1b6d83762f50896005362c250a69203e5f25313b410711e826b", + "zh:6e639b8ddc44a299fef194d5792f6df69b26e350e44185600bbac8e1a8b2fbd3", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9b396ba2682256f5321162306d2bea5c276b8cd1a5f877599746518804554e80", + "zh:ab0688723e14acdd9d9f244086be7c22e2b938add611b814ce7b1662484e5d08", + "zh:c2a6453f223b7a2491a75481ef30421bc15e1983530e082467bcfa99553dca51", + "zh:d794b429ef1c259188a31626725af18e6ac8a9bbe1478484f8d0a0db57703335", + "zh:d86fb03571f8446928659efad065a235dda6320fdf893b575c54ae9df5adfda8", + "zh:ec27eddf86ee2f2003ae87faf269fac379311531394cf5292b9c31d011b9a873", + ] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..a8db65a --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# strapi-infrastructure + +This repository holds Terraform code to provision necessary infrastructure for +running Strapi as my CMS. + +This manages the following AWS resources: + +- S3 bucket +- IAM user +- IAM user permissions +- IAM user permission attachment + +This is done for two environments, **live** and **local**. diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..fc5731c --- /dev/null +++ b/main.tf @@ -0,0 +1,214 @@ +# local development +resource "aws_s3_bucket" "strapi_uploads_local" { + bucket = "mareshq-strapi-uploads-local" + + tags = { + Name = "mareshq-strapi-uploads-local" + Environment = "local" + ManagedBy = "Terraform" + For = "cms.mareshq.com" + } +} + +resource "aws_s3_bucket_ownership_controls" "strapi_uploads_local" { + bucket = aws_s3_bucket.strapi_uploads_local.id + + rule { + object_ownership = "BucketOwnerPreferred" + } +} + +resource "aws_s3_bucket_public_access_block" "strapi_uploads_local" { + bucket = aws_s3_bucket.strapi_uploads_local.id + + block_public_acls = false + block_public_policy = true + ignore_public_acls = false + restrict_public_buckets = true +} + +resource "aws_s3_bucket_cors_configuration" "strapi_uploads_local" { + bucket = aws_s3_bucket.strapi_uploads_local.id + + cors_rule { + allowed_headers = ["*"] + allowed_methods = ["GET"] + allowed_origins = ["*"] + expose_headers = [] + max_age_seconds = 3000 + } +} + +resource "aws_iam_user" "strapi_uploads_local" { + name = "mareshq-strapi-uploads-local" + + tags = { + Name = "gitlab-backup" + Environment = "production" + ManagedBy = "Terraform" + For = "cms.mareshq.com" + } +} + +resource "aws_iam_user_policy" "strapi_uploads_local" { + name = "mareshq-strapi-uploads-local" + user = aws_iam_user.strapi_uploads_local.name + + policy = data.aws_iam_policy_document.strapi_uploads_local.json +} + +resource "aws_iam_access_key" "strapi_uploads_local" { + user = aws_iam_user.strapi_uploads_local.name +} + +output "strapi_uploads_local_credentials" { + value = { + access_key = aws_iam_access_key.strapi_uploads_local.id + secret_key = aws_iam_access_key.strapi_uploads_local.secret + } + sensitive = true +} + +data "aws_iam_policy_document" "strapi_uploads_local" { + version = "2012-10-17" + + statement { + effect = "Allow" + actions = [ + "s3:AbortMultipartUpload", + "s3:GetBucketAcl", + "s3:GetBucketLocation", + "s3:GetObject", + "s3:GetObjectAcl", + "s3:ListBucketMultipartUploads", + "s3:PutObject", + "s3:PutObjectAcl" + ] + resources = ["arn:aws:s3:::mareshq-strapi-uploads-local/*"] + } + + statement { + effect = "Allow" + actions = [ + "s3:GetBucketLocation", + "s3:ListAllMyBuckets" + ] + resources = ["*"] + } + + statement { + effect = "Allow" + actions = [ + "s3:ListBucket" + ] + resources = ["arn:aws:s3:::mareshq-strapi-uploads-local"] + } +} + +# live environment + +resource "aws_s3_bucket" "strapi_uploads_live" { + bucket = "mareshq-strapi-uploads-live" + + tags = { + Name = "mareshq-strapi-uploads-live" + Environment = "live" + ManagedBy = "Terraform" + For = "cms.mareshq.com" + } +} + +resource "aws_s3_bucket_ownership_controls" "strapi_uploads_live" { + bucket = aws_s3_bucket.strapi_uploads_live.id + + rule { + object_ownership = "BucketOwnerPreferred" + } +} + +resource "aws_s3_bucket_public_access_block" "strapi_uploads_live" { + bucket = aws_s3_bucket.strapi_uploads_live.id + + block_public_acls = false + block_public_policy = true + ignore_public_acls = false + restrict_public_buckets = true +} + +resource "aws_s3_bucket_cors_configuration" "strapi_uploads_live" { + bucket = aws_s3_bucket.strapi_uploads_live.id + + cors_rule { + allowed_headers = ["*"] + allowed_methods = ["GET"] + allowed_origins = ["*"] + expose_headers = [] + max_age_seconds = 3000 + } +} + +resource "aws_iam_user" "strapi_uploads_live" { + name = "mareshq-strapi-uploads-live" + + tags = { + Name = "gitlab-backup" + Environment = "production" + ManagedBy = "Terraform" + For = "cms.mareshq.com" + } +} + +resource "aws_iam_user_policy" "strapi_uploads_live" { + name = "mareshq-strapi-uploads-live" + user = aws_iam_user.strapi_uploads_live.name + + policy = data.aws_iam_policy_document.strapi_uploads_live.json +} + +resource "aws_iam_access_key" "strapi_uploads_live" { + user = aws_iam_user.strapi_uploads_live.name +} + +output "strapi_uploads_live_credentials" { + value = { + access_key = aws_iam_access_key.strapi_uploads_live.id + secret_key = aws_iam_access_key.strapi_uploads_live.secret + } + sensitive = true +} + +data "aws_iam_policy_document" "strapi_uploads_live" { + version = "2012-10-17" + + statement { + effect = "Allow" + actions = [ + "s3:AbortMultipartUpload", + "s3:GetBucketAcl", + "s3:GetBucketLocation", + "s3:GetObject", + "s3:GetObjectAcl", + "s3:ListBucketMultipartUploads", + "s3:PutObject", + "s3:PutObjectAcl" + ] + resources = ["arn:aws:s3:::mareshq-strapi-uploads-live/*"] + } + + statement { + effect = "Allow" + actions = [ + "s3:GetBucketLocation", + "s3:ListAllMyBuckets" + ] + resources = ["*"] + } + + statement { + effect = "Allow" + actions = [ + "s3:ListBucket" + ] + resources = ["arn:aws:s3:::mareshq-strapi-uploads-live"] + } +} diff --git a/versions.tf b/versions.tf new file mode 100644 index 0000000..c5fd81e --- /dev/null +++ b/versions.tf @@ -0,0 +1,25 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.72" + } + } +} + +# Configure the AWS Provider +provider "aws" { + region = "eu-central-1" + access_key = var.aws_access_key + secret_key = var.aws_secret_key +} + +variable "aws_access_key" { + type = string + sensitive = true +} + +variable "aws_secret_key" { + type = string + sensitive = true +}