@fishawack/lab-env 4.26.0 → 4.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/_Test/provision.js +39 -16
  3. package/_Test/s3.js +35 -0
  4. package/_Test/utilities.js +35 -1
  5. package/cli.js +0 -2
  6. package/commands/create/cmds/deprovision.js +31 -19
  7. package/commands/create/cmds/provision.js +47 -26
  8. package/commands/create/libs/prompts.js +18 -0
  9. package/commands/create/libs/utilities.js +32 -1
  10. package/commands/create/libs/vars.js +329 -1
  11. package/commands/create/services/aws/cloudfront.js +6 -13
  12. package/commands/create/services/aws/ec2.js +17 -0
  13. package/commands/create/services/aws/elasticbeanstalk.js +96 -0
  14. package/commands/create/services/aws/iam.js +123 -4
  15. package/commands/create/services/aws/index.js +98 -3
  16. package/commands/create/services/aws/misc.js +2 -0
  17. package/commands/create/services/aws/s3.js +48 -5
  18. package/commands/create/services/email.js +20 -23
  19. package/commands/create/templates/elasticbeanstalk/.ebextensions/{apache → httpd}/auto-ssl.config +18 -6
  20. package/commands/create/templates/elasticbeanstalk/.ebextensions/laravel/software.config +1 -12
  21. package/commands/create/templates/elasticbeanstalk/.ebextensions/misc/enable-https-lb.config +9 -0
  22. package/commands/create/templates/elasticbeanstalk/.ebextensions/misc/s3-env.config +41 -0
  23. package/commands/create/templates/elasticbeanstalk/.ebextensions/misc/setvars.config +8 -2
  24. package/commands/create/templates/elasticbeanstalk/.ebextensions/nginx/alb-health.config +28 -0
  25. package/commands/create/templates/elasticbeanstalk/.ebextensions/nginx/auto-ssl.config +19 -7
  26. package/commands/create/templates/elasticbeanstalk/.ebextensions/wordpress/alb-health.config +28 -0
  27. package/commands/create/templates/elasticbeanstalk/.ebextensions/wordpress/cron.config +42 -0
  28. package/commands/create/templates/elasticbeanstalk/.ebextensions/wordpress/environment.config +3 -1
  29. package/commands/create/templates/elasticbeanstalk/.ebextensions/wordpress/post-deploy.config +11 -8
  30. package/commands/create/templates/elasticbeanstalk/.ebextensions/wordpress/software.config +1 -3
  31. package/commands/create/templates/elasticbeanstalk/.elasticbeanstalk/config.yml +7 -0
  32. package/commands/create/templates/elasticbeanstalk/.platform/confighooks/postdeploy/rewrite-flush.sh +4 -0
  33. package/commands/create/templates/elasticbeanstalk/.platform/hooks/postdeploy/rewrite-flush.sh +4 -0
  34. package/commands/create/templates/elasticbeanstalk/.platform/hooks/postdeploy/s3-env.sh +7 -0
  35. package/commands/create/templates/elasticbeanstalk/.platform/hooks/predeploy/deactivate-plugins-single.sh +30 -0
  36. package/commands/create/templates/elasticbeanstalk/.platform/hooks/predeploy/deactivate-plugins.sh +55 -0
  37. package/commands/create/templates/elasticbeanstalk/.platform/httpd/conf.d/elasticbeanstalk/80/forward-https-proto.conf +3 -0
  38. package/commands/create/templates/elasticbeanstalk/.platform/httpd/conf.d/elasticbeanstalk/z-wordpress-htpasswd.conf +13 -0
  39. package/commands/create/templates/elasticbeanstalk/.platform/httpd/conf.d/security_headers-wordpress.conf +11 -0
  40. package/commands/create/templates/elasticbeanstalk/.platform/nginx/conf.d/elasticbeanstalk/health.conf +4 -0
  41. package/commands/create/templates/elasticbeanstalk/.platform/nginx/conf.d/elasticbeanstalk/htpasswd.conf +2 -0
  42. package/globals.js +2 -0
  43. package/package.json +6 -1
  44. /package/commands/create/templates/elasticbeanstalk/.platform/httpd/conf.d/elasticbeanstalk/{443 → 80}/www-to-nonwww-redirection.conf +0 -0
