mirror of https://github.com/docusealco/docuseal
				
				
				
			
							parent
							
								
									a317c030a1
								
							
						
					
					
						commit
						e39ab1fba3
					
				| @ -0,0 +1,5 @@ | |||||||
|  | node_modules | ||||||
|  | 
 | ||||||
|  | # CDK asset staging directory | ||||||
|  | .cdk.staging | ||||||
|  | cdk.out | ||||||
| @ -0,0 +1,3 @@ | |||||||
|  | # CDK asset staging directory | ||||||
|  | .cdk.staging | ||||||
|  | cdk.out | ||||||
| @ -0,0 +1,153 @@ | |||||||
|  | # CP Docuseal CDK Infrastructure | ||||||
|  | 
 | ||||||
|  | This directory contains AWS CDK v2 infrastructure code for deploying the CP Docuseal app. At present it only deploys to development and staging; production will follow. | ||||||
|  | 
 | ||||||
|  | ## Architecture Overview | ||||||
|  | 
 | ||||||
|  | This infrastructure is basically nicked wholesale from the Integration Station application, just dialed down a notch as our needs are a bit less than theirs. | ||||||
|  | 
 | ||||||
|  | - **Internal Application Load Balancer (ALB)** - Routes traffic to ECS services within the VPC | ||||||
|  | - **Amazon ECS Cluster** - Runs containerized applications on EC2 instances (ARM64 t4g.small) | ||||||
|  | - **ECS Service** - Manages container deployment and scaling | ||||||
|  | - **ECS Task Definition** - Defines container configuration and resource requirements | ||||||
|  | - **CloudWatch Logging** - Centralized logging for application monitoring | ||||||
|  | - **Security Groups** - Network security controls | ||||||
|  | - **ECR Integration** - Uses existing "integration-station" ECR repository | ||||||
|  | 
 | ||||||
|  | ## Prerequisites | ||||||
|  | 
 | ||||||
|  | 1. **AWS CLI** configured with appropriate permissions | ||||||
|  | 2. **Node.js** (version 22 or later) | ||||||
|  | 3. **AWS CDK v2** installed globally: `npm install -g aws-cdk` | ||||||
|  | 4. **Existing AWS Infrastructure**: | ||||||
|  |    - VPC with public and private subnets | ||||||
|  |    - ECR repository named "cp-docuseal" | ||||||
|  |    - Appropriate IAM permissions for CDK deployment | ||||||
|  | 
 | ||||||
|  | ## Setup | ||||||
|  | 
 | ||||||
|  | 1. **Install dependencies**: | ||||||
|  |    ```bash | ||||||
|  |    cd cdk_deploy | ||||||
|  |    npm install | ||||||
|  |    ``` | ||||||
|  | 
 | ||||||
|  | 2. **Bootstrap CDK** (application setup ONLY): | ||||||
|  |    ```bash | ||||||
|  |    npm run bootstrap | ||||||
|  |    ``` | ||||||
|  | 
 | ||||||
|  | 3. **Update VPC and Subnet IDs**: | ||||||
|  |    Edit `app.js` and replace the placeholder IDs with your actual VPC and subnet IDs: | ||||||
|  |    ```javascript | ||||||
|  |    vpcId: 'vpc-your-actual-vpc-id', | ||||||
|  |    privateSubnetIds: ['subnet-your-private-1', 'subnet-your-private-2'], | ||||||
|  |    publicSubnetIds: ['subnet-your-public-1', 'subnet-your-public-2'] | ||||||
|  |    ``` | ||||||
|  | 
 | ||||||
|  | ## Environment Configuration | ||||||
|  | 
 | ||||||
|  | The infrastructure supports three environments with different resource allocations: | ||||||
|  | 
 | ||||||
|  | ### Development | ||||||
|  | - **Instances**: 1 ECS instance | ||||||
|  | - **CPU**: 512 units | ||||||
|  | - **Memory**: 1024 MB | ||||||
|  | 
 | ||||||
|  | ### Staging | ||||||
|  | - **Instances**: 1 ECS instance | ||||||
|  | - **CPU**: 512 units | ||||||
|  | - **Memory**: 1024 MB | ||||||
|  | 
 | ||||||
|  | ### Production | ||||||
|  | - N/A | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## Deployment | ||||||
|  | 
 | ||||||
|  | ### Deploy to Development | ||||||
|  | ```bash | ||||||
|  | npm run deploy:dev | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Deploy to Staging | ||||||
|  | ```bash | ||||||
|  | npm run deploy:staging | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Deploy to Production - NOT YET SUPPORTED | ||||||
|  | ```bash | ||||||
|  | npm run deploy:prod | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### View CloudFormation Template | ||||||
|  | ```bash | ||||||
|  | npm run synth | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Compare Changes | ||||||
|  | ```bash | ||||||
|  | npm run diff | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Cleanup | ||||||
|  | 
 | ||||||
|  | ### Destroy Development Environment | ||||||
|  | ```bash | ||||||
|  | npm run destroy:dev | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Destroy Staging Environment | ||||||
|  | ```bash | ||||||
|  | npm run destroy:staging | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Destroy Production Environment - NOT YET SUPPORTED | ||||||
|  | ```bash | ||||||
|  | npm run destroy:prod | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Important Notes | ||||||
|  | 
 | ||||||
|  | 1. **Internal ALB**: The Application Load Balancer is configured as internal-only and deployed in private subnets for security. | ||||||
|  | 
 | ||||||
|  | 2. **ARM64 Instances**: The ECS cluster uses t4g.small ARM64 instances for cost efficiency. Ensure your container images are built for ARM64 architecture. | ||||||
|  | 
 | ||||||
|  | 3. **Health Checks**: The ALB target group is configured to perform health checks on `/health` endpoint. Make sure your application responds to this endpoint. | ||||||
|  | 
 | ||||||
|  | 4. **Logging**: All ECS tasks automatically log to CloudWatch under `/ecs/cp-docuseal-{environment}` log groups. | ||||||
|  | 
 | ||||||
|  | 5. **Security**: Security groups are configured to allow: | ||||||
|  |    - ALB: HTTP (80) and HTTPS (443) traffic | ||||||
|  |    - ECS: Traffic from ALB on port 3000 | ||||||
|  | 
 | ||||||
|  | ## Troubleshooting | ||||||
|  | 
 | ||||||
|  | 1. **VPC Lookup Issues**: Ensure the VPC IDs and subnet IDs in `app.js` are correct and exist in your AWS account. | ||||||
|  | 
 | ||||||
|  | 2. **ECR Repository**: Verify that the "cp-docuseal" ECR repository exists and contains the required Docker images. | ||||||
|  | 
 | ||||||
|  | 3. **Permissions**: Ensure your AWS credentials have sufficient permissions for: | ||||||
|  |    - EC2 (VPC, Security Groups, Launch Templates) | ||||||
|  |    - ECS (Clusters, Services, Tasks) | ||||||
|  |    - ELB (Application Load Balancers, Target Groups) | ||||||
|  |    - CloudWatch (Log Groups) | ||||||
|  |    - IAM (Roles and Policies) | ||||||
|  | 
 | ||||||
|  | 4. **Container Health**: If services fail to start, check CloudWatch logs for container startup issues. | ||||||
|  | 
 | ||||||
|  | ## Customization | ||||||
|  | 
 | ||||||
|  | You can modify the following aspects: | ||||||
|  | 
 | ||||||
