Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mantaining OAuth keys between elastic beanstalk deployment

I have a laravel application run in AWS Elastic Beanstalk environment. I use Laravel Passport to handle the authentication.

Every time I run eb deploy the keys will be deleted, since it is not part of the version control files (included in .gitignore). Thus, I have to manually run php artisan passport:keys in the EC2 instance to generate the keys. But this will make all users need to login again because the old token is now invalid, since it's a new key pair.

What is the best practice to provide a consistent oauth-public and oauth-private key for my configuration?

I am thinking of including the key into the repository, but I believe this is not recommended.

Another way is that I generate the key once, then upload it to S3. Then have a post-deployment script to retrieve the S3.

Is there any better way?

like image 800
Fadli Avatar asked Jan 05 '18 03:01

Fadli


1 Answers

I managed to solve this yesterday, with S3.

  • Create a private S3 Repository, where you store your sensitive files (oauth-private.key, etc.)
  • In your .ebextensions directory, you have to create a .config file where you define a Resource(see https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html#linux-files - authentication section) - looking like this:
Resources:
  AWSEBAutoScalingGroup:
    Metadata:
      AWS::CloudFormation::Authentication:
        S3Auth:
          type: "s3"
          buckets: ["<BUCKET-NAME>"]
          roleName:
            "Fn::GetOptionSetting":
              Namespace: "aws:autoscaling:launchconfiguration"
              OptionName: "IamInstanceProfile"
              DefaultValue: "aws-elasticbeanstalk-ec2-role"
  • Assuming A) Your S3 Bucket is called <BUCKET-NAME> and B) The IAM instance profile in your ElasticBeanstalk environment is called aws-elasticbeanstalk-ec2-role
  • Now you have to add the files to a location on the instance, where you can access it, you're free too choose where. In your .config file insert following:
files:
    "/etc/keys/oauth-private.key":
        mode: "000755"
        owner: webapp
        group: webapp
        authentication: "S3Auth" # Notice, this is the same as specified in the Resources section
        source: "https://<BUCKET-NAME>.s3-<REGION>.amazonaws.com/<PATH-TO-THE-FILE-IN-THE-BUCKET>"
  • Now for this to work, you still need to grant access to the IAM instance profile (aws-elasticbeanstalk-ec2-role), therefore you need to edit the ACL of your Bucket, like this:
{
    "Version": "2012-10-17",
    "Id": "BeanstalkS3Copy",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<ID>:role/aws-elasticbeanstalk-ec2-role"
            },
            "Action": [
                "s3:ListBucketVersions",
                "s3:ListBucket",
                "s3:GetObjectVersion",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::<BUCKET-NAME>/*"
            ]
        }
    ]
}
  • You can find the ARN of the IAM instance profile by going to the IAM Dashboard > Roles > aws-elasticbeanstalk-ec2-role and the copy the Role ARN

  • In your Laravel application you have to use Passport::loadKeysFrom('/etc/keys')

like image 91
eneskaya Avatar answered Sep 18 '22 17:09

eneskaya