@@ -1,12 +1,18 @@
1
- const { s3Safe } = require("../../libs/utilities.js");
1
+ const md5 = require("apache-md5")
2
+ const fs = require("fs-extra");
3
+
4
+ const { nameSafe } = require("../../libs/utilities.js");
5
+ const { eb } = require("../../libs/vars.js");
2
6
 
3
7
  module.exports.s3 = require("./s3.js");
4
8
  module.exports.cloudfront = require("./cloudfront.js");
5
9
  module.exports.iam = require("./iam.js");
10
+ module.exports.elasticbeanstalk = require("./elasticbeanstalk.js");
11
+ module.exports.ec2 = require("./ec2.js");
6
12
 
7
- module.exports.slug = (repo, client, branch) => s3Safe(`${branch}-${repo}-${client}`);
13
+ module.exports.slug = (repo, client, branch, service = "s3") => nameSafe(`${branch}-${repo}-${client}`, service);
8
14
 
9
- module.exports.clients = ['fishawack', 'abbvie', 'sanofigenzyme', 'gsk', 'janssen', 'astrazeneca', 'ptc', 'jazz', 'pfizer', 'heron', 'novartis', 'training', 'merck', 'acadia', 'travere', 'roche', 'utc', 'bayer', 'alcon', 'uhc', 'chiesi', '3m', 'sarepta', 'ipsen', 'novocure', 'anthem', 'kyowakirin', 'optum', 'rally', 'menarini', 'childrensminnesota', 'gore', 'axogen', 'gedeonrichter'];
15
+ module.exports.clients = ['fishawack', 'abbvie', 'sanofigenzyme', 'gsk', 'janssen', 'astrazeneca', 'ptc', 'jazz', 'pfizer', 'heron', 'novartis', 'training', 'merck', 'acadia', 'travere', 'roche', 'utc', 'bayer', 'alcon', 'uhc', 'chiesi', '3m', 'sarepta', 'ipsen', 'novocure', 'anthem', 'kyowakirin', 'optum', 'rally', 'menarini', 'childrensminnesota', 'gore', 'axogen', 'gedeonrichter', 'relievantmedsystems', 'gilead'];
10
16
 
