Octopus - EKS Reference Architecture

Octopus.TerraformApply exported 2023-10-18 by mcasperson belongs to ‘Octopus’ category.

This step populates an Octopus space with the environments, feeds, accounts, lifecycles, projects, and runbooks required to deploy a sample application to an AWS EKS Kubernetes cluster. These resources combine to form a reference architecture teams can use to bootstrap an Octopus space with best practices and example projects. It is recommended that you run this step with the octopuslabs/terraform-workertools container image.

That this step assumes it is run on a cloud Octopus instance, or the default worker runs Linux, has Docker installed, and has PowerShell Core installed.

The step will not update existing projects, environments etc. If you wish to recreate these resource with the latest configuration, for example if this step is updated and you wish to see the latest settings, you must manually delete or rename the resources to be recreated.

Parameters

When steps based on the template are included in a project’s deployment process, the parameters below can be set.

AWS Access Key

ReferenceArchitecture.Eks.Aws.AccessKey =

This is the AWS Access Key. See the AWS docs for more information on creating access keys.

AWS Secret Key

ReferenceArchitecture.Eks.Aws.SecretKey =

This is the AWS Secret Key. See the AWS docs for more information on creating access keys.

Docker Hub Username

ReferenceArchitecture.Eks.Docker.Username =

The Docker Hub username. See the Docker docs for more information on creating a Docker Hub account.

Docker Hub Password

ReferenceArchitecture.Eks.Docker.Password =

The Docker Hub password. See the Docker docs for more information on creating a Docker Hub account.

GitHub Access Token

ReferenceArchitecture.Eks.GitHub.AccessToken =

The GitHub access token. Find more details in the GitHub documentation.

This value is used when populating GitHub repos with template projects. It can be left blank if you do not use the Create Template Github <platform> Project runbooks.

Octopus API Key

ReferenceArchitecture.Eks.Octopus.ApiKey =

The Octopus API key. See the Octopus docs for more details on creating an API Key.

Octopus Space ID

ReferenceArchitecture.Eks.Octopus.SpaceId = #{Octopus.Space.Id}

The Octopus space ID.

Octopus Server URL

ReferenceArchitecture.Eks.Octopus.ServerUrl = #{Octopus.Web.ServerUri}

The Octopus server URL.

Optional Terraform Apply Args

ReferenceArchitecture.Terraform.ApplyArgs =

Optional arguments passed to the terraform apply command. See the documentation for details on any optional variables that can be defined here. Leave this field blank unless you have a specific reason to change it.

Optional Terraform Init Args

ReferenceArchitecture.Terraform.InitArgs =

Optional arguments passed to the terraform init command. See the documentation for details on any optional variables that can be defined here. Leave this field blank unless you have a specific reason to change it.

Script body

Steps based on this template will execute the following undefined script.

undefined

Provided under the Apache License version 2.0.

Report an issue

To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.

{
  "Id": "87b2154a-5c8d-4c31-9680-575bb6df9789",
  "Name": "Octopus - EKS Reference Architecture",
  "Description": "This step populates an Octopus space with the environments, feeds, accounts, lifecycles, projects, and runbooks required to deploy a sample application to an AWS EKS Kubernetes cluster. These resources combine to form a reference architecture teams can use to bootstrap an Octopus space with best practices and example projects. It is recommended that you run this step with the `octopuslabs/terraform-workertools` [container image](https://octopus.com/docs/projects/steps/execution-containers-for-workers). \n\nThat this step assumes it is run on a cloud Octopus instance, or the default worker runs Linux, has Docker installed, and has PowerShell Core installed.\n\nThe step will not update existing projects, environments etc. If you wish to recreate these resource with the latest configuration, for example if this step is updated and you wish to see the latest settings, you must manually delete or rename the resources to be recreated.",
  "Version": 16,
  "ExportedAt": "2023-10-18T22:44:44.053Z",
  "ActionType": "Octopus.TerraformApply",
  "Author": "mcasperson",
  "Packages": [],
  "Parameters": [
    {
      "Id": "4b7395e1-97a2-4a5b-91a9-c82ac6e5c495",
      "Name": "ReferenceArchitecture.Eks.Aws.AccessKey",
      "Label": "AWS Access Key",
      "HelpText": "This is the AWS Access Key. See the [AWS docs](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html) for more information on creating access keys.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "bab9514f-4096-48ec-90b5-f55e42044e77",
      "Name": "ReferenceArchitecture.Eks.Aws.SecretKey",
      "Label": "AWS Secret Key",
      "HelpText": "This is the AWS Secret Key. See the [AWS docs](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html) for more information on creating access keys.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "0c3fd236-398d-4dd9-a39a-442f877c59e8",
      "Name": "ReferenceArchitecture.Eks.Docker.Username",
      "Label": "Docker Hub Username",
      "HelpText": "The Docker Hub username. See the [Docker docs](https://docs.docker.com/docker-id/) for more information on creating a Docker Hub account.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "e865ed5a-c17d-40cd-86d1-8cfb102d5b26",
      "Name": "ReferenceArchitecture.Eks.Docker.Password",
      "Label": "Docker Hub Password",
      "HelpText": "The Docker Hub password. See the [Docker docs](https://docs.docker.com/docker-id/) for more information on creating a Docker Hub account.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "2c8e5092-cb2b-4bcd-90f7-a1f969267497",
      "Name": "ReferenceArchitecture.Eks.GitHub.AccessToken",
      "Label": "GitHub Access Token",
      "HelpText": "The GitHub access token. Find more details in the [GitHub documentation](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens).\n\n\nThis value is used when populating GitHub repos with template projects. It can be left blank if you do not use the `Create Template Github <platform> Project` runbooks.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "03759c5c-fce1-4770-8bcc-0ed3004a0d81",
      "Name": "ReferenceArchitecture.Eks.Octopus.ApiKey",
      "Label": "Octopus API Key",
      "HelpText": "The Octopus API key. See the [Octopus docs](https://octopus.com/docs/octopus-rest-api/how-to-create-an-api-key) for more details on creating an API Key.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "003255fd-8bdb-4e5c-9646-5588eef5c524",
      "Name": "ReferenceArchitecture.Eks.Octopus.SpaceId",
      "Label": "Octopus Space ID",
      "HelpText": "The Octopus space ID.",
      "DefaultValue": "#{Octopus.Space.Id}",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "cf35bbb0-eb2f-4dec-84bd-1cef24361d0d",
      "Name": "ReferenceArchitecture.Eks.Octopus.ServerUrl",
      "Label": "Octopus Server URL",
      "HelpText": "The Octopus server URL.",
      "DefaultValue": "#{Octopus.Web.ServerUri}",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "e45078c1-d344-4315-a6f5-1295f6057d77",
      "Name": "ReferenceArchitecture.Terraform.ApplyArgs",
      "Label": "Optional Terraform Apply Args",
      "HelpText": "Optional arguments passed to the `terraform apply` command. See the [documentation](https://oc.to/wRvMoP) for details on any optional variables that can be defined here. Leave this field blank unless you have a specific reason to change it.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "MultiLineText"
      }
    },
    {
      "Id": "d68e37c6-23d1-4224-a973-1edcfa55fa2f",
      "Name": "ReferenceArchitecture.Terraform.InitArgs",
      "Label": "Optional Terraform Init Args",
      "HelpText": "Optional arguments passed to the `terraform init` command. See the [documentation](https://oc.to/wRvMoP) for details on any optional variables that can be defined here. Leave this field blank unless you have a specific reason to change it.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "MultiLineText"
      }
    }
  ],
  "Properties": {
    "Octopus.Action.GoogleCloud.UseVMServiceAccount": "True",
    "Octopus.Action.GoogleCloud.ImpersonateServiceAccount": "False",
    "Octopus.Action.Terraform.GoogleCloudAccount": "False",
    "Octopus.Action.Terraform.AzureAccount": "False",
    "Octopus.Action.Terraform.ManagedAccount": "None",
    "Octopus.Action.Terraform.AllowPluginDownloads": "True",
    "Octopus.Action.Script.ScriptSource": "Inline",
    "Octopus.Action.Terraform.RunAutomaticFileSubstitution": "True",
    "Octopus.Action.Terraform.PlanJsonOutput": "False",
    "Octopus.Action.Terraform.Template": "terraform {\n  required_providers {\n    octopusdeploy = { source = \"OctopusDeployLabs/octopusdeploy\", version = \"0.21.1\" }\n  }\n}\n\n#region Locals\nlocals {\n  # These local variables define the name of the projects created by this module.\n  infrastructure_project_name   = \"_ AWS EKS Infrastructure\"\n  project_template_project_name = \"Docker Project Templates\"\n  frontend_project_name         = \"EKS Octopub Frontend\"\n  products_project_name         = \"EKS Octopub Products\"\n  audits_project_name           = \"EKS Octopub Audits\"\n\n  development_environment_id         = length(data.octopusdeploy_environments.environment_development.environments) == 0 ? octopusdeploy_environment.environment_development[0].id : data.octopusdeploy_environments.environment_development.environments[0].id\n  test_environment_id                = length(data.octopusdeploy_environments.environment_test.environments) == 0 ? octopusdeploy_environment.environment_test[0].id : data.octopusdeploy_environments.environment_test.environments[0].id\n  production_environment_id          = length(data.octopusdeploy_environments.environment_production.environments) == 0 ? octopusdeploy_environment.environment_production[0].id : data.octopusdeploy_environments.environment_production.environments[0].id\n  sync_environment_id                = length(data.octopusdeploy_environments.environment_sync.environments) == 0 ? octopusdeploy_environment.environment_sync[0].id : data.octopusdeploy_environments.environment_sync.environments[0].id\n  security_environment_id            = length(data.octopusdeploy_environments.environment_security.environments) == 0 ? octopusdeploy_environment.environment_security[0].id : data.octopusdeploy_environments.environment_security.environments[0].id\n  featurebranch_environment_id       = length(data.octopusdeploy_environments.environment_featurebranch.environments) == 0 ? octopusdeploy_environment.environment_featurebranch[0].id : data.octopusdeploy_environments.environment_featurebranch.environments[0].id\n  this_instance_library_variable_set = length(data.octopusdeploy_library_variable_sets.this_instance.library_variable_sets) == 0 ? octopusdeploy_library_variable_set.this_instance[0].id : data.octopusdeploy_library_variable_sets.this_instance.library_variable_sets[0].id\n  github_library_variable_set        = length(data.octopusdeploy_library_variable_sets.github.library_variable_sets) == 0 ? octopusdeploy_library_variable_set.github[0].id : data.octopusdeploy_library_variable_sets.github.library_variable_sets[0].id\n  docker_library_variable_set        = length(data.octopusdeploy_library_variable_sets.docker.library_variable_sets) == 0 ? octopusdeploy_library_variable_set.docker[0].id : data.octopusdeploy_library_variable_sets.docker.library_variable_sets[0].id\n  docker_hub_feed_id                 = length(data.octopusdeploy_feeds.dockerhub.feeds) == 0 ? octopusdeploy_docker_container_registry.docker_hub[0].id : data.octopusdeploy_feeds.dockerhub.feeds[0].id\n  github_feed_id                     = length(data.octopusdeploy_feeds.github_feed.feeds) == 0 ? octopusdeploy_github_repository_feed.github_feed[0].id : data.octopusdeploy_feeds.github_feed.feeds[0].id\n  worker_pool_id                     = length(data.octopusdeploy_worker_pools.workerpool_hosted_ubuntu.worker_pools) == 0 ? \"\" : data.octopusdeploy_worker_pools.workerpool_hosted_ubuntu.worker_pools[0].id\n  aws_account                        = length(data.octopusdeploy_accounts.aws_account.accounts) == 0 ? octopusdeploy_aws_account.aws_account[0].id : data.octopusdeploy_accounts.aws_account.accounts[0].id\n  devops_lifecycle_id                = length(data.octopusdeploy_lifecycles.devsecops.lifecycles) == 0 ? octopusdeploy_lifecycle.lifecycle_devsecops[0].id : data.octopusdeploy_lifecycles.devsecops.lifecycles[0].id\n  featurebranch_lifecycle_id         = length(data.octopusdeploy_lifecycles.featurebranch.lifecycles) == 0 ? octopusdeploy_lifecycle.lifecycle_featurebranch[0].id : data.octopusdeploy_lifecycles.featurebranch.lifecycles[0].id\n  eks_project_group_id               = length(data.octopusdeploy_project_groups.eks.project_groups) == 0 ? octopusdeploy_project_group.project_group_eks[0].id : data.octopusdeploy_project_groups.eks.project_groups[0].id\n  project_templates_project_group_id = length(data.octopusdeploy_project_groups.project_templates.project_groups) == 0 ? octopusdeploy_project_group.project_group_project_templates[0].id : data.octopusdeploy_project_groups.project_templates.project_groups[0].id\n  application_lifecycle_id           = length(data.octopusdeploy_lifecycles.application.lifecycles) == 0 ? octopusdeploy_lifecycle.lifecycle_application[0].id : data.octopusdeploy_lifecycles.application.lifecycles[0].id\n  create_cluster_script              = <<-EOT\n  # Check to see if $IsWindows is available\n  if ($null -eq $IsWindows)\n  {\n      Write-Host \"Determining Operating System...\"\n      $IsWindows = ([System.Environment]::OSVersion.Platform -eq \"Win32NT\")\n      $IsLinux = ([System.Environment]::OSVersion.Platform -eq \"Unix\")\n  }\n\n  Function Invoke-CustomCommand\n  {\n      Param (\n          $commandPath,\n          $commandArguments,\n          $workingDir = (Get-Location),\n          $path = @()\n      )\n\n      $path += $env:PATH\n      $newPath = $path -join [IO.Path]::PathSeparator\n\n      $pinfo = New-Object System.Diagnostics.ProcessStartInfo\n      $pinfo.FileName = $commandPath\n      $pinfo.WorkingDirectory = $workingDir\n      $pinfo.RedirectStandardError = $true\n      $pinfo.RedirectStandardOutput = $true\n      $pinfo.UseShellExecute = $false\n      $pinfo.Arguments = $commandArguments\n      $pinfo.EnvironmentVariables[\"PATH\"] = $newPath\n      $p = New-Object System.Diagnostics.Process\n      $p.StartInfo = $pinfo\n      $p.Start() | Out-Null\n      $p.WaitForExit()\n      $executionResults = [pscustomobject]@{\n          StdOut = $p.StandardOutput.ReadToEnd()\n          StdErr = $p.StandardError.ReadToEnd()\n          ExitCode = $p.ExitCode\n      }\n\n      return $executionResults\n\n  }\n\n  function Write-Results\n  {\n      param (\n          $results\n      )\n\n      if (![String]::IsNullOrWhiteSpace($results.StdOut))\n      {\n          Write-Verbose $results.StdOut\n      }\n      if (![String]::IsNullOrWhiteSpace($results.StdErr))\n      {\n          Write-Verbose $results.StdErr\n      }\n  }\n\n  function Install-App\n  {\n      param (\n          $app,\n          $versionArgument,\n          $download,\n          $downloadFileName,\n          $downloadBinary\n      )\n\n      Try\n      {\n          if ($versionArgument -is [array])\n          {\n              $results = Invoke-CustomCommand $app $versionArgument\n          } else {\n              $results = Invoke-CustomCommand $app @($versionArgument)\n          }\n          if ($results.ExitCode -ne 0)\n          {\n              throw \"Exit code was \" + $results.ExitCode\n          }\n          return $app\n      }\n      Catch\n      {\n          # Ignore the error, we assume the app does not exist\n      }\n\n      $fileWithoutExtenion = [System.IO.Path]::GetFileNameWithoutExtension($downloadFileName)\n      $extension = [System.IO.Path]::GetExtension($downloadFileName)\n\n      Write-Host \"Downloading $download\"\n      Invoke-WebRequest -Uri $download -OutFile $downloadFileName\n\n      if ($extension -eq \".zip\")\n      {\n          Write-Host \"Extracting $downloadFileName\"\n          New-Item -ItemType Directory -Path $fileWithoutExtenion | Out-Null\n          Expand-Archive -Path $downloadFileName -DestinationPath $fileWithoutExtenion\n\n          $binary = Join-Path -Path $fileWithoutExtenion -ChildPath $downloadBinary\n          $results = Invoke-CustomCommand $binary @($versionArgument)\n          Write-Results $results\n          if ($results.ExitCode -ne 0)\n          {\n              throw \"Installed app failed to execute \" + $binary + \". Returned \" + $results.ExitCode\n          }\n          return $binary\n      }\n      elseif ($extension -eq \".gz\")\n      {\n          Write-Host \"Extracting $downloadFileName\"\n          $extractedFile = [System.IO.Path]::GetFileNameWithoutExtension($downloadFileName)\n          $extractedDir = [System.IO.Path]::GetFileNameWithoutExtension($extractedFile)\n          New-Item -ItemType Directory -Path $extractedDir | Out-Null\n\n          $results = Invoke-CustomCommand \"tar\" @(\"xzf\", $downloadFileName, \"-C\", $extractedDir)\n          Write-Results $results\n          if ($results.ExitCode -ne 0)\n          {\n              throw \"Failed to extract file \" + $results.ExitCode\n          }\n\n          $binary = Join-Path -Path $extractedDir -ChildPath $downloadBinary\n          $results = Invoke-CustomCommand $binary @($versionArgument)\n          Write-Results $results\n          if ($results.ExitCode -ne 0)\n          {\n              throw \"Installed app failed to execute \" + $binary + \". Returned \" + $results.ExitCode\n          }\n          return $binary\n      }\n      else\n      {\n          # We likely have to make a downloaded binary executable\n          if ($IsLinux)\n          {\n              $results = Invoke-CustomCommand \"chmod\" @(\"+x\", $downloadFileName)\n              Write-Results $results\n              if ($results.ExitCode -ne 0)\n              {\n                  throw \"Failed to make download executable\"\n              }\n          }\n\n          $results = Invoke-CustomCommand $downloadFileName @($versionArgument)\n          Write-Results $results\n          if ($results.ExitCode -ne 0)\n          {\n              throw \"Installed app failed to execute \" + $downloadFileName + \". Returned \" + $results.ExitCode\n          }\n          return $downloadFileName\n      }\n  }\n\n  function Install-CustomModule\n  {\n      param (\n          $module\n      )\n\n      if (!(Get-Module -ListAvailable -Name $module))\n      {\n          Install-Module -Scope CurrentUser -Force $module\n      }\n  }\n\n  function Install-Eksctl\n  {\n      if ($IsWindows)\n      {\n          return Install-App \"eksctl.exe\" \"version\" \"https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_Windows_amd64.zip\" \"eksctl.zip\" \"eksctl.exe\"\n      }\n      elseif ($IsLinux)\n      {\n          return Install-App \"eksctl\" \"version\" \"https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_Linux_amd64.tar.gz\" \"eksctl.tar.gz\" \"eksctl\"\n      }\n\n      throw \"Unexpected operation system\"\n  }\n\n  function Install-IamAuthenticator\n  {\n      if ($IsWindows)\n      {\n          return Install-App \"aws-iam-authenticator.exe\" \"version\" \"https://github.com/kubernetes-sigs/aws-iam-authenticator/releases/download/v0.5.9/aws-iam-authenticator_0.5.9_windows_amd64.exe\" \"aws-iam-authenticator.exe\" \"aws-iam-authenticator.exe\"\n      }\n      elseif ($IsLinux)\n      {\n          return Install-App \"aws-iam-authenticator\" \"version\" \"https://github.com/kubernetes-sigs/aws-iam-authenticator/releases/download/v0.5.9/aws-iam-authenticator_0.5.9_linux_amd64\" \"aws-iam-authenticator\" \"aws-iam-authenticator\"\n      }\n\n      throw \"Unexpected operation system\"\n  }\n\n  function Install-Helm\n  {\n      if ($IsWindows)\n      {\n          return Install-App \"helm\" \"version\" \"https://get.helm.sh/helm-v3.12.3-windows-amd64.zip\" \"helm.zip\" \"windows-amd64/helm.exe\"\n      }\n      elseif ($IsLinux)\n      {\n          return Install-App \"helm\" \"version\" \"https://get.helm.sh/helm-v3.12.3-linux-amd64.tar.gz\" \"helm.tar.gz\" \"linux-amd64/helm\"\n      }\n\n      throw \"Unexpected operation system\"\n  }\n\n  function Install-Kubectl\n  {\n      if ($IsWindows)\n      {\n          return Install-App \"kubectl\" @(\"version\", \"--client=true\") \"https://dl.k8s.io/release/v1.28.2/bin/windows/amd64/kubectl.exe\" \"kubectl.exe\" \"kubectl.exe\"\n      }\n      elseif ($IsLinux)\n      {\n          return Install-App \"kubectl\" @(\"version\", \"--client=true\") \"https://dl.k8s.io/release/v1.28.2/bin/linux/amd64/kubectl\" \"kubectl\" \"kubectl\"\n      }\n\n      throw \"Unexpected operation system\"\n  }\n\n  function Write-EksConfig\n  {\n      param (\n          $clusterName,\n          $clusterRegion\n      )\n\n      Set-Content -Path \"cluster.yaml\" -Value @\"\n  apiVersion: eksctl.io/v1alpha5\n  kind: ClusterConfig\n\n  metadata:\n    name: $clusterName\n    region: $clusterRegion\n\n  # A regular node group is required for NGINX\n  nodeGroups:\n    - name: ng-1\n      instanceType: t3a.small\n      desiredCapacity: 1\n      volumeSize: 80\n\n  fargateProfiles:\n    - name: fp-default\n      selectors:\n        # All workloads in the \"default\" Kubernetes namespace will be\n        # scheduled onto Fargate:\n        - namespace: default\n        # All workloads in the \"kube-system\" Kubernetes namespace will be\n        # scheduled onto Fargate:\n        - namespace: kube-system\n    - name: fp-development\n      selectors:\n        - namespace: development\n    - name: fp-test\n      selectors:\n        - namespace: test\n    - name: fp-production\n      selectors:\n        - namespace: production\n  \"@\n  }\n\n  Install-CustomModule powershell-yaml\n\n  $clusterName = $OctopusParameters[\"AWS.EKS.Name\"]\n  $clusterRegion = $OctopusParameters[\"AWS.EKS.Region\"]\n  $awsAccountVariable = $OctopusParameters[\"Octopus.Action.AwsAccount.Variable\"]\n  $awsAccount = $OctopusParameters[$awsAccountVariable]\n  $environment = $OctopusParameters[\"Octopus.Environment.Name\"]\n  $sortOrder = $OctopusParameters[\"Octopus.Environment.SortOrder\"]\n\n  # When multiple environments share a cluster, we want to make sure eksctl doesn't attempt to\n  # create the same cluster at the same time.\n  $sleep = ([int]$sortOrder - 10) * 5\n\n  # Sanity check in the case of existing environments\n  if ($sleep -lt 0) {\n      $sleep = 0\n  }\n  Write-Host \"Sleeping for $sleep seconds\"\n  Start-Sleep -Seconds $sleep\n\n  Install-IamAuthenticator | Out-Null\n  $helm = Install-Helm\n  $kubectl = Install-Kubectl\n  $eksctl = Install-Eksctl\n  Write-EksConfig $clusterName $clusterRegion\n  $results = Invoke-CustomCommand $eksctl @(\"get\", \"cluster\", \"--name\", $clusterName, \"--region\", $clusterRegion) -Path @((Get-Location))\n  if ($results.ExitCode -eq 0)\n  {\n      Write-Host \"Getting cluster details\"\n      $result = Invoke-CustomCommand $eksctl @(\"utils\", \"write-kubeconfig\", \"--cluster\", $clusterName, \"--region\", $clusterRegion, \"--kubeconfig\", \"eks-config.yaml\") -Path @((Get-Location))\n      Write-Results $result\n  }\n  else\n  {\n      Write-Host \"Creating cluster - this can take a while\"\n      $result = Invoke-CustomCommand $eksctl @(\"create\", \"cluster\", \"-f\", \"cluster.yaml\", \"--kubeconfig\", 'eks-config.yaml') -Path @((Get-Location))\n      Write-Results $result\n  }\n\n  # https://kubernetes.github.io/ingress-nginx/deploy/#aws\n  $result = Invoke-CustomCommand $kubectl @(\"apply\", \"-f\", \"https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/aws/deploy.yaml\", \"--kubeconfig\", \"eks-config.yaml\") -Path @((Get-Location))\n\n  Write-Results $result\n\n  $kubeConfig = ConvertFrom-Yaml (Get-Content eks-config.yaml -Raw)\n\n  New-OctopusKubernetesTarget `\n      -name \"$clusterName $($environment.ToLower())\" `\n      -octopusRoles \"EKS_Reference_Cluster,Kubernetes\" `\n      -clusterUrl $kubeConfig.clusters[0].cluster.server `\n      -octopusAccountIdOrName $awsAccount `\n      -clusterName $clusterName `\n      -namespace $($environment -replace '[^A-Za-z0-9]', '_').ToLower() `\n      -updateIfExisting `\n      -skipTlsVerification True\n  EOT\n  variable_script                    = <<-EOT\n  Set-OctopusVariable -name \"OctopusEnvironmentName\" -value $OctopusParameters[\"Octopus.Environment.Name\"]\n  EOT\n  orchestration_project_script       = <<-EOT\n  # If we are deploying to the feature branch environment, the \"Kubernetes.Namespace\" variable is defined,\n  # and it is passed down as a prompted variable. Otherwise, pass down a placeholder that is not used.\n  $value = if ([string]::IsNullOrWhitespace($OctopusParameters[\"Kubernetes.Namespace\"])) {$($OctopusParameters[\"Octopus.Environment.Name\"] -replace '[^A-Za-z0-9]', '_').ToLower()} else {$OctopusParameters[\"Kubernetes.Namespace\"]}\n  Set-OctopusVariable -name \"KubernetesNamespaceValue\" -value $value\n\n  # Define the deployment condition used by the \"Deploy a release\" steps.\n  # Mainline deployments ignore existing deployments. Feature branch deployments are always redeployed.\n  $deploymentCondition = if ([string]::IsNullOrWhitespace($OctopusParameters[\"Kubernetes.Namespace\"])) {\"IfNotCurrentVersion\"} else {\"Always\"}\n  Set-OctopusVariable -name \"DeploymentCondition\" -value $deploymentCondition\n  EOT\n  smoke_test                         = <<-EOT\n  for i in {1..30}\n  do\n      HOSTNAME=$(kubectl get ingress #{Kubernetes.Ingress.Name} -o json -n #{Kubernetes.Namespace} | jq -r '.status.loadBalancer.ingress[0].hostname')\n      if [[ -n \"$${HOSTNAME}\" && \"$${HOSTNAME}\" != \"null\" ]]\n      then\n          break\n      fi\n      echo \"Waiting for ingress hostname\"\n      sleep 10\n  done\n\n  # Load balancers can take a minute or so before their DNS is propagated.\n  # A status code of 000 means curl could not resolve the DNS name, so we wait for a bit until DNS is updated.\n  write_highlight \"Testing [http://$${HOSTNAME}#{Kubernetes.App.HealthCheck}](http://$${HOSTNAME}#{Kubernetes.App.HealthCheck})\"\n  echo \"Waiting for DNS to propagate. This can take a while for a new load balancer.\"\n  for i in {1..30}\n  do\n    CODE=$(curl -o /dev/null -s -w \"%%{http_code}\\n\" http://$${HOSTNAME}#{Kubernetes.App.HealthCheck})\n    if [[ \"$${CODE}\" == \"200\" ]]\n    then\n      break\n    fi\n    echo \"Waiting for DNS name to be resolvable and for service to respond\"\n    sleep 10\n  done\n\n  echo \"response code: $${CODE}\"\n  if [[ \"$${CODE}\" == \"200\" ]]\n  then\n      echo \"success\"\n      exit 0\n  else\n      echo \"error\"\n      exit 1\n  fi\n  EOT\n  security_scan_script               = <<-EOT\n  echo \"Pulling Trivy Docker Image\"\n  echo \"##octopus[stdout-verbose]\"\n  docker pull aquasec/trivy\n  echo \"##octopus[stdout-default]\"\n\n  echo \"Installing umoci\"\n  echo \"##octopus[stdout-verbose]\"\n  # Install umoci\n  if ! which umoci\n  then\n    curl -o umoci -L https://github.com/opencontainers/umoci/releases/latest/download/umoci.amd64 2>&1\n    chmod +x umoci\n  fi\n  echo \"##octopus[stdout-default]\"\n\n  echo \"Extracting Application Docker Image\"\n  echo \"##octopus[stdout-verbose]\"\n  # Download and extract the docker image\n  # https://manpages.ubuntu.com/manpages/jammy/man1/umoci-raw-unpack.1.html\n  docker pull quay.io/skopeo/stable:latest 2>&1\n  docker run -v $(pwd):/output quay.io/skopeo/stable:latest copy docker://#{Octopus.Action[Deploy Container].Package[web].PackageId}:#{Octopus.Action[Deploy Container].Package[web].PackageVersion} oci:/output/image:latest 2>&1\n  ./umoci unpack --image image --rootless bundle 2>&1\n  echo \"##octopus[stdout-default]\"\n\n  TIMESTAMP=$(date +%s%3N)\n  SUCCESS=0\n  for x in $(find . -name bom.json -type f -print); do\n      echo \"Scanning $${x}\"\n\n      # Delete any existing report file\n      if [[ -f \"$PWD/depscan-bom.json\" ]]; then\n        rm \"$PWD/depscan-bom.json\"\n      fi\n\n      # Generate the report, capturing the output, and ensuring $? is set to the exit code\n      OUTPUT=$(bash -c \"docker run --rm -v \\\"$PWD/$${x}:/app/$${x}\\\" aquasec/trivy sbom \\\"/app/$${x}\\\"; exit \\$?\" 2>&1)\n\n      # Success is set to 1 if the exit code is not zero\n      if [[ $? -ne 0 ]]; then\n          SUCCESS=1\n      fi\n\n      # Print the output stripped of ANSI colour codes\n      echo -e \"$${OUTPUT}\" | sed 's/\\x1b\\[[0-9;]*m//g'\n  done\n\n  # Cleanup\n  for i in {1..10}\n  do\n      chmod -R +rw bundle &> /dev/null\n      rm -rf bundle &> /dev/null\n      if [[ $? == 0 ]]; then break; fi\n      echo \"Attempting to clean up files\"\n      sleep 1\n  done\n\n  set_octopusvariable \"VerificationResult\" $SUCCESS\n\n  if [[ $SUCCESS -ne 0 ]]; then\n    >&2 echo \"Critical vulnerabilities were detected\"\n  fi\n\n  exit 0\n  EOT\n}\n#endregion\n\n#region Provider\nvariable \"octopus_server\" {\n  type        = string\n  nullable    = false\n  sensitive   = false\n  description = \"The URL of the Octopus server e.g. https://myinstance.octopus.app.\"\n  default     = \"#{Octopus.Web.ServerUri}\"\n}\n\nvariable \"octopus_apikey\" {\n  type        = string\n  nullable    = false\n  sensitive   = true\n  description = \"The API key used to access the Octopus server. See https://octopus.com/docs/octopus-rest-api/how-to-create-an-api-key for details on creating an API key.\"\n}\n\nvariable \"octopus_space_id\" {\n  type        = string\n  nullable    = false\n  sensitive   = false\n  description = \"The ID of the Octopus space to populate.\"\n  default     = \"#{Octopus.Space.Id}\"\n}\n\nprovider \"octopusdeploy\" {\n  address  = var.octopus_server\n  api_key  = var.octopus_apikey\n  space_id = var.octopus_space_id\n}\n#endregion\n\n#region Environments\ndata \"octopusdeploy_environments\" \"environment_development\" {\n  ids          = null\n  partial_name = \"Development\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_environment\" \"environment_development\" {\n  count                        = length(data.octopusdeploy_environments.environment_development.environments) == 0 ? 1 : 0\n  name                         = \"Development\"\n  description                  = \"\"\n  allow_dynamic_infrastructure = true\n  use_guided_failure           = true\n  sort_order                   = 10\n\n  jira_extension_settings {\n    environment_type = \"development\"\n  }\n\n  jira_service_management_extension_settings {\n    is_enabled = false\n  }\n\n  servicenow_extension_settings {\n    is_enabled = false\n  }\n}\n\ndata \"octopusdeploy_environments\" \"environment_test\" {\n  ids          = null\n  partial_name = \"Test\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_environment\" \"environment_test\" {\n  count                        = length(data.octopusdeploy_environments.environment_test.environments) == 0 ? 1 : 0\n  name                         = \"Test\"\n  description                  = \"\"\n  allow_dynamic_infrastructure = true\n  use_guided_failure           = true\n  sort_order                   = 12\n\n  jira_extension_settings {\n    environment_type = \"testing\"\n  }\n\n  jira_service_management_extension_settings {\n    is_enabled = false\n  }\n\n  servicenow_extension_settings {\n    is_enabled = false\n  }\n}\n\ndata \"octopusdeploy_environments\" \"environment_production\" {\n  ids          = null\n  partial_name = \"Production\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_environment\" \"environment_production\" {\n  count                        = length(data.octopusdeploy_environments.environment_production.environments) == 0 ? 1 : 0\n  name                         = \"Production\"\n  description                  = \"\"\n  allow_dynamic_infrastructure = true\n  use_guided_failure           = true\n  sort_order                   = 13\n\n  jira_extension_settings {\n    environment_type = \"production\"\n  }\n\n  jira_service_management_extension_settings {\n    is_enabled = false\n  }\n\n  servicenow_extension_settings {\n    is_enabled = false\n  }\n}\n\ndata \"octopusdeploy_environments\" \"environment_security\" {\n  ids          = null\n  partial_name = \"Security\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_environment\" \"environment_security\" {\n  count                        = length(data.octopusdeploy_environments.environment_security.environments) == 0 ? 1 : 0\n  name                         = \"Security\"\n  description                  = \"\"\n  allow_dynamic_infrastructure = true\n  use_guided_failure           = false\n  sort_order                   = 14\n\n  jira_extension_settings {\n    environment_type = \"production\"\n  }\n\n  jira_service_management_extension_settings {\n    is_enabled = false\n  }\n\n  servicenow_extension_settings {\n    is_enabled = false\n  }\n}\n\ndata \"octopusdeploy_environments\" \"environment_sync\" {\n  ids          = null\n  partial_name = \"Sync\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_environment\" \"environment_sync\" {\n  count                        = length(data.octopusdeploy_environments.environment_sync.environments) == 0 ? 1 : 0\n  name                         = \"Sync\"\n  description                  = \"\"\n  allow_dynamic_infrastructure = true\n  use_guided_failure           = false\n  sort_order                   = 15\n\n  jira_extension_settings {\n    environment_type = \"development\"\n  }\n\n  jira_service_management_extension_settings {\n    is_enabled = false\n  }\n\n  servicenow_extension_settings {\n    is_enabled = false\n  }\n}\n\ndata \"octopusdeploy_environments\" \"environment_featurebranch\" {\n  ids          = null\n  partial_name = \"Feature Branch\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_environment\" \"environment_featurebranch\" {\n  count                        = length(data.octopusdeploy_environments.environment_featurebranch.environments) == 0 ? 1 : 0\n  name                         = \"Feature Branch\"\n  description                  = \"\"\n  allow_dynamic_infrastructure = true\n  use_guided_failure           = false\n  sort_order                   = 11\n\n  jira_extension_settings {\n    environment_type = \"development\"\n  }\n\n  jira_service_management_extension_settings {\n    is_enabled = false\n  }\n\n  servicenow_extension_settings {\n    is_enabled = false\n  }\n}\n\ndata \"octopusdeploy_lifecycles\" \"featurebranch\" {\n  ids          = []\n  partial_name = \"Feature Branch\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_lifecycle\" \"lifecycle_featurebranch\" {\n  count       = length(data.octopusdeploy_lifecycles.featurebranch.lifecycles) == 0 ? 1 : 0\n  name        = \"Feature Branch\"\n  description = \"\"\n\n  phase {\n    automatic_deployment_targets = []\n    optional_deployment_targets  = [\n      local.featurebranch_environment_id\n    ]\n    name                                  = \"Feature Branch\"\n    is_optional_phase                     = false\n    minimum_environments_before_promotion = 0\n  }\n\n  release_retention_policy {\n    quantity_to_keep    = 3\n    should_keep_forever = false\n    unit                = \"Days\"\n  }\n\n  tentacle_retention_policy {\n    quantity_to_keep    = 3\n    should_keep_forever = false\n    unit                = \"Days\"\n  }\n}\n\ndata \"octopusdeploy_lifecycles\" \"sync\" {\n  ids          = []\n  partial_name = \"Sync\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_lifecycle\" \"sync\" {\n  count       = length(data.octopusdeploy_lifecycles.sync.lifecycles) == 0 ? 1 : 0\n  name        = \"Sync\"\n  description = \"\"\n\n  phase {\n    automatic_deployment_targets = []\n    optional_deployment_targets  = [\n      local.sync_environment_id\n    ]\n    name                                  = \"Sync\"\n    is_optional_phase                     = false\n    minimum_environments_before_promotion = 0\n  }\n\n  release_retention_policy {\n    quantity_to_keep    = 3\n    should_keep_forever = false\n    unit                = \"Days\"\n  }\n\n  tentacle_retention_policy {\n    quantity_to_keep    = 3\n    should_keep_forever = false\n    unit                = \"Days\"\n  }\n}\n\ndata \"octopusdeploy_lifecycles\" \"devsecops\" {\n  ids          = []\n  partial_name = \"DevSecOps\"\n  skip         = 0\n  take         = 1\n}\n\ndata \"octopusdeploy_lifecycles\" \"application\" {\n  ids          = []\n  partial_name = \"Application\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_lifecycle\" \"lifecycle_devsecops\" {\n  count       = length(data.octopusdeploy_lifecycles.devsecops.lifecycles) == 0 ? 1 : 0\n  name        = \"DevSecOps\"\n  description = \"\"\n\n  phase {\n    automatic_deployment_targets = []\n    optional_deployment_targets  = [\n      local.development_environment_id\n    ]\n    name                                  = \"Development\"\n    is_optional_phase                     = false\n    minimum_environments_before_promotion = 0\n  }\n  phase {\n    automatic_deployment_targets = []\n    optional_deployment_targets  = [\n      local.featurebranch_environment_id\n    ]\n    name                                  = \"Feature Branch\"\n    is_optional_phase                     = true\n    minimum_environments_before_promotion = 0\n  }\n  phase {\n    automatic_deployment_targets = []\n    optional_deployment_targets  = [\n      local.test_environment_id\n    ]\n    name                                  = \"Test\"\n    is_optional_phase                     = false\n    minimum_environments_before_promotion = 0\n  }\n  phase {\n    automatic_deployment_targets = []\n    optional_deployment_targets  = [\n      local.production_environment_id\n    ]\n    name                                  = \"Production\"\n    is_optional_phase                     = false\n    minimum_environments_before_promotion = 0\n  }\n  phase {\n    automatic_deployment_targets = [\n      local.security_environment_id\n    ]\n    optional_deployment_targets           = []\n    name                                  = \"Security\"\n    is_optional_phase                     = false\n    minimum_environments_before_promotion = 0\n  }\n\n  release_retention_policy {\n    quantity_to_keep    = 3\n    should_keep_forever = false\n    unit                = \"Days\"\n  }\n\n  tentacle_retention_policy {\n    quantity_to_keep    = 3\n    should_keep_forever = false\n    unit                = \"Days\"\n  }\n}\n\nresource \"octopusdeploy_lifecycle\" \"lifecycle_application\" {\n  count       = length(data.octopusdeploy_lifecycles.application.lifecycles) == 0 ? 1 : 0\n  name        = \"Application\"\n  description = \"\"\n\n  phase {\n    automatic_deployment_targets = []\n    optional_deployment_targets  = [\n      local.development_environment_id\n    ]\n    name                                  = \"Development\"\n    is_optional_phase                     = false\n    minimum_environments_before_promotion = 0\n  }\n  phase {\n    automatic_deployment_targets = []\n    optional_deployment_targets  = [\n      local.featurebranch_environment_id\n    ]\n    name                                  = \"Feature Branch\"\n    is_optional_phase                     = true\n    minimum_environments_before_promotion = 0\n  }\n  phase {\n    automatic_deployment_targets = []\n    optional_deployment_targets  = [\n      local.test_environment_id\n    ]\n    name                                  = \"Test\"\n    is_optional_phase                     = false\n    minimum_environments_before_promotion = 0\n  }\n  phase {\n    automatic_deployment_targets = []\n    optional_deployment_targets  = [\n      local.production_environment_id\n    ]\n    name                                  = \"Production\"\n    is_optional_phase                     = false\n    minimum_environments_before_promotion = 0\n  }\n\n  release_retention_policy {\n    quantity_to_keep    = 3\n    should_keep_forever = false\n    unit                = \"Days\"\n  }\n\n  tentacle_retention_policy {\n    quantity_to_keep    = 3\n    should_keep_forever = false\n    unit                = \"Days\"\n  }\n}\n#endregion\n\n#region Feeds\n\ndata \"octopusdeploy_feeds\" \"project\" {\n  feed_type = \"OctopusProject\"\n  ids       = []\n  skip      = 0\n  take      = 1\n}\n\ndata \"octopusdeploy_feeds\" \"bitnami\" {\n  feed_type    = \"Helm\"\n  ids          = []\n  partial_name = \"Bitnami\"\n  skip         = 0\n  take         = 1\n}\n\n\nresource \"octopusdeploy_helm_feed\" \"feed_helm\" {\n  count                                = length(data.octopusdeploy_feeds.bitnami.feeds) == 0 ? 1 : 0\n  name                                 = \"Bitnami\"\n  feed_uri                             = \"https://repo.vmware.com/bitnami-files/\"\n  package_acquisition_location_options = [\"ExecutionTarget\", \"NotAcquired\"]\n}\n\ndata \"octopusdeploy_feeds\" \"dockerhub\" {\n  feed_type    = \"Docker\"\n  ids          = []\n  partial_name = \"Docker Hub\"\n  skip         = 0\n  take         = 1\n}\n\nvariable \"feed_docker_hub_username\" {\n  type        = string\n  nullable    = false\n  sensitive   = true\n  description = \"The username used by the feed Docker Hub\"\n}\n\nvariable \"feed_docker_hub_password\" {\n  type        = string\n  nullable    = false\n  sensitive   = true\n  description = \"The password used by the feed Docker Hub\"\n}\n\nresource \"octopusdeploy_docker_container_registry\" \"docker_hub\" {\n  count                                = length(data.octopusdeploy_feeds.dockerhub.feeds) == 0 ? 1 : 0\n  name                                 = \"Docker Hub\"\n  password                             = var.feed_docker_hub_password\n  username                             = var.feed_docker_hub_username\n  api_version                          = \"v1\"\n  feed_uri                             = \"https://index.docker.io\"\n  package_acquisition_location_options = [\"ExecutionTarget\", \"NotAcquired\"]\n}\n\ndata \"octopusdeploy_feeds\" \"sales_maven_feed\" {\n  feed_type    = \"Maven\"\n  ids          = []\n  partial_name = \"Sales Maven Feed\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_maven_feed\" \"feed_sales_maven_feed\" {\n  count                                = length(data.octopusdeploy_feeds.sales_maven_feed.feeds) == 0 ? 1 : 0\n  name                                 = \"Sales Maven Feed\"\n  feed_uri                             = \"https://octopus-sales-public-maven-repo.s3.ap-southeast-2.amazonaws.com/snapshot\"\n  package_acquisition_location_options = [\"Server\", \"ExecutionTarget\"]\n  download_attempts                    = 3\n  download_retry_backoff_seconds       = 20\n}\n\ndata \"octopusdeploy_feeds\" \"github_feed\" {\n  feed_type    = \"GitHub\"\n  ids          = []\n  partial_name = \"Github Releases\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_github_repository_feed\" \"github_feed\" {\n  count                          = length(data.octopusdeploy_feeds.github_feed.feeds) == 0 ? 1 : 0\n  download_attempts              = 1\n  download_retry_backoff_seconds = 30\n  feed_uri                       = \"https://api.github.com\"\n  name                           = \"Github Releases\"\n}\n#endregion\n\n#region Library Variable Sets\ndata \"octopusdeploy_library_variable_sets\" \"this_instance\" {\n  partial_name = \"This Instance\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_library_variable_set\" \"this_instance\" {\n  count       = length(data.octopusdeploy_library_variable_sets.this_instance.library_variable_sets) == 0 ? 1 : 0\n  name        = \"This Instance\"\n  description = \"Credentials used to interact with this Octopus instance\"\n}\n\nresource \"octopusdeploy_variable\" \"octopus_admin_api_key\" {\n  count           = length(data.octopusdeploy_library_variable_sets.this_instance.library_variable_sets) == 0 ? 1 : 0\n  name            = \"Octopus.ApiKey\"\n  type            = \"Sensitive\"\n  description     = \"Octopus API Key\"\n  is_sensitive    = true\n  is_editable     = true\n  owner_id        = octopusdeploy_library_variable_set.this_instance[0].id\n  sensitive_value = var.octopus_apikey\n}\n\ndata \"octopusdeploy_library_variable_sets\" \"github\" {\n  partial_name = \"GitHub\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_library_variable_set\" \"github\" {\n  count       = length(data.octopusdeploy_library_variable_sets.github.library_variable_sets) == 0 ? 1 : 0\n  name        = \"GitHub\"\n  description = \"Credentials used to interact with GitHub\"\n}\n\nvariable \"github_access_token\" {\n  type        = string\n  nullable    = false\n  sensitive   = true\n  description = \"The GitHub access token\"\n}\n\nresource \"octopusdeploy_variable\" \"github_access_token\" {\n  count           = length(data.octopusdeploy_library_variable_sets.github.library_variable_sets) == 0 ? 1 : 0\n  name            = \"Git.Credentials.Password\"\n  type            = \"Sensitive\"\n  description     = \"The GitHub access token\"\n  is_sensitive    = true\n  is_editable     = true\n  owner_id        = octopusdeploy_library_variable_set.github[0].id\n  sensitive_value = var.github_access_token\n}\n\ndata \"octopusdeploy_library_variable_sets\" \"docker\" {\n  partial_name = \"Docker\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_library_variable_set\" \"docker\" {\n  count       = length(data.octopusdeploy_library_variable_sets.docker.library_variable_sets) == 0 ? 1 : 0\n  name        = \"Docker\"\n  description = \"Credentials used to interact with Docker\"\n}\n\nresource \"octopusdeploy_variable\" \"docker_username\" {\n  count        = length(data.octopusdeploy_library_variable_sets.docker.library_variable_sets) == 0 ? 1 : 0\n  name         = \"Docker.Credentials.Username\"\n  type         = \"String\"\n  description  = \"The docker username\"\n  is_sensitive = false\n  is_editable  = true\n  owner_id     = octopusdeploy_library_variable_set.docker[0].id\n  value        = var.feed_docker_hub_username\n}\n\nresource \"octopusdeploy_variable\" \"docker_password\" {\n  count           = length(data.octopusdeploy_library_variable_sets.docker.library_variable_sets) == 0 ? 1 : 0\n  name            = \"Docker.Credentials.Password\"\n  type            = \"Sensitive\"\n  description     = \"The docker password\"\n  is_sensitive    = true\n  is_editable     = true\n  owner_id        = octopusdeploy_library_variable_set.docker[0].id\n  sensitive_value = var.feed_docker_hub_password\n}\n\ndata \"octopusdeploy_library_variable_sets\" \"aws\" {\n  partial_name = \"AWS\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_library_variable_set\" \"aws\" {\n  count       = length(data.octopusdeploy_library_variable_sets.aws.library_variable_sets) == 0 ? 1 : 0\n  name        = \"AWS\"\n  description = \"Credentials used to interact with AWS\"\n}\n\nresource \"octopusdeploy_variable\" \"library_var_set_aws_access_key\" {\n  count        = length(data.octopusdeploy_library_variable_sets.aws.library_variable_sets) == 0 ? 1 : 0\n  name         = \"AWS.Credentials.AccessKey\"\n  type         = \"String\"\n  description  = \"AWS Access Key\"\n  is_sensitive = false\n  is_editable  = true\n  owner_id     = octopusdeploy_library_variable_set.aws[0].id\n  value        = var.account_aws_access_key\n}\n\nresource \"octopusdeploy_variable\" \"library_var_set_aws_secret_key\" {\n  count           = length(data.octopusdeploy_library_variable_sets.aws.library_variable_sets) == 0 ? 1 : 0\n  name            = \"AWS.Credentials.SecretKey\"\n  type            = \"Sensitive\"\n  description     = \"AWS Secret Key\"\n  is_sensitive    = true\n  is_editable     = true\n  owner_id        = octopusdeploy_library_variable_set.aws[0].id\n  sensitive_value = var.account_aws_secret_key\n}\n#endregion\n\n#region Accounts\n\ndata \"octopusdeploy_accounts\" \"aws_account\" {\n  account_type = \"AmazonWebServicesAccount\"\n  ids          = []\n  partial_name = \"AWS Account\"\n  skip         = 0\n  take         = 1\n}\n\nvariable \"account_aws_access_key\" {\n  type        = string\n  nullable    = false\n  sensitive   = false\n  description = \"The AWS access key associated with the account AWS Account\"\n}\n\nvariable \"account_aws_secret_key\" {\n  type        = string\n  nullable    = false\n  sensitive   = true\n  description = \"The AWS secret key associated with the account AWS Account\"\n}\n\nresource \"octopusdeploy_aws_account\" \"aws_account\" {\n  count                             = length(data.octopusdeploy_accounts.aws_account.accounts) == 0 ? 1 : 0\n  name                              = \"AWS Account\"\n  description                       = \"\"\n  environments                      = []\n  tenant_tags                       = []\n  tenants                           = []\n  tenanted_deployment_participation = \"Untenanted\"\n  access_key                        = var.account_aws_access_key\n  secret_key                        = var.account_aws_secret_key\n}\n\n#endregion\n\n#region Project Groups\ndata \"octopusdeploy_project_groups\" \"eks\" {\n  ids          = []\n  partial_name = \"EKS\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_project_group\" \"project_group_eks\" {\n  count       = length(data.octopusdeploy_project_groups.eks.project_groups) == 0 ? 1 : 0\n  name        = \"EKS\"\n  description = \"EKS projects.\"\n}\n\ndata \"octopusdeploy_project_groups\" \"project_templates\" {\n  ids          = []\n  partial_name = \"Project Templates\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_project_group\" \"project_group_project_templates\" {\n  count       = length(data.octopusdeploy_project_groups.project_templates.project_groups) == 0 ? 1 : 0\n  name        = \"Project Templates\"\n  description = \"Sample code project generators\"\n}\n#endregion\n\n#region Worker Pools\n\ndata \"octopusdeploy_worker_pools\" \"workerpool_hosted_ubuntu\" {\n  partial_name = \"Hosted Ubuntu\"\n  ids          = null\n  skip         = 0\n  take         = 1\n}\n#endregion\n\n#region Projects\n\n#region AWS Infrastructure\nvariable \"infrastructure_project_name\" {\n  type    = string\n  default = \"\"\n}\n\ndata \"octopusdeploy_projects\" \"aws_infrastructure\" {\n  cloned_from_project_id = \"\"\n  ids                    = []\n  is_clone               = true\n  partial_name           = var.infrastructure_project_name == \"\" ? local.infrastructure_project_name : var.infrastructure_project_name\n  skip                   = 0\n  take                   = 1\n}\n\nresource \"octopusdeploy_project\" \"aws_infrastructure\" {\n  count                                = length(data.octopusdeploy_projects.aws_infrastructure.projects) == 0 ? 1 : 0\n  name                                 = var.infrastructure_project_name == \"\" ? local.infrastructure_project_name : var.infrastructure_project_name\n  auto_create_release                  = false\n  default_guided_failure_mode          = \"EnvironmentDefault\"\n  default_to_skip_if_already_installed = false\n  discrete_channel_release             = false\n  is_disabled                          = false\n  is_version_controlled                = true\n  lifecycle_id                         = local.devops_lifecycle_id\n  project_group_id                     = local.eks_project_group_id\n  included_library_variable_sets       = []\n  tenanted_deployment_participation    = \"Untenanted\"\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = false\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n\n  versioning_strategy {\n    template = \"\"\n  }\n\n  lifecycle {\n    ignore_changes = [\"connectivity_policy\"]\n  }\n  description = \"AWS infrastrucutre runbooks\"\n}\n\nresource \"octopusdeploy_variable\" \"library_variable_set_variables_octopub_aws_account_1\" {\n  count        = length(data.octopusdeploy_projects.aws_infrastructure.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.aws_infrastructure[0].id\n  value        = local.aws_account\n  name         = \"AWS.Account\"\n  type         = \"AmazonWebServicesAccount\"\n  description  = \"\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"aws_infrastructure_aws_eks_name_1\" {\n  count        = length(data.octopusdeploy_projects.aws_infrastructure.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.aws_infrastructure[0].id\n  value        = \"octopus\"\n  name         = \"AWS.EKS.Name\"\n  type         = \"String\"\n  is_sensitive = false\n\n  prompt {\n    description = \"EKS Cluster Name\"\n    label       = \"EKS Cluster Name\"\n    is_required = true\n    display_settings {\n      control_type = \"SingleLineText\"\n    }\n  }\n}\n\nresource \"octopusdeploy_variable\" \"aws_infrastructure_aws_eks_region_1\" {\n  count        = length(data.octopusdeploy_projects.aws_infrastructure.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.aws_infrastructure[0].id\n  value        = \"ap-southeast-2\"\n  name         = \"AWS.EKS.Region\"\n  type         = \"String\"\n  is_sensitive = false\n\n  prompt {\n    description = \"EKS Cluster Region\"\n    label       = \"EKS Cluster Region\"\n    is_required = true\n    display_settings {\n      control_type = \"SingleLineText\"\n    }\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_create_eks_cluster\" {\n  count             = length(data.octopusdeploy_projects.aws_infrastructure.projects) == 0 ? 1 : 0\n  name              = \"🛠️ Create EKS Cluster\"\n  project_id        = octopusdeploy_project.aws_infrastructure[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n    local.featurebranch_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"EnvironmentDefault\"\n  description                 = <<EOT\n**Action**: Creates the EKS cluster.\n\n**Affects**: No existing resources are affected. If the cluster exists, it is not modified.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_eks_create_eks_cluster\" {\n  count      = length(data.octopusdeploy_projects.aws_infrastructure.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_create_eks_cluster[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Create EKS Cluster\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.AwsRunScript\"\n      name                               = \"Create EKS Cluster\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"                = \"true\"\n        \"Octopus.Action.Script.ScriptBody\"          = local.create_cluster_script\n        \"Octopus.Action.AwsAccount.UseInstanceRole\" = \"False\"\n        \"Octopus.Action.AwsAccount.Variable\"        = \"AWS.Account\"\n        \"Octopus.Action.Aws.Region\"                 = \"#{AWS.EKS.Region}\"\n        \"Octopus.Action.Script.ScriptSource\"        = \"Inline\"\n        \"Octopus.Action.Aws.AssumeRole\"             = \"False\"\n        \"Octopus.Action.Script.Syntax\"              = \"PowerShell\"\n        \"OctopusUseBundledTooling\"                  = \"False\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n        local.featurebranch_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/aws-workertools\"\n      }\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_get_nodes\" {\n  count             = length(data.octopusdeploy_projects.aws_infrastructure.projects) == 0 ? 1 : 0\n  project_id        = octopusdeploy_project.aws_infrastructure[0].id\n  name              = \"🛠️ Get Nodes\"\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Returns the cluster nodes.\n\n**Affects**: Nothing - this runbook makes no changes.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_get_nodes\" {\n  count      = length(data.octopusdeploy_projects.aws_infrastructure.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_get_nodes[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Get Nodes\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Get Nodes\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"K8SInspectCreateArtifact\"                      = \"False\"\n        \"Octopus.Action.Script.ScriptBody\"              = \"<#\\n    This script provides a general purpose method for querying Kubernetes resources. It supports common operations\\n    like get, describe, logs and output formats like yaml and json. Output can be captured as artifacts.\\n#>\\n\\n<#\\n.Description\\nExecute an application, capturing the output. Based on https://stackoverflow.com/a/33652732/157605\\n#>\\nFunction Execute-Command ($commandPath, $commandArguments)\\n{\\n  Write-Host \\\"Executing: $commandPath $($commandArguments -join \\\" \\\")\\\"\\n  \\n  Try {\\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\\n    $pinfo.FileName = $commandPath\\n    $pinfo.RedirectStandardError = $true\\n    $pinfo.RedirectStandardOutput = $true\\n    $pinfo.UseShellExecute = $false\\n    $pinfo.Arguments = $commandArguments\\n    $p = New-Object System.Diagnostics.Process\\n    $p.StartInfo = $pinfo\\n    $p.Start() | Out-Null\\n    [pscustomobject]@{\\n        stdout = $p.StandardOutput.ReadToEnd()\\n        stderr = $p.StandardError.ReadToEnd()\\n        ExitCode = $p.ExitCode\\n    }\\n    $p.WaitForExit()\\n  }\\n  Catch {\\n     exit\\n  }\\n}\\n\\n<#\\n.Description\\nFind any resource names that match a wildcard input if one was specified\\n#>\\nfunction Get-Resources() \\n{\\n    $names = $OctopusParameters[\\\"K8SInspectNames\\\"] -Split \\\"`n\\\" | % {$_.Trim()}\\n    \\n    if ($OctopusParameters[\\\"K8SInspectNames\\\"] -match '\\\\*' )\\n    {\\n        return Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", $OctopusParameters[\\\"K8SInspectResource\\\"])) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Extract the name\\n            % {$_.metadata.name} |\\n            # Find any matching resources\\n            ? {$k8sName = $_; ($names | ? {$k8sName -like $_}).Count -ne 0}\\n    }\\n    else\\n    {\\n        return $names\\n    }\\n}\\n\\n<#\\n.Description\\nGet the kubectl arguments for a given action\\n#>\\nfunction Get-KubectlVerb() \\n{\\n    switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {return ,@(\\\"-o\\\", \\\"json\\\", \\\"get\\\")}\\n        \\\"get yaml\\\" {return ,@(\\\"-o\\\", \\\"yaml\\\", \\\"get\\\")}\\n        \\\"describe\\\" {return ,@(\\\"describe\\\")}\\n        \\\"logs\\\" {return ,@(\\\"logs\\\")}\\n        \\\"logs tail\\\" {return ,@(\\\"logs\\\", \\\"--tail\\\", \\\"100\\\")}\\n        \\\"previous logs\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\")}\\n        \\\"previous logs tail\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\", \\\"--tail\\\", \\\"100\\\")}\\n        default {return ,@(\\\"get\\\")}\\n    }\\n}\\n\\n<#\\n.Description\\nGet an appropiate file extension based on the selected action\\n#>\\nfunction Get-ArtifactExtension() \\n{\\n   switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {\\\"json\\\"}\\n        \\\"get yaml\\\" {\\\"yaml\\\"}\\n        default {\\\"txt\\\"}\\n    }\\n}\\n\\nif ($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"] -like \\\"*logs*\\\") \\n{\\n    if ( -not @($OctopusParameters[\\\"K8SInspectResource\\\"]) -like \\\"pod*\\\")\\n    {\\n        Write-Error \\\"Logs can only be returned for pods, not $($OctopusParameters[\\\"K8SInspectResource\\\"])\\\"\\n    }\\n    else\\n    {\\n        Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", \\\"pods\\\") + (Get-Resources)) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Get the pod logs for each container\\n            % {\\n                $podDetails = $_\\n                @{\\n                    logs=$podDetails.spec.containers | % {$logs=\\\"\\\"} {$logs += (Select-Object -InputObject (Execute-Command kubectl ((Get-KubectlVerb) + @($podDetails.metadata.name, \\\"-c\\\", $_.name))) -ExpandProperty stdout)} {$logs}; \\n                    name=$podDetails.metadata.name\\n                }                \\n            } |\\n            # Write the output\\n            % {Write-Host $_.logs; $_} |\\n            # Optionally capture the artifact\\n            % {\\n                if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n                {\\n                    Set-Content -Path \\\"$($_.name).$(Get-ArtifactExtension)\\\" -Value $_.logs\\n                    New-OctopusArtifact \\\"$($_.name).$(Get-ArtifactExtension)\\\"\\n                }\\n            }\\n    }      \\n}\\nelse\\n{\\n    Execute-Command kubectl ((Get-KubectlVerb) + @($OctopusParameters[\\\"K8SInspectResource\\\"]) + (Get-Resources)) |\\n        % {Select-Object -InputObject $_ -ExpandProperty stdout} |\\n        % {Write-Host $_; $_} |\\n        % {\\n            if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n            {\\n                Set-Content -Path \\\"output.$(Get-ArtifactExtension)\\\" -Value $_\\n                New-OctopusArtifact \\\"output.$(Get-ArtifactExtension)\\\"\\n            }\\n        }\\n}\\n\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"K8SInspectResource\"                            = \"node\"\n        \"Octopus.Action.Script.Syntax\"                  = \"PowerShell\"\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{if K8SInspectNamespace}#{K8SInspectNamespace}#{/if}#{unless K8SInspectNamespace}#{Octopus.Action.Kubernetes.Namespace}#{/unless}\"\n        \"K8SInspectNames\"                               = \"*\"\n        \"K8SInspectKubectlVerb\"                         = \"get\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_delete_eks_cluster\" {\n  count             = length(data.octopusdeploy_projects.aws_infrastructure.projects) == 0 ? 1 : 0\n  name              = \"🗑️ Delete EKS Cluster\"\n  project_id        = octopusdeploy_project.aws_infrastructure[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"EnvironmentDefault\"\n  description                 = <<EOT\n**WARNING**: This is a destructive operation. All applications will are deleted, and the cluster is destroyed.\n\n**Action**: Deletes the EKS cluster.\n\n**Affects**: All applications installed into the Kubernetes cluster.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_aws_infrastructure_destroy_eks_cluster\" {\n  count      = length(data.octopusdeploy_projects.aws_infrastructure.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_delete_eks_cluster[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Delete EKS Cluster\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.AwsRunScript\"\n      name                               = \"Delete EKS Cluster\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.Aws.AssumeRole\"             = \"False\"\n        \"OctopusUseBundledTooling\"                  = \"False\"\n        \"Octopus.Action.Script.Syntax\"              = \"PowerShell\"\n        \"Octopus.Action.AwsAccount.UseInstanceRole\" = \"False\"\n        \"Octopus.Action.Script.ScriptBody\"          = \"eksctl delete cluster --name $OctopusParameters[\\\"AWS.EKS.Name\\\"]\"\n        \"Octopus.Action.Aws.Region\"                 = \"#{AWS.EKS.Region}\"\n        \"Octopus.Action.AwsAccount.Variable\"        = \"AWS.Account\"\n        \"Octopus.Action.Script.ScriptSource\"        = \"Inline\"\n        \"Octopus.Action.RunOnServer\"                = \"true\"\n      }\n\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/aws-workertools\"\n      }\n\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n#endregion\n\n#region Project Templates\nvariable \"project_template_project_name\" {\n  type    = string\n  default = \"\"\n}\n\ndata \"octopusdeploy_projects\" \"docker_project_template\" {\n  partial_name = var.project_template_project_name == \"\" ? local.project_template_project_name : var.project_template_project_name\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_variable\" \"docker_project_template_git_organization\" {\n  count        = length(data.octopusdeploy_projects.docker_project_template.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.docker_project_template[0].id\n  value        = \"\"\n  name         = \"Git.Url.Organization\"\n  type         = \"String\"\n  description  = \"The GitHub organization to create the repo in.\"\n  is_sensitive = false\n\n  prompt {\n    description = \"The Github organization where the repo will be created. This is the `owner` part of the URL `https://github.com/owner/myrepo`.\"\n    label       = \"Github Organization\"\n    is_required = true\n    display_settings {\n      control_type = \"SingleLineText\"\n    }\n  }\n\n  scope {\n    actions      = []\n    channels     = []\n    environments = [local.sync_environment_id]\n    machines     = []\n    roles        = null\n    tenant_tags  = null\n  }\n}\n\nresource \"octopusdeploy_variable\" \"docker_project_template_git_repo\" {\n  count        = length(data.octopusdeploy_projects.docker_project_template.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.docker_project_template[0].id\n  value        = \"\"\n  name         = \"Git.Url.Repo\"\n  type         = \"String\"\n  description  = \"The GitHub repo to create.\"\n  is_sensitive = false\n\n  prompt {\n    description = \"The Github repo to be created. This is the `myrepo` part of the URL `https://github.com/owner/myrepo`.\"\n    label       = \"Github Repo\"\n    is_required = true\n    display_settings {\n      control_type = \"SingleLineText\"\n    }\n  }\n\n  scope {\n    actions      = []\n    channels     = []\n    environments = [local.sync_environment_id]\n    machines     = []\n    roles        = null\n    tenant_tags  = null\n  }\n}\n\nresource \"octopusdeploy_variable\" \"docker_project_template_image_name\" {\n  count        = length(data.octopusdeploy_projects.docker_project_template.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.docker_project_template[0].id\n  value        = \"\"\n  name         = \"Application.Docker.Image\"\n  type         = \"String\"\n  description  = \"The Docker image to create containing the new application.\"\n  is_sensitive = false\n\n  prompt {\n    description = \"The Docker image to create containing the new application.\"\n    label       = \"Docker Image\"\n    is_required = true\n    display_settings {\n      control_type = \"SingleLineText\"\n    }\n  }\n\n  scope {\n    actions      = []\n    channels     = []\n    environments = [local.sync_environment_id]\n    machines     = []\n    roles        = null\n    tenant_tags  = null\n  }\n}\n\nresource \"octopusdeploy_variable\" \"docker_project_template_octopus_project\" {\n  count        = length(data.octopusdeploy_projects.docker_project_template.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.docker_project_template[0].id\n  value        = \"\"\n  name         = \"Application.Octopus.Project\"\n  type         = \"String\"\n  description  = \"The Octopus project to associate with the new application.\"\n  is_sensitive = false\n\n  prompt {\n    description = \"The Octopus project to associate with the new application. A release is created in this project when the image is successfully built.\"\n    label       = \"Octopus Project\"\n    is_required = true\n    display_settings {\n      control_type = \"SingleLineText\"\n    }\n  }\n\n  scope {\n    actions      = []\n    channels     = []\n    environments = [local.sync_environment_id]\n    machines     = []\n    roles        = null\n    tenant_tags  = null\n  }\n}\n\nresource \"octopusdeploy_project\" \"docker_project_template\" {\n  count                                = length(data.octopusdeploy_projects.docker_project_template.projects) == 0 ? 1 : 0\n  name                                 = var.project_template_project_name == \"\" ? local.project_template_project_name : var.project_template_project_name\n  auto_create_release                  = false\n  default_guided_failure_mode          = \"Off\"\n  default_to_skip_if_already_installed = false\n  discrete_channel_release             = false\n  is_disabled                          = false\n  is_version_controlled                = false\n  lifecycle_id                         = local.application_lifecycle_id\n  project_group_id                     = local.project_templates_project_group_id\n  included_library_variable_sets       = [\n    local.this_instance_library_variable_set, local.github_library_variable_set, local.docker_library_variable_set\n  ]\n  tenanted_deployment_participation = \"Untenanted\"\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n\n  versioning_strategy {\n    template = \"#{Octopus.Version.LastMajor}.#{Octopus.Version.LastMinor}.#{Octopus.Version.NextPatch}\"\n  }\n\n  lifecycle {\n    ignore_changes = []\n  }\n  description = <<EOT\nCreates Project Templates.\nEOT\n}\n\nresource \"octopusdeploy_runbook\" \"docker_project_template_create_nodejs_template\" {\n  count                       = length(data.octopusdeploy_projects.docker_project_template.projects) == 0 ? 1 : 0\n  name                        = \"📗 Create Template Github Node.js Project\"\n  project_id                  = octopusdeploy_project.docker_project_template[0].id\n  environment_scope           = \"Specified\"\n  environments                = [local.sync_environment_id]\n  force_package_download      = false\n  default_guided_failure_mode = \"EnvironmentDefault\"\n  description                 = \"This runbook populates a GitHub repo with a sample Node.js project and GitHub Actions Workflow that builds a Docker image, pushes it to DockerHub, and triggers the deployment of the associated Octopus project in the Development environment. \\n\\n**Action**: Creates a new GitHub repo (if it doesn't exist) and populates it with the output of a Yeoman generator.\\n\\n\\n**Affects**: This will overwrite files in the target Git repo. Changes can be reverted with git.\"\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"docker_project_template_create_nodejs_template\" {\n  runbook_id = octopusdeploy_runbook.docker_project_template_create_nodejs_template[0].id\n  count      = length(data.octopusdeploy_projects.docker_project_template.projects) == 0 ? 1 : 0\n\n  step {\n    condition           = \"Success\"\n    name                = \"Get Variables\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Get Variables\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.Script.ScriptBody\"   = \"# This is a workaround to the issue where octostache templates in the Terraform\\n# project are replaced during deployment, when we actually want some variables\\n# at run time.\\n\\nSet-OctopusVariable -name \\\"Project.Name\\\" -value $OctopusParameters[\\\"Octopus.Project.Name\\\"]\\nSet-OctopusVariable -name \\\"Web.ServerUri\\\" -value $OctopusParameters[\\\"Octopus.Web.ServerUri\\\"]\\nSet-OctopusVariable -name \\\"Space.Id\\\" -value $OctopusParameters[\\\"Octopus.Space.Id\\\"]\\nSet-OctopusVariable -name \\\"Space.Name\\\" -value $OctopusParameters[\\\"Octopus.Space.Name\\\"]\"\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n  step {\n    condition           = \"Success\"\n    name                = \"Create Repo\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Create Repo\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"CreateGithubRepo.Git.Url.Organization\"        = \"#{Git.Url.Organization}\"\n        \"Octopus.Action.Script.Syntax\"                 = \"Python\"\n        \"Octopus.Action.RunOnServer\"                   = \"true\"\n        \"CreateGithubRepo.Git.Url.NewRepoNamePrefix\"   = \"\"\n        \"CreateGithubRepo.Git.Credentials.AccessToken\" = \"#{Git.Credentials.Password}\"\n        \"Octopus.Action.Script.ScriptBody\"             = \"# This script forks a GitHub repo. It creates a token from a GitHub App installation to avoid\\n# having to use a regular user account.\\nimport subprocess\\nimport sys\\n\\n# Install our own dependencies\\nsubprocess.check_call([sys.executable, '-m', 'pip', 'install', 'jwt', '--disable-pip-version-check'])\\n\\nimport json\\nimport subprocess\\nimport sys\\nimport os\\nimport urllib.request\\nimport base64\\nimport re\\nimport jwt\\nimport time\\nimport argparse\\nimport platform\\nfrom urllib.request import urlretrieve\\n\\n# If this script is not being run as part of an Octopus step, setting variables is a noop\\nif 'set_octopusvariable' not in globals():\\n    def set_octopusvariable(variable, value):\\n        pass\\n\\n# If this script is not being run as part of an Octopus step, return variables from environment variables.\\n# Periods are replaced with underscores, and the variable name is converted to uppercase\\nif \\\"get_octopusvariable\\\" not in globals():\\n    def get_octopusvariable(variable):\\n        return os.environ[re.sub('\\\\\\\\.', '_', variable.upper())]\\n\\n# If this script is not being run as part of an Octopus step, print directly to std out.\\nif 'printverbose' not in globals():\\n    def printverbose(msg):\\n        print(msg)\\n\\n\\ndef printverbose_noansi(output):\\n    \\\"\\\"\\\"\\n    Strip ANSI color codes and print the output as verbose\\n    :param output: The output to print\\n    \\\"\\\"\\\"\\n    output_no_ansi = re.sub(r'\\\\x1b\\\\[[0-9;]*m', '', output)\\n    printverbose(output_no_ansi)\\n\\n\\ndef get_octopusvariable_quiet(variable):\\n    \\\"\\\"\\\"\\n    Gets an octopus variable, or an empty string if it does not exist.\\n    :param variable: The variable name\\n    :return: The variable value, or an empty string if the variable does not exist\\n    \\\"\\\"\\\"\\n    try:\\n        return get_octopusvariable(variable)\\n    except:\\n        return ''\\n\\n\\ndef execute(args, cwd=None, env=None, print_args=None, print_output=printverbose_noansi, raise_on_non_zero=False,\\n            append_to_path=None):\\n    \\\"\\\"\\\"\\n        The execute method provides the ability to execute external processes while capturing and returning the\\n        output to std err and std out and exit code.\\n    \\\"\\\"\\\"\\n\\n    my_env = os.environ.copy() if env is None else env\\n\\n    if append_to_path is not None:\\n        my_env[\\\"PATH\\\"] = append_to_path + os.pathsep + my_env['PATH']\\n\\n    process = subprocess.Popen(args,\\n                               stdout=subprocess.PIPE,\\n                               stderr=subprocess.PIPE,\\n                               stdin=open(os.devnull),\\n                               text=True,\\n                               cwd=cwd,\\n                               env=my_env)\\n    stdout, stderr = process.communicate()\\n    retcode = process.returncode\\n\\n    if not retcode == 0 and raise_on_non_zero:\\n        raise Exception('command returned exit code ' + retcode)\\n\\n    if print_args is not None:\\n        print_output(' '.join(args))\\n\\n    if print_output is not None:\\n        print_output(stdout)\\n        print_output(stderr)\\n\\n    return stdout, stderr, retcode\\n\\n\\ndef init_argparse():\\n    parser = argparse.ArgumentParser(\\n        usage='%(prog)s [OPTION]',\\n        description='Create a GitHub repo'\\n    )\\n    parser.add_argument('--new-repo-name', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGithubRepo.Git.Url.NewRepoName') or get_octopusvariable_quiet(\\n                            'Git.Url.NewRepoName') or get_octopusvariable_quiet('Octopus.Project.Name'))\\n    parser.add_argument('--new-repo-name-prefix', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGithubRepo.Git.Url.NewRepoNamePrefix') or get_octopusvariable_quiet(\\n                            'Git.Url.NewRepoNamePrefix'))\\n    parser.add_argument('--git-organization', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGithubRepo.Git.Url.Organization') or get_octopusvariable_quiet(\\n                            'Git.Url.Organization'))\\n    parser.add_argument('--github-app-id', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGithubRepo.GitHub.App.Id') or get_octopusvariable_quiet('GitHub.App.Id'))\\n    parser.add_argument('--github-app-installation-id', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGithubRepo.GitHub.App.InstallationId') or get_octopusvariable_quiet(\\n                            'GitHub.App.InstallationId'))\\n    parser.add_argument('--github-app-private-key', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGithubRepo.GitHub.App.PrivateKey') or get_octopusvariable_quiet(\\n                            'GitHub.App.PrivateKey'))\\n    parser.add_argument('--github-access-token', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGithubRepo.Git.Credentials.AccessToken') or get_octopusvariable_quiet(\\n                            'Git.Credentials.AccessToken'),\\n                        help='The git password')\\n\\n    return parser.parse_known_args()\\n\\n\\ndef generate_github_token(github_app_id, github_app_private_key, github_app_installation_id):\\n    # Generate the tokens used by git and the GitHub API\\n    app_id = github_app_id\\n    signing_key = jwt.jwk_from_pem(github_app_private_key.encode('utf-8'))\\n\\n    payload = {\\n        # Issued at time\\n        'iat': int(time.time()),\\n        # JWT expiration time (10 minutes maximum)\\n        'exp': int(time.time()) + 600,\\n        # GitHub App's identifier\\n        'iss': app_id\\n    }\\n\\n    # Create JWT\\n    jwt_instance = jwt.JWT()\\n    encoded_jwt = jwt_instance.encode(payload, signing_key, alg='RS256')\\n\\n    # Create access token\\n    url = 'https://api.github.com/app/installations/' + github_app_installation_id + '/access_tokens'\\n    headers = {\\n        'Authorization': 'Bearer ' + encoded_jwt,\\n        'Accept': 'application/vnd.github+json',\\n        'X-GitHub-Api-Version': '2022-11-28'\\n    }\\n    request = urllib.request.Request(url, headers=headers, method='POST')\\n    response = urllib.request.urlopen(request)\\n    response_json = json.loads(response.read().decode())\\n    return response_json['token']\\n\\n\\ndef generate_auth_header(token):\\n    auth = base64.b64encode(('x-access-token:' + token).encode('ascii'))\\n    return 'Basic ' + auth.decode('ascii')\\n\\n\\ndef verify_new_repo(token, cac_org, new_repo):\\n    # Attempt to view the new repo\\n    try:\\n        url = 'https://api.github.com/repos/' + cac_org + '/' + new_repo\\n        headers = {\\n            'Accept': 'application/vnd.github+json',\\n            'Authorization': 'Bearer ' + token,\\n            'X-GitHub-Api-Version': '2022-11-28'\\n        }\\n        request = urllib.request.Request(url, headers=headers)\\n        urllib.request.urlopen(request)\\n        return True\\n    except:\\n        return False\\n\\n\\ndef create_new_repo(token, cac_org, new_repo):\\n    # If we could not view the repo, assume it needs to be created.\\n    # https://docs.github.com/en/rest/repos/repos?apiVersion=2022-11-28#create-an-organization-repository\\n    # Note you have to use the token rather than the JWT:\\n    # https://stackoverflow.com/questions/39600396/bad-credentails-for-jwt-for-github-integrations-api\\n\\n    headers = {\\n        'Authorization': 'token ' + token,\\n        'Content-Type': 'application/json',\\n        'Accept': 'application/vnd.github+json',\\n        'X-GitHub-Api-Version': '2022-11-28',\\n    }\\n\\n    try:\\n        # First try to create an organization repo:\\n        # https://docs.github.com/en/free-pro-team@latest/rest/repos/repos#create-an-organization-repository\\n        url = 'https://api.github.com/orgs/' + cac_org + '/repos'\\n        body = {'name': new_repo}\\n        request = urllib.request.Request(url, headers=headers, data=json.dumps(body).encode('utf-8'))\\n        urllib.request.urlopen(request)\\n    except urllib.error.URLError as ex:\\n        # Then fall back to creating a repo for the user:\\n        # https://docs.github.com/en/free-pro-team@latest/rest/repos/repos?apiVersion=2022-11-28#create-a-repository-for-the-authenticated-user\\n        if ex.code == 404:\\n            url = 'https://api.github.com/user/repos'\\n            body = {'name': new_repo}\\n            request = urllib.request.Request(url, headers=headers, data=json.dumps(body).encode('utf-8'))\\n            urllib.request.urlopen(request)\\n        else:\\n            raise ValueError(\\\"Failed to create thew new repository. This could indicate bad credentials.\\\") from ex\\n\\n\\ndef is_windows():\\n    return platform.system() == 'Windows'\\n\\n\\nparser, _ = init_argparse()\\n\\nif not parser.github_access_token.strip() and not (\\n        parser.github_app_id.strip() and parser.github_app_private_key.strip() and parser.github_app_installation_id.strip()):\\n    print(\\\"You must supply the GitHub token, or the GitHub App ID and private key and installation ID\\\")\\n    sys.exit(1)\\n\\nif not parser.new_repo_name.strip():\\n    print(\\\"You must define the new repo name\\\")\\n    sys.exit(1)\\n\\n# The access token is generated from a github app or supplied directly as an access token\\ntoken = generate_github_token(parser.github_app_id, parser.github_app_private_key, parser.github_app_installation_id) \\\\\\n    if not parser.github_access_token.strip() else parser.github_access_token.strip()\\n\\ncac_org = parser.git_organization.strip()\\nnew_repo_custom_prefix = re.sub('[^a-zA-Z0-9-]', '_', parser.new_repo_name_prefix.strip())\\nproject_repo_sanitized = re.sub('[^a-zA-Z0-9-]', '_', parser.new_repo_name.strip())\\n\\n# The prefix is optional\\nnew_repo_prefix_with_separator = new_repo_custom_prefix + '_' if new_repo_custom_prefix else ''\\n\\n# The new repo name is the prefix + the name of thew new project\\nnew_repo = new_repo_prefix_with_separator + project_repo_sanitized\\n\\n# This is the value of the forked git repo\\nset_octopusvariable('NewRepoUrl', 'https://github.com/' + cac_org + '/' + new_repo)\\nset_octopusvariable('NewRepo', new_repo)\\n\\nif not verify_new_repo(token, cac_org, new_repo):\\n    create_new_repo(token, cac_org, new_repo)\\n    print(\\n        'New repo was created at https://github.com/' + cac_org + '/' + new_repo)\\nelse:\\n    print('Repo at https://github.com/' + cac_org + '/' + new_repo + ' already exists and has not been modified')\\n\\nprint('New repo URL is defined in the output variable \\\"NewRepoUrl\\\": #{Octopus.Action[' +\\n      get_octopusvariable_quiet('Octopus.Step.Name') + '].Output.NewRepoUrl}')\\nprint('New repo name is defined in the output variable \\\"NewRepo\\\": #{Octopus.Action[' +\\n      get_octopusvariable_quiet('Octopus.Step.Name') + '].Output.NewRepo}')\\n\"\n        \"CreateGithubRepo.Git.Url.NewRepoName\"         = \"#{Git.Url.Repo}\"\n        \"Octopus.Action.Script.ScriptSource\"           = \"Inline\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n  step {\n    condition           = \"Success\"\n    name                = \"Create Octopus API Key Secret\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Create Octopus API Key Secret\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.Script.Syntax\"                = \"Python\"\n        \"CreateGitHubSecret.Git.Credentials.Password\" = \"#{Git.Credentials.Password}\"\n        \"CreateGitHubSecret.GitHub.Secret.Value\"      = \"#{Octopus.ApiKey}\"\n        \"CreateGitHubSecret.Git.Url.Repo\"             = \"#{Octopus.Action[Create Repo].Output.NewRepo}\"\n        \"Octopus.Action.RunOnServer\"                  = \"true\"\n        \"Octopus.Action.Script.ScriptSource\"          = \"Inline\"\n        \"CreateGitHubSecret.GitHub.Secret.Name\"       = \"OCTOPUS_API_TOKEN\"\n        \"CreateGitHubSecret.Git.Url.Organization\"     = \"#{Git.Url.Organization}\"\n        \"Octopus.Action.Script.ScriptBody\"            = \"# https://gist.github.com/comdotlinux/9a53bb00767a16d6646464c4b8249094\\n\\n# This script forks a GitHub repo. It creates a token from a GitHub App installation to avoid\\n# having to use a regular user account.\\nimport subprocess\\nimport sys\\n\\n# Install our own dependencies\\nsubprocess.check_call([sys.executable, '-m', 'pip', 'install', 'jwt', '--disable-pip-version-check'])\\nsubprocess.check_call([sys.executable, '-m', 'pip', 'install', 'pynacl', '--disable-pip-version-check'])\\n\\nimport requests\\nimport json\\nimport subprocess\\nimport sys\\nimport os\\nimport urllib.request\\nimport base64\\nimport re\\nimport jwt\\nimport time\\nimport argparse\\nimport urllib3\\nfrom base64 import b64encode\\nfrom typing import TypedDict\\nfrom nacl import public, encoding\\n\\n# Disable insecure http request warnings\\nurllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)\\n\\n# If this script is not being run as part of an Octopus step, setting variables is a noop\\nif 'set_octopusvariable' not in globals():\\n    def set_octopusvariable(variable, value):\\n        pass\\n\\n# If this script is not being run as part of an Octopus step, return variables from environment variables.\\n# Periods are replaced with underscores, and the variable name is converted to uppercase\\nif \\\"get_octopusvariable\\\" not in globals():\\n    def get_octopusvariable(variable):\\n        return os.environ[re.sub('\\\\\\\\.', '_', variable.upper())]\\n\\n# If this script is not being run as part of an Octopus step, print directly to std out.\\nif 'printverbose' not in globals():\\n    def printverbose(msg):\\n        print(msg)\\n\\n\\ndef printverbose_noansi(output):\\n    \\\"\\\"\\\"\\n    Strip ANSI color codes and print the output as verbose\\n    :param output: The output to print\\n    \\\"\\\"\\\"\\n    output_no_ansi = re.sub(r'\\\\x1b\\\\[[0-9;]*m', '', output)\\n    printverbose(output_no_ansi)\\n\\n\\ndef get_octopusvariable_quiet(variable):\\n    \\\"\\\"\\\"\\n    Gets an octopus variable, or an empty string if it does not exist.\\n    :param variable: The variable name\\n    :return: The variable value, or an empty string if the variable does not exist\\n    \\\"\\\"\\\"\\n    try:\\n        return get_octopusvariable(variable)\\n    except:\\n        return ''\\n\\n\\ndef execute(args, cwd=None, env=None, print_args=None, print_output=printverbose_noansi, raise_on_non_zero=False,\\n            append_to_path=None):\\n    \\\"\\\"\\\"\\n        The execute method provides the ability to execute external processes while capturing and returning the\\n        output to std err and std out and exit code.\\n    \\\"\\\"\\\"\\n\\n    my_env = os.environ.copy() if env is None else env\\n\\n    if append_to_path is not None:\\n        my_env[\\\"PATH\\\"] = append_to_path + os.pathsep + my_env['PATH']\\n\\n    process = subprocess.Popen(args,\\n                               stdout=subprocess.PIPE,\\n                               stderr=subprocess.PIPE,\\n                               stdin=open(os.devnull),\\n                               text=True,\\n                               cwd=cwd,\\n                               env=my_env)\\n    stdout, stderr = process.communicate()\\n    retcode = process.returncode\\n\\n    if not retcode == 0 and raise_on_non_zero:\\n        raise Exception('command returned exit code ' + retcode)\\n\\n    if print_args is not None:\\n        print_output(' '.join(args))\\n\\n    if print_output is not None:\\n        print_output(stdout)\\n        print_output(stderr)\\n\\n    return stdout, stderr, retcode\\n\\n\\ndef init_argparse():\\n    parser = argparse.ArgumentParser(\\n        usage='%(prog)s [OPTION]',\\n        description='Fork a GitHub repo'\\n    )\\n\\n    parser.add_argument('--secret-name', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.Secret.Name') or get_octopusvariable_quiet(\\n                            'GitHub.Secret.Name'))\\n    parser.add_argument('--secret-value', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.Secret.Value') or get_octopusvariable_quiet(\\n                            'GitHub.Secret.Value'))\\n\\n    parser.add_argument('--repo', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.Git.Url.Repo') or get_octopusvariable_quiet(\\n                            'Git.Url.Repo') or get_octopusvariable_quiet('Octopus.Project.Name'))\\n    parser.add_argument('--git-organization', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.Git.Url.Organization') or get_octopusvariable_quiet(\\n                            'Git.Url.Organization'))\\n    parser.add_argument('--github-app-id', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.App.Id') or get_octopusvariable_quiet('GitHub.App.Id'))\\n    parser.add_argument('--github-app-installation-id', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.App.InstallationId') or get_octopusvariable_quiet(\\n                            'GitHub.App.InstallationId'))\\n    parser.add_argument('--github-app-private-key', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.App.PrivateKey') or get_octopusvariable_quiet(\\n                            'GitHub.App.PrivateKey'))\\n    parser.add_argument('--git-password', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.Git.Credentials.Password') or get_octopusvariable_quiet(\\n                            'Git.Credentials.Password'),\\n                        help='The git password. This takes precedence over the --github-app-id,  --github-app-installation-id, and --github-app-private-key')\\n\\n    return parser.parse_known_args()\\n\\n\\ndef generate_github_token(github_app_id, github_app_private_key, github_app_installation_id):\\n    # Generate the tokens used by git and the GitHub API\\n    app_id = github_app_id\\n    signing_key = jwt.jwk_from_pem(github_app_private_key.encode('utf-8'))\\n\\n    payload = {\\n        # Issued at time\\n        'iat': int(time.time()),\\n        # JWT expiration time (10 minutes maximum)\\n        'exp': int(time.time()) + 600,\\n        # GitHub App's identifier\\n        'iss': app_id\\n    }\\n\\n    # Create JWT\\n    jwt_instance = jwt.JWT()\\n    encoded_jwt = jwt_instance.encode(payload, signing_key, alg='RS256')\\n\\n    # Create access token\\n    url = 'https://api.github.com/app/installations/' + github_app_installation_id + '/access_tokens'\\n    headers = {\\n        'Authorization': 'Bearer ' + encoded_jwt,\\n        'Accept': 'application/vnd.github+json',\\n        'X-GitHub-Api-Version': '2022-11-28'\\n    }\\n    request = urllib.request.Request(url, headers=headers, method='POST')\\n    response = urllib.request.urlopen(request)\\n    response_json = json.loads(response.read().decode())\\n    return response_json['token']\\n\\n\\ndef generate_auth_header(token):\\n    auth = base64.b64encode(('x-access-token:' + token).encode('ascii'))\\n    return 'Basic ' + auth.decode('ascii')\\n\\n\\ndef verify_new_repo(token, cac_org, new_repo):\\n    # Attempt to view the new repo\\n    try:\\n        url = 'https://api.github.com/repos/' + cac_org + '/' + new_repo\\n        headers = {\\n            'Accept': 'application/vnd.github+json',\\n            'Authorization': 'Bearer ' + token,\\n            'X-GitHub-Api-Version': '2022-11-28'\\n        }\\n        request = urllib.request.Request(url, headers=headers)\\n        urllib.request.urlopen(request)\\n        return True\\n    except:\\n        return False\\n\\n\\ndef encrypt(public_key_for_repo: str, secret_value_input: str) -> str:\\n    \\\"\\\"\\\"Encrypt a Unicode string using the public key.\\\"\\\"\\\"\\n    sealed_box = public.SealedBox(public.PublicKey(public_key_for_repo.encode(\\\"utf-8\\\"), encoding.Base64Encoder()))\\n    encrypted = sealed_box.encrypt(secret_value_input.encode(\\\"utf-8\\\"))\\n    return b64encode(encrypted).decode(\\\"utf-8\\\")\\n\\n\\ndef get_public_key(gh_base_url: str, gh_owner: str, gh_repo: str, gh_auth_token: str) -> (str, str):\\n    public_key_endpoint: str = f\\\"{gh_base_url}/{gh_owner}/{gh_repo}/actions/secrets/public-key\\\"\\n    headers: TypedDict[str, str] = {\\\"Authorization\\\": f\\\"Bearer {gh_auth_token}\\\"}\\n    response = requests.get(url=public_key_endpoint, headers=headers)\\n    if response.status_code != 200:\\n        raise IOError(\\n            f\\\"Could not get public key for repository {gh_owner}/{gh_repo}. The Response code was {response.status_code}\\\")\\n\\n    public_key_json = response.json()\\n    return public_key_json['key_id'], public_key_json['key']\\n\\n\\ndef set_secret(gh_base_url: str, gh_owner: str, gh_repo: str, gh_auth_token: str, public_key_id: str, secret_key: str,\\n               encrypted_secret_value: str):\\n    secret_creation_url = f\\\"{gh_base_url}/{gh_owner}/{gh_repo}/actions/secrets/{secret_key}\\\"\\n    secret_creation_body = {\\\"key_id\\\": public_key_id, \\\"encrypted_value\\\": encrypted_secret_value}\\n    headers: TypedDict[str, str] = {\\\"Authorization\\\": f\\\"Bearer {gh_auth_token}\\\", \\\"Content-Type\\\": \\\"application/json\\\"}\\n\\n    secret_creation_response = requests.put(url=secret_creation_url, json=secret_creation_body, headers=headers)\\n    if secret_creation_response.status_code == 201 or secret_creation_response.status_code == 204:\\n        print(\\\"--Secret Created / Updated!--\\\")\\n    else:\\n        print(f\\\"-- Error creating / updating github secret, the reason was : {secret_creation_response.reason}\\\")\\n\\n\\nparser, _ = init_argparse()\\n\\nif not parser.git_password.strip() and not (\\n        parser.github_app_id.strip() and parser.github_app_private_key.strip() and parser.github_app_installation_id.strip()):\\n    print(\\\"You must supply the GitHub token, or the GitHub App ID and private key and installation ID\\\")\\n    sys.exit(1)\\n\\nif not parser.git_organization.strip():\\n    print(\\\"You must define the organization\\\")\\n    sys.exit(1)\\n\\nif not parser.repo.strip():\\n    print(\\\"You must define the repo name\\\")\\n    sys.exit(1)\\n\\ntoken = generate_github_token(parser.github_app_id, parser.github_app_private_key,\\n                              parser.github_app_installation_id) if len(\\n    parser.git_password.strip()) == 0 else parser.git_password.strip()\\n\\nif not parser.git_password.strip() and not (\\n        parser.github_app_id.strip() and parser.github_app_private_key.strip() and parser.github_app_installation_id.strip()):\\n    print(\\\"You must supply the GitHub token, or the GitHub App ID and private key and installation ID\\\")\\n    sys.exit(1)\\n\\nif not parser.git_organization.strip():\\n    print(\\\"You must define the organization\\\")\\n    sys.exit(1)\\n\\nif not parser.repo.strip():\\n    print(\\\"You must define the repo name\\\")\\n    sys.exit(1)\\n\\nif not parser.secret_name.strip():\\n    print(\\\"You must define the secret name\\\")\\n    sys.exit(1)\\n    \\nif not verify_new_repo(token, parser.git_organization, parser.repo):\\n    print(\\\"Could not find the repo\\\")\\n    sys.exit(1)\\n\\nkey_id, public_key = get_public_key('https://api.github.com/repos', parser.git_organization, parser.repo,\\n                                    token)\\nencrypted_secret: str = encrypt(public_key_for_repo=public_key, secret_value_input=parser.secret_value)\\nset_secret(gh_base_url='https://api.github.com/repos', gh_owner=parser.git_organization, gh_repo=parser.repo,\\n           gh_auth_token=token, public_key_id=key_id, secret_key=parser.secret_name,\\n           encrypted_secret_value=encrypted_secret)\\n\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n  step {\n    condition           = \"Success\"\n    name                = \"Create Docker Hub Password Secret\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Create Docker Hub Password Secret\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"CreateGitHubSecret.Git.Credentials.Password\" = \"#{Git.Credentials.Password}\"\n        \"CreateGitHubSecret.GitHub.Secret.Name\"       = \"DOCKERHUB_TOKEN\"\n        \"Octopus.Action.Script.Syntax\"                = \"Python\"\n        \"CreateGitHubSecret.GitHub.Secret.Value\"      = \"#{Docker.Credentials.Password}\"\n        \"CreateGitHubSecret.Git.Url.Organization\"     = \"#{Git.Url.Organization}\"\n        \"Octopus.Action.Script.ScriptSource\"          = \"Inline\"\n        \"Octopus.Action.RunOnServer\"                  = \"true\"\n        \"CreateGitHubSecret.Git.Url.Repo\"             = \"#{Octopus.Action[Create Repo].Output.NewRepo}\"\n        \"Octopus.Action.Script.ScriptBody\"            = \"# https://gist.github.com/comdotlinux/9a53bb00767a16d6646464c4b8249094\\n\\n# This script forks a GitHub repo. It creates a token from a GitHub App installation to avoid\\n# having to use a regular user account.\\nimport subprocess\\nimport sys\\n\\n# Install our own dependencies\\nsubprocess.check_call([sys.executable, '-m', 'pip', 'install', 'jwt', '--disable-pip-version-check'])\\nsubprocess.check_call([sys.executable, '-m', 'pip', 'install', 'pynacl', '--disable-pip-version-check'])\\n\\nimport requests\\nimport json\\nimport subprocess\\nimport sys\\nimport os\\nimport urllib.request\\nimport base64\\nimport re\\nimport jwt\\nimport time\\nimport argparse\\nimport urllib3\\nfrom base64 import b64encode\\nfrom typing import TypedDict\\nfrom nacl import public, encoding\\n\\n# Disable insecure http request warnings\\nurllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)\\n\\n# If this script is not being run as part of an Octopus step, setting variables is a noop\\nif 'set_octopusvariable' not in globals():\\n    def set_octopusvariable(variable, value):\\n        pass\\n\\n# If this script is not being run as part of an Octopus step, return variables from environment variables.\\n# Periods are replaced with underscores, and the variable name is converted to uppercase\\nif \\\"get_octopusvariable\\\" not in globals():\\n    def get_octopusvariable(variable):\\n        return os.environ[re.sub('\\\\\\\\.', '_', variable.upper())]\\n\\n# If this script is not being run as part of an Octopus step, print directly to std out.\\nif 'printverbose' not in globals():\\n    def printverbose(msg):\\n        print(msg)\\n\\n\\ndef printverbose_noansi(output):\\n    \\\"\\\"\\\"\\n    Strip ANSI color codes and print the output as verbose\\n    :param output: The output to print\\n    \\\"\\\"\\\"\\n    output_no_ansi = re.sub(r'\\\\x1b\\\\[[0-9;]*m', '', output)\\n    printverbose(output_no_ansi)\\n\\n\\ndef get_octopusvariable_quiet(variable):\\n    \\\"\\\"\\\"\\n    Gets an octopus variable, or an empty string if it does not exist.\\n    :param variable: The variable name\\n    :return: The variable value, or an empty string if the variable does not exist\\n    \\\"\\\"\\\"\\n    try:\\n        return get_octopusvariable(variable)\\n    except:\\n        return ''\\n\\n\\ndef execute(args, cwd=None, env=None, print_args=None, print_output=printverbose_noansi, raise_on_non_zero=False,\\n            append_to_path=None):\\n    \\\"\\\"\\\"\\n        The execute method provides the ability to execute external processes while capturing and returning the\\n        output to std err and std out and exit code.\\n    \\\"\\\"\\\"\\n\\n    my_env = os.environ.copy() if env is None else env\\n\\n    if append_to_path is not None:\\n        my_env[\\\"PATH\\\"] = append_to_path + os.pathsep + my_env['PATH']\\n\\n    process = subprocess.Popen(args,\\n                               stdout=subprocess.PIPE,\\n                               stderr=subprocess.PIPE,\\n                               stdin=open(os.devnull),\\n                               text=True,\\n                               cwd=cwd,\\n                               env=my_env)\\n    stdout, stderr = process.communicate()\\n    retcode = process.returncode\\n\\n    if not retcode == 0 and raise_on_non_zero:\\n        raise Exception('command returned exit code ' + retcode)\\n\\n    if print_args is not None:\\n        print_output(' '.join(args))\\n\\n    if print_output is not None:\\n        print_output(stdout)\\n        print_output(stderr)\\n\\n    return stdout, stderr, retcode\\n\\n\\ndef init_argparse():\\n    parser = argparse.ArgumentParser(\\n        usage='%(prog)s [OPTION]',\\n        description='Fork a GitHub repo'\\n    )\\n\\n    parser.add_argument('--secret-name', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.Secret.Name') or get_octopusvariable_quiet(\\n                            'GitHub.Secret.Name'))\\n    parser.add_argument('--secret-value', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.Secret.Value') or get_octopusvariable_quiet(\\n                            'GitHub.Secret.Value'))\\n\\n    parser.add_argument('--repo', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.Git.Url.Repo') or get_octopusvariable_quiet(\\n                            'Git.Url.Repo') or get_octopusvariable_quiet('Octopus.Project.Name'))\\n    parser.add_argument('--git-organization', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.Git.Url.Organization') or get_octopusvariable_quiet(\\n                            'Git.Url.Organization'))\\n    parser.add_argument('--github-app-id', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.App.Id') or get_octopusvariable_quiet('GitHub.App.Id'))\\n    parser.add_argument('--github-app-installation-id', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.App.InstallationId') or get_octopusvariable_quiet(\\n                            'GitHub.App.InstallationId'))\\n    parser.add_argument('--github-app-private-key', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.App.PrivateKey') or get_octopusvariable_quiet(\\n                            'GitHub.App.PrivateKey'))\\n    parser.add_argument('--git-password', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.Git.Credentials.Password') or get_octopusvariable_quiet(\\n                            'Git.Credentials.Password'),\\n                        help='The git password. This takes precedence over the --github-app-id,  --github-app-installation-id, and --github-app-private-key')\\n\\n    return parser.parse_known_args()\\n\\n\\ndef generate_github_token(github_app_id, github_app_private_key, github_app_installation_id):\\n    # Generate the tokens used by git and the GitHub API\\n    app_id = github_app_id\\n    signing_key = jwt.jwk_from_pem(github_app_private_key.encode('utf-8'))\\n\\n    payload = {\\n        # Issued at time\\n        'iat': int(time.time()),\\n        # JWT expiration time (10 minutes maximum)\\n        'exp': int(time.time()) + 600,\\n        # GitHub App's identifier\\n        'iss': app_id\\n    }\\n\\n    # Create JWT\\n    jwt_instance = jwt.JWT()\\n    encoded_jwt = jwt_instance.encode(payload, signing_key, alg='RS256')\\n\\n    # Create access token\\n    url = 'https://api.github.com/app/installations/' + github_app_installation_id + '/access_tokens'\\n    headers = {\\n        'Authorization': 'Bearer ' + encoded_jwt,\\n        'Accept': 'application/vnd.github+json',\\n        'X-GitHub-Api-Version': '2022-11-28'\\n    }\\n    request = urllib.request.Request(url, headers=headers, method='POST')\\n    response = urllib.request.urlopen(request)\\n    response_json = json.loads(response.read().decode())\\n    return response_json['token']\\n\\n\\ndef generate_auth_header(token):\\n    auth = base64.b64encode(('x-access-token:' + token).encode('ascii'))\\n    return 'Basic ' + auth.decode('ascii')\\n\\n\\ndef verify_new_repo(token, cac_org, new_repo):\\n    # Attempt to view the new repo\\n    try:\\n        url = 'https://api.github.com/repos/' + cac_org + '/' + new_repo\\n        headers = {\\n            'Accept': 'application/vnd.github+json',\\n            'Authorization': 'Bearer ' + token,\\n            'X-GitHub-Api-Version': '2022-11-28'\\n        }\\n        request = urllib.request.Request(url, headers=headers)\\n        urllib.request.urlopen(request)\\n        return True\\n    except:\\n        return False\\n\\n\\ndef encrypt(public_key_for_repo: str, secret_value_input: str) -> str:\\n    \\\"\\\"\\\"Encrypt a Unicode string using the public key.\\\"\\\"\\\"\\n    sealed_box = public.SealedBox(public.PublicKey(public_key_for_repo.encode(\\\"utf-8\\\"), encoding.Base64Encoder()))\\n    encrypted = sealed_box.encrypt(secret_value_input.encode(\\\"utf-8\\\"))\\n    return b64encode(encrypted).decode(\\\"utf-8\\\")\\n\\n\\ndef get_public_key(gh_base_url: str, gh_owner: str, gh_repo: str, gh_auth_token: str) -> (str, str):\\n    public_key_endpoint: str = f\\\"{gh_base_url}/{gh_owner}/{gh_repo}/actions/secrets/public-key\\\"\\n    headers: TypedDict[str, str] = {\\\"Authorization\\\": f\\\"Bearer {gh_auth_token}\\\"}\\n    response = requests.get(url=public_key_endpoint, headers=headers)\\n    if response.status_code != 200:\\n        raise IOError(\\n            f\\\"Could not get public key for repository {gh_owner}/{gh_repo}. The Response code was {response.status_code}\\\")\\n\\n    public_key_json = response.json()\\n    return public_key_json['key_id'], public_key_json['key']\\n\\n\\ndef set_secret(gh_base_url: str, gh_owner: str, gh_repo: str, gh_auth_token: str, public_key_id: str, secret_key: str,\\n               encrypted_secret_value: str):\\n    secret_creation_url = f\\\"{gh_base_url}/{gh_owner}/{gh_repo}/actions/secrets/{secret_key}\\\"\\n    secret_creation_body = {\\\"key_id\\\": public_key_id, \\\"encrypted_value\\\": encrypted_secret_value}\\n    headers: TypedDict[str, str] = {\\\"Authorization\\\": f\\\"Bearer {gh_auth_token}\\\", \\\"Content-Type\\\": \\\"application/json\\\"}\\n\\n    secret_creation_response = requests.put(url=secret_creation_url, json=secret_creation_body, headers=headers)\\n    if secret_creation_response.status_code == 201 or secret_creation_response.status_code == 204:\\n        print(\\\"--Secret Created / Updated!--\\\")\\n    else:\\n        print(f\\\"-- Error creating / updating github secret, the reason was : {secret_creation_response.reason}\\\")\\n\\n\\nparser, _ = init_argparse()\\n\\nif not parser.git_password.strip() and not (\\n        parser.github_app_id.strip() and parser.github_app_private_key.strip() and parser.github_app_installation_id.strip()):\\n    print(\\\"You must supply the GitHub token, or the GitHub App ID and private key and installation ID\\\")\\n    sys.exit(1)\\n\\nif not parser.git_organization.strip():\\n    print(\\\"You must define the organization\\\")\\n    sys.exit(1)\\n\\nif not parser.repo.strip():\\n    print(\\\"You must define the repo name\\\")\\n    sys.exit(1)\\n\\ntoken = generate_github_token(parser.github_app_id, parser.github_app_private_key,\\n                              parser.github_app_installation_id) if len(\\n    parser.git_password.strip()) == 0 else parser.git_password.strip()\\n\\nif not parser.git_password.strip() and not (\\n        parser.github_app_id.strip() and parser.github_app_private_key.strip() and parser.github_app_installation_id.strip()):\\n    print(\\\"You must supply the GitHub token, or the GitHub App ID and private key and installation ID\\\")\\n    sys.exit(1)\\n\\nif not parser.git_organization.strip():\\n    print(\\\"You must define the organization\\\")\\n    sys.exit(1)\\n\\nif not parser.repo.strip():\\n    print(\\\"You must define the repo name\\\")\\n    sys.exit(1)\\n\\nif not parser.secret_name.strip():\\n    print(\\\"You must define the secret name\\\")\\n    sys.exit(1)\\n    \\nif not verify_new_repo(token, parser.git_organization, parser.repo):\\n    print(\\\"Could not find the repo\\\")\\n    sys.exit(1)\\n\\nkey_id, public_key = get_public_key('https://api.github.com/repos', parser.git_organization, parser.repo,\\n                                    token)\\nencrypted_secret: str = encrypt(public_key_for_repo=public_key, secret_value_input=parser.secret_value)\\nset_secret(gh_base_url='https://api.github.com/repos', gh_owner=parser.git_organization, gh_repo=parser.repo,\\n           gh_auth_token=token, public_key_id=key_id, secret_key=parser.secret_name,\\n           encrypted_secret_value=encrypted_secret)\\n\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n  step {\n    condition           = \"Success\"\n    name                = \"Create Docker Hub Password Username\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Create Docker Hub Password Username\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"CreateGitHubSecret.Git.Credentials.Password\" = \"#{Git.Credentials.Password}\"\n        \"Octopus.Action.RunOnServer\"                  = \"true\"\n        \"CreateGitHubSecret.GitHub.Secret.Value\"      = \"#{Docker.Credentials.Username}\"\n        \"CreateGitHubSecret.Git.Url.Repo\"             = \"#{Octopus.Action[Create Repo].Output.NewRepo}\"\n        \"Octopus.Action.Script.ScriptSource\"          = \"Inline\"\n        \"Octopus.Action.Script.ScriptBody\"            = \"# https://gist.github.com/comdotlinux/9a53bb00767a16d6646464c4b8249094\\n\\n# This script forks a GitHub repo. It creates a token from a GitHub App installation to avoid\\n# having to use a regular user account.\\nimport subprocess\\nimport sys\\n\\n# Install our own dependencies\\nsubprocess.check_call([sys.executable, '-m', 'pip', 'install', 'jwt', '--disable-pip-version-check'])\\nsubprocess.check_call([sys.executable, '-m', 'pip', 'install', 'pynacl', '--disable-pip-version-check'])\\n\\nimport requests\\nimport json\\nimport subprocess\\nimport sys\\nimport os\\nimport urllib.request\\nimport base64\\nimport re\\nimport jwt\\nimport time\\nimport argparse\\nimport urllib3\\nfrom base64 import b64encode\\nfrom typing import TypedDict\\nfrom nacl import public, encoding\\n\\n# Disable insecure http request warnings\\nurllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)\\n\\n# If this script is not being run as part of an Octopus step, setting variables is a noop\\nif 'set_octopusvariable' not in globals():\\n    def set_octopusvariable(variable, value):\\n        pass\\n\\n# If this script is not being run as part of an Octopus step, return variables from environment variables.\\n# Periods are replaced with underscores, and the variable name is converted to uppercase\\nif \\\"get_octopusvariable\\\" not in globals():\\n    def get_octopusvariable(variable):\\n        return os.environ[re.sub('\\\\\\\\.', '_', variable.upper())]\\n\\n# If this script is not being run as part of an Octopus step, print directly to std out.\\nif 'printverbose' not in globals():\\n    def printverbose(msg):\\n        print(msg)\\n\\n\\ndef printverbose_noansi(output):\\n    \\\"\\\"\\\"\\n    Strip ANSI color codes and print the output as verbose\\n    :param output: The output to print\\n    \\\"\\\"\\\"\\n    output_no_ansi = re.sub(r'\\\\x1b\\\\[[0-9;]*m', '', output)\\n    printverbose(output_no_ansi)\\n\\n\\ndef get_octopusvariable_quiet(variable):\\n    \\\"\\\"\\\"\\n    Gets an octopus variable, or an empty string if it does not exist.\\n    :param variable: The variable name\\n    :return: The variable value, or an empty string if the variable does not exist\\n    \\\"\\\"\\\"\\n    try:\\n        return get_octopusvariable(variable)\\n    except:\\n        return ''\\n\\n\\ndef execute(args, cwd=None, env=None, print_args=None, print_output=printverbose_noansi, raise_on_non_zero=False,\\n            append_to_path=None):\\n    \\\"\\\"\\\"\\n        The execute method provides the ability to execute external processes while capturing and returning the\\n        output to std err and std out and exit code.\\n    \\\"\\\"\\\"\\n\\n    my_env = os.environ.copy() if env is None else env\\n\\n    if append_to_path is not None:\\n        my_env[\\\"PATH\\\"] = append_to_path + os.pathsep + my_env['PATH']\\n\\n    process = subprocess.Popen(args,\\n                               stdout=subprocess.PIPE,\\n                               stderr=subprocess.PIPE,\\n                               stdin=open(os.devnull),\\n                               text=True,\\n                               cwd=cwd,\\n                               env=my_env)\\n    stdout, stderr = process.communicate()\\n    retcode = process.returncode\\n\\n    if not retcode == 0 and raise_on_non_zero:\\n        raise Exception('command returned exit code ' + retcode)\\n\\n    if print_args is not None:\\n        print_output(' '.join(args))\\n\\n    if print_output is not None:\\n        print_output(stdout)\\n        print_output(stderr)\\n\\n    return stdout, stderr, retcode\\n\\n\\ndef init_argparse():\\n    parser = argparse.ArgumentParser(\\n        usage='%(prog)s [OPTION]',\\n        description='Fork a GitHub repo'\\n    )\\n\\n    parser.add_argument('--secret-name', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.Secret.Name') or get_octopusvariable_quiet(\\n                            'GitHub.Secret.Name'))\\n    parser.add_argument('--secret-value', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.Secret.Value') or get_octopusvariable_quiet(\\n                            'GitHub.Secret.Value'))\\n\\n    parser.add_argument('--repo', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.Git.Url.Repo') or get_octopusvariable_quiet(\\n                            'Git.Url.Repo') or get_octopusvariable_quiet('Octopus.Project.Name'))\\n    parser.add_argument('--git-organization', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.Git.Url.Organization') or get_octopusvariable_quiet(\\n                            'Git.Url.Organization'))\\n    parser.add_argument('--github-app-id', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.App.Id') or get_octopusvariable_quiet('GitHub.App.Id'))\\n    parser.add_argument('--github-app-installation-id', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.App.InstallationId') or get_octopusvariable_quiet(\\n                            'GitHub.App.InstallationId'))\\n    parser.add_argument('--github-app-private-key', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.App.PrivateKey') or get_octopusvariable_quiet(\\n                            'GitHub.App.PrivateKey'))\\n    parser.add_argument('--git-password', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.Git.Credentials.Password') or get_octopusvariable_quiet(\\n                            'Git.Credentials.Password'),\\n                        help='The git password. This takes precedence over the --github-app-id,  --github-app-installation-id, and --github-app-private-key')\\n\\n    return parser.parse_known_args()\\n\\n\\ndef generate_github_token(github_app_id, github_app_private_key, github_app_installation_id):\\n    # Generate the tokens used by git and the GitHub API\\n    app_id = github_app_id\\n    signing_key = jwt.jwk_from_pem(github_app_private_key.encode('utf-8'))\\n\\n    payload = {\\n        # Issued at time\\n        'iat': int(time.time()),\\n        # JWT expiration time (10 minutes maximum)\\n        'exp': int(time.time()) + 600,\\n        # GitHub App's identifier\\n        'iss': app_id\\n    }\\n\\n    # Create JWT\\n    jwt_instance = jwt.JWT()\\n    encoded_jwt = jwt_instance.encode(payload, signing_key, alg='RS256')\\n\\n    # Create access token\\n    url = 'https://api.github.com/app/installations/' + github_app_installation_id + '/access_tokens'\\n    headers = {\\n        'Authorization': 'Bearer ' + encoded_jwt,\\n        'Accept': 'application/vnd.github+json',\\n        'X-GitHub-Api-Version': '2022-11-28'\\n    }\\n    request = urllib.request.Request(url, headers=headers, method='POST')\\n    response = urllib.request.urlopen(request)\\n    response_json = json.loads(response.read().decode())\\n    return response_json['token']\\n\\n\\ndef generate_auth_header(token):\\n    auth = base64.b64encode(('x-access-token:' + token).encode('ascii'))\\n    return 'Basic ' + auth.decode('ascii')\\n\\n\\ndef verify_new_repo(token, cac_org, new_repo):\\n    # Attempt to view the new repo\\n    try:\\n        url = 'https://api.github.com/repos/' + cac_org + '/' + new_repo\\n        headers = {\\n            'Accept': 'application/vnd.github+json',\\n            'Authorization': 'Bearer ' + token,\\n            'X-GitHub-Api-Version': '2022-11-28'\\n        }\\n        request = urllib.request.Request(url, headers=headers)\\n        urllib.request.urlopen(request)\\n        return True\\n    except:\\n        return False\\n\\n\\ndef encrypt(public_key_for_repo: str, secret_value_input: str) -> str:\\n    \\\"\\\"\\\"Encrypt a Unicode string using the public key.\\\"\\\"\\\"\\n    sealed_box = public.SealedBox(public.PublicKey(public_key_for_repo.encode(\\\"utf-8\\\"), encoding.Base64Encoder()))\\n    encrypted = sealed_box.encrypt(secret_value_input.encode(\\\"utf-8\\\"))\\n    return b64encode(encrypted).decode(\\\"utf-8\\\")\\n\\n\\ndef get_public_key(gh_base_url: str, gh_owner: str, gh_repo: str, gh_auth_token: str) -> (str, str):\\n    public_key_endpoint: str = f\\\"{gh_base_url}/{gh_owner}/{gh_repo}/actions/secrets/public-key\\\"\\n    headers: TypedDict[str, str] = {\\\"Authorization\\\": f\\\"Bearer {gh_auth_token}\\\"}\\n    response = requests.get(url=public_key_endpoint, headers=headers)\\n    if response.status_code != 200:\\n        raise IOError(\\n            f\\\"Could not get public key for repository {gh_owner}/{gh_repo}. The Response code was {response.status_code}\\\")\\n\\n    public_key_json = response.json()\\n    return public_key_json['key_id'], public_key_json['key']\\n\\n\\ndef set_secret(gh_base_url: str, gh_owner: str, gh_repo: str, gh_auth_token: str, public_key_id: str, secret_key: str,\\n               encrypted_secret_value: str):\\n    secret_creation_url = f\\\"{gh_base_url}/{gh_owner}/{gh_repo}/actions/secrets/{secret_key}\\\"\\n    secret_creation_body = {\\\"key_id\\\": public_key_id, \\\"encrypted_value\\\": encrypted_secret_value}\\n    headers: TypedDict[str, str] = {\\\"Authorization\\\": f\\\"Bearer {gh_auth_token}\\\", \\\"Content-Type\\\": \\\"application/json\\\"}\\n\\n    secret_creation_response = requests.put(url=secret_creation_url, json=secret_creation_body, headers=headers)\\n    if secret_creation_response.status_code == 201 or secret_creation_response.status_code == 204:\\n        print(\\\"--Secret Created / Updated!--\\\")\\n    else:\\n        print(f\\\"-- Error creating / updating github secret, the reason was : {secret_creation_response.reason}\\\")\\n\\n\\nparser, _ = init_argparse()\\n\\nif not parser.git_password.strip() and not (\\n        parser.github_app_id.strip() and parser.github_app_private_key.strip() and parser.github_app_installation_id.strip()):\\n    print(\\\"You must supply the GitHub token, or the GitHub App ID and private key and installation ID\\\")\\n    sys.exit(1)\\n\\nif not parser.git_organization.strip():\\n    print(\\\"You must define the organization\\\")\\n    sys.exit(1)\\n\\nif not parser.repo.strip():\\n    print(\\\"You must define the repo name\\\")\\n    sys.exit(1)\\n\\ntoken = generate_github_token(parser.github_app_id, parser.github_app_private_key,\\n                              parser.github_app_installation_id) if len(\\n    parser.git_password.strip()) == 0 else parser.git_password.strip()\\n\\nif not parser.git_password.strip() and not (\\n        parser.github_app_id.strip() and parser.github_app_private_key.strip() and parser.github_app_installation_id.strip()):\\n    print(\\\"You must supply the GitHub token, or the GitHub App ID and private key and installation ID\\\")\\n    sys.exit(1)\\n\\nif not parser.git_organization.strip():\\n    print(\\\"You must define the organization\\\")\\n    sys.exit(1)\\n\\nif not parser.repo.strip():\\n    print(\\\"You must define the repo name\\\")\\n    sys.exit(1)\\n\\nif not parser.secret_name.strip():\\n    print(\\\"You must define the secret name\\\")\\n    sys.exit(1)\\n    \\nif not verify_new_repo(token, parser.git_organization, parser.repo):\\n    print(\\\"Could not find the repo\\\")\\n    sys.exit(1)\\n\\nkey_id, public_key = get_public_key('https://api.github.com/repos', parser.git_organization, parser.repo,\\n                                    token)\\nencrypted_secret: str = encrypt(public_key_for_repo=public_key, secret_value_input=parser.secret_value)\\nset_secret(gh_base_url='https://api.github.com/repos', gh_owner=parser.git_organization, gh_repo=parser.repo,\\n           gh_auth_token=token, public_key_id=key_id, secret_key=parser.secret_name,\\n           encrypted_secret_value=encrypted_secret)\\n\"\n        \"CreateGitHubSecret.Git.Url.Organization\"     = \"#{Git.Url.Organization}\"\n        \"CreateGitHubSecret.GitHub.Secret.Name\"       = \"DOCKERHUB_USERNAME\"\n        \"Octopus.Action.Script.Syntax\"                = \"Python\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n  step {\n    condition           = \"Success\"\n    name                = \"Generate and Push\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Generate and Push\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"PopulateGithubRepo.Yeoman.Generator.SubGenerator\" = \"nodejs-docker-webapp\"\n        \"PopulateGithubRepo.Yeoman.Generator.Arguments\"    = \"--octopusUrl #{Octopus.Action[Get Variables].Output.Web.ServerUri} --octopusSpace \\\"#{Octopus.Action[Get Variables].Output.Space.Name}\\\" --octopusApi #{Octopus.ApiKey} --octopusProject \\\"#{Application.Octopus.Project}\\\" --dockerImage #{Application.Docker.Image}\"\n        \"PopulateGithubRepo.Yeoman.Generator.Name\"         = \"octopus-reference-architecture-apps\"\n        \"Octopus.Action.Script.Syntax\"                     = \"Python\"\n        \"Octopus.Action.Script.ScriptSource\"               = \"Inline\"\n        \"Octopus.Action.Script.ScriptBody\"                 = \"# This script forks a GitHub repo. It creates a token from a GitHub App installation to avoid\\n# having to use a regular user account.\\nimport subprocess\\nimport sys\\n\\n# Install our own dependencies\\nenv_vars = os.environ.copy()\\nenv_vars['PIP_ROOT_USER_ACTION'] = 'ignore'\\nsubprocess.check_call([sys.executable, '-m', 'pip', 'install', 'jwt', '--disable-pip-version-check'], env=env_vars)\\nsubprocess.check_call([sys.executable, '-m', 'pip', 'install', 'requests', '--disable-pip-version-check'], env=env_vars)\\nsubprocess.check_call([sys.executable, '-m', 'pip', 'install', 'anyascii', '--disable-pip-version-check'], env=env_vars)\\n\\nimport requests\\nimport json\\nimport subprocess\\nimport sys\\nimport os\\nimport urllib.request\\nimport base64\\nimport re\\nimport jwt\\nimport time\\nimport argparse\\nimport platform\\nimport zipfile\\nimport lzma\\nimport tarfile\\nimport shutil\\nimport urllib3\\nfrom shlex import split\\nfrom anyascii import anyascii\\n\\n# Disable insecure http request warnings\\nurllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)\\n\\n# If this script is not being run as part of an Octopus step, setting variables is a noop\\nif 'set_octopusvariable' not in globals():\\n    def set_octopusvariable(variable, value):\\n        pass\\n\\n# If this script is not being run as part of an Octopus step, return variables from environment variables.\\n# Periods are replaced with underscores, and the variable name is converted to uppercase\\nif \\\"get_octopusvariable\\\" not in globals():\\n    def get_octopusvariable(variable):\\n        return os.environ[re.sub('\\\\\\\\.', '_', variable.upper())]\\n\\n# If this script is not being run as part of an Octopus step, print directly to std out.\\nif 'printverbose' not in globals():\\n    def printverbose(msg):\\n        print(msg)\\n\\n\\ndef printverbose_noansi(output):\\n    \\\"\\\"\\\"\\n    Strip ANSI color codes and print the output as verbose\\n    :param output: The output to print\\n    \\\"\\\"\\\"\\n    output_no_ansi = re.sub(r'\\\\x1b\\\\[[0-9;]*m', '', output)\\n    printverbose(output_no_ansi)\\n\\n\\ndef get_octopusvariable_quiet(variable):\\n    \\\"\\\"\\\"\\n    Gets an octopus variable, or an empty string if it does not exist.\\n    :param variable: The variable name\\n    :return: The variable value, or an empty string if the variable does not exist\\n    \\\"\\\"\\\"\\n    try:\\n        return get_octopusvariable(variable)\\n    except Exception as inst:\\n        return ''\\n\\n\\ndef execute(args, cwd=None, env=None, print_args=None, print_output=printverbose_noansi, raise_on_non_zero=False,\\n            append_to_path=None):\\n    \\\"\\\"\\\"\\n        The execute method provides the ability to execute external processes while capturing and returning the\\n        output to std err and std out and exit code.\\n    \\\"\\\"\\\"\\n\\n    my_env = os.environ.copy() if env is None else env\\n\\n    if append_to_path is not None:\\n        my_env[\\\"PATH\\\"] = append_to_path + os.pathsep + my_env['PATH']\\n\\n    process = subprocess.Popen(args,\\n                               stdout=subprocess.PIPE,\\n                               stderr=subprocess.PIPE,\\n                               stdin=open(os.devnull),\\n                               text=True,\\n                               cwd=cwd,\\n                               env=my_env)\\n    stdout, stderr = process.communicate()\\n    retcode = process.returncode\\n\\n    if not retcode == 0 and raise_on_non_zero:\\n        raise Exception('command returned exit code ' + retcode)\\n\\n    if print_args is not None:\\n        print_output(' '.join(args))\\n\\n    if print_output is not None:\\n        print_output(stdout)\\n        print_output(stderr)\\n\\n    return stdout, stderr, retcode\\n\\n\\ndef init_argparse():\\n    parser = argparse.ArgumentParser(\\n        usage='%(prog)s [OPTION]',\\n        description='Fork a GitHub repo'\\n    )\\n    parser.add_argument('--generator', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'PopulateGithubRepo.Yeoman.Generator.Name') or get_octopusvariable_quiet(\\n                            'Yeoman.Generator.Name'))\\n    parser.add_argument('--sub-generator', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'PopulateGithubRepo.Yeoman.Generator.SubGenerator') or get_octopusvariable_quiet(\\n                            'Yeoman.Generator.SubGenerator'))\\n    parser.add_argument('--generator-arguments', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'PopulateGithubRepo.Yeoman.Generator.Arguments') or get_octopusvariable_quiet(\\n                            'Yeoman.Generator.Arguments'),\\n                        help='The arguments to pas to yo. Pass all arguments as a single string. This string is then parsed as if it were yo arguments.')\\n    parser.add_argument('--repo', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'PopulateGithubRepo.Git.Url.Repo') or get_octopusvariable_quiet(\\n                            'Git.Url.Repo'))\\n    parser.add_argument('--git-organization', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'PopulateGithubRepo.Git.Url.Organization') or get_octopusvariable_quiet(\\n                            'Git.Url.Organization'))\\n    parser.add_argument('--github-app-id', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'PopulateGithubRepo.GitHub.App.Id') or get_octopusvariable_quiet('GitHub.App.Id'))\\n    parser.add_argument('--github-app-installation-id', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'PopulateGithubRepo.GitHub.App.InstallationId') or get_octopusvariable_quiet(\\n                            'GitHub.App.InstallationId'))\\n    parser.add_argument('--github-app-private-key', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'PopulateGithubRepo.GitHub.App.PrivateKey') or get_octopusvariable_quiet(\\n                            'GitHub.App.PrivateKey'))\\n    parser.add_argument('--git-password', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'PopulateGithubRepo.Git.Credentials.Password') or get_octopusvariable_quiet(\\n                            'Git.Credentials.Password'),\\n                        help='The git password. This takes precedence over the --github-app-id,  --github-app-installation-id, and --github-app-private-key')\\n    parser.add_argument('--git-username', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'PopulateGithubRepo.Git.Credentials.Username') or get_octopusvariable_quiet(\\n                            'Git.Credentials.Username'),\\n                        help='The git username. This will be used for both the git authentication and the username associated with any commits.')\\n\\n    return parser.parse_known_args()\\n\\n\\ndef generate_github_token(github_app_id, github_app_private_key, github_app_installation_id):\\n    # Generate the tokens used by git and the GitHub API\\n    app_id = github_app_id\\n    signing_key = jwt.jwk_from_pem(github_app_private_key.encode('utf-8'))\\n\\n    payload = {\\n        # Issued at time\\n        'iat': int(time.time()),\\n        # JWT expiration time (10 minutes maximum)\\n        'exp': int(time.time()) + 600,\\n        # GitHub App's identifier\\n        'iss': app_id\\n    }\\n\\n    # Create JWT\\n    jwt_instance = jwt.JWT()\\n    encoded_jwt = jwt_instance.encode(payload, signing_key, alg='RS256')\\n\\n    # Create access token\\n    url = 'https://api.github.com/app/installations/' + github_app_installation_id + '/access_tokens'\\n    headers = {\\n        'Authorization': 'Bearer ' + encoded_jwt,\\n        'Accept': 'application/vnd.github+json',\\n        'X-GitHub-Api-Version': '2022-11-28'\\n    }\\n    request = urllib.request.Request(url, headers=headers, method='POST')\\n    response = urllib.request.urlopen(request)\\n    response_json = json.loads(response.read().decode())\\n    return response_json['token']\\n\\n\\ndef generate_auth_header(token):\\n    auth = base64.b64encode(('x-access-token:' + token).encode('ascii'))\\n    return 'Basic ' + auth.decode('ascii')\\n\\n\\ndef verify_new_repo(token, cac_org, new_repo):\\n    # Attempt to view the new repo\\n    try:\\n        url = 'https://api.github.com/repos/' + cac_org + '/' + new_repo\\n        headers = {\\n            'Accept': 'application/vnd.github+json',\\n            'Authorization': 'Bearer ' + token,\\n            'X-GitHub-Api-Version': '2022-11-28'\\n        }\\n        request = urllib.request.Request(url, headers=headers)\\n        urllib.request.urlopen(request)\\n        return True\\n    except Exception as inst:\\n        return False\\n\\n\\ndef is_windows():\\n    return platform.system() == 'Windows'\\n\\n\\ndef download_file(url, filename, verify_ssl=True):\\n    r = requests.get(url, verify=verify_ssl)\\n    with open(filename, 'wb') as file:\\n        file.write(r.content)\\n\\n\\ndef ensure_git_exists():\\n    if is_windows():\\n        print(\\\"Checking git is installed\\\")\\n        try:\\n            stdout, _, exit_code = execute(['git', 'version'])\\n            printverbose(stdout)\\n            if not exit_code == 0:\\n                raise \\\"git not found\\\"\\n        except:\\n            print(\\\"Downloading git\\\")\\n            download_file('https://www.7-zip.org/a/7zr.exe', '7zr.exe')\\n            download_file(\\n                'https://github.com/git-for-windows/git/releases/download/v2.42.0.windows.2/PortableGit-2.42.0.2-64-bit.7z.exe',\\n                'PortableGit.7z.exe')\\n            print(\\\"Installing git\\\")\\n            print(\\\"Consider installing git on the worker or using a standard worker-tools image\\\")\\n            execute(['7zr.exe', 'x', 'PortableGit.7z.exe', '-o' + os.path.join(os.getcwd(), 'git'), '-y'])\\n            return os.path.join(os.getcwd(), 'git', 'bin', 'git')\\n\\n    return 'git'\\n\\n\\ndef install_npm_linux():\\n    print(\\\"Downloading node\\\")\\n    download_file(\\n        'https://nodejs.org/dist/v18.18.2/node-v18.18.2-linux-x64.tar.xz',\\n        'node.tar.xz')\\n    print(\\\"Installing node on Linux\\\")\\n    with lzma.open(\\\"node.tar.xz\\\", \\\"r\\\") as lzma_ref:\\n        with open(\\\"node.tar\\\", \\\"wb\\\") as fdst:\\n            shutil.copyfileobj(lzma_ref, fdst)\\n    with tarfile.open(\\\"node.tar\\\", \\\"r\\\") as tar_ref:\\n        tar_ref.extractall(os.getcwd())\\n\\n    try:\\n        _, _, exit_code = execute([os.getcwd() + '/node-v18.18.2-linux-x64/bin/npm', '--version'],\\n                                  append_to_path=os.getcwd() + '/node-v18.18.2-linux-x64/bin')\\n        if not exit_code == 0:\\n            raise Exception(\\\"Failed to run npm\\\")\\n    except Exception as ex:\\n        print('Failed to install npm ' + str(ex))\\n        sys.exit(1)\\n    return os.getcwd() + '/node-v18.18.2-linux-x64/bin/npm', os.getcwd() + '/node-v18.18.2-linux-x64/bin'\\n\\n\\ndef install_npm_windows():\\n    print(\\\"Downloading node\\\")\\n    download_file('https://nodejs.org/dist/v18.18.2/node-v18.18.2-win-x64.zip', 'node.zip', False)\\n    print(\\\"Installing node on Windows\\\")\\n    with zipfile.ZipFile(\\\"node.zip\\\", \\\"r\\\") as zip_ref:\\n        zip_ref.extractall(os.getcwd())\\n    try:\\n        _, _, exit_code = execute([os.path.join(os.getcwd(), 'node-v18.18.2-win-x64', 'npm.cmd'), '--version'],\\n                                  append_to_path=os.path.join(os.getcwd(), 'node-v18.18.2-win-x64'))\\n        if not exit_code == 0:\\n            raise Exception(\\\"Failed to run npm\\\")\\n    except Exception as ex:\\n        print('Failed to install npm ' + str(ex))\\n        sys.exit(1)\\n\\n    return (os.path.join(os.getcwd(), 'node-v18.18.2-win-x64', 'npm.cmd'),\\n            os.path.join(os.getcwd(), 'node-v18.18.2-win-x64'))\\n\\n\\ndef ensure_node_exists():\\n    try:\\n        print(\\\"Checking node is installed\\\")\\n        _, _, exit_code = execute(['npm', '--version'])\\n        if not exit_code == 0:\\n            raise Exception(\\\"npm not found\\\")\\n    except:\\n        if is_windows():\\n            return install_npm_windows()\\n        else:\\n            return install_npm_linux()\\n\\n    return 'npm', None\\n\\n\\ndef ensure_yo_exists(npm_executable, npm_path):\\n    try:\\n        print(\\\"Checking Yeoman is installed\\\")\\n        _, _, exit_code = execute(['yo', '--version'])\\n        if not exit_code == 0:\\n            raise Exception(\\\"yo not found\\\")\\n    except:\\n        print('Installing Yeoman')\\n\\n        _, _, retcode = execute([npm_executable, 'install', '-g', 'yo'], append_to_path=npm_path)\\n\\n        if not retcode == 0:\\n            print(\\\"Failed to set install Yeoman. Check the verbose logs for details.\\\")\\n            sys.exit(1)\\n\\n        npm_bin, _, retcode = execute([npm_executable, 'config', 'get', 'prefix'], append_to_path=npm_path)\\n\\n        if not retcode == 0:\\n            print(\\\"Failed to set get the npm prefix directory. Check the verbose logs for details.\\\")\\n            sys.exit(1)\\n\\n        try:\\n            if is_windows():\\n                _, _, exit_code = execute([os.path.join(npm_bin.strip(), 'yo.cmd'), '--version'],\\n                                          append_to_path=npm_path)\\n            else:\\n                _, _, exit_code = execute([os.path.join(npm_bin.strip(), 'bin', 'yo'), '--version'],\\n                                          append_to_path=npm_path)\\n\\n            if not exit_code == 0:\\n                raise Exception(\\\"Failed to run yo\\\")\\n        except Exception as ex:\\n            print('Failed to install yo ' + str(ex))\\n            sys.exit(1)\\n\\n        # Windows and Linux save NPM binaries in different directories\\n        if is_windows():\\n            return os.path.join(npm_bin.strip(), 'yo.cmd')\\n\\n        return os.path.join(npm_bin.strip(), 'bin', 'yo')\\n\\n    return 'yo'\\n\\n\\ngit_executable = ensure_git_exists()\\nnpm_executable, npm_path = ensure_node_exists()\\nyo_executable = ensure_yo_exists(npm_executable, npm_path)\\nparser, _ = init_argparse()\\n\\nif not parser.git_password.strip() and not (\\n        parser.github_app_id.strip() and parser.github_app_private_key.strip() and parser.github_app_installation_id.strip()):\\n    print(\\\"You must supply the GitHub token, or the GitHub App ID and private key and installation ID\\\")\\n    sys.exit(1)\\n\\nif not parser.git_organization.strip():\\n    print(\\\"You must define the organization\\\")\\n    sys.exit(1)\\n\\nif not parser.repo.strip():\\n    print(\\\"You must define the repo name\\\")\\n    sys.exit(1)\\n\\nif not parser.generator.strip():\\n    print(\\\"You must define the Yeoman generator\\\")\\n    sys.exit(1)\\n\\n# Create a dir for the git clone\\nif os.path.exists('downstream'):\\n    shutil.rmtree('downstream')\\n\\nos.mkdir('downstream')\\n\\n# Create a dir for yeoman to use\\nif os.path.exists('downstream-yeoman'):\\n    shutil.rmtree('downstream-yeoman')\\n\\nos.mkdir('downstream-yeoman')\\n# Yeoman will use a less privileged user to write to this directory, so grant full access\\nif not is_windows():\\n    os.chmod('downstream-yeoman', 0o777)\\n\\ndownstream_dir = os.path.join(os.getcwd(), 'downstream')\\ndownstream_yeoman_dir = os.path.join(os.getcwd(), 'downstream-yeoman')\\n\\n# The access token is generated from a github app or supplied directly as an access token\\ntoken = generate_github_token(parser.github_app_id, parser.github_app_private_key,\\n                              parser.github_app_installation_id) if len(\\n    parser.git_password.strip()) == 0 else parser.git_password.strip()\\n\\nif not verify_new_repo(token, parser.git_organization, parser.repo):\\n    print('Repo at https://github.com/' + parser.git_organization + '/' + parser.repo + ' could not be accessed')\\n    sys.exit(1)\\n\\n# We need to disable the credentials helper prompt, which will pop open a GUI prompt that we can never close\\nif is_windows():\\n    _, _, retcode = execute([git_executable, 'config', '--system', 'credential.helper', 'manager'])\\n\\n    if not retcode == 0:\\n        print(\\\"Failed to set the credential.helper setting. Check the verbose logs for details.\\\")\\n        sys.exit(1)\\n\\n    _, _, retcode = execute([git_executable, 'config', '--system', 'credential.modalprompt', 'false'])\\n\\n    if not retcode == 0:\\n        print(\\\"Failed to srt the credential.modalprompt setting. Check the verbose logs for details.\\\")\\n        sys.exit(1)\\n\\n    # We need to disable the credentials helper prompt, which will pop open a GUI prompt that we can never close\\n    _, _, retcode = execute(\\n        [git_executable, 'config', '--system', 'credential.microsoft.visualstudio.com.interactive', 'never'])\\n\\n    if not retcode == 0:\\n        print(\\n            \\\"Failed to set the credential.microsoft.visualstudio.com.interactive setting. Check the verbose logs for details.\\\")\\n        sys.exit(1)\\n\\n_, _, retcode = execute([git_executable, 'config', '--global', 'user.email', 'octopus@octopus.com'])\\n\\nif not retcode == 0:\\n    print(\\\"Failed to set the user.email setting. Check the verbose logs for details.\\\")\\n    sys.exit(1)\\n\\n_, _, retcode = execute([git_executable, 'config', '--global', 'core.autocrlf', 'input'])\\n\\nif not retcode == 0:\\n    print(\\\"Failed to set the core.autocrlf setting. Check the verbose logs for details.\\\")\\n    sys.exit(1)\\n\\nusername = parser.git_username if len(parser.git_username) != 0 else 'Octopus'\\n_, _, retcode = execute([git_executable, 'config', '--global', 'user.name', username])\\n\\nif not retcode == 0:\\n    print(\\\"Failed to set the git username. Check the verbose logs for details.\\\")\\n    sys.exit(1)\\n\\n_, _, retcode = execute([git_executable, 'config', '--global', 'credential.helper', 'cache'])\\n\\nif not retcode == 0:\\n    print(\\\"Failed to set the git credential helper. Check the verbose logs for details.\\\")\\n    sys.exit(1)\\n\\nprint('Cloning repo')\\n\\n_, _, retcode = execute(\\n    [git_executable, 'clone',\\n     'https://' + username + ':' + token + '@github.com/' + parser.git_organization + '/' + parser.repo + '.git',\\n     'downstream'])\\n\\nif not retcode == 0:\\n    print(\\\"Failed to clone the git repo. Check the verbose logs for details.\\\")\\n    sys.exit(1)\\n\\nprint('Configuring Yeoman Generator')\\n\\n_, _, retcode = execute([npm_executable, 'install'], cwd=os.path.join(os.getcwd(), 'YeomanGenerator'), append_to_path=npm_path)\\n\\nif not retcode == 0:\\n    print(\\\"Failed to install the generator dependencies. Check the verbose logs for details.\\\")\\n    sys.exit(1)\\n\\n_, _, retcode = execute([npm_executable, 'link'], cwd=os.path.join(os.getcwd(), 'YeomanGenerator'), append_to_path=npm_path)\\n\\nif not retcode == 0:\\n    print(\\\"Failed to link the npm module. Check the verbose logs for details.\\\")\\n    sys.exit(1)\\n\\nprint('Running Yeoman Generator')\\n\\n# Treat the string of yo arguments as a raw input and parse it again. The resulting list of unknown arguments\\n# is then passed to yo. We have to convert the incoming values from utf to ascii when parsing a second time.\\nyo_args = split(anyascii(parser.generator_arguments))\\n\\ngenerator_name = parser.generator + ':' + parser.sub_generator if len(parser.sub_generator) != 0 else parser.generator\\n\\nyo_arguments = [yo_executable, generator_name, '--force', '--skip-install']\\n\\n# Yeoman has issues running as root, which it will often do in a container.\\n# So we run Yeoman in its own directory, and then copy the changes to the git directory.\\n_, _, retcode = execute(yo_arguments + yo_args, cwd=downstream_yeoman_dir, append_to_path=npm_path)\\n\\nif not retcode == 0:\\n    print(\\\"Failed to run Yeoman. Check the verbose logs for details.\\\")\\n    sys.exit(1)\\n\\nshutil.copytree(downstream_yeoman_dir, downstream_dir, dirs_exist_ok=True)\\n\\nprint('Adding changes to git')\\n\\n_, _, retcode = execute([git_executable, 'add', '.'], cwd=downstream_dir)\\n\\nif not retcode == 0:\\n    print(\\\"Failed to add the git changes. Check the verbose logs for details.\\\")\\n    sys.exit(1)\\n\\n# Check for pending changes\\n_, _, retcode = execute([git_executable, 'diff-index', '--quiet', 'HEAD'], cwd=downstream_dir)\\n\\nif not retcode == 0:\\n    print('Committing changes to git')\\n    _, _, retcode = execute([git_executable, 'commit', '-m',\\n                             'Added files from Yeoman generator ' + parser.generator + ':' + parser.sub_generator],\\n                            cwd=downstream_dir)\\n\\n    if not retcode == 0:\\n        print(\\\"Failed to set commit the git changes. Check the verbose logs for details.\\\")\\n        sys.exit(1)\\n\\n    print('Pushing changes to git')\\n\\n    _, _, retcode = execute([git_executable, 'push', 'origin', 'main'], cwd=downstream_dir)\\n\\n    if not retcode == 0:\\n        print(\\\"Failed to push the git changes. Check the verbose logs for details.\\\")\\n        sys.exit(1)\\n\"\n        \"PopulateGithubRepo.Yeoman.Generator.Package\"      = jsonencode({\n          \"PackageId\" = \"OctopusSolutionsEngineering/ReferenceArchitectureAppGenerators\"\n          \"FeedId\"    = local.github_feed_id\n        })\n        \"Octopus.Action.RunOnServer\"                  = \"true\"\n        \"PopulateGithubRepo.Git.Url.Organization\"     = \"#{Git.Url.Organization}\"\n        \"PopulateGithubRepo.Git.Url.Repo\"             = \"#{Octopus.Action[Create Repo].Output.NewRepo}\"\n        \"PopulateGithubRepo.Git.Credentials.Password\" = \"#{Git.Credentials.Password}\"\n      }\n\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopussamples/node-workertools\"\n      }\n\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n\n      package {\n        name                      = \"YeomanGenerator\"\n        package_id                = \"OctopusSolutionsEngineering/ReferenceArchitectureAppGenerators\"\n        acquisition_location      = \"Server\"\n        extract_during_deployment = false\n        feed_id                   = local.github_feed_id\n        properties                = {\n          Extract       = \"True\", PackageParameterName = \"PopulateGithubRepo.Yeoman.Generator.Package\", Purpose = \"\",\n          SelectionMode = \"deferred\"\n        }\n      }\n      features = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n#endregion\n\n#region Frontend\nvariable \"frontend_project_name\" {\n  type    = string\n  default = \"\"\n}\n\ndata \"octopusdeploy_projects\" \"octopub_frontend\" {\n  partial_name = var.frontend_project_name == \"\" ? local.frontend_project_name : var.frontend_project_name\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_variable\" \"frontend_deployment_feed\" {\n  count        = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_frontend[0].id\n  value        = local.docker_hub_feed_id\n  name         = \"Kubernetes.Deployment.Feed\"\n  type         = \"String\"\n  description  = \"The feed ID hosting the image\"\n  is_sensitive = false\n}\n\nresource \"octopusdeploy_variable\" \"frontend_deployment_image\" {\n  count        = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_frontend[0].id\n  value        = \"octopussamples/octopub-frontend\"\n  name         = \"Kubernetes.Deployment.Image\"\n  type         = \"String\"\n  description  = \"The image to deploy\"\n  is_sensitive = false\n}\n\nresource \"octopusdeploy_variable\" \"frontend_deployment_port\" {\n  count        = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_frontend[0].id\n  value        = \"8080\"\n  name         = \"Kubernetes.Deployment.Port\"\n  type         = \"String\"\n  description  = \"The port exposed by the web app\"\n  is_sensitive = false\n}\n\nresource \"octopusdeploy_variable\" \"frontend_microservice_name\" {\n  count        = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_frontend[0].id\n  value        = \"frontend\"\n  name         = \"Microservice.Name\"\n  type         = \"String\"\n  description  = \"The microservice name, which is used as the basis for K8s resources and networking paths\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"frontend_deployment_name\" {\n  count        = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_frontend[0].id\n  value        = \"#{Microservice.Name}\"\n  name         = \"Kubernetes.Deployment.Name\"\n  type         = \"String\"\n  description  = \"The name of the Kubernetes deployment resource\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"frontend_service_name\" {\n  count        = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_frontend[0].id\n  value        = \"#{Microservice.Name}\"\n  name         = \"Kubernetes.Service.Name\"\n  type         = \"String\"\n  description  = \"The name of the Kubernetes service resource\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"frontend_ingress_path\" {\n  count        = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_frontend[0].id\n  value        = \"/#{Kubernetes.Namespace}(/.*)?\"\n  name         = \"Kubernetes.Ingress.Path\"\n  type         = \"String\"\n  description  = \"The name of the Kubernetes ingress resource\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"frontend_app_path\" {\n  count        = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_frontend[0].id\n  value        = \"/#{Kubernetes.Namespace}/index.html\"\n  name         = \"Kubernetes.App.HealthCheck\"\n  type         = \"String\"\n  description  = \"The path to perform a health check on.\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"frontend_ingress_name\" {\n  count        = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_frontend[0].id\n  value        = \"#{Microservice.Name}\"\n  name         = \"Kubernetes.Ingress.Name\"\n  type         = \"String\"\n  description  = \"The name of the Kubernetes ingress resource\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"frontend_namespace_default\" {\n  count        = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_frontend[0].id\n  value        = \"#{Octopus.Action.Kubernetes.Namespace}\"\n  name         = \"Kubernetes.Namespace\"\n  type         = \"String\"\n  description  = \"The namespace to perform the deployments in.\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"frontend_namespace_featurebranch\" {\n  count        = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_frontend[0].id\n  value        = \"\"\n  name         = \"Kubernetes.Namespace\"\n  type         = \"String\"\n  description  = \"The custom namespace to use when deploying a feature branch\"\n  is_sensitive = false\n\n  scope {\n    actions      = []\n    channels     = []\n    environments = [local.featurebranch_environment_id]\n    machines     = []\n    roles        = null\n    tenant_tags  = null\n  }\n\n  prompt {\n    description = \"Feature branch namespace\"\n    label       = \"Namespace\"\n    is_required = true\n    display_settings {\n      control_type = \"SingleLineText\"\n    }\n  }\n}\n\nresource \"octopusdeploy_channel\" \"frontend_featurebranch\" {\n  count        = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  name         = \"Feature Branch\"\n  project_id   = octopusdeploy_project.project_octopub_frontend[0].id\n  description  = \"Deploy feature branch builds\"\n  is_default   = false\n  lifecycle_id = local.featurebranch_lifecycle_id\n}\n\nresource \"octopusdeploy_channel\" \"frontend_mainline\" {\n  count        = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  name         = \"Mainline\"\n  project_id   = octopusdeploy_project.project_octopub_frontend[0].id\n  description  = \"Deploy mainline builds\"\n  is_default   = true\n  lifecycle_id = local.devops_lifecycle_id\n  rule {\n    tag = \"^$\"\n    action_package {\n      deployment_action = \"Deploy Container\"\n      package_reference = \"web\"\n    }\n  }\n\n  depends_on  = [octopusdeploy_deployment_process.deployment_process_octopub_frontend]\n}\n\nresource \"octopusdeploy_project\" \"project_octopub_frontend\" {\n  count                                = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  name                                 = var.frontend_project_name == \"\" ? local.frontend_project_name : var.frontend_project_name\n  auto_create_release                  = false\n  default_guided_failure_mode          = \"Off\"\n  default_to_skip_if_already_installed = false\n  discrete_channel_release             = false\n  is_disabled                          = false\n  is_version_controlled                = false\n  lifecycle_id                         = local.devops_lifecycle_id\n  project_group_id                     = local.eks_project_group_id\n  included_library_variable_sets       = [local.this_instance_library_variable_set, local.github_library_variable_set]\n  tenanted_deployment_participation    = \"Untenanted\"\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n\n  versioning_strategy {\n    template = \"#{Octopus.Version.LastMajor}.#{Octopus.Version.LastMinor}.#{Octopus.Version.NextPatch}\"\n  }\n\n  lifecycle {\n    ignore_changes = []\n  }\n  description = <<EOT\nDeploys the Octopub Frontend\n\n**Source**: [GitHub](https://github.com/OctopusSolutionsEngineering/Octopub)\n\n**Build**: [GitHub Actions](https://github.com/OctopusSolutionsEngineering/Octopub/actions)\n\n**Issues**: [GitHub Issues](https://github.com/OctopusSolutionsEngineering/Octopub/issues)\nEOT\n}\n\nresource \"octopusdeploy_deployment_process\" \"deployment_process_octopub_frontend\" {\n  count      = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  project_id = octopusdeploy_project.project_octopub_frontend[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Generate Variables\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Generate Variables\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = local.variable_script\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Deploy Container\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesDeployContainers\"\n      name                               = \"Deploy Container\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"Octopus.Action.KubernetesContainers.Namespace\"              = \"#{Kubernetes.Namespace}\"\n        \"Octopus.Action.KubernetesContainers.Replicas\"               = \"1\"\n        \"Octopus.Action.KubernetesContainers.DeploymentResourceType\" = \"Deployment\"\n        \"Octopus.Action.KubernetesContainers.IngressAnnotations\"     = jsonencode([\n          {\n            \"optionError\"  = null\n            \"option2\"      = \"\"\n            \"option2Error\" = null\n            \"key\"          = \"nginx.ingress.kubernetes.io/rewrite-target\"\n            \"keyError\"     = null\n            \"value\"        = \"$1\"\n            \"valueError\"   = null\n            \"option\"       = \"\"\n          },\n          {\n            \"keyError\"     = null\n            \"value\"        = \"true\"\n            \"valueError\"   = null\n            \"option\"       = \"\"\n            \"optionError\"  = null\n            \"option2\"      = \"\"\n            \"option2Error\" = null\n            \"key\"          = \"nginx.ingress.kubernetes.io/use-regex\"\n          },\n        ])\n        \"Octopus.Action.KubernetesContainers.DeploymentStyle\" = \"RollingUpdate\"\n        \"Octopus.Action.KubernetesContainers.IngressName\"     = \"#{Kubernetes.Ingress.Name}\"\n        \"Octopus.Action.KubernetesContainers.DeploymentName\"  = \"#{Kubernetes.Deployment.Name}\"\n        \"Octopus.Action.KubernetesContainers.IngressRules\"    = jsonencode([\n          {\n            \"host\" = \"\"\n            \"http\" = {\n              \"paths\" = [\n                {\n                  \"key\"     = \"#{Kubernetes.Ingress.Path}\"\n                  \"value\"   = \"web\"\n                  \"option\"  = \"\"\n                  \"option2\" = \"ImplementationSpecific\"\n                },\n              ]\n            }\n          },\n        ])\n        \"OctopusUseBundledTooling\"                       = \"False\"\n        \"Octopus.Action.KubernetesContainers.Containers\" = jsonencode([\n          {\n            \"Args\"                         = []\n            \"FieldRefEnvironmentVariables\" = []\n            \"SecretEnvFromSource\"          = []\n            \"Command\"                      = []\n            \"Ports\"                        = [\n              {\n                \"option2Error\" = null\n                \"optionError\"  = null\n                \"value\"        = \"#{Kubernetes.Deployment.Port}\"\n                \"valueError\"   = null\n                \"key\"          = \"web\"\n                \"keyError\"     = null\n                \"option\"       = \"TCP\"\n                \"option2\"      = \"\"\n              },\n            ]\n            \"Resources\" = {\n              \"limits\" = {\n                \"storage\"          = \"\"\n                \"amdGpu\"           = \"\"\n                \"cpu\"              = \"\"\n                \"ephemeralStorage\" = \"\"\n                \"memory\"           = \"\"\n                \"nvidiaGpu\"        = \"\"\n              }\n              \"requests\" = {\n                \"amdGpu\"           = \"\"\n                \"cpu\"              = \"\"\n                \"ephemeralStorage\" = \"\"\n                \"memory\"           = \"\"\n                \"nvidiaGpu\"        = \"\"\n                \"storage\"          = \"\"\n              }\n            }\n            \"SecretEnvironmentVariables\" = []\n            \"SecurityContext\"            = {\n              \"runAsNonRoot\"   = \"True\"\n              \"runAsUser\"      = \"\"\n              \"seLinuxOptions\" = {\n                \"level\" = \"\"\n                \"role\"  = \"\"\n                \"type\"  = \"\"\n                \"user\"  = \"\"\n              }\n              \"allowPrivilegeEscalation\" = \"\"\n              \"capabilities\"             = {\n                \"add\"  = []\n                \"drop\" = [\n                  \"ALL\",\n                ]\n              }\n              \"privileged\"             = \"\"\n              \"readOnlyRootFilesystem\" = \"\"\n              \"runAsGroup\"             = \"\"\n            }\n            \"TerminationMessagePath\" = \"\"\n            \"EnvironmentVariables\"   = [\n              {\n                \"key\"          = \"PORT\"\n                \"keyError\"     = null\n                \"value\"        = \"#{Kubernetes.Deployment.Port}\"\n                \"valueError\"   = null\n                \"option\"       = \"\"\n                \"optionError\"  = null\n                \"option2\"      = \"\"\n                \"option2Error\" = null\n              },\n              {\n                \"key\"          = \"UDL_SETVALUE_1\"\n                \"keyError\"     = null\n                \"value\"        = \"[/usr/share/nginx/html/config.json][productEndpoint]/#{Kubernetes.Namespace}/api/products\"\n                \"valueError\"   = null\n                \"option\"       = \"\"\n                \"optionError\"  = null\n                \"option2\"      = \"\"\n                \"option2Error\" = null\n              },\n              {\n                \"key\"          = \"UDL_SETVALUE_2\"\n                \"keyError\"     = null\n                \"value\"        = \"[/usr/share/nginx/html/config.json][productHealthEndpoint]/#{Kubernetes.Namespace}/health/products\"\n                \"valueError\"   = null\n                \"option\"       = \"\"\n                \"optionError\"  = null\n                \"option2\"      = \"\"\n                \"option2Error\" = null\n              },\n              {\n                \"key\"          = \"UDL_SETVALUE_3\"\n                \"keyError\"     = null\n                \"value\"        = \"[/usr/share/nginx/html/config.json][auditEndpoint]/#{Kubernetes.Namespace}/api/audits\"\n                \"valueError\"   = null\n                \"option\"       = \"\"\n                \"optionError\"  = null\n                \"option2\"      = \"\"\n                \"option2Error\" = null\n              },\n              {\n                \"key\"          = \"UDL_SETVALUE_4\"\n                \"keyError\"     = null\n                \"value\"        = \"[/usr/share/nginx/html/config.json][auditHealthEndpoint]/#{Kubernetes.Namespace}/health/audits\"\n                \"valueError\"   = null\n                \"option\"       = \"\"\n                \"optionError\"  = null\n                \"option2\"      = \"\"\n                \"option2Error\" = null\n              },\n            ]\n            \"LivenessProbe\" = {\n              \"successThreshold\" = \"\"\n              \"tcpSocket\"        = {\n                \"port\" = \"\"\n                \"host\" = \"\"\n              }\n              \"exec\" = {\n                \"command\" = []\n              }\n              \"failureThreshold\" = \"\"\n              \"periodSeconds\"    = \"\"\n              \"type\"             = \"\"\n              \"httpGet\"          = {\n                \"host\"        = \"\"\n                \"httpHeaders\" = []\n                \"path\"        = \"\"\n                \"port\"        = \"\"\n                \"scheme\"      = \"\"\n              }\n              \"initialDelaySeconds\" = \"\"\n              \"timeoutSeconds\"      = \"\"\n            }\n            \"ReadinessProbe\" = {\n              \"exec\" = {\n                \"command\" = []\n              }\n              \"failureThreshold\" = \"\"\n              \"timeoutSeconds\"   = \"\"\n              \"successThreshold\" = \"\"\n              \"tcpSocket\"        = {\n                \"host\" = \"\"\n                \"port\" = \"\"\n              }\n              \"type\"    = \"\"\n              \"httpGet\" = {\n                \"host\"        = \"\"\n                \"httpHeaders\" = []\n                \"path\"        = \"\"\n                \"port\"        = \"\"\n                \"scheme\"      = \"\"\n              }\n              \"initialDelaySeconds\" = \"\"\n              \"periodSeconds\"       = \"\"\n            }\n            \"TerminationMessagePolicy\"      = \"\"\n            \"VolumeMounts\"                  = []\n            \"ConfigMapEnvFromSource\"        = []\n            \"ConfigMapEnvironmentVariables\" = []\n            \"CreateFeedSecrets\"             = \"False\"\n            \"Lifecycle\"                     = {\n              \"PostStart\" = null\n              \"PreStop\"   = null\n            }\n            \"Name\"         = \"web\"\n            \"StartupProbe\" = {\n              \"successThreshold\" = \"\"\n              \"tcpSocket\"        = {\n                \"host\" = \"\"\n                \"port\" = \"\"\n              }\n              \"failureThreshold\" = \"\"\n              \"httpGet\"          = {\n                \"host\"        = \"\"\n                \"httpHeaders\" = []\n                \"path\"        = \"\"\n                \"port\"        = \"\"\n                \"scheme\"      = \"\"\n              }\n              \"initialDelaySeconds\" = \"\"\n              \"type\"                = \"\"\n              \"exec\"                = {\n                \"command\" = []\n              }\n              \"periodSeconds\"  = \"\"\n              \"timeoutSeconds\" = \"\"\n            }\n          },\n        ])\n        \"Octopus.Action.KubernetesContainers.ServiceName\"         = \"#{Kubernetes.Service.Name}\"\n        \"Octopus.Action.KubernetesContainers.PodManagementPolicy\" = \"OrderedReady\"\n        \"Octopus.Action.Kubernetes.DeploymentTimeout\"             = \"180\"\n        \"Octopus.Action.RunOnServer\"                              = \"true\"\n        \"Octopus.Action.KubernetesContainers.IngressClassName\"    = \"nginx\"\n        \"Octopus.Action.KubernetesContainers.ServicePorts\"        = jsonencode([\n          {\n            \"port\"       = \"80\"\n            \"protocol\"   = \"TCP\"\n            \"targetPort\" = \"web\"\n            \"name\"       = \"web\"\n            \"nodePort\"   = \"\"\n          },\n        ])\n        \"Octopus.Action.Kubernetes.ResourceStatusCheck\"       = \"True\"\n        \"Octopus.Action.KubernetesContainers.ServiceNameType\" = \"External\"\n        \"Octopus.Action.KubernetesContainers.ServiceType\"     = \"ClusterIP\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n        local.featurebranch_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n\n      package {\n        name                      = \"web\"\n        package_id                = \"#{Kubernetes.Deployment.Image}\"\n        acquisition_location      = \"NotAcquired\"\n        extract_during_deployment = false\n        feed_id                   = \"#{Kubernetes.Deployment.Feed}\"\n        properties                = { Extract = \"False\", PackageParameterName = \"\", SelectionMode = \"immediate\" }\n      }\n      features = [\n        \"\", \"Octopus.Features.KubernetesService\", \"Octopus.Features.KubernetesIngress\",\n        \"Octopus.Features.KubernetesConfigMap\", \"Octopus.Features.KubernetesSecret\"\n      ]\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Smoke Test\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Smoke Test\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{Kubernetes.Namespace}\"\n        \"Octopus.Action.RunOnServer\"                    = \"true\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"                  = \"Bash\"\n        \"Octopus.Action.Script.ScriptBody\"              = local.smoke_test\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n        local.featurebranch_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Security Scan\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Security Scan\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"Bash\"\n        \"Octopus.Action.Script.ScriptBody\"   = local.security_scan_script\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_frontend_scale_to_zero\" {\n  count             = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  name              = \"🌃 Scale Pods to Zero\"\n  project_id        = octopusdeploy_project.project_octopub_frontend[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**WARNING**: This is a destructive operation. The service will no longer be available when scaled down.\n\n**Action**: Scales the deployment down to zero pods.\n\n**Affects**: The frontend service is effectively shut down.\n\nThis runbook is designed to be be run in non-production environments after hours to remove the Fargate nodes hosting\nthe service. This removes the cost of hosting the service out of hours.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_frontend_scale_pods_to_zero\" {\n  count      = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_frontend_scale_to_zero[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Scale Pods to Zero\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Scale Pods to Zero\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"OctopusUseBundledTooling\"           = \"False\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"kubectl scale --replicas=0 deployment/#{Kubernetes.Deployment.Name}\"\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n      }\n\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_frontend_scale_to_one\" {\n  count             = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  name              = \"🌇 Scale Pods to One\"\n  project_id        = octopusdeploy_project.project_octopub_frontend[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Scales the deployment to one pod.\n\n**Affects**: Frontend service - this will create new pods if the deployment has been scaled to zero.\n\nThis runbook is designed to be be run in non-production environments during office hours to recreate the pods after they\nwere shutdown after hours.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_frontend_scale_pods_to_one\" {\n  count      = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_frontend_scale_to_one[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Scale Pods to One\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Scale Pods to One\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"OctopusUseBundledTooling\"           = \"False\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"kubectl scale --replicas=1 deployment/#{Kubernetes.Deployment.Name}\"\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n      }\n\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_frontend_get_pod_logs\" {\n  count             = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  name              = \"🛠️ Get Pod Logs\"\n  project_id        = octopusdeploy_project.project_octopub_frontend[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Returns the pod logs.\n\n**Affects**: Nothing - this runbook makes no changes.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_frontend_get_pod_logs\" {\n  count      = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_frontend_get_pod_logs[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Get Pod Logs\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Get Pod Logs\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"K8SInspectCreateArtifact\"                      = \"False\"\n        \"Octopus.Action.Script.ScriptBody\"              = \"<#\\n    This script provides a general purpose method for querying Kubernetes resources. It supports common operations\\n    like get, describe, logs and output formats like yaml and json. Output can be captured as artifacts.\\n#>\\n\\n<#\\n.Description\\nExecute an application, capturing the output. Based on https://stackoverflow.com/a/33652732/157605\\n#>\\nFunction Execute-Command ($commandPath, $commandArguments)\\n{\\n  Write-Host \\\"Executing: $commandPath $($commandArguments -join \\\" \\\")\\\"\\n  \\n  Try {\\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\\n    $pinfo.FileName = $commandPath\\n    $pinfo.RedirectStandardError = $true\\n    $pinfo.RedirectStandardOutput = $true\\n    $pinfo.UseShellExecute = $false\\n    $pinfo.Arguments = $commandArguments\\n    $p = New-Object System.Diagnostics.Process\\n    $p.StartInfo = $pinfo\\n    $p.Start() | Out-Null\\n    [pscustomobject]@{\\n        stdout = $p.StandardOutput.ReadToEnd()\\n        stderr = $p.StandardError.ReadToEnd()\\n        ExitCode = $p.ExitCode\\n    }\\n    $p.WaitForExit()\\n  }\\n  Catch {\\n     exit\\n  }\\n}\\n\\n<#\\n.Description\\nFind any resource names that match a wildcard input if one was specified\\n#>\\nfunction Get-Resources() \\n{\\n    $names = $OctopusParameters[\\\"K8SInspectNames\\\"] -Split \\\"`n\\\" | % {$_.Trim()}\\n    \\n    if ($OctopusParameters[\\\"K8SInspectNames\\\"] -match '\\\\*' )\\n    {\\n        return Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", $OctopusParameters[\\\"K8SInspectResource\\\"])) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Extract the name\\n            % {$_.metadata.name} |\\n            # Find any matching resources\\n            ? {$k8sName = $_; ($names | ? {$k8sName -like $_}).Count -ne 0}\\n    }\\n    else\\n    {\\n        return $names\\n    }\\n}\\n\\n<#\\n.Description\\nGet the kubectl arguments for a given action\\n#>\\nfunction Get-KubectlVerb() \\n{\\n    switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {return ,@(\\\"-o\\\", \\\"json\\\", \\\"get\\\")}\\n        \\\"get yaml\\\" {return ,@(\\\"-o\\\", \\\"yaml\\\", \\\"get\\\")}\\n        \\\"describe\\\" {return ,@(\\\"describe\\\")}\\n        \\\"logs\\\" {return ,@(\\\"logs\\\")}\\n        \\\"logs tail\\\" {return ,@(\\\"logs\\\", \\\"--tail\\\", \\\"100\\\")}\\n        \\\"previous logs\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\")}\\n        \\\"previous logs tail\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\", \\\"--tail\\\", \\\"100\\\")}\\n        default {return ,@(\\\"get\\\")}\\n    }\\n}\\n\\n<#\\n.Description\\nGet an appropiate file extension based on the selected action\\n#>\\nfunction Get-ArtifactExtension() \\n{\\n   switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {\\\"json\\\"}\\n        \\\"get yaml\\\" {\\\"yaml\\\"}\\n        default {\\\"txt\\\"}\\n    }\\n}\\n\\nif ($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"] -like \\\"*logs*\\\") \\n{\\n    if ( -not @($OctopusParameters[\\\"K8SInspectResource\\\"]) -like \\\"pod*\\\")\\n    {\\n        Write-Error \\\"Logs can only be returned for pods, not $($OctopusParameters[\\\"K8SInspectResource\\\"])\\\"\\n    }\\n    else\\n    {\\n        Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", \\\"pods\\\") + (Get-Resources)) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Get the pod logs for each container\\n            % {\\n                $podDetails = $_\\n                @{\\n                    logs=$podDetails.spec.containers | % {$logs=\\\"\\\"} {$logs += (Select-Object -InputObject (Execute-Command kubectl ((Get-KubectlVerb) + @($podDetails.metadata.name, \\\"-c\\\", $_.name))) -ExpandProperty stdout)} {$logs}; \\n                    name=$podDetails.metadata.name\\n                }                \\n            } |\\n            # Write the output\\n            % {Write-Host $_.logs; $_} |\\n            # Optionally capture the artifact\\n            % {\\n                if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n                {\\n                    Set-Content -Path \\\"$($_.name).$(Get-ArtifactExtension)\\\" -Value $_.logs\\n                    New-OctopusArtifact \\\"$($_.name).$(Get-ArtifactExtension)\\\"\\n                }\\n            }\\n    }      \\n}\\nelse\\n{\\n    Execute-Command kubectl ((Get-KubectlVerb) + @($OctopusParameters[\\\"K8SInspectResource\\\"]) + (Get-Resources)) |\\n        % {Select-Object -InputObject $_ -ExpandProperty stdout} |\\n        % {Write-Host $_; $_} |\\n        % {\\n            if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n            {\\n                Set-Content -Path \\\"output.$(Get-ArtifactExtension)\\\" -Value $_\\n                New-OctopusArtifact \\\"output.$(Get-ArtifactExtension)\\\"\\n            }\\n        }\\n}\\n\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"K8SInspectResource\"                            = \"pod\"\n        \"Octopus.Action.Script.Syntax\"                  = \"PowerShell\"\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{if K8SInspectNamespace}#{K8SInspectNamespace}#{/if}#{unless K8SInspectNamespace}#{Octopus.Action.Kubernetes.Namespace}#{/unless}\"\n        \"K8SInspectNames\"                               = \"#{Kubernetes.Deployment.Name}*\"\n        \"K8SInspectKubectlVerb\"                         = \"logs\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_frontend_get_pods\" {\n  count             = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  name              = \"🛠️ Get Pods\"\n  project_id        = octopusdeploy_project.project_octopub_frontend[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Returns the pods.\n\n**Affects**: Nothing - this runbook makes no changes.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_frontend_get_pods\" {\n  count      = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_frontend_get_pods[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Get Pods\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Get Pods\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = \"\"\n      worker_pool_variable               = \"OctopusInstance.WorkerPool.Id\"\n      properties                         = {\n        \"K8SInspectCreateArtifact\"                      = \"False\"\n        \"Octopus.Action.Script.ScriptBody\"              = \"<#\\n    This script provides a general purpose method for querying Kubernetes resources. It supports common operations\\n    like get, describe, logs and output formats like yaml and json. Output can be captured as artifacts.\\n#>\\n\\n<#\\n.Description\\nExecute an application, capturing the output. Based on https://stackoverflow.com/a/33652732/157605\\n#>\\nFunction Execute-Command ($commandPath, $commandArguments)\\n{\\n  Write-Host \\\"Executing: $commandPath $($commandArguments -join \\\" \\\")\\\"\\n  \\n  Try {\\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\\n    $pinfo.FileName = $commandPath\\n    $pinfo.RedirectStandardError = $true\\n    $pinfo.RedirectStandardOutput = $true\\n    $pinfo.UseShellExecute = $false\\n    $pinfo.Arguments = $commandArguments\\n    $p = New-Object System.Diagnostics.Process\\n    $p.StartInfo = $pinfo\\n    $p.Start() | Out-Null\\n    [pscustomobject]@{\\n        stdout = $p.StandardOutput.ReadToEnd()\\n        stderr = $p.StandardError.ReadToEnd()\\n        ExitCode = $p.ExitCode\\n    }\\n    $p.WaitForExit()\\n  }\\n  Catch {\\n     exit\\n  }\\n}\\n\\n<#\\n.Description\\nFind any resource names that match a wildcard input if one was specified\\n#>\\nfunction Get-Resources() \\n{\\n    $names = $OctopusParameters[\\\"K8SInspectNames\\\"] -Split \\\"`n\\\" | % {$_.Trim()}\\n    \\n    if ($OctopusParameters[\\\"K8SInspectNames\\\"] -match '\\\\*' )\\n    {\\n        return Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", $OctopusParameters[\\\"K8SInspectResource\\\"])) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Extract the name\\n            % {$_.metadata.name} |\\n            # Find any matching resources\\n            ? {$k8sName = $_; ($names | ? {$k8sName -like $_}).Count -ne 0}\\n    }\\n    else\\n    {\\n        return $names\\n    }\\n}\\n\\n<#\\n.Description\\nGet the kubectl arguments for a given action\\n#>\\nfunction Get-KubectlVerb() \\n{\\n    switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {return ,@(\\\"-o\\\", \\\"json\\\", \\\"get\\\")}\\n        \\\"get yaml\\\" {return ,@(\\\"-o\\\", \\\"yaml\\\", \\\"get\\\")}\\n        \\\"describe\\\" {return ,@(\\\"describe\\\")}\\n        \\\"logs\\\" {return ,@(\\\"logs\\\")}\\n        \\\"logs tail\\\" {return ,@(\\\"logs\\\", \\\"--tail\\\", \\\"100\\\")}\\n        \\\"previous logs\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\")}\\n        \\\"previous logs tail\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\", \\\"--tail\\\", \\\"100\\\")}\\n        default {return ,@(\\\"get\\\")}\\n    }\\n}\\n\\n<#\\n.Description\\nGet an appropiate file extension based on the selected action\\n#>\\nfunction Get-ArtifactExtension() \\n{\\n   switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {\\\"json\\\"}\\n        \\\"get yaml\\\" {\\\"yaml\\\"}\\n        default {\\\"txt\\\"}\\n    }\\n}\\n\\nif ($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"] -like \\\"*logs*\\\") \\n{\\n    if ( -not @($OctopusParameters[\\\"K8SInspectResource\\\"]) -like \\\"pod*\\\")\\n    {\\n        Write-Error \\\"Logs can only be returned for pods, not $($OctopusParameters[\\\"K8SInspectResource\\\"])\\\"\\n    }\\n    else\\n    {\\n        Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", \\\"pods\\\") + (Get-Resources)) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Get the pod logs for each container\\n            % {\\n                $podDetails = $_\\n                @{\\n                    logs=$podDetails.spec.containers | % {$logs=\\\"\\\"} {$logs += (Select-Object -InputObject (Execute-Command kubectl ((Get-KubectlVerb) + @($podDetails.metadata.name, \\\"-c\\\", $_.name))) -ExpandProperty stdout)} {$logs}; \\n                    name=$podDetails.metadata.name\\n                }                \\n            } |\\n            # Write the output\\n            % {Write-Host $_.logs; $_} |\\n            # Optionally capture the artifact\\n            % {\\n                if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n                {\\n                    Set-Content -Path \\\"$($_.name).$(Get-ArtifactExtension)\\\" -Value $_.logs\\n                    New-OctopusArtifact \\\"$($_.name).$(Get-ArtifactExtension)\\\"\\n                }\\n            }\\n    }      \\n}\\nelse\\n{\\n    Execute-Command kubectl ((Get-KubectlVerb) + @($OctopusParameters[\\\"K8SInspectResource\\\"]) + (Get-Resources)) |\\n        % {Select-Object -InputObject $_ -ExpandProperty stdout} |\\n        % {Write-Host $_; $_} |\\n        % {\\n            if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n            {\\n                Set-Content -Path \\\"output.$(Get-ArtifactExtension)\\\" -Value $_\\n                New-OctopusArtifact \\\"output.$(Get-ArtifactExtension)\\\"\\n            }\\n        }\\n}\\n\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"K8SInspectResource\"                            = \"pod\"\n        \"Octopus.Action.Script.Syntax\"                  = \"PowerShell\"\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{if K8SInspectNamespace}#{K8SInspectNamespace}#{/if}#{unless K8SInspectNamespace}#{Octopus.Action.Kubernetes.Namespace}#{/unless}\"\n        \"K8SInspectNames\"                               = \"#{Kubernetes.Deployment.Name}*\"\n        \"K8SInspectKubectlVerb\"                         = \"get\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_frontend_describe_pods\" {\n  count             = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  name              = \"🛠️ Describe Pods\"\n  project_id        = octopusdeploy_project.project_octopub_frontend[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Returns the pods.\n\n**Affects**: Nothing - this runbook makes no changes.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_frontend_describe_pods\" {\n  count      = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_frontend_describe_pods[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Describe Pods\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Describe Pods\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"K8SInspectCreateArtifact\"                      = \"False\"\n        \"Octopus.Action.Script.ScriptBody\"              = \"<#\\n    This script provides a general purpose method for querying Kubernetes resources. It supports common operations\\n    like get, describe, logs and output formats like yaml and json. Output can be captured as artifacts.\\n#>\\n\\n<#\\n.Description\\nExecute an application, capturing the output. Based on https://stackoverflow.com/a/33652732/157605\\n#>\\nFunction Execute-Command ($commandPath, $commandArguments)\\n{\\n  Write-Host \\\"Executing: $commandPath $($commandArguments -join \\\" \\\")\\\"\\n  \\n  Try {\\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\\n    $pinfo.FileName = $commandPath\\n    $pinfo.RedirectStandardError = $true\\n    $pinfo.RedirectStandardOutput = $true\\n    $pinfo.UseShellExecute = $false\\n    $pinfo.Arguments = $commandArguments\\n    $p = New-Object System.Diagnostics.Process\\n    $p.StartInfo = $pinfo\\n    $p.Start() | Out-Null\\n    [pscustomobject]@{\\n        stdout = $p.StandardOutput.ReadToEnd()\\n        stderr = $p.StandardError.ReadToEnd()\\n        ExitCode = $p.ExitCode\\n    }\\n    $p.WaitForExit()\\n  }\\n  Catch {\\n     exit\\n  }\\n}\\n\\n<#\\n.Description\\nFind any resource names that match a wildcard input if one was specified\\n#>\\nfunction Get-Resources() \\n{\\n    $names = $OctopusParameters[\\\"K8SInspectNames\\\"] -Split \\\"`n\\\" | % {$_.Trim()}\\n    \\n    if ($OctopusParameters[\\\"K8SInspectNames\\\"] -match '\\\\*' )\\n    {\\n        return Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", $OctopusParameters[\\\"K8SInspectResource\\\"])) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Extract the name\\n            % {$_.metadata.name} |\\n            # Find any matching resources\\n            ? {$k8sName = $_; ($names | ? {$k8sName -like $_}).Count -ne 0}\\n    }\\n    else\\n    {\\n        return $names\\n    }\\n}\\n\\n<#\\n.Description\\nGet the kubectl arguments for a given action\\n#>\\nfunction Get-KubectlVerb() \\n{\\n    switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {return ,@(\\\"-o\\\", \\\"json\\\", \\\"get\\\")}\\n        \\\"get yaml\\\" {return ,@(\\\"-o\\\", \\\"yaml\\\", \\\"get\\\")}\\n        \\\"describe\\\" {return ,@(\\\"describe\\\")}\\n        \\\"logs\\\" {return ,@(\\\"logs\\\")}\\n        \\\"logs tail\\\" {return ,@(\\\"logs\\\", \\\"--tail\\\", \\\"100\\\")}\\n        \\\"previous logs\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\")}\\n        \\\"previous logs tail\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\", \\\"--tail\\\", \\\"100\\\")}\\n        default {return ,@(\\\"get\\\")}\\n    }\\n}\\n\\n<#\\n.Description\\nGet an appropiate file extension based on the selected action\\n#>\\nfunction Get-ArtifactExtension() \\n{\\n   switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {\\\"json\\\"}\\n        \\\"get yaml\\\" {\\\"yaml\\\"}\\n        default {\\\"txt\\\"}\\n    }\\n}\\n\\nif ($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"] -like \\\"*logs*\\\") \\n{\\n    if ( -not @($OctopusParameters[\\\"K8SInspectResource\\\"]) -like \\\"pod*\\\")\\n    {\\n        Write-Error \\\"Logs can only be returned for pods, not $($OctopusParameters[\\\"K8SInspectResource\\\"])\\\"\\n    }\\n    else\\n    {\\n        Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", \\\"pods\\\") + (Get-Resources)) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Get the pod logs for each container\\n            % {\\n                $podDetails = $_\\n                @{\\n                    logs=$podDetails.spec.containers | % {$logs=\\\"\\\"} {$logs += (Select-Object -InputObject (Execute-Command kubectl ((Get-KubectlVerb) + @($podDetails.metadata.name, \\\"-c\\\", $_.name))) -ExpandProperty stdout)} {$logs}; \\n                    name=$podDetails.metadata.name\\n                }                \\n            } |\\n            # Write the output\\n            % {Write-Host $_.logs; $_} |\\n            # Optionally capture the artifact\\n            % {\\n                if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n                {\\n                    Set-Content -Path \\\"$($_.name).$(Get-ArtifactExtension)\\\" -Value $_.logs\\n                    New-OctopusArtifact \\\"$($_.name).$(Get-ArtifactExtension)\\\"\\n                }\\n            }\\n    }      \\n}\\nelse\\n{\\n    Execute-Command kubectl ((Get-KubectlVerb) + @($OctopusParameters[\\\"K8SInspectResource\\\"]) + (Get-Resources)) |\\n        % {Select-Object -InputObject $_ -ExpandProperty stdout} |\\n        % {Write-Host $_; $_} |\\n        % {\\n            if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n            {\\n                Set-Content -Path \\\"output.$(Get-ArtifactExtension)\\\" -Value $_\\n                New-OctopusArtifact \\\"output.$(Get-ArtifactExtension)\\\"\\n            }\\n        }\\n}\\n\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"K8SInspectResource\"                            = \"pod\"\n        \"Octopus.Action.Script.Syntax\"                  = \"PowerShell\"\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{if K8SInspectNamespace}#{K8SInspectNamespace}#{/if}#{unless K8SInspectNamespace}#{Octopus.Action.Kubernetes.Namespace}#{/unless}\"\n        \"K8SInspectNames\"                               = \"#{Kubernetes.Deployment.Name}*\"\n        \"K8SInspectKubectlVerb\"                         = \"describe\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_frontend_get_ingress\" {\n  count             = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  name              = \"🛠️ Get Ingress\"\n  project_id        = octopusdeploy_project.project_octopub_frontend[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Returns the ingresses.\n\n**Affects**: Nothing - this runbook makes no changes.\n\n**Resolves**: Finding the public IP to access the deployed application.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_frontend_get_ingress\" {\n  count      = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_frontend_get_ingress[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Get Ingress\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Get Ingress\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"K8SInspectCreateArtifact\"                      = \"False\"\n        \"Octopus.Action.Script.ScriptBody\"              = \"<#\\n    This script provides a general purpose method for querying Kubernetes resources. It supports common operations\\n    like get, describe, logs and output formats like yaml and json. Output can be captured as artifacts.\\n#>\\n\\n<#\\n.Description\\nExecute an application, capturing the output. Based on https://stackoverflow.com/a/33652732/157605\\n#>\\nFunction Execute-Command ($commandPath, $commandArguments)\\n{\\n  Write-Host \\\"Executing: $commandPath $($commandArguments -join \\\" \\\")\\\"\\n  \\n  Try {\\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\\n    $pinfo.FileName = $commandPath\\n    $pinfo.RedirectStandardError = $true\\n    $pinfo.RedirectStandardOutput = $true\\n    $pinfo.UseShellExecute = $false\\n    $pinfo.Arguments = $commandArguments\\n    $p = New-Object System.Diagnostics.Process\\n    $p.StartInfo = $pinfo\\n    $p.Start() | Out-Null\\n    [pscustomobject]@{\\n        stdout = $p.StandardOutput.ReadToEnd()\\n        stderr = $p.StandardError.ReadToEnd()\\n        ExitCode = $p.ExitCode\\n    }\\n    $p.WaitForExit()\\n  }\\n  Catch {\\n     exit\\n  }\\n}\\n\\n<#\\n.Description\\nFind any resource names that match a wildcard input if one was specified\\n#>\\nfunction Get-Resources() \\n{\\n    $names = $OctopusParameters[\\\"K8SInspectNames\\\"] -Split \\\"`n\\\" | % {$_.Trim()}\\n    \\n    if ($OctopusParameters[\\\"K8SInspectNames\\\"] -match '\\\\*' )\\n    {\\n        return Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", $OctopusParameters[\\\"K8SInspectResource\\\"])) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Extract the name\\n            % {$_.metadata.name} |\\n            # Find any matching resources\\n            ? {$k8sName = $_; ($names | ? {$k8sName -like $_}).Count -ne 0}\\n    }\\n    else\\n    {\\n        return $names\\n    }\\n}\\n\\n<#\\n.Description\\nGet the kubectl arguments for a given action\\n#>\\nfunction Get-KubectlVerb() \\n{\\n    switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {return ,@(\\\"-o\\\", \\\"json\\\", \\\"get\\\")}\\n        \\\"get yaml\\\" {return ,@(\\\"-o\\\", \\\"yaml\\\", \\\"get\\\")}\\n        \\\"describe\\\" {return ,@(\\\"describe\\\")}\\n        \\\"logs\\\" {return ,@(\\\"logs\\\")}\\n        \\\"logs tail\\\" {return ,@(\\\"logs\\\", \\\"--tail\\\", \\\"100\\\")}\\n        \\\"previous logs\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\")}\\n        \\\"previous logs tail\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\", \\\"--tail\\\", \\\"100\\\")}\\n        default {return ,@(\\\"get\\\")}\\n    }\\n}\\n\\n<#\\n.Description\\nGet an appropiate file extension based on the selected action\\n#>\\nfunction Get-ArtifactExtension() \\n{\\n   switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {\\\"json\\\"}\\n        \\\"get yaml\\\" {\\\"yaml\\\"}\\n        default {\\\"txt\\\"}\\n    }\\n}\\n\\nif ($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"] -like \\\"*logs*\\\") \\n{\\n    if ( -not @($OctopusParameters[\\\"K8SInspectResource\\\"]) -like \\\"pod*\\\")\\n    {\\n        Write-Error \\\"Logs can only be returned for pods, not $($OctopusParameters[\\\"K8SInspectResource\\\"])\\\"\\n    }\\n    else\\n    {\\n        Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", \\\"pods\\\") + (Get-Resources)) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Get the pod logs for each container\\n            % {\\n                $podDetails = $_\\n                @{\\n                    logs=$podDetails.spec.containers | % {$logs=\\\"\\\"} {$logs += (Select-Object -InputObject (Execute-Command kubectl ((Get-KubectlVerb) + @($podDetails.metadata.name, \\\"-c\\\", $_.name))) -ExpandProperty stdout)} {$logs}; \\n                    name=$podDetails.metadata.name\\n                }                \\n            } |\\n            # Write the output\\n            % {Write-Host $_.logs; $_} |\\n            # Optionally capture the artifact\\n            % {\\n                if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n                {\\n                    Set-Content -Path \\\"$($_.name).$(Get-ArtifactExtension)\\\" -Value $_.logs\\n                    New-OctopusArtifact \\\"$($_.name).$(Get-ArtifactExtension)\\\"\\n                }\\n            }\\n    }      \\n}\\nelse\\n{\\n    Execute-Command kubectl ((Get-KubectlVerb) + @($OctopusParameters[\\\"K8SInspectResource\\\"]) + (Get-Resources)) |\\n        % {Select-Object -InputObject $_ -ExpandProperty stdout} |\\n        % {Write-Host $_; $_} |\\n        % {\\n            if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n            {\\n                Set-Content -Path \\\"output.$(Get-ArtifactExtension)\\\" -Value $_\\n                New-OctopusArtifact \\\"output.$(Get-ArtifactExtension)\\\"\\n            }\\n        }\\n}\\n\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"K8SInspectResource\"                            = \"ingress\"\n        \"Octopus.Action.Script.Syntax\"                  = \"PowerShell\"\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{if K8SInspectNamespace}#{K8SInspectNamespace}#{/if}#{unless K8SInspectNamespace}#{Octopus.Action.Kubernetes.Namespace}#{/unless}\"\n        \"K8SInspectNames\"                               = \"#{Kubernetes.Ingress.Name}*\"\n        \"K8SInspectKubectlVerb\"                         = \"get\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_frontend_get_service\" {\n  count             = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  name              = \"🛠️ Get Service\"\n  project_id        = octopusdeploy_project.project_octopub_frontend[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Returns the services.\n\n**Affects**: Nothing - this runbook makes no changes.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_frontend_get_service\" {\n  count      = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_frontend_get_service[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Get Service\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Get Service\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"K8SInspectCreateArtifact\"                      = \"False\"\n        \"Octopus.Action.Script.ScriptBody\"              = \"<#\\n    This script provides a general purpose method for querying Kubernetes resources. It supports common operations\\n    like get, describe, logs and output formats like yaml and json. Output can be captured as artifacts.\\n#>\\n\\n<#\\n.Description\\nExecute an application, capturing the output. Based on https://stackoverflow.com/a/33652732/157605\\n#>\\nFunction Execute-Command ($commandPath, $commandArguments)\\n{\\n  Write-Host \\\"Executing: $commandPath $($commandArguments -join \\\" \\\")\\\"\\n  \\n  Try {\\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\\n    $pinfo.FileName = $commandPath\\n    $pinfo.RedirectStandardError = $true\\n    $pinfo.RedirectStandardOutput = $true\\n    $pinfo.UseShellExecute = $false\\n    $pinfo.Arguments = $commandArguments\\n    $p = New-Object System.Diagnostics.Process\\n    $p.StartInfo = $pinfo\\n    $p.Start() | Out-Null\\n    [pscustomobject]@{\\n        stdout = $p.StandardOutput.ReadToEnd()\\n        stderr = $p.StandardError.ReadToEnd()\\n        ExitCode = $p.ExitCode\\n    }\\n    $p.WaitForExit()\\n  }\\n  Catch {\\n     exit\\n  }\\n}\\n\\n<#\\n.Description\\nFind any resource names that match a wildcard input if one was specified\\n#>\\nfunction Get-Resources() \\n{\\n    $names = $OctopusParameters[\\\"K8SInspectNames\\\"] -Split \\\"`n\\\" | % {$_.Trim()}\\n    \\n    if ($OctopusParameters[\\\"K8SInspectNames\\\"] -match '\\\\*' )\\n    {\\n        return Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", $OctopusParameters[\\\"K8SInspectResource\\\"])) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Extract the name\\n            % {$_.metadata.name} |\\n            # Find any matching resources\\n            ? {$k8sName = $_; ($names | ? {$k8sName -like $_}).Count -ne 0}\\n    }\\n    else\\n    {\\n        return $names\\n    }\\n}\\n\\n<#\\n.Description\\nGet the kubectl arguments for a given action\\n#>\\nfunction Get-KubectlVerb() \\n{\\n    switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {return ,@(\\\"-o\\\", \\\"json\\\", \\\"get\\\")}\\n        \\\"get yaml\\\" {return ,@(\\\"-o\\\", \\\"yaml\\\", \\\"get\\\")}\\n        \\\"describe\\\" {return ,@(\\\"describe\\\")}\\n        \\\"logs\\\" {return ,@(\\\"logs\\\")}\\n        \\\"logs tail\\\" {return ,@(\\\"logs\\\", \\\"--tail\\\", \\\"100\\\")}\\n        \\\"previous logs\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\")}\\n        \\\"previous logs tail\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\", \\\"--tail\\\", \\\"100\\\")}\\n        default {return ,@(\\\"get\\\")}\\n    }\\n}\\n\\n<#\\n.Description\\nGet an appropiate file extension based on the selected action\\n#>\\nfunction Get-ArtifactExtension() \\n{\\n   switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {\\\"json\\\"}\\n        \\\"get yaml\\\" {\\\"yaml\\\"}\\n        default {\\\"txt\\\"}\\n    }\\n}\\n\\nif ($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"] -like \\\"*logs*\\\") \\n{\\n    if ( -not @($OctopusParameters[\\\"K8SInspectResource\\\"]) -like \\\"pod*\\\")\\n    {\\n        Write-Error \\\"Logs can only be returned for pods, not $($OctopusParameters[\\\"K8SInspectResource\\\"])\\\"\\n    }\\n    else\\n    {\\n        Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", \\\"pods\\\") + (Get-Resources)) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Get the pod logs for each container\\n            % {\\n                $podDetails = $_\\n                @{\\n                    logs=$podDetails.spec.containers | % {$logs=\\\"\\\"} {$logs += (Select-Object -InputObject (Execute-Command kubectl ((Get-KubectlVerb) + @($podDetails.metadata.name, \\\"-c\\\", $_.name))) -ExpandProperty stdout)} {$logs}; \\n                    name=$podDetails.metadata.name\\n                }                \\n            } |\\n            # Write the output\\n            % {Write-Host $_.logs; $_} |\\n            # Optionally capture the artifact\\n            % {\\n                if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n                {\\n                    Set-Content -Path \\\"$($_.name).$(Get-ArtifactExtension)\\\" -Value $_.logs\\n                    New-OctopusArtifact \\\"$($_.name).$(Get-ArtifactExtension)\\\"\\n                }\\n            }\\n    }      \\n}\\nelse\\n{\\n    Execute-Command kubectl ((Get-KubectlVerb) + @($OctopusParameters[\\\"K8SInspectResource\\\"]) + (Get-Resources)) |\\n        % {Select-Object -InputObject $_ -ExpandProperty stdout} |\\n        % {Write-Host $_; $_} |\\n        % {\\n            if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n            {\\n                Set-Content -Path \\\"output.$(Get-ArtifactExtension)\\\" -Value $_\\n                New-OctopusArtifact \\\"output.$(Get-ArtifactExtension)\\\"\\n            }\\n        }\\n}\\n\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"K8SInspectResource\"                            = \"service\"\n        \"Octopus.Action.Script.Syntax\"                  = \"PowerShell\"\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{if K8SInspectNamespace}#{K8SInspectNamespace}#{/if}#{unless K8SInspectNamespace}#{Octopus.Action.Kubernetes.Namespace}#{/unless}\"\n        \"K8SInspectNames\"                               = \"#{Kubernetes.Service.Name}*\"\n        \"K8SInspectKubectlVerb\"                         = \"get\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_frontend_get_deployment\" {\n  count             = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  name              = \"🛠️ Get Deployment\"\n  project_id        = octopusdeploy_project.project_octopub_frontend[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Returns the deployments.\n\n**Affects**: Nothing - this runbook makes no changes.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_frontend_get_deployment\" {\n  count      = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_frontend_get_deployment[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Get Deployment\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Get Deployment\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"K8SInspectCreateArtifact\"                      = \"False\"\n        \"Octopus.Action.Script.ScriptBody\"              = \"<#\\n    This script provides a general purpose method for querying Kubernetes resources. It supports common operations\\n    like get, describe, logs and output formats like yaml and json. Output can be captured as artifacts.\\n#>\\n\\n<#\\n.Description\\nExecute an application, capturing the output. Based on https://stackoverflow.com/a/33652732/157605\\n#>\\nFunction Execute-Command ($commandPath, $commandArguments)\\n{\\n  Write-Host \\\"Executing: $commandPath $($commandArguments -join \\\" \\\")\\\"\\n  \\n  Try {\\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\\n    $pinfo.FileName = $commandPath\\n    $pinfo.RedirectStandardError = $true\\n    $pinfo.RedirectStandardOutput = $true\\n    $pinfo.UseShellExecute = $false\\n    $pinfo.Arguments = $commandArguments\\n    $p = New-Object System.Diagnostics.Process\\n    $p.StartInfo = $pinfo\\n    $p.Start() | Out-Null\\n    [pscustomobject]@{\\n        stdout = $p.StandardOutput.ReadToEnd()\\n        stderr = $p.StandardError.ReadToEnd()\\n        ExitCode = $p.ExitCode\\n    }\\n    $p.WaitForExit()\\n  }\\n  Catch {\\n     exit\\n  }\\n}\\n\\n<#\\n.Description\\nFind any resource names that match a wildcard input if one was specified\\n#>\\nfunction Get-Resources() \\n{\\n    $names = $OctopusParameters[\\\"K8SInspectNames\\\"] -Split \\\"`n\\\" | % {$_.Trim()}\\n    \\n    if ($OctopusParameters[\\\"K8SInspectNames\\\"] -match '\\\\*' )\\n    {\\n        return Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", $OctopusParameters[\\\"K8SInspectResource\\\"])) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Extract the name\\n            % {$_.metadata.name} |\\n            # Find any matching resources\\n            ? {$k8sName = $_; ($names | ? {$k8sName -like $_}).Count -ne 0}\\n    }\\n    else\\n    {\\n        return $names\\n    }\\n}\\n\\n<#\\n.Description\\nGet the kubectl arguments for a given action\\n#>\\nfunction Get-KubectlVerb() \\n{\\n    switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {return ,@(\\\"-o\\\", \\\"json\\\", \\\"get\\\")}\\n        \\\"get yaml\\\" {return ,@(\\\"-o\\\", \\\"yaml\\\", \\\"get\\\")}\\n        \\\"describe\\\" {return ,@(\\\"describe\\\")}\\n        \\\"logs\\\" {return ,@(\\\"logs\\\")}\\n        \\\"logs tail\\\" {return ,@(\\\"logs\\\", \\\"--tail\\\", \\\"100\\\")}\\n        \\\"previous logs\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\")}\\n        \\\"previous logs tail\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\", \\\"--tail\\\", \\\"100\\\")}\\n        default {return ,@(\\\"get\\\")}\\n    }\\n}\\n\\n<#\\n.Description\\nGet an appropiate file extension based on the selected action\\n#>\\nfunction Get-ArtifactExtension() \\n{\\n   switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {\\\"json\\\"}\\n        \\\"get yaml\\\" {\\\"yaml\\\"}\\n        default {\\\"txt\\\"}\\n    }\\n}\\n\\nif ($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"] -like \\\"*logs*\\\") \\n{\\n    if ( -not @($OctopusParameters[\\\"K8SInspectResource\\\"]) -like \\\"pod*\\\")\\n    {\\n        Write-Error \\\"Logs can only be returned for pods, not $($OctopusParameters[\\\"K8SInspectResource\\\"])\\\"\\n    }\\n    else\\n    {\\n        Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", \\\"pods\\\") + (Get-Resources)) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Get the pod logs for each container\\n            % {\\n                $podDetails = $_\\n                @{\\n                    logs=$podDetails.spec.containers | % {$logs=\\\"\\\"} {$logs += (Select-Object -InputObject (Execute-Command kubectl ((Get-KubectlVerb) + @($podDetails.metadata.name, \\\"-c\\\", $_.name))) -ExpandProperty stdout)} {$logs}; \\n                    name=$podDetails.metadata.name\\n                }                \\n            } |\\n            # Write the output\\n            % {Write-Host $_.logs; $_} |\\n            # Optionally capture the artifact\\n            % {\\n                if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n                {\\n                    Set-Content -Path \\\"$($_.name).$(Get-ArtifactExtension)\\\" -Value $_.logs\\n                    New-OctopusArtifact \\\"$($_.name).$(Get-ArtifactExtension)\\\"\\n                }\\n            }\\n    }      \\n}\\nelse\\n{\\n    Execute-Command kubectl ((Get-KubectlVerb) + @($OctopusParameters[\\\"K8SInspectResource\\\"]) + (Get-Resources)) |\\n        % {Select-Object -InputObject $_ -ExpandProperty stdout} |\\n        % {Write-Host $_; $_} |\\n        % {\\n            if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n            {\\n                Set-Content -Path \\\"output.$(Get-ArtifactExtension)\\\" -Value $_\\n                New-OctopusArtifact \\\"output.$(Get-ArtifactExtension)\\\"\\n            }\\n        }\\n}\\n\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"K8SInspectResource\"                            = \"deployment\"\n        \"Octopus.Action.Script.Syntax\"                  = \"PowerShell\"\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{if K8SInspectNamespace}#{K8SInspectNamespace}#{/if}#{unless K8SInspectNamespace}#{Octopus.Action.Kubernetes.Namespace}#{/unless}\"\n        \"K8SInspectNames\"                               = \"#{Kubernetes.Deployment.Name}*\"\n        \"K8SInspectKubectlVerb\"                         = \"get\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n#endregion\n\n#region Products\nvariable \"products_project_name\" {\n  type    = string\n  default = \"\"\n}\n\ndata \"octopusdeploy_projects\" \"octopub_products\" {\n  partial_name = var.products_project_name == \"\" ? local.products_project_name : var.products_project_name\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_variable\" \"products_deployment_feed\" {\n  count        = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_products[0].id\n  value        = local.docker_hub_feed_id\n  name         = \"Kubernetes.Deployment.Feed\"\n  type         = \"String\"\n  description  = \"The feed ID hosting the image\"\n  is_sensitive = false\n}\n\nresource \"octopusdeploy_variable\" \"products_deployment_image\" {\n  count        = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_products[0].id\n  value        = \"octopussamples/octopub-products-microservice\"\n  name         = \"Kubernetes.Deployment.Image\"\n  type         = \"String\"\n  description  = \"The image to deploy\"\n  is_sensitive = false\n}\n\nresource \"octopusdeploy_variable\" \"products_deployment_port\" {\n  count        = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_products[0].id\n  value        = \"8083\"\n  name         = \"Kubernetes.Deployment.Port\"\n  type         = \"String\"\n  description  = \"The port exposed by the web app\"\n  is_sensitive = false\n}\n\nresource \"octopusdeploy_variable\" \"products_microservice_name\" {\n  count        = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_products[0].id\n  value        = \"products\"\n  name         = \"Microservice.Name\"\n  type         = \"String\"\n  description  = \"The microservice name, which is used as the basis for K8s resources and networking paths\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"products_deployment_name\" {\n  count        = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_products[0].id\n  value        = \"#{Microservice.Name}\"\n  name         = \"Kubernetes.Deployment.Name\"\n  type         = \"String\"\n  description  = \"The name of the Kubernetes deployment resource\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"products_service_name\" {\n  count        = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_products[0].id\n  value        = \"#{Microservice.Name}\"\n  name         = \"Kubernetes.Service.Name\"\n  type         = \"String\"\n  description  = \"The name of the Kubernetes service resource\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"products_ingress_name\" {\n  count        = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_products[0].id\n  value        = \"#{Microservice.Name}\"\n  name         = \"Kubernetes.Ingress.Name\"\n  type         = \"String\"\n  description  = \"The name of the Kubernetes ingress resource\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"products_ingress_path\" {\n  count        = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_products[0].id\n  value        = \"/#{Kubernetes.Namespace}(/api/#{Microservice.Name})(/.*)?\"\n  name         = \"Kubernetes.Ingress.Path\"\n  type         = \"String\"\n  description  = \"The path of the Kubernetes ingress resource\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"products_app_path\" {\n  count        = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_products[0].id\n  value        = \"/#{Kubernetes.Namespace}/api/#{Microservice.Name}\"\n  name         = \"Kubernetes.App.HealthCheck\"\n  type         = \"String\"\n  description  = \"The path to perform a health check on.\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"products_namespace_default\" {\n  count        = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_products[0].id\n  value        = \"#{Octopus.Action.Kubernetes.Namespace}\"\n  name         = \"Kubernetes.Namespace\"\n  type         = \"String\"\n  description  = \"The namespace to perform the deployments in.\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"products_namespace_featurebranch\" {\n  count        = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_products[0].id\n  value        = \"\"\n  name         = \"Kubernetes.Namespace\"\n  type         = \"String\"\n  description  = \"The custom namespace to use when deploying a feature branch\"\n  is_sensitive = false\n\n  scope {\n    actions      = []\n    channels     = []\n    environments = [local.featurebranch_environment_id]\n    machines     = []\n    roles        = null\n    tenant_tags  = null\n  }\n\n  prompt {\n    description = \"Feature branch namespace\"\n    label       = \"Namespace\"\n    is_required = true\n    display_settings {\n      control_type = \"SingleLineText\"\n    }\n  }\n}\n\nresource \"octopusdeploy_channel\" \"products_featurebranch\" {\n  count        = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  name         = \"Feature Branch\"\n  project_id   = octopusdeploy_project.project_octopub_products[0].id\n  description  = \"Deploy feature branch builds\"\n  is_default   = false\n  lifecycle_id = local.featurebranch_lifecycle_id\n}\n\nresource \"octopusdeploy_channel\" \"products_mainline\" {\n  count        = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  name         = \"Mainline\"\n  project_id   = octopusdeploy_project.project_octopub_products[0].id\n  description  = \"Deploy mainline builds\"\n  is_default   = true\n  lifecycle_id = local.devops_lifecycle_id\n  rule {\n    tag = \"^$\"\n    action_package {\n      deployment_action = \"Deploy Container\"\n      package_reference = \"web\"\n    }\n  }\n\n  depends_on  = [octopusdeploy_deployment_process.deployment_process_octopub_products]\n}\n\nresource \"octopusdeploy_project\" \"project_octopub_products\" {\n  count                                = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  name                                 = var.products_project_name == \"\" ? local.products_project_name : var.products_project_name\n  auto_create_release                  = false\n  default_guided_failure_mode          = \"Off\"\n  default_to_skip_if_already_installed = false\n  discrete_channel_release             = false\n  is_disabled                          = false\n  is_version_controlled                = false\n  lifecycle_id                         = local.devops_lifecycle_id\n  project_group_id                     = local.eks_project_group_id\n  included_library_variable_sets       = [local.this_instance_library_variable_set, local.github_library_variable_set]\n  tenanted_deployment_participation    = \"Untenanted\"\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n\n  versioning_strategy {\n    template = \"#{Octopus.Version.LastMajor}.#{Octopus.Version.LastMinor}.#{Octopus.Version.NextPatch}\"\n  }\n\n  lifecycle {\n    ignore_changes = []\n  }\n  description = <<EOT\nDeploys the Octopub Products Service\n\n**Source**: [GitHub](https://github.com/OctopusSolutionsEngineering/Octopub)\n\n**Build**: [GitHub Actions](https://github.com/OctopusSolutionsEngineering/Octopub/actions)\n\n**Issues**: [GitHub Issues](https://github.com/OctopusSolutionsEngineering/Octopub/issues)\nEOT\n}\n\nresource \"octopusdeploy_deployment_process\" \"deployment_process_octopub_products\" {\n  count      = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  project_id = octopusdeploy_project.project_octopub_products[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Generate Variables\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Generate Variables\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = local.variable_script\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Deploy Container\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesDeployContainers\"\n      name                               = \"Deploy Container\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.KubernetesContainers.Namespace\"              = \"#{Kubernetes.Namespace}\"\n        \"Octopus.Action.KubernetesContainers.Replicas\"               = \"1\"\n        \"Octopus.Action.KubernetesContainers.DeploymentResourceType\" = \"Deployment\"\n        \"Octopus.Action.KubernetesContainers.IngressAnnotations\"     = jsonencode([\n          {\n            \"optionError\"  = null\n            \"option2\"      = \"\"\n            \"option2Error\" = null\n            \"key\"          = \"nginx.ingress.kubernetes.io/rewrite-target\"\n            \"keyError\"     = null\n            \"value\"        = \"$1$2\"\n            \"valueError\"   = null\n            \"option\"       = \"\"\n          },\n          {\n            \"keyError\"     = null\n            \"value\"        = \"true\"\n            \"valueError\"   = null\n            \"option\"       = \"\"\n            \"optionError\"  = null\n            \"option2\"      = \"\"\n            \"option2Error\" = null\n            \"key\"          = \"nginx.ingress.kubernetes.io/use-regex\"\n          },\n        ])\n        \"Octopus.Action.KubernetesContainers.DeploymentStyle\" = \"RollingUpdate\"\n        \"Octopus.Action.KubernetesContainers.IngressName\"     = \"#{Kubernetes.Ingress.Name}\"\n        \"Octopus.Action.KubernetesContainers.DeploymentName\"  = \"#{Kubernetes.Deployment.Name}\"\n        \"Octopus.Action.KubernetesContainers.IngressRules\"    = jsonencode([\n          {\n            \"host\" = \"\"\n            \"http\" = {\n              \"paths\" = [\n                {\n                  \"key\"     = \"#{Kubernetes.Ingress.Path}\"\n                  \"value\"   = \"web\"\n                  \"option\"  = \"\"\n                  \"option2\" = \"ImplementationSpecific\"\n                },\n              ]\n            }\n          },\n        ])\n        \"OctopusUseBundledTooling\"                       = \"False\"\n        \"Octopus.Action.KubernetesContainers.Containers\" = jsonencode([\n          {\n            \"Args\"                         = []\n            \"FieldRefEnvironmentVariables\" = []\n            \"SecretEnvFromSource\"          = []\n            \"Command\"                      = []\n            \"Ports\"                        = [\n              {\n                \"option2Error\" = null\n                \"optionError\"  = null\n                \"value\"        = \"#{Kubernetes.Deployment.Port}\"\n                \"valueError\"   = null\n                \"key\"          = \"web\"\n                \"keyError\"     = null\n                \"option\"       = \"TCP\"\n                \"option2\"      = \"\"\n              },\n            ]\n            \"Resources\" = {\n              \"limits\" = {\n                \"storage\"          = \"\"\n                \"amdGpu\"           = \"\"\n                \"cpu\"              = \"\"\n                \"ephemeralStorage\" = \"\"\n                \"memory\"           = \"\"\n                \"nvidiaGpu\"        = \"\"\n              }\n              \"requests\" = {\n                \"amdGpu\"           = \"\"\n                \"cpu\"              = \"\"\n                \"ephemeralStorage\" = \"\"\n                \"memory\"           = \"\"\n                \"nvidiaGpu\"        = \"\"\n                \"storage\"          = \"\"\n              }\n            }\n            \"SecretEnvironmentVariables\" = []\n            \"SecurityContext\"            = {\n              \"runAsNonRoot\"   = \"True\"\n              \"runAsUser\"      = \"\"\n              \"seLinuxOptions\" = {\n                \"level\" = \"\"\n                \"role\"  = \"\"\n                \"type\"  = \"\"\n                \"user\"  = \"\"\n              }\n              \"allowPrivilegeEscalation\" = \"\"\n              \"capabilities\"             = {\n                \"add\"  = []\n                \"drop\" = [\n                  \"ALL\",\n                ]\n              }\n              \"privileged\"             = \"\"\n              \"readOnlyRootFilesystem\" = \"\"\n              \"runAsGroup\"             = \"\"\n            }\n            \"TerminationMessagePath\" = \"\"\n            \"EnvironmentVariables\"   = [\n              {\n                \"key\"          = \"PORT\"\n                \"keyError\"     = null\n                \"value\"        = \"#{Kubernetes.Deployment.Port}\"\n                \"valueError\"   = null\n                \"option\"       = \"\"\n                \"optionError\"  = null\n                \"option2\"      = \"\"\n                \"option2Error\" = null\n              }\n            ]\n            \"LivenessProbe\" = {\n              \"successThreshold\" = \"\"\n              \"tcpSocket\"        = {\n                \"port\" = \"\"\n                \"host\" = \"\"\n              }\n              \"exec\" = {\n                \"command\" = []\n              }\n              \"failureThreshold\" = \"\"\n              \"periodSeconds\"    = \"\"\n              \"type\"             = \"\"\n              \"httpGet\"          = {\n                \"host\"        = \"\"\n                \"httpHeaders\" = []\n                \"path\"        = \"\"\n                \"port\"        = \"\"\n                \"scheme\"      = \"\"\n              }\n              \"initialDelaySeconds\" = \"\"\n              \"timeoutSeconds\"      = \"\"\n            }\n            \"ReadinessProbe\" = {\n              \"exec\" = {\n                \"command\" = []\n              }\n              \"failureThreshold\" = \"\"\n              \"timeoutSeconds\"   = \"\"\n              \"successThreshold\" = \"\"\n              \"tcpSocket\"        = {\n                \"host\" = \"\"\n                \"port\" = \"\"\n              }\n              \"type\"    = \"\"\n              \"httpGet\" = {\n                \"host\"        = \"\"\n                \"httpHeaders\" = []\n                \"path\"        = \"\"\n                \"port\"        = \"\"\n                \"scheme\"      = \"\"\n              }\n              \"initialDelaySeconds\" = \"\"\n              \"periodSeconds\"       = \"\"\n            }\n            \"TerminationMessagePolicy\"      = \"\"\n            \"VolumeMounts\"                  = []\n            \"ConfigMapEnvFromSource\"        = []\n            \"ConfigMapEnvironmentVariables\" = []\n            \"CreateFeedSecrets\"             = \"False\"\n            \"Lifecycle\"                     = {\n              \"PostStart\" = null\n              \"PreStop\"   = null\n            }\n            \"Name\"         = \"web\"\n            \"StartupProbe\" = {\n              \"successThreshold\" = \"\"\n              \"tcpSocket\"        = {\n                \"host\" = \"\"\n                \"port\" = \"\"\n              }\n              \"failureThreshold\" = \"\"\n              \"httpGet\"          = {\n                \"host\"        = \"\"\n                \"httpHeaders\" = []\n                \"path\"        = \"\"\n                \"port\"        = \"\"\n                \"scheme\"      = \"\"\n              }\n              \"initialDelaySeconds\" = \"\"\n              \"type\"                = \"\"\n              \"exec\"                = {\n                \"command\" = []\n              }\n              \"periodSeconds\"  = \"\"\n              \"timeoutSeconds\" = \"\"\n            }\n          },\n        ])\n        \"Octopus.Action.KubernetesContainers.ServiceName\"         = \"#{Kubernetes.Service.Name}\"\n        \"Octopus.Action.KubernetesContainers.PodManagementPolicy\" = \"OrderedReady\"\n        \"Octopus.Action.Kubernetes.DeploymentTimeout\"             = \"180\"\n        \"Octopus.Action.RunOnServer\"                              = \"true\"\n        \"Octopus.Action.KubernetesContainers.IngressClassName\"    = \"nginx\"\n        \"Octopus.Action.KubernetesContainers.ServicePorts\"        = jsonencode([\n          {\n            \"port\"       = \"80\"\n            \"protocol\"   = \"TCP\"\n            \"targetPort\" = \"web\"\n            \"name\"       = \"web\"\n            \"nodePort\"   = \"\"\n          },\n        ])\n        \"Octopus.Action.Kubernetes.ResourceStatusCheck\"       = \"True\"\n        \"Octopus.Action.KubernetesContainers.ServiceNameType\" = \"External\"\n        \"Octopus.Action.KubernetesContainers.ServiceType\"     = \"ClusterIP\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n        local.featurebranch_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n\n      package {\n        name                      = \"web\"\n        package_id                = \"#{Kubernetes.Deployment.Image}\"\n        acquisition_location      = \"NotAcquired\"\n        extract_during_deployment = false\n        feed_id                   = \"#{Kubernetes.Deployment.Feed}\"\n        properties                = { Extract = \"False\", PackageParameterName = \"\", SelectionMode = \"immediate\" }\n      }\n      features = [\n        \"\", \"Octopus.Features.KubernetesService\", \"Octopus.Features.KubernetesIngress\",\n        \"Octopus.Features.KubernetesConfigMap\", \"Octopus.Features.KubernetesSecret\"\n      ]\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Smoke Test\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Smoke Test\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{Kubernetes.Namespace}\"\n        \"Octopus.Action.RunOnServer\"                    = \"true\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"                  = \"Bash\"\n        \"Octopus.Action.Script.ScriptBody\"              = local.smoke_test\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n        local.featurebranch_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Security Scan\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Security Scan\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"Bash\"\n        \"Octopus.Action.Script.ScriptBody\"   = local.security_scan_script\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_products_scale_to_zero\" {\n  count             = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  name              = \"🌃 Scale Pods to Zero\"\n  project_id        = octopusdeploy_project.project_octopub_products[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**WARNING**: This is a destructive operation. The service will no longer be available when scaled down.\n\n**Action**: Scales the deployment down to zero pods.\n\n**Affects**: The products service is effectively shut down.\n\nThis runbook is designed to be be run in non-production environments after hours to remove the Fargate nodes hosting\nthe service. This removes the cost of hosting the service out of hours.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_products_scale_pods_to_zero\" {\n  count      = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_products_scale_to_zero[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Scale Pods to Zero\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Scale Pods to Zero\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"OctopusUseBundledTooling\"           = \"False\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"kubectl scale --replicas=0 deployment/#{Kubernetes.Deployment.Name}\"\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n      }\n\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_products_scale_to_one\" {\n  count             = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  name              = \"🌇 Scale Pods to One\"\n  project_id        = octopusdeploy_project.project_octopub_products[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Scales the deployment to one pod.\n\n**Affects**: Products service - this will create new pods if the deployment has been scaled to zero.\n\nThis runbook is designed to be be run in non-production environments during office hours to recreate the pods after they\nwere shutdown after hours.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_products_scale_pods_to_one\" {\n  count      = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_products_scale_to_one[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Scale Pods to One\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Scale Pods to One\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"OctopusUseBundledTooling\"           = \"False\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"kubectl scale --replicas=1 deployment/#{Kubernetes.Deployment.Name}\"\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n      }\n\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_products_get_pod_logs\" {\n  count             = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  name              = \"🛠️ Get Pod Logs\"\n  project_id        = octopusdeploy_project.project_octopub_products[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Returns the pod logs.\n\n**Affects**: Nothing - this runbook makes no changes.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_products_get_pod_logs\" {\n  count      = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_products_get_pod_logs[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Get Pod Logs\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Get Pod Logs\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"K8SInspectCreateArtifact\"                      = \"False\"\n        \"Octopus.Action.Script.ScriptBody\"              = \"<#\\n    This script provides a general purpose method for querying Kubernetes resources. It supports common operations\\n    like get, describe, logs and output formats like yaml and json. Output can be captured as artifacts.\\n#>\\n\\n<#\\n.Description\\nExecute an application, capturing the output. Based on https://stackoverflow.com/a/33652732/157605\\n#>\\nFunction Execute-Command ($commandPath, $commandArguments)\\n{\\n  Write-Host \\\"Executing: $commandPath $($commandArguments -join \\\" \\\")\\\"\\n  \\n  Try {\\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\\n    $pinfo.FileName = $commandPath\\n    $pinfo.RedirectStandardError = $true\\n    $pinfo.RedirectStandardOutput = $true\\n    $pinfo.UseShellExecute = $false\\n    $pinfo.Arguments = $commandArguments\\n    $p = New-Object System.Diagnostics.Process\\n    $p.StartInfo = $pinfo\\n    $p.Start() | Out-Null\\n    [pscustomobject]@{\\n        stdout = $p.StandardOutput.ReadToEnd()\\n        stderr = $p.StandardError.ReadToEnd()\\n        ExitCode = $p.ExitCode\\n    }\\n    $p.WaitForExit()\\n  }\\n  Catch {\\n     exit\\n  }\\n}\\n\\n<#\\n.Description\\nFind any resource names that match a wildcard input if one was specified\\n#>\\nfunction Get-Resources() \\n{\\n    $names = $OctopusParameters[\\\"K8SInspectNames\\\"] -Split \\\"`n\\\" | % {$_.Trim()}\\n    \\n    if ($OctopusParameters[\\\"K8SInspectNames\\\"] -match '\\\\*' )\\n    {\\n        return Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", $OctopusParameters[\\\"K8SInspectResource\\\"])) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Extract the name\\n            % {$_.metadata.name} |\\n            # Find any matching resources\\n            ? {$k8sName = $_; ($names | ? {$k8sName -like $_}).Count -ne 0}\\n    }\\n    else\\n    {\\n        return $names\\n    }\\n}\\n\\n<#\\n.Description\\nGet the kubectl arguments for a given action\\n#>\\nfunction Get-KubectlVerb() \\n{\\n    switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {return ,@(\\\"-o\\\", \\\"json\\\", \\\"get\\\")}\\n        \\\"get yaml\\\" {return ,@(\\\"-o\\\", \\\"yaml\\\", \\\"get\\\")}\\n        \\\"describe\\\" {return ,@(\\\"describe\\\")}\\n        \\\"logs\\\" {return ,@(\\\"logs\\\")}\\n        \\\"logs tail\\\" {return ,@(\\\"logs\\\", \\\"--tail\\\", \\\"100\\\")}\\n        \\\"previous logs\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\")}\\n        \\\"previous logs tail\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\", \\\"--tail\\\", \\\"100\\\")}\\n        default {return ,@(\\\"get\\\")}\\n    }\\n}\\n\\n<#\\n.Description\\nGet an appropiate file extension based on the selected action\\n#>\\nfunction Get-ArtifactExtension() \\n{\\n   switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {\\\"json\\\"}\\n        \\\"get yaml\\\" {\\\"yaml\\\"}\\n        default {\\\"txt\\\"}\\n    }\\n}\\n\\nif ($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"] -like \\\"*logs*\\\") \\n{\\n    if ( -not @($OctopusParameters[\\\"K8SInspectResource\\\"]) -like \\\"pod*\\\")\\n    {\\n        Write-Error \\\"Logs can only be returned for pods, not $($OctopusParameters[\\\"K8SInspectResource\\\"])\\\"\\n    }\\n    else\\n    {\\n        Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", \\\"pods\\\") + (Get-Resources)) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Get the pod logs for each container\\n            % {\\n                $podDetails = $_\\n                @{\\n                    logs=$podDetails.spec.containers | % {$logs=\\\"\\\"} {$logs += (Select-Object -InputObject (Execute-Command kubectl ((Get-KubectlVerb) + @($podDetails.metadata.name, \\\"-c\\\", $_.name))) -ExpandProperty stdout)} {$logs}; \\n                    name=$podDetails.metadata.name\\n                }                \\n            } |\\n            # Write the output\\n            % {Write-Host $_.logs; $_} |\\n            # Optionally capture the artifact\\n            % {\\n                if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n                {\\n                    Set-Content -Path \\\"$($_.name).$(Get-ArtifactExtension)\\\" -Value $_.logs\\n                    New-OctopusArtifact \\\"$($_.name).$(Get-ArtifactExtension)\\\"\\n                }\\n            }\\n    }      \\n}\\nelse\\n{\\n    Execute-Command kubectl ((Get-KubectlVerb) + @($OctopusParameters[\\\"K8SInspectResource\\\"]) + (Get-Resources)) |\\n        % {Select-Object -InputObject $_ -ExpandProperty stdout} |\\n        % {Write-Host $_; $_} |\\n        % {\\n            if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n            {\\n                Set-Content -Path \\\"output.$(Get-ArtifactExtension)\\\" -Value $_\\n                New-OctopusArtifact \\\"output.$(Get-ArtifactExtension)\\\"\\n            }\\n        }\\n}\\n\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"K8SInspectResource\"                            = \"pod\"\n        \"Octopus.Action.Script.Syntax\"                  = \"PowerShell\"\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{if K8SInspectNamespace}#{K8SInspectNamespace}#{/if}#{unless K8SInspectNamespace}#{Octopus.Action.Kubernetes.Namespace}#{/unless}\"\n        \"K8SInspectNames\"                               = \"#{Kubernetes.Deployment.Name}*\"\n        \"K8SInspectKubectlVerb\"                         = \"logs\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_products_get_pods\" {\n  count             = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  name              = \"🛠️ Get Pods\"\n  project_id        = octopusdeploy_project.project_octopub_products[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Returns the pods.\n\n**Affects**: Nothing - this runbook makes no changes.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_products_get_pods\" {\n  count      = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_products_get_pods[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Get Pods\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Get Pods\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"K8SInspectCreateArtifact\"                      = \"False\"\n        \"Octopus.Action.Script.ScriptBody\"              = \"<#\\n    This script provides a general purpose method for querying Kubernetes resources. It supports common operations\\n    like get, describe, logs and output formats like yaml and json. Output can be captured as artifacts.\\n#>\\n\\n<#\\n.Description\\nExecute an application, capturing the output. Based on https://stackoverflow.com/a/33652732/157605\\n#>\\nFunction Execute-Command ($commandPath, $commandArguments)\\n{\\n  Write-Host \\\"Executing: $commandPath $($commandArguments -join \\\" \\\")\\\"\\n  \\n  Try {\\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\\n    $pinfo.FileName = $commandPath\\n    $pinfo.RedirectStandardError = $true\\n    $pinfo.RedirectStandardOutput = $true\\n    $pinfo.UseShellExecute = $false\\n    $pinfo.Arguments = $commandArguments\\n    $p = New-Object System.Diagnostics.Process\\n    $p.StartInfo = $pinfo\\n    $p.Start() | Out-Null\\n    [pscustomobject]@{\\n        stdout = $p.StandardOutput.ReadToEnd()\\n        stderr = $p.StandardError.ReadToEnd()\\n        ExitCode = $p.ExitCode\\n    }\\n    $p.WaitForExit()\\n  }\\n  Catch {\\n     exit\\n  }\\n}\\n\\n<#\\n.Description\\nFind any resource names that match a wildcard input if one was specified\\n#>\\nfunction Get-Resources() \\n{\\n    $names = $OctopusParameters[\\\"K8SInspectNames\\\"] -Split \\\"`n\\\" | % {$_.Trim()}\\n    \\n    if ($OctopusParameters[\\\"K8SInspectNames\\\"] -match '\\\\*' )\\n    {\\n        return Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", $OctopusParameters[\\\"K8SInspectResource\\\"])) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Extract the name\\n            % {$_.metadata.name} |\\n            # Find any matching resources\\n            ? {$k8sName = $_; ($names | ? {$k8sName -like $_}).Count -ne 0}\\n    }\\n    else\\n    {\\n        return $names\\n    }\\n}\\n\\n<#\\n.Description\\nGet the kubectl arguments for a given action\\n#>\\nfunction Get-KubectlVerb() \\n{\\n    switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {return ,@(\\\"-o\\\", \\\"json\\\", \\\"get\\\")}\\n        \\\"get yaml\\\" {return ,@(\\\"-o\\\", \\\"yaml\\\", \\\"get\\\")}\\n        \\\"describe\\\" {return ,@(\\\"describe\\\")}\\n        \\\"logs\\\" {return ,@(\\\"logs\\\")}\\n        \\\"logs tail\\\" {return ,@(\\\"logs\\\", \\\"--tail\\\", \\\"100\\\")}\\n        \\\"previous logs\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\")}\\n        \\\"previous logs tail\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\", \\\"--tail\\\", \\\"100\\\")}\\n        default {return ,@(\\\"get\\\")}\\n    }\\n}\\n\\n<#\\n.Description\\nGet an appropiate file extension based on the selected action\\n#>\\nfunction Get-ArtifactExtension() \\n{\\n   switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {\\\"json\\\"}\\n        \\\"get yaml\\\" {\\\"yaml\\\"}\\n        default {\\\"txt\\\"}\\n    }\\n}\\n\\nif ($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"] -like \\\"*logs*\\\") \\n{\\n    if ( -not @($OctopusParameters[\\\"K8SInspectResource\\\"]) -like \\\"pod*\\\")\\n    {\\n        Write-Error \\\"Logs can only be returned for pods, not $($OctopusParameters[\\\"K8SInspectResource\\\"])\\\"\\n    }\\n    else\\n    {\\n        Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", \\\"pods\\\") + (Get-Resources)) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Get the pod logs for each container\\n            % {\\n                $podDetails = $_\\n                @{\\n                    logs=$podDetails.spec.containers | % {$logs=\\\"\\\"} {$logs += (Select-Object -InputObject (Execute-Command kubectl ((Get-KubectlVerb) + @($podDetails.metadata.name, \\\"-c\\\", $_.name))) -ExpandProperty stdout)} {$logs}; \\n                    name=$podDetails.metadata.name\\n                }                \\n            } |\\n            # Write the output\\n            % {Write-Host $_.logs; $_} |\\n            # Optionally capture the artifact\\n            % {\\n                if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n                {\\n                    Set-Content -Path \\\"$($_.name).$(Get-ArtifactExtension)\\\" -Value $_.logs\\n                    New-OctopusArtifact \\\"$($_.name).$(Get-ArtifactExtension)\\\"\\n                }\\n            }\\n    }      \\n}\\nelse\\n{\\n    Execute-Command kubectl ((Get-KubectlVerb) + @($OctopusParameters[\\\"K8SInspectResource\\\"]) + (Get-Resources)) |\\n        % {Select-Object -InputObject $_ -ExpandProperty stdout} |\\n        % {Write-Host $_; $_} |\\n        % {\\n            if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n            {\\n                Set-Content -Path \\\"output.$(Get-ArtifactExtension)\\\" -Value $_\\n                New-OctopusArtifact \\\"output.$(Get-ArtifactExtension)\\\"\\n            }\\n        }\\n}\\n\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"K8SInspectResource\"                            = \"pod\"\n        \"Octopus.Action.Script.Syntax\"                  = \"PowerShell\"\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{if K8SInspectNamespace}#{K8SInspectNamespace}#{/if}#{unless K8SInspectNamespace}#{Octopus.Action.Kubernetes.Namespace}#{/unless}\"\n        \"K8SInspectNames\"                               = \"#{Kubernetes.Deployment.Name}*\"\n        \"K8SInspectKubectlVerb\"                         = \"get\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_products_describe_pods\" {\n  count             = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  name              = \"🛠️ Describe Pods\"\n  project_id        = octopusdeploy_project.project_octopub_products[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Returns the pods.\n\n**Affects**: Nothing - this runbook makes no changes.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_products_describe_pods\" {\n  count      = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_products_describe_pods[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Describe Pods\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Describe Pods\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"K8SInspectCreateArtifact\"                      = \"False\"\n        \"Octopus.Action.Script.ScriptBody\"              = \"<#\\n    This script provides a general purpose method for querying Kubernetes resources. It supports common operations\\n    like get, describe, logs and output formats like yaml and json. Output can be captured as artifacts.\\n#>\\n\\n<#\\n.Description\\nExecute an application, capturing the output. Based on https://stackoverflow.com/a/33652732/157605\\n#>\\nFunction Execute-Command ($commandPath, $commandArguments)\\n{\\n  Write-Host \\\"Executing: $commandPath $($commandArguments -join \\\" \\\")\\\"\\n  \\n  Try {\\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\\n    $pinfo.FileName = $commandPath\\n    $pinfo.RedirectStandardError = $true\\n    $pinfo.RedirectStandardOutput = $true\\n    $pinfo.UseShellExecute = $false\\n    $pinfo.Arguments = $commandArguments\\n    $p = New-Object System.Diagnostics.Process\\n    $p.StartInfo = $pinfo\\n    $p.Start() | Out-Null\\n    [pscustomobject]@{\\n        stdout = $p.StandardOutput.ReadToEnd()\\n        stderr = $p.StandardError.ReadToEnd()\\n        ExitCode = $p.ExitCode\\n    }\\n    $p.WaitForExit()\\n  }\\n  Catch {\\n     exit\\n  }\\n}\\n\\n<#\\n.Description\\nFind any resource names that match a wildcard input if one was specified\\n#>\\nfunction Get-Resources() \\n{\\n    $names = $OctopusParameters[\\\"K8SInspectNames\\\"] -Split \\\"`n\\\" | % {$_.Trim()}\\n    \\n    if ($OctopusParameters[\\\"K8SInspectNames\\\"] -match '\\\\*' )\\n    {\\n        return Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", $OctopusParameters[\\\"K8SInspectResource\\\"])) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Extract the name\\n            % {$_.metadata.name} |\\n            # Find any matching resources\\n            ? {$k8sName = $_; ($names | ? {$k8sName -like $_}).Count -ne 0}\\n    }\\n    else\\n    {\\n        return $names\\n    }\\n}\\n\\n<#\\n.Description\\nGet the kubectl arguments for a given action\\n#>\\nfunction Get-KubectlVerb() \\n{\\n    switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {return ,@(\\\"-o\\\", \\\"json\\\", \\\"get\\\")}\\n        \\\"get yaml\\\" {return ,@(\\\"-o\\\", \\\"yaml\\\", \\\"get\\\")}\\n        \\\"describe\\\" {return ,@(\\\"describe\\\")}\\n        \\\"logs\\\" {return ,@(\\\"logs\\\")}\\n        \\\"logs tail\\\" {return ,@(\\\"logs\\\", \\\"--tail\\\", \\\"100\\\")}\\n        \\\"previous logs\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\")}\\n        \\\"previous logs tail\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\", \\\"--tail\\\", \\\"100\\\")}\\n        default {return ,@(\\\"get\\\")}\\n    }\\n}\\n\\n<#\\n.Description\\nGet an appropiate file extension based on the selected action\\n#>\\nfunction Get-ArtifactExtension() \\n{\\n   switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {\\\"json\\\"}\\n        \\\"get yaml\\\" {\\\"yaml\\\"}\\n        default {\\\"txt\\\"}\\n    }\\n}\\n\\nif ($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"] -like \\\"*logs*\\\") \\n{\\n    if ( -not @($OctopusParameters[\\\"K8SInspectResource\\\"]) -like \\\"pod*\\\")\\n    {\\n        Write-Error \\\"Logs can only be returned for pods, not $($OctopusParameters[\\\"K8SInspectResource\\\"])\\\"\\n    }\\n    else\\n    {\\n        Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", \\\"pods\\\") + (Get-Resources)) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Get the pod logs for each container\\n            % {\\n                $podDetails = $_\\n                @{\\n                    logs=$podDetails.spec.containers | % {$logs=\\\"\\\"} {$logs += (Select-Object -InputObject (Execute-Command kubectl ((Get-KubectlVerb) + @($podDetails.metadata.name, \\\"-c\\\", $_.name))) -ExpandProperty stdout)} {$logs}; \\n                    name=$podDetails.metadata.name\\n                }                \\n            } |\\n            # Write the output\\n            % {Write-Host $_.logs; $_} |\\n            # Optionally capture the artifact\\n            % {\\n                if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n                {\\n                    Set-Content -Path \\\"$($_.name).$(Get-ArtifactExtension)\\\" -Value $_.logs\\n                    New-OctopusArtifact \\\"$($_.name).$(Get-ArtifactExtension)\\\"\\n                }\\n            }\\n    }      \\n}\\nelse\\n{\\n    Execute-Command kubectl ((Get-KubectlVerb) + @($OctopusParameters[\\\"K8SInspectResource\\\"]) + (Get-Resources)) |\\n        % {Select-Object -InputObject $_ -ExpandProperty stdout} |\\n        % {Write-Host $_; $_} |\\n        % {\\n            if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n            {\\n                Set-Content -Path \\\"output.$(Get-ArtifactExtension)\\\" -Value $_\\n                New-OctopusArtifact \\\"output.$(Get-ArtifactExtension)\\\"\\n            }\\n        }\\n}\\n\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"K8SInspectResource\"                            = \"pod\"\n        \"Octopus.Action.Script.Syntax\"                  = \"PowerShell\"\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{if K8SInspectNamespace}#{K8SInspectNamespace}#{/if}#{unless K8SInspectNamespace}#{Octopus.Action.Kubernetes.Namespace}#{/unless}\"\n        \"K8SInspectNames\"                               = \"#{Kubernetes.Deployment.Name}*\"\n        \"K8SInspectKubectlVerb\"                         = \"describe\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_products_get_ingress\" {\n  count             = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  name              = \"🛠️ Get Ingress\"\n  project_id        = octopusdeploy_project.project_octopub_products[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Returns the ingresses.\n\n**Affects**: Nothing - this runbook makes no changes.\n\n**Resolves**: Finding the public IP to access the deployed application.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_products_get_ingress\" {\n  count      = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_products_get_ingress[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Get Ingress\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Get Ingress\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"K8SInspectCreateArtifact\"                      = \"False\"\n        \"Octopus.Action.Script.ScriptBody\"              = \"<#\\n    This script provides a general purpose method for querying Kubernetes resources. It supports common operations\\n    like get, describe, logs and output formats like yaml and json. Output can be captured as artifacts.\\n#>\\n\\n<#\\n.Description\\nExecute an application, capturing the output. Based on https://stackoverflow.com/a/33652732/157605\\n#>\\nFunction Execute-Command ($commandPath, $commandArguments)\\n{\\n  Write-Host \\\"Executing: $commandPath $($commandArguments -join \\\" \\\")\\\"\\n  \\n  Try {\\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\\n    $pinfo.FileName = $commandPath\\n    $pinfo.RedirectStandardError = $true\\n    $pinfo.RedirectStandardOutput = $true\\n    $pinfo.UseShellExecute = $false\\n    $pinfo.Arguments = $commandArguments\\n    $p = New-Object System.Diagnostics.Process\\n    $p.StartInfo = $pinfo\\n    $p.Start() | Out-Null\\n    [pscustomobject]@{\\n        stdout = $p.StandardOutput.ReadToEnd()\\n        stderr = $p.StandardError.ReadToEnd()\\n        ExitCode = $p.ExitCode\\n    }\\n    $p.WaitForExit()\\n  }\\n  Catch {\\n     exit\\n  }\\n}\\n\\n<#\\n.Description\\nFind any resource names that match a wildcard input if one was specified\\n#>\\nfunction Get-Resources() \\n{\\n    $names = $OctopusParameters[\\\"K8SInspectNames\\\"] -Split \\\"`n\\\" | % {$_.Trim()}\\n    \\n    if ($OctopusParameters[\\\"K8SInspectNames\\\"] -match '\\\\*' )\\n    {\\n        return Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", $OctopusParameters[\\\"K8SInspectResource\\\"])) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Extract the name\\n            % {$_.metadata.name} |\\n            # Find any matching resources\\n            ? {$k8sName = $_; ($names | ? {$k8sName -like $_}).Count -ne 0}\\n    }\\n    else\\n    {\\n        return $names\\n    }\\n}\\n\\n<#\\n.Description\\nGet the kubectl arguments for a given action\\n#>\\nfunction Get-KubectlVerb() \\n{\\n    switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {return ,@(\\\"-o\\\", \\\"json\\\", \\\"get\\\")}\\n        \\\"get yaml\\\" {return ,@(\\\"-o\\\", \\\"yaml\\\", \\\"get\\\")}\\n        \\\"describe\\\" {return ,@(\\\"describe\\\")}\\n        \\\"logs\\\" {return ,@(\\\"logs\\\")}\\n        \\\"logs tail\\\" {return ,@(\\\"logs\\\", \\\"--tail\\\", \\\"100\\\")}\\n        \\\"previous logs\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\")}\\n        \\\"previous logs tail\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\", \\\"--tail\\\", \\\"100\\\")}\\n        default {return ,@(\\\"get\\\")}\\n    }\\n}\\n\\n<#\\n.Description\\nGet an appropiate file extension based on the selected action\\n#>\\nfunction Get-ArtifactExtension() \\n{\\n   switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {\\\"json\\\"}\\n        \\\"get yaml\\\" {\\\"yaml\\\"}\\n        default {\\\"txt\\\"}\\n    }\\n}\\n\\nif ($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"] -like \\\"*logs*\\\") \\n{\\n    if ( -not @($OctopusParameters[\\\"K8SInspectResource\\\"]) -like \\\"pod*\\\")\\n    {\\n        Write-Error \\\"Logs can only be returned for pods, not $($OctopusParameters[\\\"K8SInspectResource\\\"])\\\"\\n    }\\n    else\\n    {\\n        Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", \\\"pods\\\") + (Get-Resources)) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Get the pod logs for each container\\n            % {\\n                $podDetails = $_\\n                @{\\n                    logs=$podDetails.spec.containers | % {$logs=\\\"\\\"} {$logs += (Select-Object -InputObject (Execute-Command kubectl ((Get-KubectlVerb) + @($podDetails.metadata.name, \\\"-c\\\", $_.name))) -ExpandProperty stdout)} {$logs}; \\n                    name=$podDetails.metadata.name\\n                }                \\n            } |\\n            # Write the output\\n            % {Write-Host $_.logs; $_} |\\n            # Optionally capture the artifact\\n            % {\\n                if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n                {\\n                    Set-Content -Path \\\"$($_.name).$(Get-ArtifactExtension)\\\" -Value $_.logs\\n                    New-OctopusArtifact \\\"$($_.name).$(Get-ArtifactExtension)\\\"\\n                }\\n            }\\n    }      \\n}\\nelse\\n{\\n    Execute-Command kubectl ((Get-KubectlVerb) + @($OctopusParameters[\\\"K8SInspectResource\\\"]) + (Get-Resources)) |\\n        % {Select-Object -InputObject $_ -ExpandProperty stdout} |\\n        % {Write-Host $_; $_} |\\n        % {\\n            if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n            {\\n                Set-Content -Path \\\"output.$(Get-ArtifactExtension)\\\" -Value $_\\n                New-OctopusArtifact \\\"output.$(Get-ArtifactExtension)\\\"\\n            }\\n        }\\n}\\n\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"K8SInspectResource\"                            = \"ingress\"\n        \"Octopus.Action.Script.Syntax\"                  = \"PowerShell\"\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{if K8SInspectNamespace}#{K8SInspectNamespace}#{/if}#{unless K8SInspectNamespace}#{Octopus.Action.Kubernetes.Namespace}#{/unless}\"\n        \"K8SInspectNames\"                               = \"#{Kubernetes.Ingress.Name}*\"\n        \"K8SInspectKubectlVerb\"                         = \"get\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_products_get_service\" {\n  count             = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  name              = \"🛠️ Get Service\"\n  project_id        = octopusdeploy_project.project_octopub_products[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Returns the services.\n\n**Affects**: Nothing - this runbook makes no changes.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_products_get_service\" {\n  count      = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_products_get_service[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Get Service\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Get Service\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"K8SInspectCreateArtifact\"                      = \"False\"\n        \"Octopus.Action.Script.ScriptBody\"              = \"<#\\n    This script provides a general purpose method for querying Kubernetes resources. It supports common operations\\n    like get, describe, logs and output formats like yaml and json. Output can be captured as artifacts.\\n#>\\n\\n<#\\n.Description\\nExecute an application, capturing the output. Based on https://stackoverflow.com/a/33652732/157605\\n#>\\nFunction Execute-Command ($commandPath, $commandArguments)\\n{\\n  Write-Host \\\"Executing: $commandPath $($commandArguments -join \\\" \\\")\\\"\\n  \\n  Try {\\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\\n    $pinfo.FileName = $commandPath\\n    $pinfo.RedirectStandardError = $true\\n    $pinfo.RedirectStandardOutput = $true\\n    $pinfo.UseShellExecute = $false\\n    $pinfo.Arguments = $commandArguments\\n    $p = New-Object System.Diagnostics.Process\\n    $p.StartInfo = $pinfo\\n    $p.Start() | Out-Null\\n    [pscustomobject]@{\\n        stdout = $p.StandardOutput.ReadToEnd()\\n        stderr = $p.StandardError.ReadToEnd()\\n        ExitCode = $p.ExitCode\\n    }\\n    $p.WaitForExit()\\n  }\\n  Catch {\\n     exit\\n  }\\n}\\n\\n<#\\n.Description\\nFind any resource names that match a wildcard input if one was specified\\n#>\\nfunction Get-Resources() \\n{\\n    $names = $OctopusParameters[\\\"K8SInspectNames\\\"] -Split \\\"`n\\\" | % {$_.Trim()}\\n    \\n    if ($OctopusParameters[\\\"K8SInspectNames\\\"] -match '\\\\*' )\\n    {\\n        return Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", $OctopusParameters[\\\"K8SInspectResource\\\"])) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Extract the name\\n            % {$_.metadata.name} |\\n            # Find any matching resources\\n            ? {$k8sName = $_; ($names | ? {$k8sName -like $_}).Count -ne 0}\\n    }\\n    else\\n    {\\n        return $names\\n    }\\n}\\n\\n<#\\n.Description\\nGet the kubectl arguments for a given action\\n#>\\nfunction Get-KubectlVerb() \\n{\\n    switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {return ,@(\\\"-o\\\", \\\"json\\\", \\\"get\\\")}\\n        \\\"get yaml\\\" {return ,@(\\\"-o\\\", \\\"yaml\\\", \\\"get\\\")}\\n        \\\"describe\\\" {return ,@(\\\"describe\\\")}\\n        \\\"logs\\\" {return ,@(\\\"logs\\\")}\\n        \\\"logs tail\\\" {return ,@(\\\"logs\\\", \\\"--tail\\\", \\\"100\\\")}\\n        \\\"previous logs\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\")}\\n        \\\"previous logs tail\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\", \\\"--tail\\\", \\\"100\\\")}\\n        default {return ,@(\\\"get\\\")}\\n    }\\n}\\n\\n<#\\n.Description\\nGet an appropiate file extension based on the selected action\\n#>\\nfunction Get-ArtifactExtension() \\n{\\n   switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {\\\"json\\\"}\\n        \\\"get yaml\\\" {\\\"yaml\\\"}\\n        default {\\\"txt\\\"}\\n    }\\n}\\n\\nif ($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"] -like \\\"*logs*\\\") \\n{\\n    if ( -not @($OctopusParameters[\\\"K8SInspectResource\\\"]) -like \\\"pod*\\\")\\n    {\\n        Write-Error \\\"Logs can only be returned for pods, not $($OctopusParameters[\\\"K8SInspectResource\\\"])\\\"\\n    }\\n    else\\n    {\\n        Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", \\\"pods\\\") + (Get-Resources)) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Get the pod logs for each container\\n            % {\\n                $podDetails = $_\\n                @{\\n                    logs=$podDetails.spec.containers | % {$logs=\\\"\\\"} {$logs += (Select-Object -InputObject (Execute-Command kubectl ((Get-KubectlVerb) + @($podDetails.metadata.name, \\\"-c\\\", $_.name))) -ExpandProperty stdout)} {$logs}; \\n                    name=$podDetails.metadata.name\\n                }                \\n            } |\\n            # Write the output\\n            % {Write-Host $_.logs; $_} |\\n            # Optionally capture the artifact\\n            % {\\n                if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n                {\\n                    Set-Content -Path \\\"$($_.name).$(Get-ArtifactExtension)\\\" -Value $_.logs\\n                    New-OctopusArtifact \\\"$($_.name).$(Get-ArtifactExtension)\\\"\\n                }\\n            }\\n    }      \\n}\\nelse\\n{\\n    Execute-Command kubectl ((Get-KubectlVerb) + @($OctopusParameters[\\\"K8SInspectResource\\\"]) + (Get-Resources)) |\\n        % {Select-Object -InputObject $_ -ExpandProperty stdout} |\\n        % {Write-Host $_; $_} |\\n        % {\\n            if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n            {\\n                Set-Content -Path \\\"output.$(Get-ArtifactExtension)\\\" -Value $_\\n                New-OctopusArtifact \\\"output.$(Get-ArtifactExtension)\\\"\\n            }\\n        }\\n}\\n\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"K8SInspectResource\"                            = \"service\"\n        \"Octopus.Action.Script.Syntax\"                  = \"PowerShell\"\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{if K8SInspectNamespace}#{K8SInspectNamespace}#{/if}#{unless K8SInspectNamespace}#{Octopus.Action.Kubernetes.Namespace}#{/unless}\"\n        \"K8SInspectNames\"                               = \"#{Kubernetes.Service.Name}*\"\n        \"K8SInspectKubectlVerb\"                         = \"get\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_products_get_deployment\" {\n  count             = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  name              = \"🛠️ Get Deployment\"\n  project_id        = octopusdeploy_project.project_octopub_products[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Returns the deployments.\n\n**Affects**: Nothing - this runbook makes no changes.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_products_get_deployment\" {\n  count      = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_products_get_deployment[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Get Deployment\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Get Deployment\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"K8SInspectCreateArtifact\"                      = \"False\"\n        \"Octopus.Action.Script.ScriptBody\"              = \"<#\\n    This script provides a general purpose method for querying Kubernetes resources. It supports common operations\\n    like get, describe, logs and output formats like yaml and json. Output can be captured as artifacts.\\n#>\\n\\n<#\\n.Description\\nExecute an application, capturing the output. Based on https://stackoverflow.com/a/33652732/157605\\n#>\\nFunction Execute-Command ($commandPath, $commandArguments)\\n{\\n  Write-Host \\\"Executing: $commandPath $($commandArguments -join \\\" \\\")\\\"\\n  \\n  Try {\\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\\n    $pinfo.FileName = $commandPath\\n    $pinfo.RedirectStandardError = $true\\n    $pinfo.RedirectStandardOutput = $true\\n    $pinfo.UseShellExecute = $false\\n    $pinfo.Arguments = $commandArguments\\n    $p = New-Object System.Diagnostics.Process\\n    $p.StartInfo = $pinfo\\n    $p.Start() | Out-Null\\n    [pscustomobject]@{\\n        stdout = $p.StandardOutput.ReadToEnd()\\n        stderr = $p.StandardError.ReadToEnd()\\n        ExitCode = $p.ExitCode\\n    }\\n    $p.WaitForExit()\\n  }\\n  Catch {\\n     exit\\n  }\\n}\\n\\n<#\\n.Description\\nFind any resource names that match a wildcard input if one was specified\\n#>\\nfunction Get-Resources() \\n{\\n    $names = $OctopusParameters[\\\"K8SInspectNames\\\"] -Split \\\"`n\\\" | % {$_.Trim()}\\n    \\n    if ($OctopusParameters[\\\"K8SInspectNames\\\"] -match '\\\\*' )\\n    {\\n        return Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", $OctopusParameters[\\\"K8SInspectResource\\\"])) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Extract the name\\n            % {$_.metadata.name} |\\n            # Find any matching resources\\n            ? {$k8sName = $_; ($names | ? {$k8sName -like $_}).Count -ne 0}\\n    }\\n    else\\n    {\\n        return $names\\n    }\\n}\\n\\n<#\\n.Description\\nGet the kubectl arguments for a given action\\n#>\\nfunction Get-KubectlVerb() \\n{\\n    switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {return ,@(\\\"-o\\\", \\\"json\\\", \\\"get\\\")}\\n        \\\"get yaml\\\" {return ,@(\\\"-o\\\", \\\"yaml\\\", \\\"get\\\")}\\n        \\\"describe\\\" {return ,@(\\\"describe\\\")}\\n        \\\"logs\\\" {return ,@(\\\"logs\\\")}\\n        \\\"logs tail\\\" {return ,@(\\\"logs\\\", \\\"--tail\\\", \\\"100\\\")}\\n        \\\"previous logs\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\")}\\n        \\\"previous logs tail\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\", \\\"--tail\\\", \\\"100\\\")}\\n        default {return ,@(\\\"get\\\")}\\n    }\\n}\\n\\n<#\\n.Description\\nGet an appropiate file extension based on the selected action\\n#>\\nfunction Get-ArtifactExtension() \\n{\\n   switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {\\\"json\\\"}\\n        \\\"get yaml\\\" {\\\"yaml\\\"}\\n        default {\\\"txt\\\"}\\n    }\\n}\\n\\nif ($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"] -like \\\"*logs*\\\") \\n{\\n    if ( -not @($OctopusParameters[\\\"K8SInspectResource\\\"]) -like \\\"pod*\\\")\\n    {\\n        Write-Error \\\"Logs can only be returned for pods, not $($OctopusParameters[\\\"K8SInspectResource\\\"])\\\"\\n    }\\n    else\\n    {\\n        Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", \\\"pods\\\") + (Get-Resources)) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Get the pod logs for each container\\n            % {\\n                $podDetails = $_\\n                @{\\n                    logs=$podDetails.spec.containers | % {$logs=\\\"\\\"} {$logs += (Select-Object -InputObject (Execute-Command kubectl ((Get-KubectlVerb) + @($podDetails.metadata.name, \\\"-c\\\", $_.name))) -ExpandProperty stdout)} {$logs}; \\n                    name=$podDetails.metadata.name\\n                }                \\n            } |\\n            # Write the output\\n            % {Write-Host $_.logs; $_} |\\n            # Optionally capture the artifact\\n            % {\\n                if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n                {\\n                    Set-Content -Path \\\"$($_.name).$(Get-ArtifactExtension)\\\" -Value $_.logs\\n                    New-OctopusArtifact \\\"$($_.name).$(Get-ArtifactExtension)\\\"\\n                }\\n            }\\n    }      \\n}\\nelse\\n{\\n    Execute-Command kubectl ((Get-KubectlVerb) + @($OctopusParameters[\\\"K8SInspectResource\\\"]) + (Get-Resources)) |\\n        % {Select-Object -InputObject $_ -ExpandProperty stdout} |\\n        % {Write-Host $_; $_} |\\n        % {\\n            if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n            {\\n                Set-Content -Path \\\"output.$(Get-ArtifactExtension)\\\" -Value $_\\n                New-OctopusArtifact \\\"output.$(Get-ArtifactExtension)\\\"\\n            }\\n        }\\n}\\n\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"K8SInspectResource\"                            = \"deployment\"\n        \"Octopus.Action.Script.Syntax\"                  = \"PowerShell\"\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{if K8SInspectNamespace}#{K8SInspectNamespace}#{/if}#{unless K8SInspectNamespace}#{Octopus.Action.Kubernetes.Namespace}#{/unless}\"\n        \"K8SInspectNames\"                               = \"#{Kubernetes.Deployment.Name}*\"\n        \"K8SInspectKubectlVerb\"                         = \"get\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n#endregion\n\n#region Audits\nvariable \"audits_project_name\" {\n  type    = string\n  default = \"\"\n}\n\ndata \"octopusdeploy_projects\" \"octopub_audits\" {\n  partial_name = var.audits_project_name == \"\" ? local.audits_project_name : var.audits_project_name\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_variable\" \"audits_deployment_feed\" {\n  count        = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_audits[0].id\n  value        = local.docker_hub_feed_id\n  name         = \"Kubernetes.Deployment.Feed\"\n  type         = \"String\"\n  description  = \"The feed ID hosting the image\"\n  is_sensitive = false\n}\n\nresource \"octopusdeploy_variable\" \"audits_deployment_image\" {\n  count        = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_audits[0].id\n  value        = \"octopussamples/octopub-audit-microservice\"\n  name         = \"Kubernetes.Deployment.Image\"\n  type         = \"String\"\n  description  = \"The image to deploy\"\n  is_sensitive = false\n}\n\nresource \"octopusdeploy_variable\" \"audits_deployment_port\" {\n  count        = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_audits[0].id\n  value        = \"10000\"\n  name         = \"Kubernetes.Deployment.Port\"\n  type         = \"String\"\n  description  = \"The port exposed by the web app\"\n  is_sensitive = false\n}\n\nresource \"octopusdeploy_variable\" \"auditss_microservice_name\" {\n  count        = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_audits[0].id\n  value        = \"audits\"\n  name         = \"Microservice.Name\"\n  type         = \"String\"\n  description  = \"The microservice name, which is used as the basis for K8s resources and networking paths\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"audits_deployment_name\" {\n  count        = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_audits[0].id\n  value        = \"#{Microservice.Name}\"\n  name         = \"Kubernetes.Deployment.Name\"\n  type         = \"String\"\n  description  = \"\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"audits_service_name\" {\n  count        = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_audits[0].id\n  value        = \"#{Microservice.Name}\"\n  name         = \"Kubernetes.Service.Name\"\n  type         = \"String\"\n  description  = \"\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"audits_ingress_name\" {\n  count        = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_audits[0].id\n  value        = \"#{Microservice.Name}\"\n  name         = \"Kubernetes.Ingress.Name\"\n  type         = \"String\"\n  description  = \"\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"audits_ingress_path\" {\n  count        = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_audits[0].id\n  value        = \"/#{Kubernetes.Namespace}(/api/#{Microservice.Name})(/.*)?\"\n  name         = \"Kubernetes.Ingress.Path\"\n  type         = \"String\"\n  description  = \"The path of the Kubernetes ingress resource\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"audits_app_path\" {\n  count        = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_audits[0].id\n  value        = \"/#{Kubernetes.Namespace}/api/#{Microservice.Name}\"\n  name         = \"Kubernetes.App.HealthCheck\"\n  type         = \"String\"\n  description  = \"The path to perform a health check on.\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"audits_namespace_default\" {\n  count        = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_audits[0].id\n  value        = \"#{Octopus.Action.Kubernetes.Namespace}\"\n  name         = \"Kubernetes.Namespace\"\n  type         = \"String\"\n  description  = \"The namespace to perform the deployments in.\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"audits_namespace_featurebranch\" {\n  count        = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project_octopub_audits[0].id\n  value        = \"\"\n  name         = \"Kubernetes.Namespace\"\n  type         = \"String\"\n  description  = \"The custom namespace to use when deploying a feature branch\"\n  is_sensitive = false\n\n  scope {\n    actions      = []\n    channels     = []\n    environments = [local.featurebranch_environment_id]\n    machines     = []\n    roles        = null\n    tenant_tags  = null\n  }\n\n  prompt {\n    description = \"Feature branch namespace\"\n    label       = \"Namespace\"\n    is_required = true\n    display_settings {\n      control_type = \"SingleLineText\"\n    }\n  }\n}\n\nresource \"octopusdeploy_channel\" \"audits_featurebranch\" {\n  count        = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  name         = \"Feature Branch\"\n  project_id   = octopusdeploy_project.project_octopub_audits[0].id\n  description  = \"Deploy feature branch builds\"\n  is_default   = false\n  lifecycle_id = local.featurebranch_lifecycle_id\n}\n\nresource \"octopusdeploy_channel\" \"audits_mainline\" {\n  count        = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  name         = \"Mainline\"\n  project_id   = octopusdeploy_project.project_octopub_audits[0].id\n  description  = \"Deploy mainline builds\"\n  is_default   = true\n  lifecycle_id = local.devops_lifecycle_id\n  rule {\n    tag = \"^$\"\n    action_package {\n      deployment_action = \"Deploy Container\"\n      package_reference = \"web\"\n    }\n  }\n\n  depends_on  = [octopusdeploy_deployment_process.deployment_process_octopub_audits]\n}\n\nresource \"octopusdeploy_project\" \"project_octopub_audits\" {\n  count                                = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  name                                 = var.audits_project_name == \"\" ? local.audits_project_name : var.audits_project_name\n  auto_create_release                  = false\n  default_guided_failure_mode          = \"Off\"\n  default_to_skip_if_already_installed = false\n  discrete_channel_release             = false\n  is_disabled                          = false\n  is_version_controlled                = false\n  lifecycle_id                         = local.devops_lifecycle_id\n  project_group_id                     = local.eks_project_group_id\n  included_library_variable_sets       = [local.this_instance_library_variable_set, local.github_library_variable_set]\n  tenanted_deployment_participation    = \"Untenanted\"\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n\n  versioning_strategy {\n    template = \"#{Octopus.Version.LastMajor}.#{Octopus.Version.LastMinor}.#{Octopus.Version.NextPatch}\"\n  }\n\n  lifecycle {\n    ignore_changes = []\n  }\n  description = <<EOT\nDeploys the Octopub Audits Service\n\n**Source**: [GitHub](https://github.com/OctopusSolutionsEngineering/Octopub)\n\n**Build**: [GitHub Actions](https://github.com/OctopusSolutionsEngineering/Octopub/actions)\n\n**Issues**: [GitHub Issues](https://github.com/OctopusSolutionsEngineering/Octopub/issues)\nEOT\n}\n\nresource \"octopusdeploy_deployment_process\" \"deployment_process_octopub_audits\" {\n  count      = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  project_id = octopusdeploy_project.project_octopub_audits[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Generate Variables\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Generate Variables\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = local.variable_script\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Deploy Container\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesDeployContainers\"\n      name                               = \"Deploy Container\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.KubernetesContainers.Namespace\"              = \"#{Kubernetes.Namespace}\"\n        \"Octopus.Action.KubernetesContainers.Replicas\"               = \"1\"\n        \"Octopus.Action.KubernetesContainers.DeploymentResourceType\" = \"Deployment\"\n        \"Octopus.Action.KubernetesContainers.IngressAnnotations\"     = jsonencode([\n          {\n            \"optionError\"  = null\n            \"option2\"      = \"\"\n            \"option2Error\" = null\n            \"key\"          = \"nginx.ingress.kubernetes.io/rewrite-target\"\n            \"keyError\"     = null\n            \"value\"        = \"$1$2\"\n            \"valueError\"   = null\n            \"option\"       = \"\"\n          },\n          {\n            \"keyError\"     = null\n            \"value\"        = \"true\"\n            \"valueError\"   = null\n            \"option\"       = \"\"\n            \"optionError\"  = null\n            \"option2\"      = \"\"\n            \"option2Error\" = null\n            \"key\"          = \"nginx.ingress.kubernetes.io/use-regex\"\n          },\n        ])\n        \"Octopus.Action.KubernetesContainers.DeploymentStyle\" = \"RollingUpdate\"\n        \"Octopus.Action.KubernetesContainers.IngressName\"     = \"#{Kubernetes.Ingress.Name}\"\n        \"Octopus.Action.KubernetesContainers.DeploymentName\"  = \"#{Kubernetes.Deployment.Name}\"\n        \"Octopus.Action.KubernetesContainers.IngressRules\"    = jsonencode([\n          {\n            \"host\" = \"\"\n            \"http\" = {\n              \"paths\" = [\n                {\n                  \"key\"     = \"#{Kubernetes.Ingress.Path}\"\n                  \"value\"   = \"web\"\n                  \"option\"  = \"\"\n                  \"option2\" = \"ImplementationSpecific\"\n                },\n              ]\n            }\n          },\n        ])\n        \"OctopusUseBundledTooling\"                       = \"False\"\n        \"Octopus.Action.KubernetesContainers.Containers\" = jsonencode([\n          {\n            \"Args\"                         = []\n            \"FieldRefEnvironmentVariables\" = []\n            \"SecretEnvFromSource\"          = []\n            \"Command\"                      = []\n            \"Ports\"                        = [\n              {\n                \"option2Error\" = null\n                \"optionError\"  = null\n                \"value\"        = \"#{Kubernetes.Deployment.Port}\"\n                \"valueError\"   = null\n                \"key\"          = \"web\"\n                \"keyError\"     = null\n                \"option\"       = \"TCP\"\n                \"option2\"      = \"\"\n              },\n            ]\n            \"Resources\" = {\n              \"limits\" = {\n                \"storage\"          = \"\"\n                \"amdGpu\"           = \"\"\n                \"cpu\"              = \"\"\n                \"ephemeralStorage\" = \"\"\n                \"memory\"           = \"\"\n                \"nvidiaGpu\"        = \"\"\n              }\n              \"requests\" = {\n                \"amdGpu\"           = \"\"\n                \"cpu\"              = \"\"\n                \"ephemeralStorage\" = \"\"\n                \"memory\"           = \"\"\n                \"nvidiaGpu\"        = \"\"\n                \"storage\"          = \"\"\n              }\n            }\n            \"SecretEnvironmentVariables\" = []\n            \"SecurityContext\"            = {\n              \"runAsNonRoot\"   = \"True\"\n              \"runAsUser\"      = \"\"\n              \"seLinuxOptions\" = {\n                \"level\" = \"\"\n                \"role\"  = \"\"\n                \"type\"  = \"\"\n                \"user\"  = \"\"\n              }\n              \"allowPrivilegeEscalation\" = \"\"\n              \"capabilities\"             = {\n                \"add\"  = []\n                \"drop\" = [\n                  \"ALL\",\n                ]\n              }\n              \"privileged\"             = \"\"\n              \"readOnlyRootFilesystem\" = \"\"\n              \"runAsGroup\"             = \"\"\n            }\n            \"TerminationMessagePath\" = \"\"\n            \"EnvironmentVariables\"   = [\n              {\n                \"key\"          = \"PORT\"\n                \"keyError\"     = null\n                \"value\"        = \"#{Kubernetes.Deployment.Port}\"\n                \"valueError\"   = null\n                \"option\"       = \"\"\n                \"optionError\"  = null\n                \"option2\"      = \"\"\n                \"option2Error\" = null\n              },\n              {\n                \"key\"          = \"COGNITO_DISABLE_AUTH\"\n                \"keyError\"     = null\n                \"value\"        = \"True\"\n                \"valueError\"   = null\n                \"option\"       = \"\"\n                \"optionError\"  = null\n                \"option2\"      = \"\"\n                \"option2Error\" = null\n              },\n              {\n                \"key\"          = \"MIGRATE_AT_START\"\n                \"keyError\"     = null\n                \"value\"        = \"True\"\n                \"valueError\"   = null\n                \"option\"       = \"\"\n                \"optionError\"  = null\n                \"option2\"      = \"\"\n                \"option2Error\" = null\n              },\n            ]\n            \"LivenessProbe\" = {\n              \"successThreshold\" = \"\"\n              \"tcpSocket\"        = {\n                \"port\" = \"\"\n                \"host\" = \"\"\n              }\n              \"exec\" = {\n                \"command\" = []\n              }\n              \"failureThreshold\" = \"\"\n              \"periodSeconds\"    = \"\"\n              \"type\"             = \"\"\n              \"httpGet\"          = {\n                \"host\"        = \"\"\n                \"httpHeaders\" = []\n                \"path\"        = \"\"\n                \"port\"        = \"\"\n                \"scheme\"      = \"\"\n              }\n              \"initialDelaySeconds\" = \"\"\n              \"timeoutSeconds\"      = \"\"\n            }\n            \"ReadinessProbe\" = {\n              \"exec\" = {\n                \"command\" = []\n              }\n              \"failureThreshold\" = \"\"\n              \"timeoutSeconds\"   = \"\"\n              \"successThreshold\" = \"\"\n              \"tcpSocket\"        = {\n                \"host\" = \"\"\n                \"port\" = \"\"\n              }\n              \"type\"    = \"\"\n              \"httpGet\" = {\n                \"host\"        = \"\"\n                \"httpHeaders\" = []\n                \"path\"        = \"\"\n                \"port\"        = \"\"\n                \"scheme\"      = \"\"\n              }\n              \"initialDelaySeconds\" = \"\"\n              \"periodSeconds\"       = \"\"\n            }\n            \"TerminationMessagePolicy\"      = \"\"\n            \"VolumeMounts\"                  = []\n            \"ConfigMapEnvFromSource\"        = []\n            \"ConfigMapEnvironmentVariables\" = []\n            \"CreateFeedSecrets\"             = \"False\"\n            \"Lifecycle\"                     = {\n              \"PostStart\" = null\n              \"PreStop\"   = null\n            }\n            \"Name\"         = \"web\"\n            \"StartupProbe\" = {\n              \"successThreshold\" = \"\"\n              \"tcpSocket\"        = {\n                \"host\" = \"\"\n                \"port\" = \"\"\n              }\n              \"failureThreshold\" = \"\"\n              \"httpGet\"          = {\n                \"host\"        = \"\"\n                \"httpHeaders\" = []\n                \"path\"        = \"\"\n                \"port\"        = \"\"\n                \"scheme\"      = \"\"\n              }\n              \"initialDelaySeconds\" = \"\"\n              \"type\"                = \"\"\n              \"exec\"                = {\n                \"command\" = []\n              }\n              \"periodSeconds\"  = \"\"\n              \"timeoutSeconds\" = \"\"\n            }\n          },\n        ])\n        \"Octopus.Action.KubernetesContainers.ServiceName\"         = \"#{Kubernetes.Service.Name}\"\n        \"Octopus.Action.KubernetesContainers.PodManagementPolicy\" = \"OrderedReady\"\n        \"Octopus.Action.Kubernetes.DeploymentTimeout\"             = \"180\"\n        \"Octopus.Action.RunOnServer\"                              = \"true\"\n        \"Octopus.Action.KubernetesContainers.IngressClassName\"    = \"nginx\"\n        \"Octopus.Action.KubernetesContainers.ServicePorts\"        = jsonencode([\n          {\n            \"port\"       = \"80\"\n            \"protocol\"   = \"TCP\"\n            \"targetPort\" = \"web\"\n            \"name\"       = \"web\"\n            \"nodePort\"   = \"\"\n          },\n        ])\n        \"Octopus.Action.Kubernetes.ResourceStatusCheck\"       = \"True\"\n        \"Octopus.Action.KubernetesContainers.ServiceNameType\" = \"External\"\n        \"Octopus.Action.KubernetesContainers.ServiceType\"     = \"ClusterIP\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n        local.featurebranch_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n\n      package {\n        name                      = \"web\"\n        package_id                = \"#{Kubernetes.Deployment.Image}\"\n        acquisition_location      = \"NotAcquired\"\n        extract_during_deployment = false\n        feed_id                   = \"#{Kubernetes.Deployment.Feed}\"\n        properties                = { Extract = \"False\", PackageParameterName = \"\", SelectionMode = \"immediate\" }\n      }\n      features = [\n        \"\", \"Octopus.Features.KubernetesService\", \"Octopus.Features.KubernetesIngress\",\n        \"Octopus.Features.KubernetesConfigMap\", \"Octopus.Features.KubernetesSecret\"\n      ]\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Smoke Test\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Smoke Test\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{Kubernetes.Namespace}\"\n        \"Octopus.Action.RunOnServer\"                    = \"true\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"                  = \"Bash\"\n        \"Octopus.Action.Script.ScriptBody\"              = local.smoke_test\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n        local.featurebranch_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Security Scan\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Security Scan\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"Bash\"\n        \"Octopus.Action.Script.ScriptBody\"   = local.security_scan_script\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_audits_get_pod_logs\" {\n  count             = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  name              = \"🛠️ Get Pod Logs\"\n  project_id        = octopusdeploy_project.project_octopub_audits[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Returns the pod logs.\n\n**Affects**: Nothing - this runbook makes no changes.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_audits_get_pod_logs\" {\n  count      = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_audits_get_pod_logs[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Get Pod Logs\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Get Pod Logs\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"K8SInspectCreateArtifact\"                      = \"False\"\n        \"Octopus.Action.Script.ScriptBody\"              = \"<#\\n    This script provides a general purpose method for querying Kubernetes resources. It supports common operations\\n    like get, describe, logs and output formats like yaml and json. Output can be captured as artifacts.\\n#>\\n\\n<#\\n.Description\\nExecute an application, capturing the output. Based on https://stackoverflow.com/a/33652732/157605\\n#>\\nFunction Execute-Command ($commandPath, $commandArguments)\\n{\\n  Write-Host \\\"Executing: $commandPath $($commandArguments -join \\\" \\\")\\\"\\n  \\n  Try {\\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\\n    $pinfo.FileName = $commandPath\\n    $pinfo.RedirectStandardError = $true\\n    $pinfo.RedirectStandardOutput = $true\\n    $pinfo.UseShellExecute = $false\\n    $pinfo.Arguments = $commandArguments\\n    $p = New-Object System.Diagnostics.Process\\n    $p.StartInfo = $pinfo\\n    $p.Start() | Out-Null\\n    [pscustomobject]@{\\n        stdout = $p.StandardOutput.ReadToEnd()\\n        stderr = $p.StandardError.ReadToEnd()\\n        ExitCode = $p.ExitCode\\n    }\\n    $p.WaitForExit()\\n  }\\n  Catch {\\n     exit\\n  }\\n}\\n\\n<#\\n.Description\\nFind any resource names that match a wildcard input if one was specified\\n#>\\nfunction Get-Resources() \\n{\\n    $names = $OctopusParameters[\\\"K8SInspectNames\\\"] -Split \\\"`n\\\" | % {$_.Trim()}\\n    \\n    if ($OctopusParameters[\\\"K8SInspectNames\\\"] -match '\\\\*' )\\n    {\\n        return Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", $OctopusParameters[\\\"K8SInspectResource\\\"])) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Extract the name\\n            % {$_.metadata.name} |\\n            # Find any matching resources\\n            ? {$k8sName = $_; ($names | ? {$k8sName -like $_}).Count -ne 0}\\n    }\\n    else\\n    {\\n        return $names\\n    }\\n}\\n\\n<#\\n.Description\\nGet the kubectl arguments for a given action\\n#>\\nfunction Get-KubectlVerb() \\n{\\n    switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {return ,@(\\\"-o\\\", \\\"json\\\", \\\"get\\\")}\\n        \\\"get yaml\\\" {return ,@(\\\"-o\\\", \\\"yaml\\\", \\\"get\\\")}\\n        \\\"describe\\\" {return ,@(\\\"describe\\\")}\\n        \\\"logs\\\" {return ,@(\\\"logs\\\")}\\n        \\\"logs tail\\\" {return ,@(\\\"logs\\\", \\\"--tail\\\", \\\"100\\\")}\\n        \\\"previous logs\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\")}\\n        \\\"previous logs tail\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\", \\\"--tail\\\", \\\"100\\\")}\\n        default {return ,@(\\\"get\\\")}\\n    }\\n}\\n\\n<#\\n.Description\\nGet an appropiate file extension based on the selected action\\n#>\\nfunction Get-ArtifactExtension() \\n{\\n   switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {\\\"json\\\"}\\n        \\\"get yaml\\\" {\\\"yaml\\\"}\\n        default {\\\"txt\\\"}\\n    }\\n}\\n\\nif ($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"] -like \\\"*logs*\\\") \\n{\\n    if ( -not @($OctopusParameters[\\\"K8SInspectResource\\\"]) -like \\\"pod*\\\")\\n    {\\n        Write-Error \\\"Logs can only be returned for pods, not $($OctopusParameters[\\\"K8SInspectResource\\\"])\\\"\\n    }\\n    else\\n    {\\n        Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", \\\"pods\\\") + (Get-Resources)) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Get the pod logs for each container\\n            % {\\n                $podDetails = $_\\n                @{\\n                    logs=$podDetails.spec.containers | % {$logs=\\\"\\\"} {$logs += (Select-Object -InputObject (Execute-Command kubectl ((Get-KubectlVerb) + @($podDetails.metadata.name, \\\"-c\\\", $_.name))) -ExpandProperty stdout)} {$logs}; \\n                    name=$podDetails.metadata.name\\n                }                \\n            } |\\n            # Write the output\\n            % {Write-Host $_.logs; $_} |\\n            # Optionally capture the artifact\\n            % {\\n                if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n                {\\n                    Set-Content -Path \\\"$($_.name).$(Get-ArtifactExtension)\\\" -Value $_.logs\\n                    New-OctopusArtifact \\\"$($_.name).$(Get-ArtifactExtension)\\\"\\n                }\\n            }\\n    }      \\n}\\nelse\\n{\\n    Execute-Command kubectl ((Get-KubectlVerb) + @($OctopusParameters[\\\"K8SInspectResource\\\"]) + (Get-Resources)) |\\n        % {Select-Object -InputObject $_ -ExpandProperty stdout} |\\n        % {Write-Host $_; $_} |\\n        % {\\n            if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n            {\\n                Set-Content -Path \\\"output.$(Get-ArtifactExtension)\\\" -Value $_\\n                New-OctopusArtifact \\\"output.$(Get-ArtifactExtension)\\\"\\n            }\\n        }\\n}\\n\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"K8SInspectResource\"                            = \"pod\"\n        \"Octopus.Action.Script.Syntax\"                  = \"PowerShell\"\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{if K8SInspectNamespace}#{K8SInspectNamespace}#{/if}#{unless K8SInspectNamespace}#{Octopus.Action.Kubernetes.Namespace}#{/unless}\"\n        \"K8SInspectNames\"                               = \"#{Kubernetes.Deployment.Name}*\"\n        \"K8SInspectKubectlVerb\"                         = \"logs\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_audits_get_pods\" {\n  count             = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  name              = \"🛠️ Get Pods\"\n  project_id        = octopusdeploy_project.project_octopub_audits[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Returns the pods.\n\n**Affects**: Nothing - this runbook makes no changes.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_audits_get_pods\" {\n  count      = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_audits_get_pods[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Get Pods\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Get Pods\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"K8SInspectCreateArtifact\"                      = \"False\"\n        \"Octopus.Action.Script.ScriptBody\"              = \"<#\\n    This script provides a general purpose method for querying Kubernetes resources. It supports common operations\\n    like get, describe, logs and output formats like yaml and json. Output can be captured as artifacts.\\n#>\\n\\n<#\\n.Description\\nExecute an application, capturing the output. Based on https://stackoverflow.com/a/33652732/157605\\n#>\\nFunction Execute-Command ($commandPath, $commandArguments)\\n{\\n  Write-Host \\\"Executing: $commandPath $($commandArguments -join \\\" \\\")\\\"\\n  \\n  Try {\\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\\n    $pinfo.FileName = $commandPath\\n    $pinfo.RedirectStandardError = $true\\n    $pinfo.RedirectStandardOutput = $true\\n    $pinfo.UseShellExecute = $false\\n    $pinfo.Arguments = $commandArguments\\n    $p = New-Object System.Diagnostics.Process\\n    $p.StartInfo = $pinfo\\n    $p.Start() | Out-Null\\n    [pscustomobject]@{\\n        stdout = $p.StandardOutput.ReadToEnd()\\n        stderr = $p.StandardError.ReadToEnd()\\n        ExitCode = $p.ExitCode\\n    }\\n    $p.WaitForExit()\\n  }\\n  Catch {\\n     exit\\n  }\\n}\\n\\n<#\\n.Description\\nFind any resource names that match a wildcard input if one was specified\\n#>\\nfunction Get-Resources() \\n{\\n    $names = $OctopusParameters[\\\"K8SInspectNames\\\"] -Split \\\"`n\\\" | % {$_.Trim()}\\n    \\n    if ($OctopusParameters[\\\"K8SInspectNames\\\"] -match '\\\\*' )\\n    {\\n        return Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", $OctopusParameters[\\\"K8SInspectResource\\\"])) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Extract the name\\n            % {$_.metadata.name} |\\n            # Find any matching resources\\n            ? {$k8sName = $_; ($names | ? {$k8sName -like $_}).Count -ne 0}\\n    }\\n    else\\n    {\\n        return $names\\n    }\\n}\\n\\n<#\\n.Description\\nGet the kubectl arguments for a given action\\n#>\\nfunction Get-KubectlVerb() \\n{\\n    switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {return ,@(\\\"-o\\\", \\\"json\\\", \\\"get\\\")}\\n        \\\"get yaml\\\" {return ,@(\\\"-o\\\", \\\"yaml\\\", \\\"get\\\")}\\n        \\\"describe\\\" {return ,@(\\\"describe\\\")}\\n        \\\"logs\\\" {return ,@(\\\"logs\\\")}\\n        \\\"logs tail\\\" {return ,@(\\\"logs\\\", \\\"--tail\\\", \\\"100\\\")}\\n        \\\"previous logs\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\")}\\n        \\\"previous logs tail\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\", \\\"--tail\\\", \\\"100\\\")}\\n        default {return ,@(\\\"get\\\")}\\n    }\\n}\\n\\n<#\\n.Description\\nGet an appropiate file extension based on the selected action\\n#>\\nfunction Get-ArtifactExtension() \\n{\\n   switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {\\\"json\\\"}\\n        \\\"get yaml\\\" {\\\"yaml\\\"}\\n        default {\\\"txt\\\"}\\n    }\\n}\\n\\nif ($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"] -like \\\"*logs*\\\") \\n{\\n    if ( -not @($OctopusParameters[\\\"K8SInspectResource\\\"]) -like \\\"pod*\\\")\\n    {\\n        Write-Error \\\"Logs can only be returned for pods, not $($OctopusParameters[\\\"K8SInspectResource\\\"])\\\"\\n    }\\n    else\\n    {\\n        Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", \\\"pods\\\") + (Get-Resources)) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Get the pod logs for each container\\n            % {\\n                $podDetails = $_\\n                @{\\n                    logs=$podDetails.spec.containers | % {$logs=\\\"\\\"} {$logs += (Select-Object -InputObject (Execute-Command kubectl ((Get-KubectlVerb) + @($podDetails.metadata.name, \\\"-c\\\", $_.name))) -ExpandProperty stdout)} {$logs}; \\n                    name=$podDetails.metadata.name\\n                }                \\n            } |\\n            # Write the output\\n            % {Write-Host $_.logs; $_} |\\n            # Optionally capture the artifact\\n            % {\\n                if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n                {\\n                    Set-Content -Path \\\"$($_.name).$(Get-ArtifactExtension)\\\" -Value $_.logs\\n                    New-OctopusArtifact \\\"$($_.name).$(Get-ArtifactExtension)\\\"\\n                }\\n            }\\n    }      \\n}\\nelse\\n{\\n    Execute-Command kubectl ((Get-KubectlVerb) + @($OctopusParameters[\\\"K8SInspectResource\\\"]) + (Get-Resources)) |\\n        % {Select-Object -InputObject $_ -ExpandProperty stdout} |\\n        % {Write-Host $_; $_} |\\n        % {\\n            if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n            {\\n                Set-Content -Path \\\"output.$(Get-ArtifactExtension)\\\" -Value $_\\n                New-OctopusArtifact \\\"output.$(Get-ArtifactExtension)\\\"\\n            }\\n        }\\n}\\n\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"K8SInspectResource\"                            = \"pod\"\n        \"Octopus.Action.Script.Syntax\"                  = \"PowerShell\"\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{if K8SInspectNamespace}#{K8SInspectNamespace}#{/if}#{unless K8SInspectNamespace}#{Octopus.Action.Kubernetes.Namespace}#{/unless}\"\n        \"K8SInspectNames\"                               = \"#{Kubernetes.Deployment.Name}*\"\n        \"K8SInspectKubectlVerb\"                         = \"get\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_audits_describe_pods\" {\n  count             = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  name              = \"🛠️ Describe Pods\"\n  project_id        = octopusdeploy_project.project_octopub_audits[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Returns the pods.\n\n**Affects**: Nothing - this runbook makes no changes.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_audits_describe_pods\" {\n  count      = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_audits_describe_pods[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Describe Pods\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Describe Pods\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"K8SInspectCreateArtifact\"                      = \"False\"\n        \"Octopus.Action.Script.ScriptBody\"              = \"<#\\n    This script provides a general purpose method for querying Kubernetes resources. It supports common operations\\n    like get, describe, logs and output formats like yaml and json. Output can be captured as artifacts.\\n#>\\n\\n<#\\n.Description\\nExecute an application, capturing the output. Based on https://stackoverflow.com/a/33652732/157605\\n#>\\nFunction Execute-Command ($commandPath, $commandArguments)\\n{\\n  Write-Host \\\"Executing: $commandPath $($commandArguments -join \\\" \\\")\\\"\\n  \\n  Try {\\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\\n    $pinfo.FileName = $commandPath\\n    $pinfo.RedirectStandardError = $true\\n    $pinfo.RedirectStandardOutput = $true\\n    $pinfo.UseShellExecute = $false\\n    $pinfo.Arguments = $commandArguments\\n    $p = New-Object System.Diagnostics.Process\\n    $p.StartInfo = $pinfo\\n    $p.Start() | Out-Null\\n    [pscustomobject]@{\\n        stdout = $p.StandardOutput.ReadToEnd()\\n        stderr = $p.StandardError.ReadToEnd()\\n        ExitCode = $p.ExitCode\\n    }\\n    $p.WaitForExit()\\n  }\\n  Catch {\\n     exit\\n  }\\n}\\n\\n<#\\n.Description\\nFind any resource names that match a wildcard input if one was specified\\n#>\\nfunction Get-Resources() \\n{\\n    $names = $OctopusParameters[\\\"K8SInspectNames\\\"] -Split \\\"`n\\\" | % {$_.Trim()}\\n    \\n    if ($OctopusParameters[\\\"K8SInspectNames\\\"] -match '\\\\*' )\\n    {\\n        return Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", $OctopusParameters[\\\"K8SInspectResource\\\"])) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Extract the name\\n            % {$_.metadata.name} |\\n            # Find any matching resources\\n            ? {$k8sName = $_; ($names | ? {$k8sName -like $_}).Count -ne 0}\\n    }\\n    else\\n    {\\n        return $names\\n    }\\n}\\n\\n<#\\n.Description\\nGet the kubectl arguments for a given action\\n#>\\nfunction Get-KubectlVerb() \\n{\\n    switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {return ,@(\\\"-o\\\", \\\"json\\\", \\\"get\\\")}\\n        \\\"get yaml\\\" {return ,@(\\\"-o\\\", \\\"yaml\\\", \\\"get\\\")}\\n        \\\"describe\\\" {return ,@(\\\"describe\\\")}\\n        \\\"logs\\\" {return ,@(\\\"logs\\\")}\\n        \\\"logs tail\\\" {return ,@(\\\"logs\\\", \\\"--tail\\\", \\\"100\\\")}\\n        \\\"previous logs\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\")}\\n        \\\"previous logs tail\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\", \\\"--tail\\\", \\\"100\\\")}\\n        default {return ,@(\\\"get\\\")}\\n    }\\n}\\n\\n<#\\n.Description\\nGet an appropiate file extension based on the selected action\\n#>\\nfunction Get-ArtifactExtension() \\n{\\n   switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {\\\"json\\\"}\\n        \\\"get yaml\\\" {\\\"yaml\\\"}\\n        default {\\\"txt\\\"}\\n    }\\n}\\n\\nif ($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"] -like \\\"*logs*\\\") \\n{\\n    if ( -not @($OctopusParameters[\\\"K8SInspectResource\\\"]) -like \\\"pod*\\\")\\n    {\\n        Write-Error \\\"Logs can only be returned for pods, not $($OctopusParameters[\\\"K8SInspectResource\\\"])\\\"\\n    }\\n    else\\n    {\\n        Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", \\\"pods\\\") + (Get-Resources)) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Get the pod logs for each container\\n            % {\\n                $podDetails = $_\\n                @{\\n                    logs=$podDetails.spec.containers | % {$logs=\\\"\\\"} {$logs += (Select-Object -InputObject (Execute-Command kubectl ((Get-KubectlVerb) + @($podDetails.metadata.name, \\\"-c\\\", $_.name))) -ExpandProperty stdout)} {$logs}; \\n                    name=$podDetails.metadata.name\\n                }                \\n            } |\\n            # Write the output\\n            % {Write-Host $_.logs; $_} |\\n            # Optionally capture the artifact\\n            % {\\n                if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n                {\\n                    Set-Content -Path \\\"$($_.name).$(Get-ArtifactExtension)\\\" -Value $_.logs\\n                    New-OctopusArtifact \\\"$($_.name).$(Get-ArtifactExtension)\\\"\\n                }\\n            }\\n    }      \\n}\\nelse\\n{\\n    Execute-Command kubectl ((Get-KubectlVerb) + @($OctopusParameters[\\\"K8SInspectResource\\\"]) + (Get-Resources)) |\\n        % {Select-Object -InputObject $_ -ExpandProperty stdout} |\\n        % {Write-Host $_; $_} |\\n        % {\\n            if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n            {\\n                Set-Content -Path \\\"output.$(Get-ArtifactExtension)\\\" -Value $_\\n                New-OctopusArtifact \\\"output.$(Get-ArtifactExtension)\\\"\\n            }\\n        }\\n}\\n\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"K8SInspectResource\"                            = \"pod\"\n        \"Octopus.Action.Script.Syntax\"                  = \"PowerShell\"\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{if K8SInspectNamespace}#{K8SInspectNamespace}#{/if}#{unless K8SInspectNamespace}#{Octopus.Action.Kubernetes.Namespace}#{/unless}\"\n        \"K8SInspectNames\"                               = \"#{Kubernetes.Deployment.Name}*\"\n        \"K8SInspectKubectlVerb\"                         = \"describe\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_audits_get_ingress\" {\n  count             = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  name              = \"🛠️ Get Ingress\"\n  project_id        = octopusdeploy_project.project_octopub_audits[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Returns the ingresses.\n\n**Affects**: Nothing - this runbook makes no changes.\n\n**Resolves**: Finding the public IP to access the deployed application.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_audits_get_ingress\" {\n  count      = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_audits_get_ingress[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Get Ingress\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Get Ingress\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"K8SInspectCreateArtifact\"                      = \"False\"\n        \"Octopus.Action.Script.ScriptBody\"              = \"<#\\n    This script provides a general purpose method for querying Kubernetes resources. It supports common operations\\n    like get, describe, logs and output formats like yaml and json. Output can be captured as artifacts.\\n#>\\n\\n<#\\n.Description\\nExecute an application, capturing the output. Based on https://stackoverflow.com/a/33652732/157605\\n#>\\nFunction Execute-Command ($commandPath, $commandArguments)\\n{\\n  Write-Host \\\"Executing: $commandPath $($commandArguments -join \\\" \\\")\\\"\\n  \\n  Try {\\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\\n    $pinfo.FileName = $commandPath\\n    $pinfo.RedirectStandardError = $true\\n    $pinfo.RedirectStandardOutput = $true\\n    $pinfo.UseShellExecute = $false\\n    $pinfo.Arguments = $commandArguments\\n    $p = New-Object System.Diagnostics.Process\\n    $p.StartInfo = $pinfo\\n    $p.Start() | Out-Null\\n    [pscustomobject]@{\\n        stdout = $p.StandardOutput.ReadToEnd()\\n        stderr = $p.StandardError.ReadToEnd()\\n        ExitCode = $p.ExitCode\\n    }\\n    $p.WaitForExit()\\n  }\\n  Catch {\\n     exit\\n  }\\n}\\n\\n<#\\n.Description\\nFind any resource names that match a wildcard input if one was specified\\n#>\\nfunction Get-Resources() \\n{\\n    $names = $OctopusParameters[\\\"K8SInspectNames\\\"] -Split \\\"`n\\\" | % {$_.Trim()}\\n    \\n    if ($OctopusParameters[\\\"K8SInspectNames\\\"] -match '\\\\*' )\\n    {\\n        return Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", $OctopusParameters[\\\"K8SInspectResource\\\"])) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Extract the name\\n            % {$_.metadata.name} |\\n            # Find any matching resources\\n            ? {$k8sName = $_; ($names | ? {$k8sName -like $_}).Count -ne 0}\\n    }\\n    else\\n    {\\n        return $names\\n    }\\n}\\n\\n<#\\n.Description\\nGet the kubectl arguments for a given action\\n#>\\nfunction Get-KubectlVerb() \\n{\\n    switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {return ,@(\\\"-o\\\", \\\"json\\\", \\\"get\\\")}\\n        \\\"get yaml\\\" {return ,@(\\\"-o\\\", \\\"yaml\\\", \\\"get\\\")}\\n        \\\"describe\\\" {return ,@(\\\"describe\\\")}\\n        \\\"logs\\\" {return ,@(\\\"logs\\\")}\\n        \\\"logs tail\\\" {return ,@(\\\"logs\\\", \\\"--tail\\\", \\\"100\\\")}\\n        \\\"previous logs\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\")}\\n        \\\"previous logs tail\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\", \\\"--tail\\\", \\\"100\\\")}\\n        default {return ,@(\\\"get\\\")}\\n    }\\n}\\n\\n<#\\n.Description\\nGet an appropiate file extension based on the selected action\\n#>\\nfunction Get-ArtifactExtension() \\n{\\n   switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {\\\"json\\\"}\\n        \\\"get yaml\\\" {\\\"yaml\\\"}\\n        default {\\\"txt\\\"}\\n    }\\n}\\n\\nif ($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"] -like \\\"*logs*\\\") \\n{\\n    if ( -not @($OctopusParameters[\\\"K8SInspectResource\\\"]) -like \\\"pod*\\\")\\n    {\\n        Write-Error \\\"Logs can only be returned for pods, not $($OctopusParameters[\\\"K8SInspectResource\\\"])\\\"\\n    }\\n    else\\n    {\\n        Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", \\\"pods\\\") + (Get-Resources)) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Get the pod logs for each container\\n            % {\\n                $podDetails = $_\\n                @{\\n                    logs=$podDetails.spec.containers | % {$logs=\\\"\\\"} {$logs += (Select-Object -InputObject (Execute-Command kubectl ((Get-KubectlVerb) + @($podDetails.metadata.name, \\\"-c\\\", $_.name))) -ExpandProperty stdout)} {$logs}; \\n                    name=$podDetails.metadata.name\\n                }                \\n            } |\\n            # Write the output\\n            % {Write-Host $_.logs; $_} |\\n            # Optionally capture the artifact\\n            % {\\n                if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n                {\\n                    Set-Content -Path \\\"$($_.name).$(Get-ArtifactExtension)\\\" -Value $_.logs\\n                    New-OctopusArtifact \\\"$($_.name).$(Get-ArtifactExtension)\\\"\\n                }\\n            }\\n    }      \\n}\\nelse\\n{\\n    Execute-Command kubectl ((Get-KubectlVerb) + @($OctopusParameters[\\\"K8SInspectResource\\\"]) + (Get-Resources)) |\\n        % {Select-Object -InputObject $_ -ExpandProperty stdout} |\\n        % {Write-Host $_; $_} |\\n        % {\\n            if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n            {\\n                Set-Content -Path \\\"output.$(Get-ArtifactExtension)\\\" -Value $_\\n                New-OctopusArtifact \\\"output.$(Get-ArtifactExtension)\\\"\\n            }\\n        }\\n}\\n\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"K8SInspectResource\"                            = \"ingress\"\n        \"Octopus.Action.Script.Syntax\"                  = \"PowerShell\"\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{if K8SInspectNamespace}#{K8SInspectNamespace}#{/if}#{unless K8SInspectNamespace}#{Octopus.Action.Kubernetes.Namespace}#{/unless}\"\n        \"K8SInspectNames\"                               = \"#{Kubernetes.Ingress.Name}*\"\n        \"K8SInspectKubectlVerb\"                         = \"get\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_audits_get_service\" {\n  count             = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  name              = \"🛠️ Get Service\"\n  project_id        = octopusdeploy_project.project_octopub_audits[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Returns the services.\n\n**Affects**: Nothing - this runbook makes no changes.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_audits_get_service\" {\n  count      = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_audits_get_service[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Get Service\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Get Service\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"K8SInspectCreateArtifact\"                      = \"False\"\n        \"Octopus.Action.Script.ScriptBody\"              = \"<#\\n    This script provides a general purpose method for querying Kubernetes resources. It supports common operations\\n    like get, describe, logs and output formats like yaml and json. Output can be captured as artifacts.\\n#>\\n\\n<#\\n.Description\\nExecute an application, capturing the output. Based on https://stackoverflow.com/a/33652732/157605\\n#>\\nFunction Execute-Command ($commandPath, $commandArguments)\\n{\\n  Write-Host \\\"Executing: $commandPath $($commandArguments -join \\\" \\\")\\\"\\n  \\n  Try {\\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\\n    $pinfo.FileName = $commandPath\\n    $pinfo.RedirectStandardError = $true\\n    $pinfo.RedirectStandardOutput = $true\\n    $pinfo.UseShellExecute = $false\\n    $pinfo.Arguments = $commandArguments\\n    $p = New-Object System.Diagnostics.Process\\n    $p.StartInfo = $pinfo\\n    $p.Start() | Out-Null\\n    [pscustomobject]@{\\n        stdout = $p.StandardOutput.ReadToEnd()\\n        stderr = $p.StandardError.ReadToEnd()\\n        ExitCode = $p.ExitCode\\n    }\\n    $p.WaitForExit()\\n  }\\n  Catch {\\n     exit\\n  }\\n}\\n\\n<#\\n.Description\\nFind any resource names that match a wildcard input if one was specified\\n#>\\nfunction Get-Resources() \\n{\\n    $names = $OctopusParameters[\\\"K8SInspectNames\\\"] -Split \\\"`n\\\" | % {$_.Trim()}\\n    \\n    if ($OctopusParameters[\\\"K8SInspectNames\\\"] -match '\\\\*' )\\n    {\\n        return Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", $OctopusParameters[\\\"K8SInspectResource\\\"])) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Extract the name\\n            % {$_.metadata.name} |\\n            # Find any matching resources\\n            ? {$k8sName = $_; ($names | ? {$k8sName -like $_}).Count -ne 0}\\n    }\\n    else\\n    {\\n        return $names\\n    }\\n}\\n\\n<#\\n.Description\\nGet the kubectl arguments for a given action\\n#>\\nfunction Get-KubectlVerb() \\n{\\n    switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {return ,@(\\\"-o\\\", \\\"json\\\", \\\"get\\\")}\\n        \\\"get yaml\\\" {return ,@(\\\"-o\\\", \\\"yaml\\\", \\\"get\\\")}\\n        \\\"describe\\\" {return ,@(\\\"describe\\\")}\\n        \\\"logs\\\" {return ,@(\\\"logs\\\")}\\n        \\\"logs tail\\\" {return ,@(\\\"logs\\\", \\\"--tail\\\", \\\"100\\\")}\\n        \\\"previous logs\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\")}\\n        \\\"previous logs tail\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\", \\\"--tail\\\", \\\"100\\\")}\\n        default {return ,@(\\\"get\\\")}\\n    }\\n}\\n\\n<#\\n.Description\\nGet an appropiate file extension based on the selected action\\n#>\\nfunction Get-ArtifactExtension() \\n{\\n   switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {\\\"json\\\"}\\n        \\\"get yaml\\\" {\\\"yaml\\\"}\\n        default {\\\"txt\\\"}\\n    }\\n}\\n\\nif ($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"] -like \\\"*logs*\\\") \\n{\\n    if ( -not @($OctopusParameters[\\\"K8SInspectResource\\\"]) -like \\\"pod*\\\")\\n    {\\n        Write-Error \\\"Logs can only be returned for pods, not $($OctopusParameters[\\\"K8SInspectResource\\\"])\\\"\\n    }\\n    else\\n    {\\n        Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", \\\"pods\\\") + (Get-Resources)) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Get the pod logs for each container\\n            % {\\n                $podDetails = $_\\n                @{\\n                    logs=$podDetails.spec.containers | % {$logs=\\\"\\\"} {$logs += (Select-Object -InputObject (Execute-Command kubectl ((Get-KubectlVerb) + @($podDetails.metadata.name, \\\"-c\\\", $_.name))) -ExpandProperty stdout)} {$logs}; \\n                    name=$podDetails.metadata.name\\n                }                \\n            } |\\n            # Write the output\\n            % {Write-Host $_.logs; $_} |\\n            # Optionally capture the artifact\\n            % {\\n                if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n                {\\n                    Set-Content -Path \\\"$($_.name).$(Get-ArtifactExtension)\\\" -Value $_.logs\\n                    New-OctopusArtifact \\\"$($_.name).$(Get-ArtifactExtension)\\\"\\n                }\\n            }\\n    }      \\n}\\nelse\\n{\\n    Execute-Command kubectl ((Get-KubectlVerb) + @($OctopusParameters[\\\"K8SInspectResource\\\"]) + (Get-Resources)) |\\n        % {Select-Object -InputObject $_ -ExpandProperty stdout} |\\n        % {Write-Host $_; $_} |\\n        % {\\n            if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n            {\\n                Set-Content -Path \\\"output.$(Get-ArtifactExtension)\\\" -Value $_\\n                New-OctopusArtifact \\\"output.$(Get-ArtifactExtension)\\\"\\n            }\\n        }\\n}\\n\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"K8SInspectResource\"                            = \"service\"\n        \"Octopus.Action.Script.Syntax\"                  = \"PowerShell\"\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{if K8SInspectNamespace}#{K8SInspectNamespace}#{/if}#{unless K8SInspectNamespace}#{Octopus.Action.Kubernetes.Namespace}#{/unless}\"\n        \"K8SInspectNames\"                               = \"#{Kubernetes.Service.Name}*\"\n        \"K8SInspectKubectlVerb\"                         = \"get\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_audits_get_deployment\" {\n  count             = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  name              = \"🛠️ Get Deployment\"\n  project_id        = octopusdeploy_project.project_octopub_audits[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Returns the deployments.\n\n**Affects**: Nothing - this runbook makes no changes.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_audits_get_deployment\" {\n  count      = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_audits_get_deployment[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Get Deployment\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Get Deployment\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"K8SInspectCreateArtifact\"                      = \"False\"\n        \"Octopus.Action.Script.ScriptBody\"              = \"<#\\n    This script provides a general purpose method for querying Kubernetes resources. It supports common operations\\n    like get, describe, logs and output formats like yaml and json. Output can be captured as artifacts.\\n#>\\n\\n<#\\n.Description\\nExecute an application, capturing the output. Based on https://stackoverflow.com/a/33652732/157605\\n#>\\nFunction Execute-Command ($commandPath, $commandArguments)\\n{\\n  Write-Host \\\"Executing: $commandPath $($commandArguments -join \\\" \\\")\\\"\\n  \\n  Try {\\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\\n    $pinfo.FileName = $commandPath\\n    $pinfo.RedirectStandardError = $true\\n    $pinfo.RedirectStandardOutput = $true\\n    $pinfo.UseShellExecute = $false\\n    $pinfo.Arguments = $commandArguments\\n    $p = New-Object System.Diagnostics.Process\\n    $p.StartInfo = $pinfo\\n    $p.Start() | Out-Null\\n    [pscustomobject]@{\\n        stdout = $p.StandardOutput.ReadToEnd()\\n        stderr = $p.StandardError.ReadToEnd()\\n        ExitCode = $p.ExitCode\\n    }\\n    $p.WaitForExit()\\n  }\\n  Catch {\\n     exit\\n  }\\n}\\n\\n<#\\n.Description\\nFind any resource names that match a wildcard input if one was specified\\n#>\\nfunction Get-Resources() \\n{\\n    $names = $OctopusParameters[\\\"K8SInspectNames\\\"] -Split \\\"`n\\\" | % {$_.Trim()}\\n    \\n    if ($OctopusParameters[\\\"K8SInspectNames\\\"] -match '\\\\*' )\\n    {\\n        return Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", $OctopusParameters[\\\"K8SInspectResource\\\"])) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Extract the name\\n            % {$_.metadata.name} |\\n            # Find any matching resources\\n            ? {$k8sName = $_; ($names | ? {$k8sName -like $_}).Count -ne 0}\\n    }\\n    else\\n    {\\n        return $names\\n    }\\n}\\n\\n<#\\n.Description\\nGet the kubectl arguments for a given action\\n#>\\nfunction Get-KubectlVerb() \\n{\\n    switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {return ,@(\\\"-o\\\", \\\"json\\\", \\\"get\\\")}\\n        \\\"get yaml\\\" {return ,@(\\\"-o\\\", \\\"yaml\\\", \\\"get\\\")}\\n        \\\"describe\\\" {return ,@(\\\"describe\\\")}\\n        \\\"logs\\\" {return ,@(\\\"logs\\\")}\\n        \\\"logs tail\\\" {return ,@(\\\"logs\\\", \\\"--tail\\\", \\\"100\\\")}\\n        \\\"previous logs\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\")}\\n        \\\"previous logs tail\\\" {return ,@(\\\"logs\\\", \\\"--previous\\\", \\\"--tail\\\", \\\"100\\\")}\\n        default {return ,@(\\\"get\\\")}\\n    }\\n}\\n\\n<#\\n.Description\\nGet an appropiate file extension based on the selected action\\n#>\\nfunction Get-ArtifactExtension() \\n{\\n   switch($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"])\\n    {\\n        \\\"get json\\\" {\\\"json\\\"}\\n        \\\"get yaml\\\" {\\\"yaml\\\"}\\n        default {\\\"txt\\\"}\\n    }\\n}\\n\\nif ($OctopusParameters[\\\"K8SInspectKubectlVerb\\\"] -like \\\"*logs*\\\") \\n{\\n    if ( -not @($OctopusParameters[\\\"K8SInspectResource\\\"]) -like \\\"pod*\\\")\\n    {\\n        Write-Error \\\"Logs can only be returned for pods, not $($OctopusParameters[\\\"K8SInspectResource\\\"])\\\"\\n    }\\n    else\\n    {\\n        Execute-Command kubectl (@(\\\"-o\\\", \\\"json\\\", \\\"get\\\", \\\"pods\\\") + (Get-Resources)) |\\n            # Select the stdout property from the execution\\n            Select-Object -ExpandProperty stdout |\\n            # Convert the output from JSON\\n            ConvertFrom-JSON | \\n            # Get the items object from the kubectl response\\n            % {if ((Get-Member -InputObject $_ -Name items).Count -ne 0) {Select-Object -InputObject $_ -ExpandProperty items} else {$_}} |\\n            # Get the pod logs for each container\\n            % {\\n                $podDetails = $_\\n                @{\\n                    logs=$podDetails.spec.containers | % {$logs=\\\"\\\"} {$logs += (Select-Object -InputObject (Execute-Command kubectl ((Get-KubectlVerb) + @($podDetails.metadata.name, \\\"-c\\\", $_.name))) -ExpandProperty stdout)} {$logs}; \\n                    name=$podDetails.metadata.name\\n                }                \\n            } |\\n            # Write the output\\n            % {Write-Host $_.logs; $_} |\\n            # Optionally capture the artifact\\n            % {\\n                if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n                {\\n                    Set-Content -Path \\\"$($_.name).$(Get-ArtifactExtension)\\\" -Value $_.logs\\n                    New-OctopusArtifact \\\"$($_.name).$(Get-ArtifactExtension)\\\"\\n                }\\n            }\\n    }      \\n}\\nelse\\n{\\n    Execute-Command kubectl ((Get-KubectlVerb) + @($OctopusParameters[\\\"K8SInspectResource\\\"]) + (Get-Resources)) |\\n        % {Select-Object -InputObject $_ -ExpandProperty stdout} |\\n        % {Write-Host $_; $_} |\\n        % {\\n            if ($OctopusParameters[\\\"K8SInspectCreateArtifact\\\"] -ieq \\\"true\\\") \\n            {\\n                Set-Content -Path \\\"output.$(Get-ArtifactExtension)\\\" -Value $_\\n                New-OctopusArtifact \\\"output.$(Get-ArtifactExtension)\\\"\\n            }\\n        }\\n}\\n\"\n        \"Octopus.Action.Script.ScriptSource\"            = \"Inline\"\n        \"K8SInspectResource\"                            = \"deployment\"\n        \"Octopus.Action.Script.Syntax\"                  = \"PowerShell\"\n        \"Octopus.Action.KubernetesContainers.Namespace\" = \"#{if K8SInspectNamespace}#{K8SInspectNamespace}#{/if}#{unless K8SInspectNamespace}#{Octopus.Action.Kubernetes.Namespace}#{/unless}\"\n        \"K8SInspectNames\"                               = \"#{Kubernetes.Deployment.Name}*\"\n        \"K8SInspectKubectlVerb\"                         = \"get\"\n      }\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_audits_scale_to_zero\" {\n  count             = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  name              = \"🌃 Scale Pods to Zero\"\n  project_id        = octopusdeploy_project.project_octopub_audits[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**WARNING**: This is a destructive operation. The service will no longer be available when scaled down.\n\n**Action**: Scales the deployment down to zero pods.\n\n**Affects**: The audits service is effectively shut down.\n\nThis runbook is designed to be be run in non-production environments after hours to remove the Fargate nodes hosting\nthe service. This removes the cost of hosting the service out of hours.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_audits_scale_pods_to_zero\" {\n  count      = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_audits_scale_to_zero[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Scale Pods to Zero\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Scale Pods to Zero\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"OctopusUseBundledTooling\"           = \"False\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"kubectl scale --replicas=0 deployment/#{Kubernetes.Deployment.Name}\"\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n      }\n\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_octopub_audits_scale_to_one\" {\n  count             = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  name              = \"🌇 Scale Pods to One\"\n  project_id        = octopusdeploy_project.project_octopub_audits[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"Off\"\n  description                 = <<EOT\n**Action**: Scales the deployment to one pod.\n\n**Affects**: Audits service - this will create new pods if the deployment has been scaled to zero.\n\nThis runbook is designed to be be run in non-production environments during office hours to recreate the pods after they\nwere shutdown after hours.\nEOT\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_octopub_audits_scale_pods_to_one\" {\n  count      = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_octopub_audits_scale_to_one[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Scale Pods to One\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.KubernetesRunScript\"\n      name                               = \"Scale Pods to One\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"OctopusUseBundledTooling\"           = \"False\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"kubectl scale --replicas=1 deployment/#{Kubernetes.Deployment.Name}\"\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n      }\n\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/k8s-workertools\"\n      }\n\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"EKS_Reference_Cluster\"]\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\ndata \"octopusdeploy_projects\" \"octopub_stack\" {\n  partial_name = \"_ Deploy EKS Octopub Stack\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_variable\" \"stack_namespace_featurebranch\" {\n  count        = length(data.octopusdeploy_projects.octopub_stack.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.project___deploy_eks_octopub_stack[0].id\n  value        = \"\"\n  name         = \"Kubernetes.Namespace\"\n  type         = \"String\"\n  description  = \"The custom namespace to use when deploying a feature branch\"\n  is_sensitive = false\n\n  scope {\n    actions      = []\n    channels     = []\n    environments = [local.featurebranch_environment_id]\n    machines     = []\n    roles        = null\n    tenant_tags  = null\n  }\n\n  prompt {\n    description = \"Feature branch namespace\"\n    label       = \"Namespace\"\n    is_required = true\n    display_settings {\n      control_type = \"SingleLineText\"\n    }\n  }\n}\n\nresource \"octopusdeploy_channel\" \"orchestration_channel_mainline\" {\n  count       = length(data.octopusdeploy_projects.octopub_stack.projects) == 0 ? 1 : 0\n  name        = \"Mainline\"\n  description = \"\"\n  project_id  = octopusdeploy_project.project___deploy_eks_octopub_stack[0].id\n  is_default  = true\n\n  rule {\n\n    action_package {\n      deployment_action = \"Deploy Frontend\"\n    }\n    action_package {\n      deployment_action = \"Deploy Audits\"\n    }\n    action_package {\n      deployment_action = \"Deploy Products\"\n    }\n\n    tag           = \"^$\"\n    version_range = \"\"\n  }\n\n  tenant_tags = []\n  depends_on  = [octopusdeploy_deployment_process.deployment_process___deploy_eks_octopub_stack]\n}\n\nresource \"octopusdeploy_project\" \"project___deploy_eks_octopub_stack\" {\n  count                                = length(data.octopusdeploy_projects.octopub_stack.projects) == 0 ? 1 : 0\n  name                                 = \"_ Deploy EKS Octopub Stack\"\n  auto_create_release                  = false\n  default_guided_failure_mode          = \"EnvironmentDefault\"\n  default_to_skip_if_already_installed = false\n  discrete_channel_release             = false\n  is_disabled                          = false\n  is_version_controlled                = false\n  lifecycle_id                         = local.application_lifecycle_id\n  project_group_id                     = local.eks_project_group_id\n  included_library_variable_sets       = []\n  tenanted_deployment_participation    = \"Untenanted\"\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n\n  versioning_strategy {\n    template = \"#{Octopus.Version.LastMajor}.#{Octopus.Version.LastMinor}.#{Octopus.Version.NextPatch}\"\n  }\n\n  lifecycle {\n    ignore_changes = []\n  }\n  description = \"Deploys the full Octopus application stack\"\n}\n\nresource \"octopusdeploy_deployment_process\" \"deployment_process___deploy_eks_octopub_stack\" {\n  count      = length(data.octopusdeploy_projects.octopub_stack.projects) == 0 ? 1 : 0\n  project_id = octopusdeploy_project.project___deploy_eks_octopub_stack[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Generate Variables\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Generate Variables\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = local.orchestration_project_script\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Deploy Frontend\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.DeployRelease\"\n      name                               = \"Deploy Frontend\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = \"\"\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"Octopus.Action.DeployRelease.ProjectId\"           = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? octopusdeploy_project.project_octopub_frontend[0].id : data.octopusdeploy_projects.octopub_frontend.projects[0].id\n        \"Octopus.Action.DeployRelease.DeploymentCondition\" = \"#{Octopus.Action[Generate Variables].Output.DeploymentCondition}\"\n        \"Octopus.Action.DeployRelease.Variables\"           = jsonencode({\n          \"Kubernetes.Namespace\" = \"#{Octopus.Action[Generate Variables].Output.KubernetesNamespaceValue}\"\n        })\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n\n      primary_package {\n        package_id           = length(data.octopusdeploy_projects.octopub_frontend.projects) == 0 ? octopusdeploy_project.project_octopub_frontend[0].id : data.octopusdeploy_projects.octopub_frontend.projects[0].id\n        acquisition_location = \"NotAcquired\"\n        feed_id              = data.octopusdeploy_feeds.project.feeds[0].id\n        properties           = {}\n      }\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n  step {\n    condition           = \"Success\"\n    name                = \"Deploy Products\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.DeployRelease\"\n      name                               = \"Deploy Products\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = \"\"\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"Octopus.Action.DeployRelease.ProjectId\"           = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? octopusdeploy_project.project_octopub_products[0].id : data.octopusdeploy_projects.octopub_products.projects[0].id\n        \"Octopus.Action.DeployRelease.DeploymentCondition\" = \"#{Octopus.Action[Generate Variables].Output.DeploymentCondition}\"\n        \"Octopus.Action.DeployRelease.Variables\"           = jsonencode({\n          \"Kubernetes.Namespace\" = \"#{Octopus.Action[Generate Variables].Output.KubernetesNamespaceValue}\"\n        })\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n\n      primary_package {\n        package_id           = length(data.octopusdeploy_projects.octopub_products.projects) == 0 ? octopusdeploy_project.project_octopub_products[0].id : data.octopusdeploy_projects.octopub_products.projects[0].id\n        acquisition_location = \"NotAcquired\"\n        feed_id              = data.octopusdeploy_feeds.project.feeds[0].id\n        properties           = {}\n      }\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n  step {\n    condition           = \"Success\"\n    name                = \"Deploy Audits\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.DeployRelease\"\n      name                               = \"Deploy Audits\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = \"\"\n      worker_pool_variable               = \"\"\n      properties                         = {\n        \"Octopus.Action.DeployRelease.ProjectId\"           = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? octopusdeploy_project.project_octopub_audits[0].id : data.octopusdeploy_projects.octopub_audits.projects[0].id\n        \"Octopus.Action.DeployRelease.DeploymentCondition\" = \"#{Octopus.Action[Generate Variables].Output.DeploymentCondition}\"\n        \"Octopus.Action.DeployRelease.Variables\"           = jsonencode({\n          \"Kubernetes.Namespace\" = \"#{Octopus.Action[Generate Variables].Output.KubernetesNamespaceValue}\"\n        })\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n\n      primary_package {\n        package_id           = length(data.octopusdeploy_projects.octopub_audits.projects) == 0 ? octopusdeploy_project.project_octopub_audits[0].id : data.octopusdeploy_projects.octopub_audits.projects[0].id\n        acquisition_location = \"NotAcquired\"\n        feed_id              = data.octopusdeploy_feeds.project.feeds[0].id\n        properties           = {}\n      }\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Write-Highlight \\\"Please share your feedback on this step in our GitHub discussion at [https://oc.to/CfiezA](https://oc.to/CfiezA).\\\"\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n#endregion\n\n#endregion\n\n",
    "Octopus.Action.Terraform.TemplateParameters": "{\"octopus_server\":\"#{ReferenceArchitecture.Eks.Octopus.ServerUrl}\",\"octopus_apikey\":\"#{ReferenceArchitecture.Eks.Octopus.ApiKey}\",\"octopus_space_id\":\"#{ReferenceArchitecture.Eks.Octopus.SpaceId}\",\"feed_docker_hub_username\":\"#{ReferenceArchitecture.Eks.Docker.Username}\",\"feed_docker_hub_password\":\"#{ReferenceArchitecture.Eks.Docker.Password}\",\"github_access_token\":\"#{ReferenceArchitecture.Eks.GitHub.AccessToken}\",\"account_aws_access_key\":\"#{ReferenceArchitecture.Eks.Aws.AccessKey}\",\"account_aws_secret_key\":\"#{ReferenceArchitecture.Eks.Aws.SecretKey}\"}",
    "Octopus.Action.RunOnServer": "true",
    "OctopusUseBundledTooling": "False",
    "Octopus.Action.Terraform.AdditionalInitParams": "#{if ReferenceArchitecture.Terraform.InitArgs}#{ReferenceArchitecture.Terraform.InitArgs}#{/if}",
    "Octopus.Action.Terraform.AdditionalActionParams": "#{if ReferenceArchitecture.Terraform.ApplyArgs}#{ReferenceArchitecture.Terraform.ApplyArgs}#{/if}"
  },
  "Category": "Octopus",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/octopus-reference-architecture-eks.json",
  "Website": "/step-templates/87b2154a-5c8d-4c31-9680-575bb6df9789",
  "Logo": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAMAAACahl6sAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAC1QTFRFT6Tl////L5Pg8vj9Y67omsvwPJrisdfzfbzs5fL7y+T32Ov5isLucLXqvt31CJPHWwAABMJJREFUeNrs3deW4jAMAFDF3U75/89dlp0ZhiU4blJEjvQ8hYubLJsA00UCBCIQgQhEIAIRiEAEIhCBCEQgAhGIQAQiEIEIhD8kJm+t+QprfdKfB9HbYpx6CWfspj8HMi+gMgHL/AmQA8W3JTKH+ALFvzCeL0RbpyoCPE9IJeNOSQwh5Z3qd6yRGWQ2qi2cZQWxqj1WzQYSjeoJmJlAklOd4VlArOqPhQEkqBERToeMcfRJBkC0Uep8CfBpjz4JsHJ0zF3dkEWNje0kiB/sUC6eApndaIiCMyAa1PiwJ0AWhRGJHJJQHG2dC7h1rNbO1QOxSA7lNCkkKrQIpJCAB1GREILYIC1NAiwbpKFJgGWDNExcwGstfExcZBCHC6nOglshHtmhViLIig1RNBCN7qjtW8C0Z1UvJcC1Z9XmwMBzzvobmgAyEzgq91dtEEsBsQSQQAFZCSBAATEEEApHZbrVBIkkEIUPSVeB+KtALA0kXQUSrwKZBCIQBnk8Y4i5CsReBeKvkqLM+BCSDWJlrZFvGk9SRTHshkgjZCGAaArIxm3H3grhVzFlW2msfl1ca79UJ1bofYvsDHHlNdTZnlh5MghuPd5NdBDUNZHyCkfktIh03XzALGRPlBDPac7qgWjHZzWcmF5zmmkhidMQ6boKiDXcDTUEaylZqCGJ0Vjvu/fLJtHqhSANEvqb2OYqkOUqEHuVMbJcZdZCGiPhKhC4yjqiIjEE7XThMp8fAWII3mY3kUIQD+AMKQTzPiBhgQ63HlT/KSvgtoi0dq5mCPah1UIE0eh3sT0NhOByvKeAkFzi8PgQomumFhsyOxpIzZN4gLOj5plVwNpR0b2AuePWKBEHQu24pSsJA+LVCeHHQxZ1SiyDIdqok8IOhSSnTottHEQTdyt4ettAj4KkzA4dMikk2Dht2S5ptm1vswnPDxn0YyDZ5oDM3iToo2T5voWaYe+Q+vdjH80QyAzZhCgcDtLMI1Tmtz9w++XHgziHQHJJu/OZ3bs9Xn8gQ72NcP3dKqEfkp10F51xhoIi2I91R+LurXV/5q7pH+wx061CzO16oSQleMyr8fXvwMA0Pro8432DPD/ySx8XrHfSuDAM8n6UhnjQabaiXf5Bq/lREHvEeNtn1rJ08+C/uXkQZHeguxAPC3UvtcJYUogLzZX5hhZZvS6onG5lxXtzWGaygwb79vT/IXhdlNibwlKYOR6T8xjI7W8n+xV7T+GH4tMzWwR+lZhRkJYSsC0thpmCYqyngOz3rN2FLBZ2wZflBCggUHF0Vnp88JKienzIXLSEZCZqU7IKr/gQW9yx3pzV7Y9kvWZWTRRIqDmTtRUnU7b2lLcTYmoqHqnmiO1poER0SPkAeZMAZxaJx0Y3TCdAclsIqDz03ALcyxfTCZBsthoGXWmigGyVhWPLFJJfuuKQWycoEFdXbH4dJJoJxNR1eD/kshz6yn48cF8yW8sFoitflB1w6Q8n+/15Za7oA17/pYNmYgP5fmWm8L1NOHPWgK8kuFew1/JXtOA0yJCv7ah7X8ObUuT5kObU30+fDZm8+zqP+HTIpK0xQ796b5Kv2hSIQAQiEIEIRCACEYhABCIQgQhEIAIRiEAEIpBf8UeAAQAEjtYmlDTcCgAAAABJRU5ErkJggg==",
  "$Meta": {
    "Type": "ActionTemplate"
  }
}

History

Page updated on Wednesday, October 18, 2023