diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml new file mode 100644 index 0000000..4386e48 --- /dev/null +++ b/.github/workflows/deploy.yaml @@ -0,0 +1,44 @@ +name: Deploy to Cloud Run + +on: + push: + branches: [ "main" ] + workflow_dispatch: + +jobs: + deploy: + runs-on: ubuntu-latest + + permissions: + contents: read # clone the repository contents + id-token: write # federates with GCP + + steps: + - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v3 + + - uses: google-github-actions/auth@ceee102ec2387dd9e844e01b530ccd4ec87ce955 # v0 + id: auth + with: + token_format: 'access_token' + project_id: 'octo-sts' + workload_identity_provider: 'projects/96355665038/locations/global/workloadIdentityPools/github-pool/providers/github-provider' + service_account: 'github-identity@octo-sts.iam.gserviceaccount.com' + + - uses: 'docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a' # v2 + with: + username: 'oauth2accesstoken' + password: '${{ steps.auth.outputs.access_token }}' + registry: 'gcr.io' + + # Attempt to deploy the terraform configuration + - uses: hashicorp/setup-terraform@a1502cd9e758c50496cc9ac5308c4843bcd56d36 # v2.0.0 + with: + terraform_version: 1.6 + + - working-directory: ./iac + run: | + terraform init + + terraform plan + + terraform apply -auto-approve diff --git a/iac/bootstrap/main.tf b/iac/bootstrap/main.tf new file mode 100644 index 0000000..59418da --- /dev/null +++ b/iac/bootstrap/main.tf @@ -0,0 +1,65 @@ +terraform { + backend "gcs" { + bucket = "octo-sts-terraform-state" + prefix = "/bootstrap" + } +} + +provider "google" { project = var.project_id } +provider "google-beta" { project = var.project_id } + +resource "google_project_service" "iamcredentials-api" { + project = var.project_id + service = "iamcredentials.googleapis.com" + disable_dependent_services = false + disable_on_destroy = false +} + +resource "google_iam_workload_identity_pool" "github_pool" { + project = var.project_id + provider = google-beta + workload_identity_pool_id = "github-pool" + display_name = "Github pool" + depends_on = [google_project_service.iamcredentials-api] +} + +resource "google_iam_workload_identity_pool_provider" "github_provider" { + project = var.project_id + provider = google-beta + workload_identity_pool_id = google_iam_workload_identity_pool.github_pool.workload_identity_pool_id + workload_identity_pool_provider_id = "github-provider" # This gets 4-32 alphanumeric characters (and '-') + display_name = "Github provider" + + attribute_mapping = { + "google.subject" = "assertion.sub" + "attribute.sub" = "assertion.sub" + } + + oidc { + issuer_uri = "https://token.actions.githubusercontent.com" + } +} + +output "provider" { + value = google_iam_workload_identity_pool_provider.github_provider.name +} + +resource "google_service_account" "github_identity" { + project = var.project_id + account_id = "github-identity" +} + +resource "google_service_account_iam_binding" "allow_github_impersonation" { + service_account_id = google_service_account.github_identity.name + role = "roles/iam.workloadIdentityUser" + + members = [ + "principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.github_pool.name}/attribute.sub/repo:mattmoor/octo-sts:ref:refs/heads/main", + ] +} + +resource "google_project_iam_member" "github_owner" { + project = var.project_id + role = "roles/owner" + member = "serviceAccount:${google_service_account.github_identity.email}" +} diff --git a/iac/bootstrap/terraform.tfvars b/iac/bootstrap/terraform.tfvars new file mode 100644 index 0000000..1958372 --- /dev/null +++ b/iac/bootstrap/terraform.tfvars @@ -0,0 +1 @@ +project_id = "octo-sts" diff --git a/iac/bootstrap/variables.tf b/iac/bootstrap/variables.tf new file mode 100644 index 0000000..75d745e --- /dev/null +++ b/iac/bootstrap/variables.tf @@ -0,0 +1,3 @@ +variable "project_id" { + description = "The project ID where all resources created will reside." +} diff --git a/iac/main.tf b/iac/main.tf index 14f4923..ec17a5b 100644 --- a/iac/main.tf +++ b/iac/main.tf @@ -1,12 +1,15 @@ terraform { backend "gcs" { - bucket = "mattmoor-chainguard-terraform-state" + bucket = "octo-sts-terraform-state" prefix = "/octo-sts" + # bucket = "mattmoor-chainguard-terraform-state" + # prefix = "/octo-sts" } } provider "google" { project = var.project_id } provider "google-beta" { project = var.project_id } +provider "ko" { docker_repo = "gcr.io/${var.project_id}" } // Create a network with several regional subnets module "networking" {