11
17
  module.exports.static = async (name, account, tags = [], credentials = []) => {
12
18
  let s3 = await module.exports.s3.createS3Bucket(name, account, tags);
@@ -24,4 +30,93 @@ module.exports.static = async (name, account, tags = [], credentials = []) => {
24
30
  };
25
31
 
26
32
  return config;
33
+ }
34
+
35
+ module.exports.staticTerminate = async (name, account, repo, branch, id) => {
36
+ try { await module.exports.s3.emptyS3Bucket(name, account); } catch(e) {}
37
+
38
+ try { await module.exports.s3.removeS3Bucket(name, account); } catch(e) {}
39
+
40
+ try { await module.exports.cloudfront.removeCloudFrontDistribution(id, account); } catch(e) {}
41
+
42
+ try { await module.exports.cloudfront.removeCloudFrontFunction(name, account); } catch(e) {}
43
+ }
44
+
45
+ module.exports.fullstack = async (name, account, tags = [], credentials = [], repo, branch, framework, availability) => {
46
+ const { platform, language } = eb.configurations[framework];
47
+
48
+ const s3Slug = module.exports.slug(repo, account, branch, "s3");
49
+
50
+ await module.exports.iam.createIAMUser(s3Slug, account, tags);
51
+ await module.exports.iam.attachIAMPolicy(s3Slug, account, 'arn:aws:iam::aws:policy/AmazonS3FullAccess');
52
+ const { AccessKey: { AccessKeyId }, AccessKey: { SecretAccessKey } } = await module.exports.iam.createAccessKey(s3Slug, account);
53
+
54
+ await module.exports.s3.createS3Bucket(s3Slug, account, tags, false, "BucketOwnerPreferred");
55
+
56
+ await module.exports.iam.ensureEBInstanceProfileExists(account);
57
+
58
+ try { await module.exports.elasticbeanstalk.createElasticBeanstalkApplication(repo, account); } catch (e) {}
59
+
60
+ let hasKeyPair = false;
61
+
62
+ try { await module.exports.ec2.getKeyPair("id_rsa_prev", account); hasKeyPair = true; } catch(e) {};
63
+
64
+ // LetsEncrypt CN records are limited to 64 chars so use only the hash from the generated name
65
+ const CNAMEPrefix = `fw-auto-${name.split('-')[name.split('-').length - 1]}`;
66
+ process.env.DOMAIN_LINK = `${CNAMEPrefix}.${process.env.AWS_REGION}.elasticbeanstalk.com`;
67
+
68
+ const OptionSettings = eb.merge("environments", {framework, availability, platform, language}, {s3Slug, AccessKeyId, SecretAccessKey});
69
+
70
+ if(hasKeyPair){
71
+ OptionSettings.push({
72
+ OptionName: 'EC2KeyName',
73
+ Value: 'id_rsa_prev',
74
+ Namespace: 'aws:autoscaling:launchconfiguration'
75
+ });
76
+ }
77
+
78
+ const environment = await module.exports.elasticbeanstalk.createElasticBeanstalkEnvironment(name, account, repo, OptionSettings, CNAMEPrefix, tags);
79
+
80
+ const configurations = eb.merge("configurations", {framework, availability, platform, language});
81
+
82
+ if(credentials.length){
83
+ configurations.push(`.platform/${platform}/conf.d/elasticbeanstalk/${platform === "httpd" ? `z-${framework}-` : ''}htpasswd.conf`);
84
+ fs.outputFileSync(`.platform/${platform}/conf.d/elasticbeanstalk/.htpasswd-${branch}`, credentials.map(d => `${d.username}:${md5(d.password)}`).join('\n'));
85
+ }
86
+
87
+ await module.exports.elasticbeanstalk.copyElasticBeanstalkConfigs(configurations);
88
+
89
+ if(credentials.length){
90
+ configurations.push(`.platform/${platform}/conf.d/elasticbeanstalk/.htpasswd-${branch}`);
91
+ }
92
+
93
+ let config = {
94
+ "url": `https://${environment.CNAME}`,
95
+ "environment": environment.EnvironmentName,
96
+ "paths": configurations.map(d => {
97
+ const obj = { "src": d, "dest": d };
98
+ // Fix for core mistakenly mapping .htpasswd to directory
99
+ if(d.includes(`.htpasswd-${branch}`)){
100
+ obj.file = true;
101
+ obj.dest = d.split(`-${branch}`)[0];
102
+ }
103
+ return obj;
104
+ })
105
+ };
106
+
107
+ return config;
108
+ }
109
+
110
+ module.exports.fullstackTerminate = async (name, account, repo, branch) => {
111
+ const s3Slug = module.exports.slug(repo, account, branch, "s3");
112
+
113
+ try { await module.exports.iam.removeIAMUser(s3Slug, account); } catch(e) {}
114
+
115
+ try { await module.exports.s3.emptyS3Bucket(s3Slug, account); } catch(e) {}
116
+
117
+ try { await module.exports.s3.removeS3Bucket(s3Slug, account); } catch(e) {}
118
+
119
+ try { await module.exports.elasticbeanstalk.removeElasticBeanstalkEnvironment(name, account); } catch(e) {}
120
+
121
+ try { await module.exports.elasticbeanstalk.removeElasticBeanstalkApplication(repo, account); } catch(e) {}
27
122
  }
