<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: portfield</title>
    <description>The latest articles on DEV Community by portfield (@portfield10).</description>
    <link>https://dev.to/portfield10</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F262868%2F349e7d58-2772-4819-83c1-a20bea2c47f9.jpg</url>
      <title>DEV Community: portfield</title>
      <link>https://dev.to/portfield10</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/portfield10"/>
    <language>en</language>
    <item>
      <title>S3 operation using AWS SDK for PHP</title>
      <dc:creator>portfield</dc:creator>
      <pubDate>Thu, 10 Sep 2020 12:25:07 +0000</pubDate>
      <link>https://dev.to/portfield10/s3-operation-using-aws-sdk-for-php-3m27</link>
      <guid>https://dev.to/portfield10/s3-operation-using-aws-sdk-for-php-3m27</guid>
      <description>&lt;p&gt;Since I had a chance to touch it, I will organize the S3 operation using the AWS SDK for PHP.&lt;/p&gt;

&lt;p&gt;An example of building the necessary resources on AWS and operating S3 with an application that uses FuelPHP.&lt;/p&gt;

&lt;h3&gt;
  
  
  Work environment
&lt;/h3&gt;

&lt;p&gt;・MacOS&lt;br&gt;
・Composer 1.10.13&lt;br&gt;
・FuelPHP 1.8.2&lt;br&gt;
・AWS SDK for PHP 3.152.1&lt;/p&gt;


&lt;h3&gt;
  
  
  Environment
&lt;/h3&gt;
&lt;h4&gt;
  
  
  infrastructure
&lt;/h4&gt;

&lt;p&gt;I often see examples of hard-coding IAM user access keys and secret access keys on personal blogs.&lt;/p&gt;

&lt;p&gt;It's an anti-pattern, and I don't think it will be used in actual operation, so I'll summarize an example using an IAM role.&lt;/p&gt;

&lt;p&gt;Set an IAM user who has given S3 access authority to EC2 for verification, and use it in EC2.&lt;br&gt;
Use CloudFormation for construction.&lt;/p&gt;
&lt;h5&gt;
  
  
  EC2
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;CloudFormation definition will be described.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;
  
  
  S3
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;CloudFormation definition will be described.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;
  
  
  IAM
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;CloudFormation definition will be described.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;
  
  
  EC2 instance profile
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;CloudFormation definition will be described.&lt;/li&gt;
&lt;/ul&gt;


&lt;h4&gt;
  
  
  App
&lt;/h4&gt;
&lt;h5&gt;
  
  
  composer installation
&lt;/h5&gt;

&lt;p&gt;Since composer is not included in mac, install it using Homebrew.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install composer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;h5&gt;
  
  
  FuelPHP project creation
&lt;/h5&gt;

&lt;p&gt;The framework uses FuelPHP. Create a project with composer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer create-project fuel/fuel:1.8.2 aws_php_sdk
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As an aside, &lt;code&gt;composer create-project&lt;/code&gt; seems to git clone the specified project and then composer install.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://getcomposer.org/doc/03-cli.md#create-project"&gt;https://getcomposer.org/doc/03-cli.md#create-project&lt;/a&gt;&lt;/p&gt;




&lt;h5&gt;
  
  
  AWS SDK for PHP installation
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/getting-started_installation.html"&gt;https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/getting-started_installation.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Execute the following under the project directory.&lt;br&gt;
Sdk is installed under fuel/vendor/aws/aws-sdk-php&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require aws/aws-sdk-php
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;h3&gt;
  
  
  App development
&lt;/h3&gt;

&lt;p&gt;Create and arrange the file according to the source configuration.&lt;br&gt;
Actually, I feel that it is better to create a class and make it a wrapper function individually.&lt;br&gt;
Below, only the code is summarized.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="c1"&gt;// Import settings&lt;/span&gt;
&lt;span class="k"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'fuel/vendor/autoload.php'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Set according to FuelPHP path&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Aws\S3\S3Client&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Set to operate S3&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Aws\Exception\AwsException&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// SDK general exceptions&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Aws\S3\Exception\S3Exception&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// S3 specific exceptions&lt;/span&gt;

