diff --git a/backend/src/integrations/sync.ts b/backend/src/integrations/sync.ts index 95478fc5b..296549246 100644 --- a/backend/src/integrations/sync.ts +++ b/backend/src/integrations/sync.ts @@ -1855,6 +1855,7 @@ const syncSecretsTerraformCloud = async ({ Promise.all(payload); + // get secrets from Terraform Cloud // const getSecretsRes = ( // await standardRequest.get( @@ -1867,7 +1868,7 @@ const syncSecretsTerraformCloud = async ({ // }, // } // ) - // ).data?.data; + // ).data; // delete secrets from Terraform Cloud // getSecretsRes.forEach(async (data: any) => { diff --git a/backend/src/variables/integration.ts b/backend/src/variables/integration.ts index 687355949..39b9169bd 100644 --- a/backend/src/variables/integration.ts +++ b/backend/src/variables/integration.ts @@ -195,6 +195,15 @@ export const getIntegrationOptions = async () => { clientId: await getClientIdGitLab(), docsLink: "", }, + { + name: "Terraform Cloud", + slug: "terraform-cloud", + image: "Terraform Cloud.png", + isAvailable: true, + type: "pat", + cliendId: "", + docsLink: "", + }, { name: "Travis CI", slug: "travisci", @@ -222,15 +231,6 @@ export const getIntegrationOptions = async () => { clientId: "", docsLink: "", }, - { - name: "Terraform Cloud", - slug: "terraform-cloud", - image: "Terraform Cloud.png", - isAvailable: true, - type: "pat", - cliendId: "", - docsLink: "", - }, { name: "HashiCorp Vault", slug: "hashicorp-vault", diff --git a/docs/integrations/cloud/terraform-cloud.mdx b/docs/integrations/cloud/terraform-cloud.mdx new file mode 100644 index 000000000..9000fe194 --- /dev/null +++ b/docs/integrations/cloud/terraform-cloud.mdx @@ -0,0 +1,42 @@ +--- +title: "Terraform Cloud" +description: "How to sync secrets from Infisical to Terraform Cloud" +--- + +Prerequisites: + +- Set up and add envars to [Infisical Cloud](https://app.infisical.com) + +## Navigate to your project's integrations tab + +![integrations](../../images/integrations.png) + +## Enter your Terraform Cloud API Token and Workspace Id + +Obtain a Terraform Cloud API Token in User Settings > Tokens + +![integrations terraform cloud dashboard](../../images/integrations-terraformcloud-dashboard.png) +![integrations terraform cloud tokens](../../images/integrations-terraformcloud-tokens.png) + +Obtain your Terraform Cloud Workspace Id in Projects & Workspaces > Workspace > ID + +![integrations terraform cloud projects & workspaces](../../images/integrations-terraformcloud-workspaces.png) +![integrations terraform cloud workspace id](../../images/integrations-terraformcloud-workspaceid.png) + +Press on the Terraform Cloud tile and input your Terraform Cloud API Token and Workspace Id to grant Infisical access to your Terraform Cloud account. + +![integrations terraform cloud authorization](../../images/integrations-terraformcloud-auth.png) + + + If this is your project's first cloud integration, then you'll have to grant + Infisical access to your project's environment variables. Although this step + breaks E2EE, it's necessary for Infisical to sync the environment variables to + the cloud platform. + + +## Start integration + +Select which Infisical environment secrets and Terraform Cloud variable type you want to sync to which Terraform Cloud workspace/project and press create integration to start syncing secrets to Terraform Cloud. + +![integrations terraform cloud](../../images/integrations-terraformcloud-create.png) +![integrations terraform cloud](../../images/integrations-terraformcloud.png) diff --git a/docs/integrations/overview.mdx b/docs/integrations/overview.mdx index b054a52cd..5827c0eac 100644 --- a/docs/integrations/overview.mdx +++ b/docs/integrations/overview.mdx @@ -20,6 +20,7 @@ Missing an integration? [Throw in a request](https://github.com/Infisical/infisi | [Render](/integrations/cloud/render) | Cloud | Available | | [Laravel Forge](/integrations/cloud/laravel-forge) | Cloud | Available | | [Railway](/integrations/cloud/railway) | Cloud | Available | +| [Terraform Cloud](/integrations/cloud/terraform-cloud) | Cloud | Available | | [Fly.io](/integrations/cloud/flyio) | Cloud | Available | | [Supabase](/integrations/cloud/supabase) | Cloud | Available | | [Cloudflare Pages](/integrations/cloud/cloudflare-pages) | Cloud | Available | diff --git a/docs/mint.json b/docs/mint.json index ba66b271f..9c4aeb87b 100644 --- a/docs/mint.json +++ b/docs/mint.json @@ -130,7 +130,6 @@ "self-hosting/deployment-options/standalone-infisical", "self-hosting/deployment-options/fly.io", "self-hosting/deployment-options/render", - "self-hosting/deployment-options/laravel-forge", "self-hosting/deployment-options/digital-ocean-marketplace" ] }, @@ -198,6 +197,7 @@ "integrations/cloud/flyio", "integrations/cloud/laravel-forge", "integrations/cloud/supabase", + "integrations/cloud/terraform-cloud", "integrations/cloud/cloudflare-pages", "integrations/cloud/checkly", "integrations/cloud/hashicorp-vault", diff --git a/frontend/src/pages/integrations/terraform-cloud/create.tsx b/frontend/src/pages/integrations/terraform-cloud/create.tsx index 9e46f4c97..9e3c51804 100644 --- a/frontend/src/pages/integrations/terraform-cloud/create.tsx +++ b/frontend/src/pages/integrations/terraform-cloud/create.tsx @@ -33,6 +33,7 @@ export default function TerraformCloudCreateIntegrationPage() { const [targetApp, setTargetApp] = useState(""); const [secretPath, setSecretPath] = useState("/"); const [variableType, setVariableType] = useState(""); + const [variableTypeErrorText, setVariableTypeErrorText] = useState(""); const [isLoading, setIsLoading] = useState(false); useEffect(() => { @@ -55,6 +56,12 @@ export default function TerraformCloudCreateIntegrationPage() { try { if (!integrationAuth?._id) return; + setVariableTypeErrorText(""); + if (variableType.length === 0 ) { + setVariableTypeErrorText("Variable Type cannot be blank!") + return; + } + setIsLoading(true); await createIntegration({ @@ -119,7 +126,8 @@ export default function TerraformCloudCreateIntegrationPage() { placeholder="Provide a path, default is /" /> - +