|
3 | 3 | * Deletes in reverse dependency order: EC2 → Application → DQS → OSIS → IAM → (preserves AOS/AMP). |
4 | 4 | */ |
5 | 5 | import { OSISClient, DeletePipelineCommand, GetPipelineCommand } from '@aws-sdk/client-osis'; |
6 | | -import { OpenSearchClient, ListApplicationsCommand, DeleteApplicationCommand, DeleteDirectQueryDataSourceCommand, GetApplicationCommand, DescribeDomainCommand } from '@aws-sdk/client-opensearch'; |
| 6 | +import { OpenSearchClient, ListApplicationsCommand, DeleteApplicationCommand, DeleteDirectQueryDataSourceCommand, GetApplicationCommand, DescribeDomainCommand, DeleteDomainCommand } from '@aws-sdk/client-opensearch'; |
7 | 7 | import { IAMClient, DeleteRolePolicyCommand, DeleteRoleCommand, ListRolePoliciesCommand, ListAttachedRolePoliciesCommand, DetachRolePolicyCommand } from '@aws-sdk/client-iam'; |
8 | 8 | import { printStep, printSuccess, printWarning, printInfo, createSpinner } from './ui.mjs'; |
9 | 9 | import { teardownDemoInstance } from './ec2-demo.mjs'; |
@@ -150,7 +150,36 @@ export async function destroy(cfg) { |
150 | 150 | if (e.name !== 'ResourceNotFoundException') printWarning(`Secret cleanup: ${e.message}`); |
151 | 151 | } |
152 | 152 |
|
| 153 | + // 7. OpenSearch domain (if tagged with this stack) |
| 154 | + try { |
| 155 | + const { ResourceGroupsTaggingAPIClient, GetResourcesCommand } = await import('@aws-sdk/client-resource-groups-tagging-api'); |
| 156 | + const tagging = new ResourceGroupsTaggingAPIClient({ region }); |
| 157 | + const { ResourceTagMappingList } = await tagging.send(new GetResourcesCommand({ |
| 158 | + TagFilters: [{ Key: 'observability-stack', Values: [pipelineName] }], |
| 159 | + ResourceTypeFilters: ['es:domain'], |
| 160 | + })); |
| 161 | + for (const r of ResourceTagMappingList || []) { |
| 162 | + const domainName = r.ResourceARN.split('/').pop(); |
| 163 | + const spinner = createSpinner(`Deleting OpenSearch domain '${domainName}'...`); |
| 164 | + await os.send(new DeleteDomainCommand({ DomainName: domainName })); |
| 165 | + spinner.stop(`Domain '${domainName}' deleted`); |
| 166 | + } |
| 167 | + } catch (e) { printWarning(`Domain cleanup: ${e.message}`); } |
| 168 | + |
| 169 | + // 8. AMP workspace (if tagged with this stack) |
| 170 | + try { |
| 171 | + const { AMPClient, ListWorkspacesCommand, DeleteWorkspaceCommand } = await import('@aws-sdk/client-amp'); |
| 172 | + const amp = new AMPClient({ region }); |
| 173 | + const { workspaces } = await amp.send(new ListWorkspacesCommand({ alias: pipelineName })); |
| 174 | + for (const w of workspaces || []) { |
| 175 | + if (w.alias === pipelineName) { |
| 176 | + const spinner = createSpinner(`Deleting AMP workspace '${w.alias}'...`); |
| 177 | + await amp.send(new DeleteWorkspaceCommand({ workspaceId: w.workspaceId })); |
| 178 | + spinner.stop(`AMP workspace '${w.alias}' deleted`); |
| 179 | + } |
| 180 | + } |
| 181 | + } catch (e) { printWarning(`AMP cleanup: ${e.message}`); } |
| 182 | + |
153 | 183 | console.error(); |
154 | 184 | printSuccess('Destroy complete'); |
155 | | - printInfo('Note: OpenSearch domain and AMP workspace were preserved (shared resources)'); |
156 | 185 | } |
0 commit comments