|  | - **Instance Types**: Change `ec2.InstanceClass.T4G` and `ec2.InstanceSize.SMALL` in the stack | ||||||
|  | - **Container Port**: Update port mappings if your application uses a different port | ||||||
|  | - **Resource Limits**: Adjust CPU and memory allocations in the environment configurations | ||||||
|  | - **Auto Scaling**: Modify `minCapacity` and `maxCapacity` for different scaling behaviors | ||||||
|  | 
 | ||||||
|  | ## Stack Outputs | ||||||
|  | 
 | ||||||
|  | After deployment, the stack provides: | ||||||
|  | - **ALB DNS Name**: Internal DNS name for the Application Load Balancer | ||||||
|  | - **ECS Cluster Name**: Name of the created ECS cluster | ||||||
|  | - **ECS Service Name**: Name of the ECS service  | ||||||
| @ -0,0 +1,109 @@ | |||||||
|  | #!/usr/bin/env node
 | ||||||
|  | 
 | ||||||
|  | const { App } = require('aws-cdk-lib'); | ||||||
|  | const { CPDocusealStack } = require('./lib/cp-docuseal-stack'); | ||||||
|  | const fs = require('fs'); | ||||||
|  | 
 | ||||||
|  | const app = new App(); | ||||||
|  | 
 | ||||||
|  | const userDataScript = fs.readFileSync('./userdata.txt', 'utf8'); | ||||||
|  | 
 | ||||||
|  | // Get staging number from context if provided
 | ||||||
|  | const stagingNumber = app.node.tryGetContext('stagingNumber'); | ||||||
|  | 
 | ||||||
|  | // Function to get certificate ARN based on staging number
 | ||||||