&lt;span class="c1"&gt;// Get credentials&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Aws\Credentials\CredentialProvider&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Set to get credentials&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CredentialProvider&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;instanceProfile&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$memoizedProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CredentialProvider&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;memoize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$provider&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;AwsException&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// S3 client credentials settings&lt;/span&gt;
&lt;span class="nv"&gt;$client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;S3Client&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="s1"&gt;'region'&lt;/span&gt;      &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'ap-northeast-1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'version'&lt;/span&gt;     &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'latest'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'credentials'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$memoizedProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'debug'&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;  &lt;span class="c1"&gt;// If debug is specified, the error log can be seen in detail at the time of verification.&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// S3 StreamWrapper registration&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$client&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;registerStreamWrapper&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;S3Exception&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Bucket list display&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$iter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Aws\recursive_dir_iterator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'s3://bucket/key'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$iter&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$filename&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;S3Exception&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Download data&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;file_get_contents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'s3://bucket/key'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;S3Exception&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Upload data&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;file_put_contents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'s3://bucket/key'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Hello!'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;S3Exception&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Move data&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;rename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'s3://bucket/src'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'s3://bucket/dist'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;S3Exception&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Import settings
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/getting-started_basic-usage.html"&gt;https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/getting-started_basic-usage.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add import settings.&lt;/p&gt;




&lt;h4&gt;
  
  
  Get credentials
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials_provider.html"&gt;https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials_provider.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Get credentials. This time, get it from the instance profile.&lt;/p&gt;




&lt;h4&gt;
  
  
  S3 Client Credential Settings
&lt;/h4&gt;

&lt;p&gt;Define an S3 client and set credentials&lt;/p&gt;




&lt;h4&gt;
  
  
  S3 stream wrapper registration
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/s3-stream-wrapper.html"&gt;https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/s3-stream-wrapper.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Register to use S3 stream wrapper for S3 operation.&lt;/p&gt;




&lt;h4&gt;
  
  
  Bucket list display
&lt;/h4&gt;

&lt;p&gt;How to get recursively with few HTTP requests.&lt;/p&gt;




&lt;h4&gt;
  
  
  Download / upload / move data
&lt;/h4&gt;

&lt;p&gt;It is difficult to understand how to use the move if it is a document.&lt;br&gt;
You can use it like an mv command by passing the path of the move source and move destination.&lt;/p&gt;




</description>
      <category>php</category>
      <category>aws</category>
    </item>
    <item>
      <title>Aurora Serverless Secrets Manager user information management (using CloudFormation)</title>
      <dc:creator>portfield</dc:creator>
      <pubDate>Wed, 15 Apr 2020 03:36:02 +0000</pubDate>
      <link>https://dev.to/portfield10/aurora-serverless-secrets-manager-user-information-management-using-cloudformation-51m4</link>
      <guid>https://dev.to/portfield10/aurora-serverless-secrets-manager-user-information-management-using-cloudformation-51m4</guid>
      <description>&lt;p&gt;In CloudFormation, I want to manage Aurora Serverless user login information using Secrets Manager.&lt;/p&gt;

&lt;p&gt;At the moment, it works with mysql engine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  SecretAuroraServerlessRoot:
    Type: AWS::SecretsManager::Secret
    Properties:
      Description: "Aurora Serverless Root Secrets" 
      SecretString: !Sub 
        -
          '{
              "dbInstanceIdentifier": "${RDSIdentifier}",
              "engine": "${RDSEngine}",
              "host": "${RDSHost}",
              "port": "${RDSPort}",
              "username": "${MasterUsername}", 
              "password": "${MasterUserPassword}"
           }'
        - 
          RDSIdentifier: !Ref AuroraServerlessCluster
          RDSEngine: mysql
          RDSHost: !GetAtt AuroraServerlessCluster.Endpoint.Address
          RDSPort: !GetAtt AuroraServerlessCluster.Endpoint.Port
      Name: !Sub ${TagName}_${EnvTag}_serverless_root_user
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>aws</category>
      <category>cloudformation</category>
      <category>rds</category>
      <category>serverless</category>
    </item>
    <item>
      <title>What components do you use to do TDD with Python? </title>
      <dc:creator>portfield</dc:creator>
      <pubDate>Sun, 03 Nov 2019 13:22:09 +0000</pubDate>
      <link>https://dev.to/portfield10/what-components-do-you-use-to-do-tdd-with-python-1jde</link>
      <guid>https://dev.to/portfield10/what-components-do-you-use-to-do-tdd-with-python-1jde</guid>
      <description>&lt;p&gt;I plan to use pytest, but I would like to know the pros and cons.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>python</category>
      <category>tdd</category>
      <category>pytest</category>
    </item>
  </channel>
</rss>
