Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wait for ConfigurationVersion to be ready when using Terraform Cloud #655

Merged
merged 3 commits into from
Apr 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions packages/cdktf-cli/bin/cmds/ui/models/terraform-cloud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { TerraformJsonConfigBackendRemote } from '../terraform-json'
import * as TerraformCloudClient from '@skorfmann/terraform-cloud'
import archiver from 'archiver';
import { WritableStreamBuffer } from 'stream-buffers';
import { logger } from '../../../../lib/logging';

export class TerraformCloudPlan implements TerraformPlan {
constructor(public readonly planFile: string, public readonly plan: { [key: string]: any }, public readonly url: string) { }
Expand Down Expand Up @@ -145,6 +146,9 @@ export class TerraformCloud implements Terraform {
if (!zipBuffer) throw new Error("Couldn't upload directory to Terraform Cloud");

await this.client.ConfigurationVersion.upload(version.attributes.uploadUrl, zipBuffer)

// we might get an HTTP 422 error if we don't wait for the processing and try to run too early. see #647
await this.waitForConfigurationVersionToBeReady();
}

@BeautifyErrors
Expand Down Expand Up @@ -279,4 +283,39 @@ export class TerraformCloud implements Terraform {
throw e;
}
}

private async isConfigurationVersionReady(): Promise<boolean> {
if (!this.configurationVersionId) throw new Error('No ConfigurationVersionId known. Cannot wait for ConfigurationVersion to become ready');
const configVersion = await this.client.ConfigurationVersion.show(this.configurationVersionId);
const { status } = configVersion.attributes;
switch (status) {
case 'uploaded': return true;
case 'errored': {
const { error, errorMessage } = configVersion.attributes;
logger.error(`ConfigurationVersion in Terraform Cloud has status "${status}". Returned config version was ${JSON.stringify(configVersion)}`);
throw new Error(`Terraform Cloud ConfigurationVersion ${this.configurationVersionId} has status "errored" ${JSON.stringify({ error, errorMessage })}`);
}
case 'pending': // fallthrough
default:
logger.debug(`ConfigurationVersion in Terraform Cloud not considered ready with status "${status}".`)
return false;
}
}

private async waitForConfigurationVersionToBeReady(timeoutMs = 60_000): Promise<void> {
logger.debug('waiting for Configuration Version to be ready in Terraform Cloud');
let timeoutReached = false;
const ready = async () => {
while (!(await this.isConfigurationVersionReady() && !timeoutReached)) {
await wait(1000);
}
};
const timeout = async () => {
await wait(timeoutMs);
timeoutReached = true;
throw new Error(`Waiting for Terraform Cloud ConfigurationVersion to become ready timed out (timeout was ${timeoutMs}ms)`);
};
await Promise.race([ready(), timeout()]);
logger.debug('Configuration Version is ready in Terraform Cloud');
}
}
2 changes: 1 addition & 1 deletion packages/cdktf-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"dependencies": {
"@cdktf/hcl2json": "0.0.0",
"@skorfmann/ink-confirm-input": "^3.0.0",
"@skorfmann/terraform-cloud": "^1.9.1",
"@skorfmann/terraform-cloud": "^1.10.0",
"@types/node": "^14.0.26",
"archiver": "^5.1.0",
"cdktf": "0.0.0",
Expand Down
8 changes: 8 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1406,6 +1406,14 @@
prop-types "^15.5.10"
yn "^3.1.1"

"@skorfmann/terraform-cloud@^1.10.0":
version "1.10.0"
resolved "https://registry.yarnpkg.com/@skorfmann/terraform-cloud/-/terraform-cloud-1.10.0.tgz#cba669213dacf92aa1a80c8e8d112f0b5e422cc9"
integrity sha512-Yd5WWmmUjFYBpQpsAnAntwQMerilNRpHILNPA7x0EkwHhf+5KTSKYZwzYL/bOY1QfGJX6DTnOSHXIRStHZDUgg==
dependencies:
axios "^0.21.1"
camelcase-keys "^6.2.2"

"@skorfmann/terraform-cloud@^1.9.1":
version "1.9.1"
resolved "https://registry.yarnpkg.com/@skorfmann/terraform-cloud/-/terraform-cloud-1.9.1.tgz#6fbdf6846efd6fdeb3405126cc91cd7d5c846eff"
Expand Down