@@ -1,8 +1,10 @@
1
1
  module.exports.createClient = (client, account, region = 'us-east-1') => {
2
2
  delete process.env.AWS_PROFILE;
3
+ delete process.env.AWS_REGION;
3
4
 
4
5
  if(account){
5
6
  process.env.AWS_PROFILE = account;
7
+ process.env.AWS_REGION = region;
6
8
  }
7
9
 
8
10
  return new client({ region });
@@ -1,19 +1,19 @@
1
- const { S3Client, CreateBucketCommand, DeleteBucketCommand, ListBucketsCommand, PutPublicAccessBlockCommand, PutBucketTaggingCommand, PutBucketPolicyCommand, PutObjectCommand, DeleteObjectCommand } = require("@aws-sdk/client-s3");
1
+ const { S3Client, CreateBucketCommand, DeleteBucketCommand, ListBucketsCommand, ListObjectsV2Command, PutPublicAccessBlockCommand, PutBucketTaggingCommand, PutBucketPolicyCommand, PutObjectCommand, DeleteObjectCommand, DeleteObjectsCommand } = require("@aws-sdk/client-s3");
2
2
  const { Spinner } = require('../../libs/utilities');
3
3
  const { createClient } = require('./misc.js');
4
4
 
5
- module.exports.createS3Bucket = async (bucket, account, tags = []) => {
5
+ module.exports.createS3Bucket = async (bucket, account, tags = [], blockAccess = true, ObjectOwnership = "BucketOwnerEnforced") => {
6
6
  const client = createClient(S3Client, account);
7
7
 
8
8
  let res = await Spinner.prototype.simple(`Creating s3 bucket ${bucket}`, () => {
9
9
  return client.send(
10
- new CreateBucketCommand({ Bucket: bucket })
10
+ new CreateBucketCommand({ Bucket: bucket, ObjectOwnership })
11
11
  );
12
12
  });
13
13
 
14
- await Spinner.prototype.simple(`Blocking all public access to s3 bucket`, () => {
14
+ await Spinner.prototype.simple(`${blockAccess ? 'Blocking' : 'Allowing'} all public access to s3 bucket`, () => {
15
15
  return client.send(
16
- new PutPublicAccessBlockCommand({ Bucket: bucket, PublicAccessBlockConfiguration: { BlockPublicAcls: true, BlockPublicPolicy: true, IgnorePublicAcls: true, RestrictPublicBuckets: true } })
16
+ new PutPublicAccessBlockCommand({ Bucket: bucket, PublicAccessBlockConfiguration: { BlockPublicAcls: blockAccess, BlockPublicPolicy: blockAccess, IgnorePublicAcls: blockAccess, RestrictPublicBuckets: blockAccess } })
17
17
  );
18
18
  });
19
19
 
@@ -106,4 +106,47 @@ module.exports.removeFileToS3Bucket = async (bucket, account, filepath) => {
106
106
  });
107
107
 
108
108
  return res;
109
+ }
110
+
111
+ module.exports.emptyS3Bucket = async (bucket, account) => {
112
+ const client = createClient(S3Client, account);
113
+
114
+ await Spinner.prototype.simple(`Emptying s3 bucket`, () => {
115
+ return new Promise(async (resolve, reject) => {
116
+ try {
117
+ let ContinuationToken = null;
118
+
119
+ do {
120
+ let list = await client.send(
121
+ new ListObjectsV2Command({
122
+ Bucket: bucket,
123
+ ContinuationToken
124
+ })
125
+ );
126
+
127
+ if (list.KeyCount) {
128
+ let deleted = await client.send(
129
+ new DeleteObjectsCommand({
130
+ Bucket: bucket,
131
+ Delete: {
132
+ Objects: list.Contents.map((item) => ({ Key: item.Key })),
133
+ Quiet: false,
134
+ },
135
+ })
136
+ );
137
+
138
+ if (deleted.Errors) {
139
+ deleted.Errors.map((error) => console.log(`${error.Key} could not be deleted - ${error.Code}`));
140
+ }
141
+ }
142
+
143
+ ContinuationToken = list.NextContinuationToken;
144
+ } while (ContinuationToken)
145
+
146
+ resolve();
147
+ } catch (e){
148
+ reject(e);
149
+ }
150
+ });
151
+ });
109
152
  }
@@ -1,37 +1,22 @@
1
1
  const nodemailer = require("nodemailer");
2
2
  const { misc } = require('../libs/vars');
3
3
 
4
- module.exports.send = async (to, subject, html, text, test = false, from = `digitalautomation@fishawack.com`) => {
5
- let transporter = await module.exports.transport(test);
6
-
7
- let info = await transporter.sendMail({
8
- from,
9
- to,
10
- subject,
11
- html,
12
- text
13
- });
14
-
15
- if(test){
16
- console.log("Preview URL: %s", nodemailer.getTestMessageUrl(info));
17
- }
18
-
19
- return info;
20
- };
21
-
22
- module.exports.transport = async (test = false) => {
23
- let username = misc?.nodemailer?.office365.username;
24
- let password = misc?.nodemailer?.office365.password;
4
+ module.exports.send = async (to, subject, html, text, test = false) => {
5
+ const { nodemailer: _nodemailer } = misc || {};
6
+ const { driver, from } = _nodemailer;
7
+ const mailer = _nodemailer[driver] || _nodemailer;
8
+ let { username, password, host } = mailer;
25
9
 
26
10
  if(test){
27
11
  let testAccount = await nodemailer.createTestAccount();
28
12
 
29
13
  username = testAccount.user;
30
14
  password = testAccount.pass;
15
+ host = 'smtp.ethereal.email';
31
16
  }
32
17
 
33
18
  let transporter = nodemailer.createTransport({
34
- host: test ? 'smtp.ethereal.email' : 'smtp.office365.com',
19
+ host,
35
20
  port: 587,
36
21
  secure: false,
37
22
  auth: {
@@ -40,5 +25,17 @@ module.exports.transport = async (test = false) => {
40
25
  },
41
26
  });
42
27
 
43
- return transporter;
28
+ let info = await transporter.sendMail({
29
+ from,
30
+ to,
31
+ subject,
32
+ html,
33
+ text
34
+ });
35
+
36
+ if(test){
37
+ console.log("Preview URL: %s", nodemailer.getTestMessageUrl(info));
38
+ }
39
+
40
+ return info;
44
41
  };
@@ -1,9 +1,23 @@
1
1
  files:
2
- /etc/cron.d/certbot_renew:
3
- content: "@weekly root certbot renew\n"
2
+ "/usr/local/bin/certbot_renew_cron.sh":
3
+ mode: "000755"
4
+ owner: root
4
5
  group: root
6
+ content: |
7
+ #!/bin/bash
8
+ certbot renew
9
+
10
+ "/etc/cron.d/certbot_renew_cron":
5
11
  mode: "000644"
6
12
  owner: root
13
+ group: root
14
+ content: |
15
+ 0 0 * * * root bash -l /usr/local/bin/certbot_renew_cron.sh >> /var/log/certbot_renew_cron.log 2>&1
16
+
17
+ commands:
18
+ rm_old_cron:
19
+ command: "rm -f /etc/cron.d/certbot_renew_cron.bak"
20
+ ignoreErrors: true
7
21
 
8
22
  container_commands:
9
23
  10_downloadepel:
@@ -15,10 +29,8 @@ container_commands:
15
29
  40_installcertbot:
16
30
  command: "yum install -y certbot"
17
31
  50_getcert:
18
- command: "certbot certonly --debug --non-interactive --email ${EMAIL_LINK} --agree-tos --standalone --expand --domains ${DOMAIN_LINK} --keep-until-expiring --pre-hook \"service httpd stop\""
32
+ command: "certbot certonly --debug --non-interactive --email ${EMAIL_LINK} --agree-tos --standalone --expand --domains ${DOMAIN_LINK} --keep-until-expiring --pre-hook \"service httpd stop\" --post-hook \"service httpd restart\""
19
33
  60_link:
20
34
  command: "ln -sf /etc/letsencrypt/live/$(echo ${DOMAIN_LINK} | cut -d, -f1) /etc/letsencrypt/live/ebcert"
21
- 70_startserver:
22
- command: "service httpd start"
23
- 80_cleanup:
35
+ 70_cleanup:
24
36
  command: "rm -rf dl.fedoraproject.org"
@@ -2,15 +2,4 @@ option_settings:
2
2
  aws:elasticbeanstalk:container:php:phpini:
3
3
  document_root: /public
4
4
  aws:elasticbeanstalk:environment:proxy:
5
- ProxyServer: nginx
6
-
7
- files:
8
- "/etc/php.d/custom.ini":
9
- mode: "000755"
10
- owner: root
11
- group: root
12
- content: |
13
- memory_limit = 500M
14
- upload_max_filesize = 500M
15
- post_max_size = 500M
16
- max_execution_time = 600
5
+ ProxyServer: nginx
@@ -0,0 +1,9 @@
1
+ Resources:
2
+ sslSecurityGroupIngress:
3
+ Type: AWS::EC2::SecurityGroupIngress
4
+ Properties:
5
+ GroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]}
6
+ IpProtocol: tcp
7
+ ToPort: 443
8
+ FromPort: 443
9
+ SourceSecurityGroupId: {"Fn::GetAtt" : ["AWSEBLoadBalancerSecurityGroup" , "GroupId"]}
@@ -0,0 +1,41 @@
1
+ Resources:
2
+ AWSEBAutoScalingGroup:
3
+ Metadata:
4
+ AWS::ElasticBeanstalk::Ext:
5
+ _ContainerConfigFileContent:
6
+ plugins:
7
+ s3env:
8
+ description: Environment variables loaded from s3
9
+ env: {}
10
+ AWS::CloudFormation::Authentication:
11
+ S3Auth:
12
+ type: "s3"
13
+ buckets: ["elasticbeanstalk-us-east-1-549109292206"]
14
+ roleName:
15
+ "Fn::GetOptionSetting":
16
+ Namespace: "aws:autoscaling:launchconfiguration"
17
+ OptionName: "IamInstanceProfile"
18
+ DefaultValue: "aws-elasticbeanstalk-ec2-role"
19
+ files:
20
+ "/home/ec2-user/.env":
21
+ mode: "000400"
22
+ owner: root
23
+ group: root
24
+ authentication: "S3Auth"
25
+ source: https://elasticbeanstalk-us-east-1-549109292206.s3.amazonaws.com/.env
26
+
27
+ commands:
28
+ s3env_commands:
29
+ command: |
30
+ wget https://github.com/ko1nksm/shdotenv/releases/latest/download/shdotenv -O /home/ec2-user/shdotenv
31
+ chmod +x /home/ec2-user/shdotenv
32
+ jq --argjson S3ENV "$(sudo /home/ec2-user/shdotenv --env /home/ec2-user/.env --format json)" '.AsgResource."AWS::ElasticBeanstalk::Ext"._ContainerConfigFileContent.plugins.s3env.env += $S3ENV' /opt/elasticbeanstalk/deployment/cfn-metadata-cache.json > /home/ec2-user/cfn-metadata-cache.json
33
+ cp /home/ec2-user/cfn-metadata-cache.json /opt/elasticbeanstalk/deployment/cfn-metadata-cache.json
34
+
35
+ container_commands:
36
+ s3env_container_commands:
37
+ command: cp /home/ec2-user/cfn-metadata-cache.json /opt/elasticbeanstalk/deployment/cfn-metadata-cache.json
38
+
39
+ packages:
40
+ yum:
41
+ jq: []
@@ -1,6 +1,12 @@
1
+ option_settings:
2
+ - option_name: BASH_ENV
3
+ value: /etc/profile.d/sh.local
4
+
1
5
  commands:
2
6
  setvars:
3
- command: /opt/elasticbeanstalk/bin/get-config environment | jq -r 'to_entries | .[] | "export \(.key)=\"\(.value)\""' > /etc/profile.d/sh.local
7
+ command: |
8
+ /opt/elasticbeanstalk/bin/get-config environment | jq -r "to_entries | .[] | \"export \(.key)='\(.value)'\"" > /etc/profile.d/sh.local
9
+
4
10
  packages:
5
11
  yum:
6
- jq: []
12
+ jq: []
@@ -0,0 +1,28 @@
1
+ ###################################################################################################
2
+ #### Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ ####
4
+ #### Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file
5
+ #### except in compliance with the License. A copy of the License is located at
6
+ ####
7
+ #### http://aws.amazon.com/apache2.0/
8
+ ####
9
+ #### or in the "license" file accompanying this file. This file is distributed on an "AS IS"
10
+ #### BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11
+ #### License for the specific language governing permissions and limitations under the License.
12
+ ###################################################################################################
13
+
14
+ ###################################################################################################
15
+ #### This configuration file modifies the default port 80 listener attached to an Application Load Balancer
16
+ #### to automatically redirect incoming connections on HTTP to HTTPS.
17
+ #### This will not work with an environment using the load balancer type Classic or Network.
18
+ #### A prerequisite is that the 443 listener has already been created.
19
+ #### Please use the below link for more information about creating an Application Load Balancer on
20
+ #### the Elastic Beanstalk console.
21
+ #### https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/environments-cfg-alb.html#environments-cfg-alb-console
22
+ ###################################################################################################
23
+
24
+ Resources:
25
+ AWSEBV2LoadBalancerTargetGroup:
26
+ Type: AWS::ElasticLoadBalancingV2::TargetGroup
27
+ Properties:
28
+ HealthCheckPath: /health
@@ -1,10 +1,24 @@
1
1
  files:
2
- /etc/cron.d/certbot_renew:
3
- content: "@weekly root certbot renew\n"
2
+ "/usr/local/bin/certbot_renew_cron.sh":
3
+ mode: "000755"
4
+ owner: root
4
5
  group: root
6
+ content: |
7
+ #!/bin/bash
8
+ certbot renew
9
+
10
+ "/etc/cron.d/certbot_renew_cron":
5
11
  mode: "000644"
6
12
  owner: root
7
-
13
+ group: root
14
+ content: |
15
+ 0 0 * * * root bash -l /usr/local/bin/certbot_renew_cron.sh >> /var/log/certbot_renew_cron.log 2>&1
16
+
17
+ commands:
18
+ rm_old_cron:
19
+ command: "rm -f /etc/cron.d/certbot_renew_cron.bak"
20
+ ignoreErrors: true
21
+
8
22
  container_commands:
9
23
  10_downloadepel:
10
24
  command: "wget -r --no-parent -A 'epel-release-*.rpm' https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/"
@@ -15,10 +29,8 @@ container_commands:
15
29
  40_installcertbot:
16
30
  command: "yum install -y certbot"
17
31
  50_getcert:
18
- command: "certbot certonly --debug --non-interactive --email ${EMAIL_LINK} --agree-tos --standalone --expand --domains ${DOMAIN_LINK} --keep-until-expiring --pre-hook \"service nginx stop\""
32
+ command: "certbot certonly --debug --non-interactive --email ${EMAIL_LINK} --agree-tos --standalone --expand --domains ${DOMAIN_LINK} --keep-until-expiring --pre-hook \"service nginx stop\" --post-hook \"service nginx restart\""
19
33
  60_link:
20
34
  command: "ln -sf /etc/letsencrypt/live/$(echo ${DOMAIN_LINK} | cut -d, -f1) /etc/letsencrypt/live/ebcert"
21
- 70_startserver:
22
- command: "service nginx start"
23
- 80_cleanup:
35
+ 70_cleanup:
24
36
  command: "rm -rf dl.fedoraproject.org"
@@ -0,0 +1,28 @@
1
+ ###################################################################################################
2
+ #### Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ ####
4
+ #### Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file
5
+ #### except in compliance with the License. A copy of the License is located at
6
+ ####
7
+ #### http://aws.amazon.com/apache2.0/
8
+ ####
9
+ #### or in the "license" file accompanying this file. This file is distributed on an "AS IS"
10
+ #### BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11
+ #### License for the specific language governing permissions and limitations under the License.
12
+ ###################################################################################################
13
+
14
+ ###################################################################################################
15
+ #### This configuration file modifies the default port 80 listener attached to an Application Load Balancer
16
+ #### to automatically redirect incoming connections on HTTP to HTTPS.
17
+ #### This will not work with an environment using the load balancer type Classic or Network.
18
+ #### A prerequisite is that the 443 listener has already been created.
19
+ #### Please use the below link for more information about creating an Application Load Balancer on
20
+ #### the Elastic Beanstalk console.
21
+ #### https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/environments-cfg-alb.html#environments-cfg-alb-console
22
+ ###################################################################################################
23
+
24
+ Resources:
25
+ AWSEBV2LoadBalancerTargetGroup:
26
+ Type: AWS::ElasticLoadBalancingV2::TargetGroup
27
+ Properties:
28
+ HealthCheckPath: /wp-content/themes/fishawack/health.html
@@ -0,0 +1,42 @@
1
+ files:
2
+ "/usr/local/bin/is_first_instance.sh":
3
+ mode: "000755"
4
+ owner: root
5
+ group: root
6
+ content: |
7
+ #!/bin/bash
8
+ INSTANCE_ID=`curl http://169.254.169.254/latest/meta-data/instance-id 2>/dev/null`
9
+ REGION=`curl -s http://169.254.169.254/latest/dynamic/instance-identity/document 2>/dev/null | jq -r .region`
10
+
11
+ # Find the Auto Scaling Group name from the Elastic Beanstalk environment
12
+ ASG=`aws ec2 describe-tags --filters "Name=resource-id,Values=$INSTANCE_ID" \
13
+ --region $REGION --output json | jq -r '.[][] | select(.Key=="aws:autoscaling:groupName") | .Value'`
14
+
15
+ # Find the first instance in the Auto Scaling Group
16
+ FIRST=`aws autoscaling describe-auto-scaling-groups --auto-scaling-group-names $ASG \
17
+ --region $REGION --output json | \
18
+ jq -r '.AutoScalingGroups[].Instances[] | select(.LifecycleState=="InService") | .InstanceId' | sort | head -1`
19
+
20
+ # If the instance ids are the same exit 0
21
+ [ "$FIRST" = "$INSTANCE_ID" ]
22
+
23
+ "/usr/local/bin/wordpress_cron.sh":
24
+ mode: "000755"
25
+ owner: root
26
+ group: root
27
+ content: |
28
+ #!/bin/bash
29
+ /usr/local/bin/is_first_instance.sh || exit
30
+ cd /var/www/html && echo $(date -u) $(wp cron event run --due-now)
31
+
32
+ "/etc/cron.d/wordpress_cron":
33
+ mode: "000644"
34
+ owner: root
35
+ group: root
36
+ content: |
37
+ * * * * * root bash -l /usr/local/bin/wordpress_cron.sh >> /var/log/wordpress_cron.log 2>&1
38
+
39
+ commands:
40
+ rm_old_cron:
41
+ command: "rm -f /etc/cron.d/wordpress_cron.bak"
42
+ ignoreErrors: true
@@ -1,3 +1,5 @@
1
1
  option_settings:
2
2
  - option_name: WP_CLI_ALLOW_ROOT
3
- value: true
3
+ value: true
4
+ - option_name: PATH
5
+ value: "/var/app/staging/vendor/bin:/var/app/current/vendor/bin:$PATH"
@@ -1,14 +1,17 @@
1
1
  container_commands:
2
2
  10-db-import:
3
- command: if [ -f auto-ci-db.sql ]; then vendor/bin/wp db reset --yes; vendor/bin/wp db import auto-ci-db.sql; fi
3
+ command: if [ -f auto-ci-db.sql ]; then wp db reset --yes; wp db import auto-ci-db.sql; fi
4
4
  leader_only: true
5
5
  20-db-remove:
6
6
  command: "rm -rf auto-ci-db.sql"
7
- 30-cleanup-plugins:
8
- command: "wp option update active_plugins {} --format=json"
9
- 40-activate-plugins:
7
+ 30-activate-plugins:
10
8
  command: "wp plugin activate --all"
11
- 50-rewrite-flush:
12
- command: "vendor/bin/wp rewrite flush --hard"
13
- 60-rewrite-flush:
14
- command: "vendor/bin/wp cli cache clear"
9
+ leader_only: true
10
+ ignoreErrors: true
11
+ 40-import-cpt:
12
+ command: "bash _Scripts/import-cpt.sh"
13
+ leader_only: true
14
+ ignoreErrors: true
15
+ 50-clear-cache:
16
+ command: "wp cli cache clear"
17
+ ignoreErrors: true
@@ -1,5 +1,3 @@
1
1
  option_settings:
2
2
  aws:elasticbeanstalk:container:php:phpini:
3
- document_root: /wordpress
4
- aws:elasticbeanstalk:environment:proxy:
5
- ProxyServer: apache
3
+ document_root: /wordpress
@@ -0,0 +1,7 @@
1
+ deploy:
2
+ artifact: _Zips/Deploy.zip
3
+ global:
4
+ application_name: <%= REPO %>
5
+ default_region: <%= AWS_REGION %>
6
+ profile: <%= AWS_PROFILE %>
7
+ workspace_type: Application
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+
3
+ # Flush rewrites to recreate .htaccess files for existing permalink structure
4
+ wp rewrite flush --hard || true
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+
3
+ # Flush rewrites to recreate .htaccess files for existing permalink structure
4
+ wp rewrite flush --hard || true
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+
3
+ echo "EnvironmentFile=/home/ec2-user/.env" >> /etc/systemd/system/php-fpm.service.d/php-fpm.conf
4
+
5
+ systemctl daemon-reload
6
+
7
+ service php-fpm restart
@@ -0,0 +1,30 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ # Exit out if no current folder exists as that means this is a brand new instance
6
+ if [ ! -d "/var/app/current/" ]; then
7
+ echo "New instance - skipping as no existing web dir exists"
8
+ exit 0;
9
+ fi
10
+
11
+ # Get a list of plugins from the current dir and staging dir for comparison
12
+ PREVPLUGINS=$(cd /var/app/current/; wp plugin list --fields=name --format=json) || echo "{}"
13
+ CURRENTPLUGINS=$(cd /var/app/staging/; wp plugin list --fields=name --format=json) || echo "{}"
14
+
15
+ # Loop through current plugins and check if they still exist in the staging dir - otherwise add them to the missing list
16
+ MISSING=''
17
+ for i in `echo $PREVPLUGINS | jq -rc '.[].name'`; do
18
+ if [ $(echo $CURRENTPLUGINS | jq -rc "any(.[]; .name == \"$i\")") == "false" ]; then
19
+ MISSING="${MISSING} $i"
20
+ fi
21
+ done
22
+
23
+ # Exit out if no missing plugins
24
+ if [ -z "$MISSING" ]; then
25
+ echo "No missing plugins - skipping deactivation"
26
+ exit 0;
27
+ fi
28
+
29
+ # Deactivate missing plugins
30
+ (cd /var/app/current/; wp plugin deactivate $MISSING)