diff --git a/terraform/digitalocean/spacelift/backend-vars/main.tfvars b/terraform/digitalocean/spacelift/backend-vars/main.tfvars new file mode 100644 index 000000000..785e094ac --- /dev/null +++ b/terraform/digitalocean/spacelift/backend-vars/main.tfvars @@ -0,0 +1,18 @@ +# Copyright (C) Nicolas Lamirault +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +bucket = "portefaix-digitalocean-tfstates" +key = "spacelift/terraform.tfstate" diff --git a/terraform/digitalocean/spacelift/backend.tf b/terraform/digitalocean/spacelift/backend.tf new file mode 100644 index 000000000..b97f3303e --- /dev/null +++ b/terraform/digitalocean/spacelift/backend.tf @@ -0,0 +1,31 @@ +# Copyright (C) Nicolas Lamirault +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +terraform { + backend "s3" { + region = "us-east-1" # "auto" + + skip_credentials_validation = true + skip_region_validation = true + skip_requesting_account_id = true + skip_metadata_api_check = true + skip_s3_checksum = true + + endpoints { + s3 = format("https://%s.r2.cloudflarestorage.com", var.cloudflare_account_id) + } + } +} diff --git a/terraform/digitalocean/spacelift/contexts.tf b/terraform/digitalocean/spacelift/contexts.tf new file mode 100644 index 000000000..bce6e1866 --- /dev/null +++ b/terraform/digitalocean/spacelift/contexts.tf @@ -0,0 +1,87 @@ +# Copyright (C) Nicolas Lamirault +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +resource "spacelift_context" "this" { + for_each = toset(var.environments) + + name = format("%s-%s", local.cloud_provider, each.value) + space_id = spacelift_space.environment[each.value].id + description = "Created by Terraform" + labels = local.labels +} + +resource "spacelift_environment_variable" "aws_acces_key" { + for_each = toset(var.environments) + + context_id = spacelift_context.this[each.value].id + name = "AWS_ACCESS_KEY_ID" + value = var.access_key + write_only = true +} + +resource "spacelift_environment_variable" "aws_secret_key" { + for_each = toset(var.environments) + + context_id = spacelift_context.this[each.value].id + name = "AWS_SECRET_ACCESS_KEY" + value = var.secret_access_key + write_only = true +} + +resource "spacelift_environment_variable" "aws_endpoint_url_s3" { + for_each = toset(var.environments) + + context_id = spacelift_context.this[each.value].id + name = "AWS_ENDPOINT_URL_S3" + value = format("https://%s.r2.cloudflarestorage.com", var.cloudflare_account_id) + write_only = true +} + +resource "spacelift_environment_variable" "cloudflare_account_id" { + for_each = toset(var.environments) + + context_id = spacelift_context.this[each.value].id + name = "TF_VAR_cloudflare_account_id" + value = var.cloudflare_account_id + write_only = true +} + +resource "spacelift_environment_variable" "cloudflare_api_token" { + for_each = toset(var.environments) + + context_id = spacelift_context.this[each.value].id + name = "TF_VAR_cloudflare_api_token" + value = var.cloudflare_api_token + write_only = true +} + +# resource "spacelift_environment_variable" "github_oauth_client_id" { +# for_each = toset(var.environments) + +# context_id = spacelift_context.this[each.value].id +# name = "TF_VAR_github_oauth_client_id" +# value = var.github_oauth_client_id +# write_only = true +# } + +# resource "spacelift_environment_variable" "github_oauth_client_secret" { +# for_each = toset(var.environments) + +# context_id = spacelift_context.this[each.value].id +# name = "TF_VAR_github_oauth_client_secret" +# value = var.github_oauth_client_secret +# write_only = true +# } diff --git a/terraform/digitalocean/vpc/dev/backend.tf b/terraform/digitalocean/spacelift/data.tf similarity index 78% rename from terraform/digitalocean/vpc/dev/backend.tf rename to terraform/digitalocean/spacelift/data.tf index eb59b6f07..994d4efa4 100644 --- a/terraform/digitalocean/vpc/dev/backend.tf +++ b/terraform/digitalocean/spacelift/data.tf @@ -14,13 +14,6 @@ # # SPDX-License-Identifier: Apache-2.0 -terraform { - backend "remote" { - hostname = "app.terraform.io" - organization = "portefaix" - - workspaces { - name = "portefaix-digitalocean-dev-vpc" - } - } +data "spacelift_space" "this" { + space_id = var.root_space_id } diff --git a/terraform/digitalocean/spacelift/locals.tf b/terraform/digitalocean/spacelift/locals.tf new file mode 100644 index 000000000..0d80f5d01 --- /dev/null +++ b/terraform/digitalocean/spacelift/locals.tf @@ -0,0 +1,29 @@ +# Copyright (C) Nicolas Lamirault +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +locals { + cloud_provider = "digitalocean" + labels = [local.cloud_provider] + + stack_dependencies = flatten([ + for stack_key, stack in var.stacks : [ + for dependency in stack.dependencies : { + stack_name = stack_key + dependency_name = dependency + } + ] + ]) +} diff --git a/terraform/digitalocean/spacelift/main.tf b/terraform/digitalocean/spacelift/main.tf new file mode 100644 index 000000000..b1ea2b514 --- /dev/null +++ b/terraform/digitalocean/spacelift/main.tf @@ -0,0 +1,30 @@ +# Copyright (C) Nicolas Lamirault +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +terraform { + required_version = ">= 1.0.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = "5.82.2" + } + spacelift = { + source = "spacelift-io/spacelift" + version = "1.19.0" + } + } +} diff --git a/terraform/digitalocean/spacelift/outputs.tf b/terraform/digitalocean/spacelift/outputs.tf new file mode 100644 index 000000000..fa5bec036 --- /dev/null +++ b/terraform/digitalocean/spacelift/outputs.tf @@ -0,0 +1,15 @@ +# Copyright (C) Nicolas Lamirault +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 diff --git a/terraform/digitalocean/spacelift/provider.tf b/terraform/digitalocean/spacelift/provider.tf new file mode 100644 index 000000000..ab85e4470 --- /dev/null +++ b/terraform/digitalocean/spacelift/provider.tf @@ -0,0 +1,31 @@ +# Copyright (C) Nicolas Lamirault +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +provider "aws" { + alias = "cloudflare_r2" + region = "auto" + skip_credentials_validation = true + skip_region_validation = true + skip_requesting_account_id = true + skip_metadata_api_check = true + skip_get_ec2_platforms = true + endpoints { + s3 = format("https://%s.r2.cloudflarestorage.com", var.cloudflare_account_id) + } +} + +provider "spacelift" { +} diff --git a/terraform/digitalocean/spacelift/spaces.tf b/terraform/digitalocean/spacelift/spaces.tf new file mode 100644 index 000000000..5fd332bb8 --- /dev/null +++ b/terraform/digitalocean/spacelift/spaces.tf @@ -0,0 +1,31 @@ +# Copyright (C) Nicolas Lamirault +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +resource "spacelift_space" "this" { + name = var.space + parent_space_id = data.spacelift_space.this.id + description = "Created by Terraform." + labels = concat(local.labels) +} + +resource "spacelift_space" "environment" { + for_each = toset(var.environments) + + name = format("%s-%s", var.space, each.value) + parent_space_id = spacelift_space.this.id + description = "Created by Terraform." + labels = concat(local.labels, [each.value]) +} diff --git a/terraform/digitalocean/spacelift/stacks.tf b/terraform/digitalocean/spacelift/stacks.tf new file mode 100644 index 000000000..23e719c67 --- /dev/null +++ b/terraform/digitalocean/spacelift/stacks.tf @@ -0,0 +1,53 @@ +# Copyright (C) Nicolas Lamirault +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +resource "spacelift_stack" "this" { + for_each = var.stacks + + administrative = true + autodeploy = false + branch = each.value.branch + description = "Created by Terraform" + name = each.key + project_root = format("%s/%s", each.value.project_root, each.value.environment) + space_id = spacelift_space.environment[each.value.environment].id + protect_from_deletion = false + manage_state = true + terraform_external_state_access = true + terraform_workflow_tool = "OPEN_TOFU" + repository = var.repository + labels = concat(local.labels, each.value.labels, [each.value.environment]) + additional_project_globs = [ + format("%s/modules/*", each.value.project_root) + ] +} + +resource "spacelift_context_attachment" "this" { + for_each = var.stacks + + context_id = spacelift_context.this[each.value.environment].id + stack_id = spacelift_stack.this[each.key].id + priority = 0 +} + +resource "spacelift_stack_dependency" "this" { + for_each = tomap({ + for dep in local.stack_dependencies : "${dep.stack_name}.${dep.dependency_name}" => dep + }) + + stack_id = spacelift_stack.this[each.value.stack_name].id + depends_on_stack_id = spacelift_stack.this[each.value.dependency_name].id +} diff --git a/terraform/digitalocean/spacelift/tfvars/main.tfvars b/terraform/digitalocean/spacelift/tfvars/main.tfvars new file mode 100644 index 000000000..928fa8485 --- /dev/null +++ b/terraform/digitalocean/spacelift/tfvars/main.tfvars @@ -0,0 +1,52 @@ +# Copyright (C) Nicolas Lamirault +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +#####################################################################"" +# Provider + + +############################################################################## +# + +repository = "portefaix-infrastructure" + +space = "digitalocean" + +environments = ["dev"] + +stacks = { + portefaix-digitalocean-dev-vpc = { + project_root = "terraform/digitalocean/vpc" + labels = ["core", "vpc"] + environment = "dev" + branch = "main" + dependencies = [] + }, + portefaix-digitalocean-dev-doks = { + project_root = "terraform/digitalocean/doks" + labels = ["core", "doks"] + environment = "dev" + branch = "main" + dependencies = [] + }, + portefaix-digitalocean-dev-containerregistry = { + project_root = "terraform/digitalocean/containerregistry" + labels = ["core", "containerregistry"] + environment = "dev" + branch = "main" + dependencies = [] + } +} diff --git a/terraform/digitalocean/spacelift/variables.tf b/terraform/digitalocean/spacelift/variables.tf new file mode 100644 index 000000000..4c974d223 --- /dev/null +++ b/terraform/digitalocean/spacelift/variables.tf @@ -0,0 +1,77 @@ +# Copyright (C) Nicolas Lamirault +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +############################################################################# +# Provider + +variable "cloudflare_account_id" { + description = "The Cloudflare account ID" + type = string +} + +variable "cloudflare_api_token" { + description = "The Cloudflare API token" + type = string +} + +############################################################################# +# Spacelift + +variable "root_space_id" { + type = string + description = "The Portefaix space" +} + +variable "space" { + type = string + description = "The space for this project" +} + +variable "environments" { + type = list(string) + description = "List of environments" +} + +variable "repository" { + type = string + description = "Github repository" +} + +variable "stacks" { + type = map(object({ + project_root = string + branch = string + labels = list(string) + environment = string + dependencies = list(string) + })) + description = "Spacelift stacks" +} + +variable "access_key" { + type = string + description = "AWS access key for Cloudflare R2" +} + +variable "secret_access_key" { + type = string + description = "AWS secret key for Cloudflare R2" +} + +variable "env_do_token" { + type = string + description = "The DigitalOcean API token" +} diff --git a/terraform/digitalocean/terraform-cloud/backend-vars/main.tfvars b/terraform/digitalocean/terraform-cloud/backend-vars/main.tfvars index 572aa10c4..785e094ac 100644 --- a/terraform/digitalocean/terraform-cloud/backend-vars/main.tfvars +++ b/terraform/digitalocean/terraform-cloud/backend-vars/main.tfvars @@ -15,4 +15,4 @@ # SPDX-License-Identifier: Apache-2.0 bucket = "portefaix-digitalocean-tfstates" -key = "terraform-cloud/terraform.tfstate" +key = "spacelift/terraform.tfstate" diff --git a/terraform/digitalocean/terraform-cloud/backend.tf b/terraform/digitalocean/terraform-cloud/backend.tf index 68f87f1c5..b97f3303e 100644 --- a/terraform/digitalocean/terraform-cloud/backend.tf +++ b/terraform/digitalocean/terraform-cloud/backend.tf @@ -16,11 +16,16 @@ terraform { backend "s3" { - # https://developers.cloudflare.com/r2/platform/s3-compatibility/api/#bucket-region - region = "auto" - # skip checks that don't work in CloudFlare R2 + region = "us-east-1" # "auto" + skip_credentials_validation = true skip_region_validation = true + skip_requesting_account_id = true skip_metadata_api_check = true + skip_s3_checksum = true + + endpoints { + s3 = format("https://%s.r2.cloudflarestorage.com", var.cloudflare_account_id) + } } } diff --git a/terraform/digitalocean/terraform-cloud/provider.tf b/terraform/digitalocean/terraform-cloud/provider.tf index 14b9603ba..3001f6c48 100644 --- a/terraform/digitalocean/terraform-cloud/provider.tf +++ b/terraform/digitalocean/terraform-cloud/provider.tf @@ -40,6 +40,5 @@ provider "aws" { } } -provider "tfe" { - hostname = "app.terraform.io" +provider "spacelift" { }