|  | function getStagingCertificateArn(stagingNumber) { | ||||||
|  |   if (!stagingNumber) { | ||||||
|  |     // Default certificate for staging when no staging number is provided
 | ||||||
|  |     return 'arn:aws:acm:us-east-1:788066832395:certificate/5b1f59b9-ab27-4056-a5e2-0d89554e5f35'; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   const num = parseInt(stagingNumber); | ||||||
|  | 
 | ||||||
|  |   if (num >= 1 && num <= 11) { | ||||||
|  |     return 'arn:aws:acm:us-east-1:788066832395:certificate/d3ae2320-6da3-4a6f-a3d9-0f00f85033cb'; | ||||||
|  |   } else if (num >= 12 && num <= 22) { | ||||||
|  |     return 'arn:aws:acm:us-east-1:788066832395:certificate/5b1f59b9-ab27-4056-a5e2-0d89554e5f35'; | ||||||
|  |   } else if (num >= 23 && num <= 24) { | ||||||
|  |     return 'arn:aws:acm:us-east-1:788066832395:certificate/69a8fe61-f12f-4251-9e55-d68c21553388'; | ||||||
|  |   } else if (num >= 25 && num <= 27) { | ||||||
|  |     return 'arn:aws:acm:us-east-1:788066832395:certificate/3ce231d1-b2ec-4013-80db-b231db5a1e02'; | ||||||
|  |   } else { | ||||||
|  |     // Default certificate for staging numbers outside defined ranges
 | ||||||
|  |     return 'arn:aws:acm:us-east-1:788066832395:certificate/5b1f59b9-ab27-4056-a5e2-0d89554e5f35'; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Environment configurations
 | ||||||
|  | const environments = { | ||||||
|  |   dev: { | ||||||
|  |     account: process.env.CDK_DEFAULT_ACCOUNT, | ||||||
|  |     region: process.env.CDK_DEFAULT_REGION || 'us-east-1', | ||||||
|  |     vpcId: 'vpc-95c19df2', | ||||||
|  |     publicSubnetIds: ['subnet-ff02dbb6', 'subnet-69fe1132', 'subnet-cb8e63f7' ], | ||||||
|  |     instanceCount: 1, | ||||||
|  |     instanceSize: 'SMALL', | ||||||
|  |     cpu: 512, | ||||||
|  |     memory: 1024, | ||||||
|  |     securityGroupIds: ["sg-0f0da2fa2d6088742", "sg-006e8df67aec60469"], | ||||||
|  |     userDataScript: userDataScript, | ||||||
|  |     certificateArn: 'arn:aws:acm:us-east-1:788066832395:certificate/5b1f59b9-ab27-4056-a5e2-0d89554e5f35', | ||||||
|  |   }, | ||||||
|  |   staging: { | ||||||
|  |     account: process.env.CDK_DEFAULT_ACCOUNT, | ||||||
|  |     region: process.env.CDK_DEFAULT_REGION || 'us-east-1', | ||||||
|  |     vpcId: 'vpc-95c19df2', | ||||||
|  |     publicSubnetIds: ['subnet-ff02dbb6', 'subnet-69fe1132', 'subnet-cb8e63f7'], | ||||||
|  |     instanceCount: 1, | ||||||
|  |     instanceSize: 'SMALL', | ||||||
|  |     apiCpu: 512, | ||||||
|  |     apiMemory: 1024, | ||||||
|  |     securityGroupIds: ["sg-0f0da2fa2d6088742", "sg-006e8df67aec60469"], | ||||||
|  |     userDataScript: userDataScript, | ||||||
|  |     certificateArn: getStagingCertificateArn(stagingNumber), | ||||||
|  |   }, | ||||||
|  |   // production: {
 | ||||||
|  |   //   account: process.env.CDK_DEFAULT_ACCOUNT,
 | ||||||
|  |   //   region: process.env.CDK_DEFAULT_REGION || 'us-east-1',
 | ||||||
|  |   //   vpcId: 'vpc-95c19df2',
 | ||||||
|  |   //   publicSubnetIds: ['subnet-ff02dbb6', 'subnet-69fe1132', 'subnet-cb8e63f7' ],
 | ||||||
|  |   //   instanceCount: 2,
 | ||||||
|  |   //   instanceSize: 'LARGE',
 | ||||||
|  |   //   apiCpu: 900,
 | ||||||
|  |   //   apiMemory: 3000,
 | ||||||
|  |   //   sidekiqCpu: 900,
 | ||||||
|  |   //   sidekiqMemory: 3000,
 | ||||||
|  |   //   securityGroupIds: ["sg-09fa17711757036e6", "sg-006e8df67aec60469"],
 | ||||||
|  |   //   userDataScript: userDataScript,
 | ||||||
|  |   //   certificateArn: 'arn:aws:acm:us-east-1:788066832395:certificate/05fa2bb8-5589-4425-9f28-427f1082a64b',
 | ||||||
|  |   // }
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // Create stacks for each environment
 | ||||||
|  | Object.entries(environments).forEach(([envName, config]) => { | ||||||
|  |   // Construct stack name with staging number if provided
 | ||||||
|  |   let stackName = `CPDocusealStack-${envName}`; | ||||||
|  |   let environmentName = envName; | ||||||
|  | 
 | ||||||
|  |   // Append staging number for staging environments
 | ||||||
|  |   if (envName === 'staging' && stagingNumber) { | ||||||
|  |     stackName += `-${stagingNumber}`; | ||||||
|  |     environmentName += `-${stagingNumber}`; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   new CPDocusealStack(app, stackName, { | ||||||
|  |     env: { | ||||||
|  |       account: config.account, | ||||||
|  |       region: config.region | ||||||
|  |     }, | ||||||
|  |     environment: envName, | ||||||
|  |     vpcConfig: { | ||||||
|  |       vpcId: config.vpcId, | ||||||
|  |       publicSubnetIds: config.publicSubnetIds | ||||||
|  |     }, | ||||||
|  |     ecsConfig: config, | ||||||
|  |     certificateArn: config.certificateArn, | ||||||
|  |     securityGroupIds: config.securityGroupIds, | ||||||
|  |     userDataScript: config.userDataScript | ||||||
|  |   }); | ||||||
|  | });  | ||||||
| @ -0,0 +1,82 @@ | |||||||
|  | { | ||||||
|  |   "vpc-provider:account=788066832395:filter.vpc-id=vpc-95c19df2:region=us-east-1:returnAsymmetricSubnets=true": { | ||||||
|  |     "vpcId": "vpc-95c19df2", | ||||||
|  |     "vpcCidrBlock": "172.30.0.0/16", | ||||||
|  |     "ownerAccountId": "788066832395", | ||||||
|  |     "availabilityZones": [], | ||||||
|  |     "subnetGroups": [ | ||||||
|  |       { | ||||||
|  |         "name": "Public", | ||||||
|  |         "type": "Public", | ||||||
|  |         "subnets": [ | ||||||
|  |           { | ||||||
|  |             "subnetId": "subnet-ff02dbb6", | ||||||
|  |             "cidr": "172.30.0.0/24", | ||||||
|  |             "availabilityZone": "us-east-1a", | ||||||
|  |             "routeTableId": "rtb-27219141" | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             "subnetId": "subnet-69fe1132", | ||||||
|  |             "cidr": "172.30.1.0/24", | ||||||
|  |             "availabilityZone": "us-east-1b", | ||||||
|  |             "routeTableId": "rtb-27219141" | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             "subnetId": "subnet-95927bb8", | ||||||
|  |             "cidr": "172.30.2.0/24", | ||||||
|  |             "availabilityZone": "us-east-1d", | ||||||
|  |             "routeTableId": "rtb-27219141" | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             "subnetId": "subnet-0a1feb6c1333efbab", | ||||||
|  |             "cidr": "172.30.8.0/24", | ||||||
|  |             "availabilityZone": "us-east-1d", | ||||||
|  |             "routeTableId": "rtb-27219141" | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             "subnetId": "subnet-cb8e63f7", | ||||||
|  |             "cidr": "172.30.3.0/24", | ||||||
|  |             "availabilityZone": "us-east-1e", | ||||||
|  |             "routeTableId": "rtb-27219141" | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             "subnetId": "subnet-0f5743e7967df31ef", | ||||||
|  |             "cidr": "172.30.4.0/24", | ||||||
|  |             "availabilityZone": "us-east-1f", | ||||||
|  |             "routeTableId": "rtb-27219141" | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             "subnetId": "subnet-0118637ce4cf80f0a", | ||||||
|  |             "cidr": "172.30.10.0/24", | ||||||
|  |             "availabilityZone": "us-east-1f", | ||||||
|  |             "routeTableId": "rtb-27219141" | ||||||
|  |           } | ||||||
|  |         ] | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "Private", | ||||||
|  |         "type": "Private", | ||||||
|  |         "subnets": [ | ||||||
|  |           { | ||||||
|  |             "subnetId": "subnet-0a263997449735cfd", | ||||||
|  |             "cidr": "172.30.5.0/24", | ||||||
|  |             "availabilityZone": "us-east-1a", | ||||||
|  |             "routeTableId": "rtb-07ee1e39f005b06f2" | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             "subnetId": "subnet-05e98535001316fe8", | ||||||
|  |             "cidr": "172.30.6.0/24", | ||||||
|  |             "availabilityZone": "us-east-1b", | ||||||
|  |             "routeTableId": "rtb-07ee1e39f005b06f2" | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             "subnetId": "subnet-0bcf29b2a2a47fbb7", | ||||||
|  |             "cidr": "172.30.9.0/24", | ||||||
|  |             "availabilityZone": "us-east-1e", | ||||||
|  |             "routeTableId": "rtb-07ee1e39f005b06f2" | ||||||
|  |           } | ||||||
|  |         ] | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,64 @@ | |||||||
|  | { | ||||||
|  |   "app": "node app.js", | ||||||
|  |   "watch": { | ||||||
|  |     "include": [ | ||||||
|  |       "**" | ||||||
|  |     ], | ||||||
|  |     "exclude": [ | ||||||
|  |       "README.md", | ||||||
|  |       "cdk*.json", | ||||||
|  |       "**/*.js", | ||||||
|  |       "package*.json", | ||||||
|  |       "yarn.lock", | ||||||
|  |       "node_modules" | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  |   "context": { | ||||||
|  |     "@aws-cdk/aws-lambda:recognizeLayerVersion": true, | ||||||
|  |     "@aws-cdk/core:checkSecretUsage": true, | ||||||
|  |     "@aws-cdk/core:target-partitions": [ | ||||||
|  |       "aws", | ||||||
|  |       "aws-cn" | ||||||
|  |     ], | ||||||
|  |     "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, | ||||||
|  |     "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, | ||||||
|  |     "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, | ||||||
|  |     "@aws-cdk/aws-iam:minimizePolicies": true, | ||||||
|  |     "@aws-cdk/core:validateSnapshotRemovalPolicy": true, | ||||||
|  |     "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, | ||||||
|  |     "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, | ||||||
|  |     "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, | ||||||
|  |     "@aws-cdk/aws-apigateway:disableCloudWatchRole": true, | ||||||
|  |     "@aws-cdk/core:enablePartitionLiterals": true, | ||||||
|  |     "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, | ||||||
|  |     "@aws-cdk/aws-iam:standardizedServicePrincipals": true, | ||||||
|  |     "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, | ||||||
|  |     "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, | ||||||
|  |     "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, | ||||||
|  |     "@aws-cdk/aws-route53-patters:useCertificate": true, | ||||||
|  |     "@aws-cdk/customresources:installLatestAwsSdkDefault": false, | ||||||
|  |     "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, | ||||||
|  |     "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, | ||||||
|  |     "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, | ||||||
|  |     "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, | ||||||
|  |     "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, | ||||||
|  |     "@aws-cdk/aws-redshift:columnId": true, | ||||||
|  |     "@aws-cdk/aws-stepfunctions-tasks:enableLoggingConfiguration": true, | ||||||
|  |     "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, | ||||||
|  |     "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, | ||||||
|  |     "@aws-cdk/aws-kms:aliasNameRef": true, | ||||||
|  |     "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true, | ||||||
|  |     "@aws-cdk/core:includePrefixInUniqueNameGeneration": true, | ||||||
|  |     "@aws-cdk/aws-efs:denyAnonymousAccess": true, | ||||||
|  |     "@aws-cdk/aws-opensearchservice:enableLogging": true, | ||||||
|  |     "@aws-cdk/aws-noralization:emptyOperationContext": true, | ||||||
|  |     "@aws-cdk/aws-lambda:codecommitPolicyDefaultTargetsBranch": true, | ||||||
|  |     "@aws-cdk/aws-lambda:recognizeVersionProps": true, | ||||||
|  |     "@aws-cdk/aws-cloudformation:parseParamsAndSecretsConfiguration": true, | ||||||
|  |     "@aws-cdk/aws-eks:nodegroupNameAttribute": true, | ||||||
|  |     "@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true, | ||||||
|  |     "@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": true, | ||||||
|  |     "@aws-cdk/aws-ec2:disableSubnetCreateDefaultRouteToIgw": true, | ||||||
|  |     "@aws-cdk/aws-ec2:ipv4IpamPoolPublicIpSource": true | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,382 @@ | |||||||
|  | const { | ||||||
|  |   Stack, | ||||||
|  |   Duration, | ||||||
|  |   aws_ec2: ec2, | ||||||
|  |   aws_ecs: ecs, | ||||||
|  |   aws_elasticloadbalancingv2: elbv2, | ||||||
|  |   aws_logs: logs, | ||||||
|  |   aws_iam: iam, | ||||||
|  |   aws_ecr: ecr, | ||||||
|  |   aws_secretsmanager: secretsmanager, | ||||||
|  |   aws_certificatemanager: acm, | ||||||
|  |   aws_route53: route53, | ||||||
|  |   aws_route53_targets: targets, | ||||||
|  |   Aspects, | ||||||
|  |   RemovalPolicy | ||||||
|  | } = require('aws-cdk-lib'); | ||||||
|  | const { Construct } = require('constructs'); | ||||||
|  | 
 | ||||||
|  | class CPDocusealStack extends Stack { | ||||||
|  |   constructor(scope, id, props) { | ||||||
|  |     super(scope, id, props); | ||||||
|  | 
 | ||||||
|  |     const { environment, vpcConfig, ecsConfig, securityGroupIds, userDataScript } = props; | ||||||
|  |      | ||||||
|  |     // Get the image tag from CDK context, default to 'latest' if not provided
 | ||||||
|  |     const imageTag = this.node.tryGetContext('imageTag') || 'latest'; | ||||||
|  |     const stagingNumber = this.node.tryGetContext('stagingNumber') || null; | ||||||
|  |     const envDescription = stagingNumber ? `${environment}-${stagingNumber}` : environment; | ||||||
|  | 
 | ||||||
|  |     // Import existing VPC
 | ||||||
|  |     const vpc = ec2.Vpc.fromLookup(this, 'VPC', { | ||||||
|  |       vpcId: vpcConfig.vpcId | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     // Import existing subnets
 | ||||||
|  |     const publicSubnets = vpcConfig.publicSubnetIds.map((subnetId, index) => | ||||||
|  |       ec2.Subnet.fromSubnetId(this, `PublicSubnet${index}`, subnetId) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     // Security Group for ALB
 | ||||||
|  |     const albSecurityGroup = new ec2.SecurityGroup(this, 'ALBSecurityGroup', { | ||||||
|  |       vpc, | ||||||
|  |       description: `ALB Security Group for ${envDescription}`, | ||||||
|  |       allowAllOutbound: true | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     // we may not need this...
 | ||||||
|  |     albSecurityGroup.addIngressRule( | ||||||
|  |       ec2.Peer.anyIpv4(), | ||||||
|  |       ec2.Port.tcp(80), | ||||||
|  |       'Allow HTTP traffic' | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     albSecurityGroup.addIngressRule( | ||||||
|  |       ec2.Peer.anyIpv4(), | ||||||
|  |       ec2.Port.tcp(443), | ||||||
|  |       'Allow HTTPS traffic' | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     // Security Group for ECS Tasks
 | ||||||
|  |     const ecsSecurityGroup = new ec2.SecurityGroup(this, 'ECSSecurityGroup', { | ||||||
|  |       vpc, | ||||||
|  |       description: `ECS Security Group for ${envDescription}`, | ||||||
|  |       allowAllOutbound: true | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     ecsSecurityGroup.addIngressRule( | ||||||
|  |       albSecurityGroup, | ||||||
|  |       ec2.Port.tcp(3001), | ||||||
|  |       'Allow traffic from ALB' | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     // Internal Application Load Balancer
 | ||||||
|  |     const alb = new elbv2.ApplicationLoadBalancer(this, 'InternalALB', { | ||||||
|  |       vpc, | ||||||
|  |       internetFacing: true, | ||||||
|  |       vpcSubnets: { | ||||||
|  |         subnets: publicSubnets | ||||||
|  |       }, | ||||||
|  |       securityGroup: albSecurityGroup, | ||||||
|  |       loadBalancerName: `cpd-alb-${envDescription}` | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     // Target Group for ECS Service
 | ||||||
|  |     const targetGroup = new elbv2.ApplicationTargetGroup(this, 'ECSTargetGroup', { | ||||||
|  |       vpc, | ||||||
|  |       port: 3001, | ||||||
|  |       protocol: elbv2.ApplicationProtocol.HTTP, | ||||||
|  |       targetType: elbv2.TargetType.INSTANCE, | ||||||
|  |       healthCheck: { | ||||||
|  |         enabled: true, | ||||||
|  |         healthyHttpCodes: '200', | ||||||
|  |         path: '/up', | ||||||
|  |         protocol: elbv2.Protocol.HTTP, | ||||||
|  |         interval: Duration.seconds(30), | ||||||
|  |         timeout: Duration.seconds(5), | ||||||
|  |         healthyThresholdCount: 2, | ||||||
|  |         unhealthyThresholdCount: 5 | ||||||
|  |       }, | ||||||
|  |       deregistrationDelay: Duration.seconds(20), | ||||||
|  |       targetGroupName: `cpd-tg-${envDescription}` | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     // ALB Listener
 | ||||||
|  |     const listener = alb.addListener('ALBListener', { | ||||||
|  |       port: 80, | ||||||
|  |       protocol: elbv2.ApplicationProtocol.HTTP, | ||||||
|  |       defaultTargetGroups: [targetGroup] | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     // Accept certificateArn as input (default to provided value if not in props)
 | ||||||
|  |     const certificateArn = props.certificateArn || 'arn:aws:acm:us-east-1:788066832395:certificate/05fa2bb8-5589-4425-9f28-427f1082a64b'; | ||||||
|  | 
 | ||||||
|  |     // Add HTTPS Listener with ACM certificate
 | ||||||
|  |     const certificate = acm.Certificate.fromCertificateArn(this, 'ALBCertificate', certificateArn); | ||||||
|  |     alb.addListener('ALBListenerHTTPS', { | ||||||
|  |       port: 443, | ||||||
|  |       protocol: elbv2.ApplicationProtocol.HTTPS, | ||||||
|  |       certificates: [certificate], | ||||||
|  |       defaultTargetGroups: [targetGroup] | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     // Create Route53 A record for staging and production environments
 | ||||||
|  |     let hostedZoneDomain = null; | ||||||
|  |      | ||||||
|  |     if (environment === 'staging' && stagingNumber) { | ||||||
|  |       hostedZoneDomain = `cpstaging${stagingNumber}.name`; | ||||||
|  |     // } else if (environment === 'production') {
 | ||||||
|  |     //   hostedZoneDomain = 'careerplug.com';
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (hostedZoneDomain) { | ||||||
|  |       const recordName = 'cpd'; | ||||||
|  | 
 | ||||||
|  |       // Import the existing hosted zone
 | ||||||
|  |       const hostedZone = route53.HostedZone.fromLookup(this, 'HostedZone', { | ||||||
|  |         domainName: hostedZoneDomain | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       // Create A record pointing to ALB
 | ||||||
|  |       new route53.ARecord(this, 'ALBARecord', { | ||||||
|  |         zone: hostedZone, | ||||||
|  |         recordName: recordName, | ||||||
|  |         target: route53.RecordTarget.fromAlias(new targets.LoadBalancerTarget(alb)), | ||||||
|  |         ttl: Duration.minutes(1), | ||||||
|  |         comment: `A record for CP Docuseal ${envDescription}` | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // ECS Cluster
 | ||||||
|  |     const cluster = new ecs.Cluster(this, 'ECSCluster', { | ||||||
|  |       vpc, | ||||||
|  |       clusterName: `cp-docuseal-${envDescription}`, | ||||||
|  |       containerInsightsV2: ecs.ContainerInsights.ENABLED | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     // Determine instance size based on configuration
 | ||||||
|  |     const instanceSize = ecsConfig.instanceSize || 'SMALL'; | ||||||
|  |      | ||||||
|  |     // Import additional existing security groups by ID from props
 | ||||||
|  |     const importedSecurityGroups = (securityGroupIds || []).map((sgId, idx) => | ||||||
|  |       ec2.SecurityGroup.fromSecurityGroupId(this, `ImportedSG${idx + 1}`, sgId) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     // Auto Scaling Group for ECS with ARM64 instances
 | ||||||
|  |     const autoScalingGroup = cluster.addCapacity('ECSAutoScalingGroup', { | ||||||
|  |       instanceType: ec2.InstanceType.of(ec2.InstanceClass.T4G, ec2.InstanceSize[instanceSize]), // ARM64
 | ||||||
|  |       machineImage: ecs.EcsOptimizedImage.amazonLinux2(ecs.AmiHardwareType.ARM), | ||||||
|  |       minCapacity: ecsConfig.instanceCount, | ||||||
|  |       maxCapacity: ecsConfig.instanceCount, | ||||||
|  |       vpcSubnets: { | ||||||
|  |         subnets: publicSubnets | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     // Attach imported security groups to the EC2 instances
 | ||||||
|  |     importedSecurityGroups.forEach((sg, idx) => { | ||||||
|  |       autoScalingGroup.addSecurityGroup(sg); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     // Add security group rule to EC2 instances for HOST network mode
 | ||||||
|  |     // Allow ALB to reach containers on port 3001
 | ||||||
|  |     autoScalingGroup.addSecurityGroup(ecsSecurityGroup); | ||||||
|  | 
 | ||||||
|  |     if (userDataScript) { | ||||||
|  |       autoScalingGroup.addUserData(userDataScript); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // CloudWatch Log Groups
 | ||||||
|  |     const apiLogGroup = new logs.LogGroup(this, 'APILogGroup', { | ||||||
|  |       logGroupName: `/ecs/cp-docuseal-api-${envDescription}`, | ||||||
|  |       retention: logs.RetentionDays.ONE_WEEK | ||||||
|  |     }); | ||||||
|  |     apiLogGroup.applyRemovalPolicy(RemovalPolicy.DESTROY); | ||||||
|  | 
 | ||||||
|  |     // const sidekiqLogGroup = new logs.LogGroup(this, 'SidekiqLogGroup', {
 | ||||||
|  |     //   logGroupName: `/ecs/cp-docuseal-sidekiq-${envDescription}`,
 | ||||||
|  |     //   retention: logs.RetentionDays.ONE_WEEK
 | ||||||
|  |     // });
 | ||||||
|  |     // sidekiqLogGroup.applyRemovalPolicy(RemovalPolicy.DESTROY);
 | ||||||
|  | 
 | ||||||
|  |     // Import ECR Repository
 | ||||||
|  |     const ecrRepository = ecr.Repository.fromRepositoryName( | ||||||
|  |       this, | ||||||
|  |       'ECRRepository', | ||||||
|  |       'cp-docuseal' | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     // Task Definition
 | ||||||
|  |     const taskDefinition = new ecs.Ec2TaskDefinition(this, 'TaskDefinition', { | ||||||
|  |       family: `cp-docuseal-task-${envDescription}`, | ||||||
|  |       networkMode: ecs.NetworkMode.HOST | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     // Base environment variables
 | ||||||
|  |     const containerEnvironment = { | ||||||
|  |       NODE_ENV: environment, | ||||||
|  |       PORT: '3001', | ||||||
|  |       RAILS_ENV: environment | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     // Add environment-specific variables
 | ||||||
|  |     if (environment === 'staging') { // || environment === 'production') {
 | ||||||
|  |       // For staging and production, we'll use Secrets Manager
 | ||||||
|  |       containerEnvironment.AWS_REGION = this.region; | ||||||
|  |       // Map production environment to prod for secret naming
 | ||||||
|  |       const secretEnvironment = environment; // === 'production' ? 'prod' : environment;
 | ||||||
|  |       containerEnvironment.DB_SECRETS_NAME = `${secretEnvironment}/db_creds`; | ||||||
|  | 
 | ||||||
|  |       // set DB name
 | ||||||
|  |       containerEnvironment.DB_NAME = `cpdocuseal${stagingNumber ? `${stagingNumber}` : ''}`; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Check if we need multi-container setup (staging and production)
 | ||||||
|  |     const isMultiContainer = environment === 'staging'; // || environment === 'production';
 | ||||||
|  | 
 | ||||||
|  |     if (isMultiContainer) { | ||||||
|  |       // API Container Definition
 | ||||||
|  |       const apiContainerConfig = { | ||||||
|  |         image: ecs.ContainerImage.fromEcrRepository(ecrRepository, imageTag), | ||||||
|  |         cpu: ecsConfig.apiCpu, | ||||||
|  |         memoryLimitMiB: ecsConfig.apiMemory, | ||||||
|  |         essential: true, | ||||||
|  |         logging: ecs.LogDrivers.awsLogs({ | ||||||
|  |           streamPrefix: 'api', | ||||||
|  |           logGroup: apiLogGroup | ||||||
|  |         }), | ||||||
|  |         environment: containerEnvironment, | ||||||
|  |         healthCheck: { | ||||||
|  |           command: ['CMD-SHELL', 'curl -f http://localhost:3001/up || exit 1'], | ||||||
|  |           interval: Duration.seconds(30), | ||||||
|  |           timeout: Duration.seconds(5), | ||||||
|  |           retries: 3, | ||||||
|  |           startPeriod: Duration.seconds(60) | ||||||
|  |         } | ||||||
|  |       }; | ||||||
|  | 
 | ||||||
|  |       // Set the appropriate startup script for staging and production
 | ||||||
|  |       if (environment === 'staging') { | ||||||
|  |         apiContainerConfig.command = ['./bin/start_staging', 'api']; | ||||||
|  |       } | ||||||
|  |       // } else if (environment === 'production') {
 | ||||||
|  |       //   apiContainerConfig.command = ['./bin/start_production', 'api'];
 | ||||||
|  |       // }
 | ||||||
|  | 
 | ||||||
|  |       const apiContainer = taskDefinition.addContainer('APIContainer', apiContainerConfig); | ||||||
|  |        | ||||||
|  |       // Add port mapping for HOST network mode
 | ||||||
|  |       apiContainer.addPortMappings({ | ||||||
|  |         containerPort: 3001, | ||||||
|  |         protocol: ecs.Protocol.TCP | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       // Sidekiq Container Definition
 | ||||||
|  |       // const sidekiqContainerConfig = {
 | ||||||
|  |       //   image: ecs.ContainerImage.fromEcrRepository(ecrRepository, imageTag),
 | ||||||
|  |       //   cpu: ecsConfig.sidekiqCpu,
 | ||||||
|  |       //   memoryLimitMiB: ecsConfig.sidekiqMemory,
 | ||||||
|  |       //   essential: true,
 | ||||||
|  |       //   logging: ecs.LogDrivers.awsLogs({
 | ||||||
|  |       //     streamPrefix: 'sidekiq',
 | ||||||
|  |       //     logGroup: sidekiqLogGroup
 | ||||||
|  |       //   }),
 | ||||||
|  |       //   environment: containerEnvironment,
 | ||||||
|  |       // };
 | ||||||
|  | 
 | ||||||
|  |       // Set the appropriate startup script for staging and production
 | ||||||
|  |       // if (environment === 'staging') {
 | ||||||
|  |       //   sidekiqContainerConfig.command = ['./bin/start_staging', 'sidekiq'];
 | ||||||
|  |       // } else if (environment === 'production') {
 | ||||||
|  |       //   sidekiqContainerConfig.command = ['./bin/start_production', 'sidekiq'];
 | ||||||
|  |       // }
 | ||||||
|  | 
 | ||||||
|  |       // const sidekiqContainer = taskDefinition.addContainer('SidekiqContainer', sidekiqContainerConfig);
 | ||||||
|  | 
 | ||||||
|  |       // // Make Sidekiq container depend on API container
 | ||||||
|  |       // sidekiqContainer.addContainerDependencies({
 | ||||||
|  |       //   container: apiContainer,
 | ||||||
|  |       //   condition: ecs.ContainerDependencyCondition.HEALTHY
 | ||||||
|  |       // });
 | ||||||
|  | 
 | ||||||
|  |     } else { | ||||||
|  |       // Single container setup for dev environment
 | ||||||
|  |       const containerConfig = { | ||||||
|  |         image: ecs.ContainerImage.fromEcrRepository(ecrRepository, imageTag), | ||||||
|  |         cpu: ecsConfig.cpu, | ||||||
|  |         memoryLimitMiB: ecsConfig.memory, | ||||||
|  |         essential: true, | ||||||
|  |         logging: ecs.LogDrivers.awsLogs({ | ||||||
|  |           streamPrefix: 'ecs', | ||||||
|  |           logGroup: apiLogGroup | ||||||
|  |         }), | ||||||
|  |         environment: containerEnvironment | ||||||
|  |       }; | ||||||
|  | 
 | ||||||
|  |       const container = taskDefinition.addContainer('CPDocusealContainer', containerConfig); | ||||||
|  |        | ||||||
|  |       // Add port mapping for HOST network mode
 | ||||||
|  |       container.addPortMappings({ | ||||||
|  |         containerPort: 3001, | ||||||
|  |         protocol: ecs.Protocol.TCP | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // ECS Service
 | ||||||
|  |     const service = new ecs.Ec2Service(this, 'ECSService', { | ||||||
|  |       cluster, | ||||||
|  |       taskDefinition, | ||||||
|  |       serviceName: `cp-docuseal-service-${envDescription}`, | ||||||
|  |       desiredCount: ecsConfig.instanceCount, | ||||||
|  |       deploymentConfiguration: { | ||||||
|  |         maximumPercent: 200, | ||||||
|  |         minimumHealthyPercent: 50 | ||||||
|  |       }, | ||||||
|  |       enableExecuteCommand: true // For debugging
 | ||||||
|  |       // vpcSubnets and securityGroups removed - HOST network mode uses EC2 instance network configuration
 | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     // Attach the service to the target group
 | ||||||
|  |     service.attachToApplicationTargetGroup(targetGroup); | ||||||
|  | 
 | ||||||
|  |     // Task Role for CloudWatch logging and ECR access
 | ||||||
|  |     taskDefinition.taskRole.addManagedPolicy( | ||||||
|  |       iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonECSTaskExecutionRolePolicy') | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     // Add Secrets Manager permissions for staging and production environments
 | ||||||
|  |     if (environment === 'staging') { // || environment === 'production') {
 | ||||||
|  |       // Map production environment to prod for secret naming
 | ||||||
|  |       const secretEnvironment = environment; // === 'production' ? 'prod' : environment;
 | ||||||
|  |       const secretsManagerPolicy = new iam.PolicyStatement({ | ||||||
|  |         effect: iam.Effect.ALLOW, | ||||||
|  |         actions: [ | ||||||
|  |           'secretsmanager:GetSecretValue', | ||||||
|  |           'secretsmanager:DescribeSecret' | ||||||
|  |         ], | ||||||
|  |         resources: [ | ||||||
|  |           `arn:aws:secretsmanager:${this.region}:${this.account}:secret:${secretEnvironment}/db_creds*`, | ||||||
|  |           // `arn:aws:secretsmanager:${this.region}:${this.account}:secret:integration_station/encryption_key*`
 | ||||||
|  |         ] | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       taskDefinition.taskRole.addToPolicy(secretsManagerPolicy); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Output important values
 | ||||||
|  |     this.albDnsName = alb.loadBalancerDnsName; | ||||||
|  |     this.clusterName = cluster.clusterName; | ||||||
|  |     this.serviceName = service.serviceName; | ||||||
|  | 
 | ||||||
|  |     // Output Route53 record name for environments that create DNS records
 | ||||||
|  |     if (hostedZoneDomain) { | ||||||
|  |       if (environment === 'staging' && stagingNumber) { | ||||||
|  |         this.route53RecordName = `cpd.cpstaging${stagingNumber}.name`; | ||||||
|  |       // } else if (environment === 'production') {
 | ||||||
|  |       //   this.route53RecordName = 'cpd.careerplug.com';
 | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | module.exports = { CPDocusealStack };  | ||||||
| @ -0,0 +1,468 @@ | |||||||
|  | { | ||||||
|  |   "name": "cdk_deploy", | ||||||
|  |   "version": "0.1.0", | ||||||
|  |   "lockfileVersion": 3, | ||||||
|  |   "requires": true, | ||||||
|  |   "packages": { | ||||||
|  |     "": { | ||||||
|  |       "name": "cdk_deploy", | ||||||
|  |       "version": "0.1.0", | ||||||
|  |       "dependencies": { | ||||||
|  |         "aws-cdk-lib": "^2.205.0", | ||||||
|  |         "cdk-nag": "^2.36.22", | ||||||
|  |         "constructs": "^10.3.0" | ||||||
|  |       }, | ||||||
|  |       "bin": { | ||||||
|  |         "cdk_deploy": "bin/cdk_deploy.js" | ||||||
|  |       }, | ||||||
|  |       "devDependencies": { | ||||||
|  |         "aws-cdk": "2.1021.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@aws-cdk/asset-awscli-v1": { | ||||||
|  |       "version": "2.2.242", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.242.tgz", | ||||||
|  |       "integrity": "sha512-4c1bAy2ISzcdKXYS1k4HYZsNrgiwbiDzj36ybwFVxEWZXVAP0dimQTCaB9fxu7sWzEjw3d+eaw6Fon+QTfTIpQ==", | ||||||
|  |       "license": "Apache-2.0" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@aws-cdk/asset-node-proxy-agent-v6": { | ||||||
|  |       "version": "2.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@aws-cdk/asset-node-proxy-agent-v6/-/asset-node-proxy-agent-v6-2.1.0.tgz", | ||||||
|  |       "integrity": "sha512-7bY3J8GCVxLupn/kNmpPc5VJz8grx+4RKfnnJiO1LG+uxkZfANZG3RMHhE+qQxxwkyQ9/MfPtTpf748UhR425A==", | ||||||
|  |       "license": "Apache-2.0" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@aws-cdk/cloud-assembly-schema": { | ||||||
|  |       "version": "45.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-45.2.0.tgz", | ||||||
|  |       "integrity": "sha512-5TTUkGHQ+nfuUGwKA8/Yraxb+JdNUh4np24qk/VHXmrCMq+M6HfmGWfhcg/QlHA2S5P3YIamfYHdQAB4uSNLAg==", | ||||||
|  |       "bundleDependencies": [ | ||||||
|  |         "jsonschema", | ||||||
|  |         "semver" | ||||||
|  |       ], | ||||||
|  |       "license": "Apache-2.0", | ||||||
|  |       "dependencies": { | ||||||
|  |         "jsonschema": "~1.4.1", | ||||||
|  |         "semver": "^7.7.2" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 18.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@aws-cdk/cloud-assembly-schema/node_modules/jsonschema": { | ||||||
|  |       "version": "1.4.1", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "engines": { | ||||||
|  |         "node": "*" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@aws-cdk/cloud-assembly-schema/node_modules/semver": { | ||||||
|  |       "version": "7.7.2", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "ISC", | ||||||
|  |       "bin": { | ||||||
|  |         "semver": "bin/semver.js" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=10" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk": { | ||||||
|  |       "version": "2.1021.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1021.0.tgz", | ||||||
|  |       "integrity": "sha512-kE557b4N9UFWax+7km3R6D56o4tGhpzOks/lRDugaoC8su3mocLCXJhb954b/IRl0ipnbZnY/Sftq+RQ/sxivg==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "Apache-2.0", | ||||||
|  |       "bin": { | ||||||
|  |         "cdk": "bin/cdk" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 18.0.0" | ||||||
|  |       }, | ||||||
|  |       "optionalDependencies": { | ||||||
|  |         "fsevents": "2.3.2" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib": { | ||||||
|  |       "version": "2.205.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.205.0.tgz", | ||||||
|  |       "integrity": "sha512-GZHy/F8jql+1aFlgIhGQuLl9zHvceHL0VRuBgaYngwWrflHc+ZN3eCEtfzCblA2bXmi4NbLljpSUBIGBVx2EEQ==", | ||||||
|  |       "bundleDependencies": [ | ||||||
|  |         "@balena/dockerignore", | ||||||
|  |         "case", | ||||||
|  |         "fs-extra", | ||||||
|  |         "ignore", | ||||||
|  |         "jsonschema", | ||||||
|  |         "minimatch", | ||||||
|  |         "punycode", | ||||||
|  |         "semver", | ||||||
|  |         "table", | ||||||
|  |         "yaml", | ||||||
|  |         "mime-types" | ||||||
|  |       ], | ||||||
|  |       "license": "Apache-2.0", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@aws-cdk/asset-awscli-v1": "2.2.242", | ||||||
|  |         "@aws-cdk/asset-node-proxy-agent-v6": "^2.1.0", | ||||||
|  |         "@aws-cdk/cloud-assembly-schema": "^45.0.0", | ||||||
|  |         "@balena/dockerignore": "^1.0.2", | ||||||
|  |         "case": "1.6.3", | ||||||
|  |         "fs-extra": "^11.3.0", | ||||||
|  |         "ignore": "^5.3.2", | ||||||
|  |         "jsonschema": "^1.5.0", | ||||||
|  |         "mime-types": "^2.1.35", | ||||||
|  |         "minimatch": "^3.1.2", | ||||||
|  |         "punycode": "^2.3.1", | ||||||
|  |         "semver": "^7.7.2", | ||||||
|  |         "table": "^6.9.0", | ||||||
|  |         "yaml": "1.10.2" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 14.15.0" | ||||||
|  |       }, | ||||||
|  |       "peerDependencies": { | ||||||
|  |         "constructs": "^10.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/@balena/dockerignore": { | ||||||
|  |       "version": "1.0.2", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "Apache-2.0" | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/ajv": { | ||||||
|  |       "version": "8.17.1", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "fast-deep-equal": "^3.1.3", | ||||||
|  |         "fast-uri": "^3.0.1", | ||||||
|  |         "json-schema-traverse": "^1.0.0", | ||||||
|  |         "require-from-string": "^2.0.2" | ||||||
|  |       }, | ||||||
|  |       "funding": { | ||||||
|  |         "type": "github", | ||||||
|  |         "url": "https://github.com/sponsors/epoberezkin" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/ansi-regex": { | ||||||
|  |       "version": "5.0.1", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/ansi-styles": { | ||||||
|  |       "version": "4.3.0", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "color-convert": "^2.0.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8" | ||||||
|  |       }, | ||||||
|  |       "funding": { | ||||||
|  |         "url": "https://github.com/chalk/ansi-styles?sponsor=1" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/astral-regex": { | ||||||
|  |       "version": "2.0.0", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/balanced-match": { | ||||||
|  |       "version": "1.0.2", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/brace-expansion": { | ||||||
|  |       "version": "1.1.12", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "balanced-match": "^1.0.0", | ||||||
|  |         "concat-map": "0.0.1" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/case": { | ||||||
|  |       "version": "1.6.3", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "(MIT OR GPL-3.0-or-later)", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 0.8.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/color-convert": { | ||||||
|  |       "version": "2.0.1", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "color-name": "~1.1.4" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=7.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/color-name": { | ||||||
|  |       "version": "1.1.4", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/concat-map": { | ||||||
|  |       "version": "0.0.1", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/emoji-regex": { | ||||||
|  |       "version": "8.0.0", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/fast-deep-equal": { | ||||||
|  |       "version": "3.1.3", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/fast-uri": { | ||||||
|  |       "version": "3.0.6", | ||||||
|  |       "funding": [ | ||||||
|  |         { | ||||||
|  |           "type": "github", | ||||||
|  |           "url": "https://github.com/sponsors/fastify" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "type": "opencollective", | ||||||
|  |           "url": "https://opencollective.com/fastify" | ||||||
|  |         } | ||||||
|  |       ], | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "BSD-3-Clause" | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/fs-extra": { | ||||||
|  |       "version": "11.3.0", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "graceful-fs": "^4.2.0", | ||||||
|  |         "jsonfile": "^6.0.1", | ||||||
|  |         "universalify": "^2.0.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=14.14" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/graceful-fs": { | ||||||
|  |       "version": "4.2.11", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "ISC" | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/ignore": { | ||||||
|  |       "version": "5.3.2", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 4" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/is-fullwidth-code-point": { | ||||||
|  |       "version": "3.0.0", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/json-schema-traverse": { | ||||||
|  |       "version": "1.0.0", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/jsonfile": { | ||||||
|  |       "version": "6.1.0", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "universalify": "^2.0.0" | ||||||
|  |       }, | ||||||
|  |       "optionalDependencies": { | ||||||
|  |         "graceful-fs": "^4.1.6" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/jsonschema": { | ||||||
|  |       "version": "1.5.0", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "engines": { | ||||||
|  |         "node": "*" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/lodash.truncate": { | ||||||
|  |       "version": "4.4.2", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/mime-db": { | ||||||
|  |       "version": "1.52.0", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 0.6" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/mime-types": { | ||||||
|  |       "version": "2.1.35", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "mime-db": "1.52.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 0.6" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/minimatch": { | ||||||
|  |       "version": "3.1.2", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "ISC", | ||||||
|  |       "dependencies": { | ||||||
|  |         "brace-expansion": "^1.1.7" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": "*" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/punycode": { | ||||||
|  |       "version": "2.3.1", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=6" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/require-from-string": { | ||||||
|  |       "version": "2.0.2", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=0.10.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/semver": { | ||||||
|  |       "version": "7.7.2", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "ISC", | ||||||
|  |       "bin": { | ||||||
|  |         "semver": "bin/semver.js" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=10" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/slice-ansi": { | ||||||
|  |       "version": "4.0.0", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "ansi-styles": "^4.0.0", | ||||||
|  |         "astral-regex": "^2.0.0", | ||||||
|  |         "is-fullwidth-code-point": "^3.0.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=10" | ||||||
|  |       }, | ||||||
|  |       "funding": { | ||||||
|  |         "url": "https://github.com/chalk/slice-ansi?sponsor=1" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/string-width": { | ||||||
|  |       "version": "4.2.3", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "emoji-regex": "^8.0.0", | ||||||
|  |         "is-fullwidth-code-point": "^3.0.0", | ||||||
|  |         "strip-ansi": "^6.0.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/strip-ansi": { | ||||||
|  |       "version": "6.0.1", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "ansi-regex": "^5.0.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/table": { | ||||||
|  |       "version": "6.9.0", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "BSD-3-Clause", | ||||||
|  |       "dependencies": { | ||||||
|  |         "ajv": "^8.0.1", | ||||||
|  |         "lodash.truncate": "^4.4.2", | ||||||
|  |         "slice-ansi": "^4.0.0", | ||||||
|  |         "string-width": "^4.2.3", | ||||||
|  |         "strip-ansi": "^6.0.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=10.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/universalify": { | ||||||
|  |       "version": "2.0.1", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 10.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/aws-cdk-lib/node_modules/yaml": { | ||||||
|  |       "version": "1.10.2", | ||||||
|  |       "inBundle": true, | ||||||
|  |       "license": "ISC", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 6" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/cdk-nag": { | ||||||
|  |       "version": "2.36.40", | ||||||
|  |       "resolved": "https://registry.npmjs.org/cdk-nag/-/cdk-nag-2.36.40.tgz", | ||||||
|  |       "integrity": "sha512-8ZmVuGMAfwJcz88uGBj0plGi7qNN4jTmlj/td7jzNcaBoPx4ZGq/hresTTY8uvg26apjxgSZgZswzLoWGyMfOg==", | ||||||
|  |       "license": "Apache-2.0", | ||||||
|  |       "peerDependencies": { | ||||||
|  |         "aws-cdk-lib": "^2.156.0", | ||||||
|  |         "constructs": "^10.0.5" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/constructs": { | ||||||
|  |       "version": "10.4.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.4.2.tgz", | ||||||
|  |       "integrity": "sha512-wsNxBlAott2qg8Zv87q3eYZYgheb9lchtBfjHzzLHtXbttwSrHPs1NNQbBrmbb1YZvYg2+Vh0Dor76w4mFxJkA==", | ||||||
|  |       "license": "Apache-2.0" | ||||||
|  |     }, | ||||||
|  |     "node_modules/fsevents": { | ||||||
|  |       "version": "2.3.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", | ||||||
|  |       "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", | ||||||
|  |       "dev": true, | ||||||
|  |       "hasInstallScript": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "optional": true, | ||||||
|  |       "os": [ | ||||||
|  |         "darwin" | ||||||
|  |       ], | ||||||
|  |       "engines": { | ||||||
|  |         "node": "^8.16.0 || ^10.6.0 || >=11.0.0" | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,34 @@ | |||||||
|  | { | ||||||
|  |   "name": "cdk_deploy", | ||||||
|  |   "version": "0.1.0", | ||||||
|  |   "bin": { | ||||||
|  |     "cdk_deploy": "bin/cdk_deploy.js" | ||||||
|  |   }, | ||||||
|  |   "scripts": { | ||||||
|  |     "cdk": "cdk", | ||||||
|  |     "deploy:dev": "cdk deploy CPDocusealStack-dev --profile default", | ||||||
|  |     "deploy:staging": "cdk deploy CPDocusealStack-staging --profile default", | ||||||
|  |     "deploy:prod": "cdk deploy CPDocusealStack-production --profile default", | ||||||
|  |     "destroy:dev": "cdk destroy CPDocusealStack-dev --profile default", | ||||||
|  |     "destroy:staging": "cdk destroy CPDocusealStack-staging --profile default", | ||||||
|  |     "destroy:prod": "cdk destroy CPDocusealStack-production --profile default", | ||||||
|  |     "synth": "cdk synth", | ||||||
|  |     "diff": "cdk diff", | ||||||
|  |     "bootstrap": "cdk bootstrap" | ||||||
|  |   }, | ||||||
|  |   "devDependencies": { | ||||||
|  |     "aws-cdk": "2.1021.0" | ||||||
|  |   }, | ||||||
|  |   "dependencies": { | ||||||
|  |     "aws-cdk-lib": "^2.205.0", | ||||||
|  |     "cdk-nag": "^2.36.22", | ||||||
|  |     "constructs": "^10.3.0" | ||||||
|  |   }, | ||||||
|  |   "keywords": [ | ||||||
|  |     "aws", | ||||||
|  |     "cdk", | ||||||
|  |     "infrastructure", | ||||||
|  |     "ecs", | ||||||
|  |     "alb" | ||||||
|  |   ] | ||||||
|  | } | ||||||
| @ -0,0 +1,39 @@ | |||||||
|  | sudo yum install -y ec2-instance-connect | ||||||
|  | cat >/home/ec2-user/.bashrc <<'EOF' | ||||||
|  |  # .bashrc | ||||||
|  | 
 | ||||||
|  |   # Source global definitions | ||||||
|  |   if [ -f /etc/bashrc ]; then | ||||||
|  |           . /etc/bashrc | ||||||
|  |   fi | ||||||
|  | 
 | ||||||
|  |   # User specific aliases and functions | ||||||
|  |   function setContainer { | ||||||
|  |     CONTAINER_ID=`sudo docker ps | grep "rails/bin" | awk '{ print $1; }' | head -1` | ||||||
|  |   } | ||||||
|  |   function execDocker { | ||||||
|  |     setContainer | ||||||
|  |     sudo docker exec -u rails -i -t $CONTAINER_ID $@ | ||||||
|  |   } | ||||||
|  |   function copy_from { | ||||||
|  |     setContainer | ||||||
|  |     sudo docker cp "$CONTAINER_ID:/rails/$1" "$2" | ||||||
|  |   } | ||||||
|  |   function copy_to { | ||||||
|  |     setContainer | ||||||
|  |     sudo docker cp "$1" "$CONTAINER_ID:/rails/$2" | ||||||
|  |     sudo docker exec -u root -t $CONTAINER_ID /bin/sh -c 'chown rails:rails /rails/$2' | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function dangerConsole { | ||||||
|  |     echo | ||||||
|  |     echo "********** Accessing the WRITE & READ console **********" | ||||||
|  |     echo "********** THIS IS DANGEROUS AND CHANGES YOU MAKE WILL IMPACT THE DATABASE **********" | ||||||
|  |     echo | ||||||
|  |     sleep 3 | ||||||
|  |     execDocker bin/rails console | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   alias console='dangerConsole' | ||||||
|  |   alias shell='execDocker /bin/bash' | ||||||
|  | EOF | ||||||
					Loading…
					
					
				
		Reference in new issue