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

fix(cli): dont upload .terraform folders #758

Merged
merged 4 commits into from
Jun 23, 2021
Merged
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
15 changes: 14 additions & 1 deletion packages/cdktf-cli/bin/cmds/ui/models/terraform-cloud.ts
Original file line number Diff line number Diff line change
@@ -60,9 +60,12 @@ function BeautifyErrors(name: string) {
} catch (e) {
if (e.response && e.response.status >= 400 && e.response.status <= 599){
const errors = e.response.data?.errors as (object[] | undefined);
logger.error(`Error in ${name}: ${JSON.stringify(e)}`);
if (errors) {
throw new Error(`${name}: Request to Terraform Cloud failed with status ${e.response.status}: ${errors.map(e => JSON.stringify(e)).join(', ')}`);
}
} else {
logger.warn(`Error in ${name}: ${JSON.stringify(e)}`);
}
throw e;
}
@@ -113,7 +116,7 @@ export class TerraformCloud implements Terraform {

@BeautifyErrors("Init")
public async init(): Promise<void> {
if (fs.existsSync(path.join(process.cwd(), 'terraform.tfstate'))) throw new Error('Found a "terraform.tfstate" file in your current working directory. Please migrate the state manually to Terraform Cloud and delete the file afterwards. https://cdk.tf/migrate-state')
if (fs.existsSync(path.join(process.cwd(), `terraform.${this.stack.name}.tfstate`))) throw new Error('Found a "terraform.tfstate" file in your current working directory. Please migrate the state manually to Terraform Cloud and delete the file afterwards. https://cdk.tf/migrate-state')
const workspace = await this.workspace()
const version = await this.client.ConfigurationVersion.create(workspace.id, {
data: {
@@ -127,6 +130,8 @@ export class TerraformCloud implements Terraform {

this.configurationVersionId = version.id

this.removeLocalTerraformDirectory()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two modes for Terraform Cloud: local execution and remote execution. Could this possibly break local execution or be unwanted (as it destroys the local cache containing already initialized Terraform providers)? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would guess no as this is the terraform cloud implementation of this function. The Cli implementation would need to be able to deal with a blank state so it should work IMHO

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think this should be ok - since that's scoped to the stack anyway. Even if you had multiple stacks targeting local and cloud, it should still be ok.


const zipBuffer = await zipDirectory(this.workDir)
if (!zipBuffer) throw new Error("Couldn't upload directory to Terraform Cloud");

@@ -320,4 +325,12 @@ export class TerraformCloud implements Terraform {
await Promise.race([ready(), timeout()]);
logger.debug('Configuration Version is ready in Terraform Cloud');
}

private removeLocalTerraformDirectory() {
try {
fs.rmdirSync(path.resolve(this.stack.synthesizedStackPath, ".terraform"), {recursive: true});
} catch (error) {
logger.debug(`Could not remove .terraform folder`, error);
}
}
}
21 changes: 12 additions & 9 deletions test/typescript/terraform-cloud/main.ts
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ import * as path from 'path';
const token = process.env.TERRAFORM_CLOUD_TOKEN;
const name = process.env.TERRAFORM_CLOUD_WORKSPACE_NAME;
const organization = process.env.TERRAFORM_CLOUD_ORGANIZATION;
const localExecution = process.env.TF_EXECUTE_LOCAL === "true";

export class HelloTerra extends TerraformStack {
constructor(scope: Construct, id: string) {
@@ -18,15 +19,17 @@ export class HelloTerra extends TerraformStack {
}
}]);

this.addOverride('terraform.backend', {
remote: {
organization,
workspaces: {
name
},
token
}
});
if (!localExecution) {
this.addOverride('terraform.backend', {
remote: {
organization,
workspaces: {
name
},
token
}
});
}

new TerraformOutput(this, "output", {
value: "constant value"
22 changes: 22 additions & 0 deletions test/typescript/terraform-cloud/test.ts
Original file line number Diff line number Diff line change
@@ -48,4 +48,26 @@ describe("full integration test", () => {
expect(driver.deploy()).toMatchSnapshot()
await client.Workspaces.deleteByName(orgName, workspaceName)
})

withAuth("deploy locally and then in Terraform Cloud", async () => {
const client = new TerraformCloud(TERRAFORM_CLOUD_TOKEN)

await client.Workspaces.create(orgName, {
data: {
attributes: {
name: workspaceName,
executionMode: 'remote',
terraformVersion: TERRAFORM_VERSION
},
type: 'workspaces'
}
})

process.env.TF_EXECUTE_LOCAL = "true";
driver.deploy();
process.env.TF_EXECUTE_LOCAL = undefined;
driver.deploy();

await client.Workspaces.deleteByName(orgName, workspaceName)
})
})