Skip to content

Commit d6bf5d5

Browse files
Improve terraform property escaping
1 parent c7f8155 commit d6bf5d5

2 files changed

Lines changed: 36 additions & 19 deletions

File tree

packages/blocks/terraform/src/lib/hcledit-cli.ts

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,10 @@ export async function updateResourceProperties(
9292
template: string,
9393
resourceType: string,
9494
resourceName: string,
95-
modifications: { propertyName: string; propertyValue: string }[],
95+
modifications: {
96+
propertyName: string;
97+
propertyValue: string | number | boolean;
98+
}[],
9699
): Promise<string> {
97100
validateIdentifier(resourceType, 'Resource type');
98101
validateIdentifier(resourceName, 'Resource name');
@@ -110,7 +113,9 @@ export async function updateResourceProperties(
110113
const updates = [];
111114
for (const modification of modifications) {
112115
const propertyName = modification.propertyName;
113-
const propertyValue = sanitizePropertyValue(modification.propertyValue);
116+
const propertyValue = escapeAttributeValue(
117+
modification.propertyValue,
118+
).replace(/"/g, '\\"');
114119

115120
const attributeCommand = await getAttributeCommand(
116121
filePath,
@@ -247,20 +252,3 @@ async function executeHclEditCommand(
247252
): Promise<CommandResult> {
248253
return await executeCommand('/bin/bash', ['-c', `hcledit ${parameters}`]);
249254
}
250-
251-
function sanitizePropertyValue(propertyValue: string): string {
252-
// In the future we may need to check the type.
253-
// We currently only support number boolean and string
254-
255-
propertyValue = propertyValue.trim();
256-
257-
if (
258-
Number.isInteger(Number(propertyValue)) ||
259-
propertyValue === 'false' ||
260-
propertyValue === 'true'
261-
) {
262-
return propertyValue;
263-
}
264-
265-
return `\\"${propertyValue}\\"`;
266-
}

packages/blocks/terraform/test/hcledit-cli.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,35 @@ describe('Update Resource Properties', () => {
214214
);
215215
});
216216

217+
test('should preserve numeric and boolean property values', async () => {
218+
const modifications = [
219+
{ propertyName: 'enable_feature', propertyValue: true },
220+
{ propertyName: 'max_count', propertyValue: 3 },
221+
];
222+
223+
mockExecuteCommand
224+
.mockResolvedValueOnce({ exitCode: 1, stdOut: '', stdError: 'missing' })
225+
.mockResolvedValueOnce({ exitCode: 0, stdOut: 'current', stdError: '' })
226+
.mockResolvedValueOnce({ exitCode: 0, stdOut: 'result', stdError: '' });
227+
228+
const result = await updateResourceProperties(
229+
testTemplate,
230+
'aws_instance',
231+
'example',
232+
modifications,
233+
);
234+
235+
expect(result).toContain('result');
236+
expect(mockExecuteCommand).toHaveBeenCalledTimes(3);
237+
const executedCommand = mockExecuteCommand.mock.calls[2][1][1];
238+
expect(executedCommand).toContain(
239+
`attribute append resource.aws_instance.example.enable_feature 'true'`,
240+
);
241+
expect(executedCommand).toContain(
242+
`attribute set resource.aws_instance.example.max_count '3'`,
243+
);
244+
});
245+
217246
test.each<{
218247
description: string;
219248
resourceType: string;

0 commit comments

Comments
 (0)