Docker Directory Mount on Windows 10

To place a local folder in a Docker Container on Windows 10 to mount, you can either use Docker for Windows or if you are using the Windows 10 Home Edition used, one is forced, This by hand with Virtual Box Do.

To do this, you have to use the Docker default Select Box in Virtual Box:

virtual_box_shared_folder

and add a new Shared Folder:virtual_box_shared_folder_add

Then you have to restart the docker-machine in the Docker Toolbox, this will restart the docker default Virtual Box:

docker-machine restart

Now you can mount your directory in his docker-compose.yml:

volumes:
  - /htdocs/my_project:/var/www/html/

Now the folder in the Docker container is successfully mounted.

The following command can be used to test, whether the mount was successful:

docker exec -it CONTAINER_ID ls -ll /var/www/html

Configuring Monolog Logging for AWS Cloudwatch Logs

So that the logs are beautifully formatted from a Symfony 4 Arrive application in AWS Cloudwatch, must be Monologue configure as follows:

# config/services.yaml
Monolog\Formatter\JsonFormatter:
    calls:
        - [includeStacktraces]

and

# config/packages/prod/monolog.yaml
monolog:
  handlers:
    main:
      type:  stream
      level: error
      path:  '%kernel.logs_dir%/error.log'
      formatter: Monolog\Formatter\JsonFormatter

After that, you have to Cloudwatch Daemon to configure:

# /etc/awslogs/awslogs.conf
[general]
# Path to the CloudWatch Logs agent's state file. The agent uses this file to maintain
# client side state across its executions.
state_file = /var/lib/awslogs/agent-state

[/var/www/html/var/log/error.prod.log]
datetime_format = [%Y-%m-%d H:%M:%S]
file = /var/www/html/var/log/error.log
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = test_group_name/error_log

and you get wonderful (Aggregated) ErrorLog Information in Cloudwatch Logs Insight:

 

 

11 AWS Cloudformation Expert Tricks

I've collected a lot of useful tips in my work with Cloudfromation, which I would like to share.

1. Using an IDE with Autocomplete

For the Jetbrains IDEs like PHPStorm, Webstorm or IntelliJ there is a very good AWS Cloudfromation plugin called AWS Cloudfromation by Leonid Shalupov:

AWS Cloudfromation Plugin by Leonid Shalupov

This offers Autocomplete for the IDE and an automatic format check, whether attributes are set, which are not allowed there. On this way you can find many errors even before validating and saves a lot of time.

AWS Cloudfromation Autocomple

2. Using AWS CLI Commands more…

Cloud formation reboot of an EC2 instance

To restart an instance, after the setup has been done, the following command must be entered in the UserData section in the Cloudformation Template:

UserData:
  # is executed as root user
  Fn::Base64:
    !Sub |
      #!/bin/bash -xe
      yum update -y aws-cfn-bootstrap
      /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WebServerInstance --configsets InstallAndRun --region ${AWS::Region}
      /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WebServerInstance --region ${AWS::Region}
      reboot

AWS Lanbda Create a Route53 A Records Record

You can use the following Python AWS Lambda function to create/update an A Record in Route53:

import json
import boto3

route53 = boto3.client('route53')

def lambda_handler(event, context):
    print("Received event: " + json.dumps(event, indent=2))
    domain = event['domain']

    route53.change_resource_record_sets(
        HostedZoneId='HostedZoneId',
        ChangeBatch={
            'Comment': 'Update or Insert an A Record',
            'Changes': [
                {
                    'Action': 'UPSERT',
                    'ResourceRecordSet': {
                        'Name': domain,
                        'Type': 'A',
                        'SetIdentifier': domain,
                        'Region': 'region',
                        'ResourceRecords': [
                            {
                                'Value': '1.1.1.1'
                            }
                        ],
                        'TTL': 300
                    }
                }
            ]
        }
    )

 

To do this, the Labda function must have the necessary rights for Route53.

The documentation is here.

The function can be tested with:

{
  "domain": "foo.bar.de"
}

AWS Cloudfromation Template YAML Zeilenumbruch

To place a multiline text in Cloudformation Templates, there is an elegant solution – yaML >- Operator:

/var/www/html/public/index.php:
  content: >-
    <html>
      <body>
        <h1>Welcome to the AWS CloudFormation PHP Sample</h1>
        <p/>
        <?php
          // Print out the current data and time
          print "The Current Date and Time is: <br/>";
          print date("g:i A l, F j Y.");
        ?>
        <?php  phpinfo(); ?>
      </body>
    </html>

Alternatively, in many official examples the very unwieldy format is used with the join function:

  /var/www/html/index.php:
    content: !Join
      - ''
      - - |
          <html>
        - |2
            <body>
        - |2
              <h1>Welcome to the AWS CloudFormation PHP Sample</h1>
        - |2
              <p/>
        - |2
              <?php
        - |2
                // Print out the current data and time
        - |2
                print "The Current Date and Time is: <br/>";
        - |2
                print date("g:i A l, F j Y.");
        - |2
              ?>
        - |2
              <?php  phpinfo(); ?>
        - |2
            </body>
        - |
          </html>

 

AWS Opsworks Changes SSH Keys to EC2 Instances

I just had the problem, that I could no longer log in to my EC2 instance with my SSH key:

Server refused our key

I found out, that it was because of, I AWS Opsworks Stacks and had shaken exactly this key for the new stack.

My salvation was, that you can also connect to the instances with SSH via the AWS Console without the certificate:

What Opsworks did then, the key was to be copied from the existing instances and the root user, no longer allocate my ec2-user.

Unfortunately, this was also not done correctly, but the key in /root/.ssh/authorized_keys had been changed to an incorrect format by Opsworks:

command="echo 'Please login as the ec2-user user rather than root user.';echo;sleep 10" xxxxxxxxxxxxxxxxxxxMY SSH Keyxxxxxxxxxxxxxxxxxxx

To restore login, I removed the text in front of my SSH key and copied it to /home/ec2-user/.ssh/.

After that, the appropriate rights have to be set as ec2-user:

mkdir /home/ec2-user/.ssh
sudo chown -R ec2-user:ec2-user /home/ec2-user/.ssh
chmod 700 /home/ec2-user/.ssh
chmod 600 /home/ec2-user/.ssh/authorized_keys

After that, the login was possible again. It should not be forgotten, remove the root SSH Key.

AWS time zone adjust Amazon Linux 2 and RDS MySQL PHP

In the logs and the database use the correct time stamp of the own time zone, must be

1. Configure the system time of the EC2 instance

sudo ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime

and in the file /etc/sysconfig/clock Enter the time zone:

sudo vi /etc/sysconfig/clock
ZONE="Europe/Berlin"

After a reboot of the instance must be:

sudo reboot

The adjustment can be checked with

date

Those more…

letsencrypt AWS http challenge

I had the problem, that when renewing the Letsencrypt certificate via cronjob Amazon Linux 2

certbot renew --post-hook "systemctl reload httpd"  >> /var/log/certbot.log 2>&1

the SSL certificate was not renewed, but following error occurred:

Could not choose appropriate plugin: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',)
Attempting to renew cert (foo.de) from /etc/letsencrypt/renewal/foo.conf produced an unexpected error: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',). Skipping.

I then looked in configuration: /etc/letsencrypt/renewal/foo.conf&nbsp;and the Authentificator modified on Apache and the challenge of Authentificator on HTTP (through the Web server).

# Options used in the renewal process
[renewalparams]
account = xxx
server = https://acme-v02.api.letsencrypt.org/directory
authenticator = apache
installer = apache
pref_challs = http-01,

After that was the important Port 80 unlock the security group for authentication and another command

certbot renew

was the certificate was successfully renewed.

Cert is due for renewal, auto-renewing...
Plugins selected: Authenticator apache, Installer apache
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for foo.de
Waiting for verification...
Cleaning up challenges

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
new certificate deployed with reload of apache server; fullchain is
/etc/letsencrypt/live/foo.de/fullchain.pem