目次
はじめに
こんにちは、クラウド事業部の菅です。
前回の記事投稿後にcurlコマンドによるアクセス方法を調べていたところ、AWS Signature Version 4 (AWS SigV4)を使用したアクセス方法があることを知りました。
docs.aws.amazon.com
今回は、AWS SigV4をcurlで使用してAWSの操作を行ってみたいと思います。
※AWS SigV4について詳しく説明している記事が既にありますので、説明は省略します。
AWS SigV4を使用する
認証情報の取得
AWS SigV4を使用するためには、アクセスキーIDやシークレットアクセスキーなどの認証情報が必要です。
EC2インスタンスにアタッチされたIAMロールから認証情報を取得できるので、インスタンスメタデータ (IMDSv2) から認証情報を取得します。
sh-5.2$ TOKEN=`curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 3600"`
sh-5.2$ PROFILE=`curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/`
sh-5.2$ CREDENTIALS=`curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/$PROFILE`
sh-5.2$ echo $CREDENTIALS | jq 'keys'
[
"AccessKeyId",
"Code",
"Expiration",
"LastUpdated",
"SecretAccessKey",
"Token",
"Type"
]
S3の操作
APIリファレンスを参考に、curlを使用してS3バケットの操作を行います。
docs.aws.amazon.com
ListObjectV2
S3バケット「apc-kan-s3-bucket」に格納されているファイルの一覧を取得します。
sh-5.2$ curl -s "https://apc-kan-s3-bucket.s3.ap-northeast-3.amazonaws.com/?list-type=2" --aws-sigv4 "aws:amz:ap-northeast-3:s3" --user "`echo $CREDENTIALS | jq -r '.AccessKeyId + ":" + .SecretAccessKey'`" -H "X-Amz-Security-Token: `echo $CREDENTIALS | jq -r '.Token'`" | xmllint --format -
<?xml version="1.0" encoding="UTF-8"?><ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Name>apc-kan-s3-bucket</Name>
<Prefix/>
<KeyCount>1</KeyCount>
<MaxKeys>1000</MaxKeys>
<IsTruncated>false</IsTruncated>
<Contents>
<Key>test.txt</Key>
<LastModified>2025-04-17T01:08:51.000Z</LastModified>
<ETag>"fe8e2156220b7550626693c26baeb2fe"</ETag>
<ChecksumAlgorithm>CRC64NVME</ChecksumAlgorithm>
<ChecksumType>FULL_OBJECT</ChecksumType>
<Size>35</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
</ListBucketResult>
S3オブジェクト内に「test.txt」というファイルが格納されていることを確認できました。
GetObject
S3バケット内のファイルにアクセスします。
sh-5.2$ curl -s https://apc-kan-s3-bucket.s3.ap-northeast-3.amazonaws.com/test.txt
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>XAMES1H8P7JTW27T</RequestId><HostId>(省略)</HostId></Error>sh-5.2$
sh-5.2$ curl -s "https://apc-kan-s3-bucket.s3.ap-northeast-3.amazonaws.com/test.txt" --aws-sigv4 "aws:amz:ap-northeast-3:s3" --user "`echo $CREDENTIALS | jq -r '.AccessKeyId + ":" + .SecretAccessKey'`" -H "X-Amz-Security-Token: `echo $CREDENTIALS | jq -r '.Token'`"
This is the contents of test.txt!
AWS SigV4無しではアクセスが拒否されましたが、AWS SigV4有りでは許可されました。
PutObject
S3バケットへファイルをアップロードします。
sh-5.2$ cat << EOS > test2.txt
> ----- test2 text -----
> EOS
sh-5.2$ aws s3 ls s3://apc-kan-s3-bucket
2025-04-17 01:08:51 35 test.txt
sh-5.2$ curl -T test2.txt "https://apc-kan-s3-bucket.s3.ap-northeast-3.amazonaws.com" --aws-sigv4 "aws:amz:ap-northeast-3:s3" --user "`echo $CREDENTIALS | jq -r '.AccessKeyId + ":" + .SecretAccessKey'`" -H "X-Amz-Security-Token: `echo $CREDENTIALS | jq -r '.Token'`"
sh-5.2$ aws s3 ls s3://apc-kan-s3-bucket
2025-04-17 01:08:51 35 test.txt
2025-04-17 01:27:34 23 test2.txt
sh-5.2$ curl -s "https://apc-kan-s3-bucket.s3.ap-northeast-3.amazonaws.com/test2.txt" --aws-sigv4 "aws:amz:ap-northeast-3:s3" --user "`echo $CREDENTIALS | jq -r '.AccessKeyId + ":" + .SecretAccessKey'`" -H "X-Amz-Security-Token: `echo $CREDENTIALS | jq -r '.Token'`"
----- test2 text -----
S3バケットへファイルをアップロードすることができました。
また、ファイルアップロード後にGetObjectアクションを使用してテキストデータが正常にアップロードされていることも確認できました。
DeleteObject
S3バケットに格納されているファイルを削除します。
今回は、S3バケットに格納されているファイル「test.txt」「test2.txt」のうち、「test.txt」のみ削除します。
sh-5.2$ aws s3 ls s3://apc-kan-s3-bucket
2025-04-17 01:08:51 35 test.txt
2025-04-17 01:27:34 23 test2.txt
sh-5.2$ curl -X DELETE https://apc-kan-s3-bucket.s3.ap-northeast-3.amazonaws.com/test.txt --aws-sigv4 "aws:amz:ap-northeast-3:s3" --user "`echo $CREDENTIALS | jq -r '.AccessKeyId + ":" + .SecretAccessKey'`" -H "X-Amz-Security-Token: `echo $CREDENTIALS | jq -r '.Token'`"
sh-5.2$ aws s3 ls s3://apc-kan-s3-bucket
2025-04-17 01:27:34 23 test2.txt
S3バケットからファイルを削除することができました。
EC2の操作
S3の操作ができましたので、EC2の操作も行ってみます。
DescribeRouteTables
VPCルートテーブルの一覧を取得します。
※VPCルートテーブルの数が多いので、ルートテーブルIDでフィルタしています。
sh-5.2$ curl "https://ec2.ap-northeast-3.amazonaws.com/?Action=DescribeRouteTables&Version=2016-11-15&RouteTableId.1=rtb-02cf6277a355f6a69" --aws-sigv4 "aws:amz:ap-northeast-3:ec2" --user "`echo $CREDENTIALS | jq -r '.AccessKeyId + ":" + .SecretAccessKey'`" -H "X-Amz-Security-Token: `echo $CREDENTIALS | jq -r '.Tok
en'`"
<?xml version="1.0" encoding="UTF-8"?>
<DescribeRouteTablesResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
<requestId>7bd784dc-3cf5-46af-b1b7-30faccfd4383</requestId>
<routeTableSet>
<item>
<routeTableId>rtb-02cf6277a355f6a69</routeTableId>
<vpcId>vpc-0dbe445807821e5a8</vpcId>
<ownerId>(省略)</ownerId>
<routeSet>
<item>
<destinationCidrBlock>10.0.0.0/24</destinationCidrBlock>
<gatewayId>local</gatewayId>
<state>active</state>
<origin>CreateRouteTable</origin>
</item>
</routeSet>
<associationSet>
<item>
<routeTableAssociationId>rtbassoc-0a22f5c5ac9bf52fc</routeTableAssociationId>
<routeTableId>rtb-02cf6277a355f6a69</routeTableId>
<main>true</main>
<associationState>
<state>associated</state>
</associationState>
</item>
</associationSet>
<propagatingVgwSet/>
<tagSet/>
</item>
</routeTableSet>
</DescribeRouteTablesResponse>sh-5.2$
DescribeSecurityGroups
セキュリティグループの一覧を表示します。
※セキュリティグループの数が多いので、セキュリティグループIDでフィルタしています。
</DescribeRouteTablesResponse>sh-5.2$ curl "https://ec2.ap-northeast-3.amazonaws.com/?Action=DescribeSecurityGroups&Version=2016-11-15&GroupId.1=sg-035ab51ee395f801e" --aws-sigv4 "aws:amz:ap-northeast-3:ec2" --user "`echo $CREDENTIALS | jq -r '.AccessKeyId + ":" + .SecretAccessKey'`" -H "X-Amz-Security-Token: `echo
$CREDENTIALS | jq -r '.Token'`"
<?xml version="1.0" encoding="UTF-8"?>
<DescribeSecurityGroupsResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
<requestId>6c2958a6-2125-4279-aa7a-7c4bf9ec9b7d</requestId>
<securityGroupInfo>
<item>
<ownerId>(省略)</ownerId>
<groupId>sg-035ab51ee395f801e</groupId>
<groupName>apc-kan-test-stack2-SecurityGroupEC2-gLim3KcG9leR</groupName>
<groupDescription>VPC Endpoint</groupDescription>
<vpcId>vpc-0dbe445807821e5a8</vpcId>
<ipPermissions/>
<ipPermissionsEgress>
<item>
<ipProtocol>-1</ipProtocol>
<groups/>
<ipRanges>
<item>
<cidrIp>0.0.0.0/0</cidrIp>
</item>
</ipRanges>
<ipv6Ranges/>
<prefixListIds/>
</item>
</ipPermissionsEgress>
<tagSet>
<item>
<key>aws:cloudformation:stack-name</key>
<value>apc-kan-test-stack2</value>
</item>
<item>
<key>aws:cloudformation:logical-id</key>
<value>SecurityGroupEC2</value>
</item>
<item>
<key>Name</key>
<value>apc-kan-sg-ec2</value>
</item>
<item>
<key>aws:cloudformation:stack-id</key>
<value>arn:aws:cloudformation:ap-northeast-3:(省略):stack/apc-kan-test-stack2/1206b150-1b1f-11f0-b8fa-0635c5a004ad</value>
</item>
</tagSet>
<securityGroupArn>arn:aws:ec2:ap-northeast-3:(省略):security-group/sg-035ab51ee395f801e</securityGroupArn>
</item>
</securityGroupInfo>
</DescribeSecurityGroupsResponse>sh-5.2$
DescribeInstances
EC2インスタンスの一覧を表示します。
※EC2インスタンスの数が多いので、インスタンスIDでフィルタしています。
sh-5.2$ curl "https://ec2.ap-northeast-3.amazonaws.com/?Action=DescribeInstances&Version=2016-11-15&InstanceId=i-08c4bec27b91b32fe" --aws-sigv4 "aws:amz:ap-northeast-3:ec2" --user "`echo $CREDENTIALS | jq -r '.AccessKeyId + ":" + .SecretAccessKey'`" -H "X-Amz-Security-Token: `echo $CREDENTIALS | jq -r '.Token'`"
<?xml version="1.0" encoding="UTF-8"?>
<DescribeInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
<requestId>42e443a6-f7ed-40ce-a48c-66cb5a300fea</requestId>
<reservationSet>
<item>
<reservationId>r-0dee8c953f7041ef5</reservationId>
<ownerId>(省略)</ownerId>
<groupSet/>
<instancesSet>
<item>
<instanceId>i-08c4bec27b91b32fe</instanceId>
<imageId>ami-08ea1604ee9ff115d</imageId>
<instanceState>
<code>16</code>
<name>running</name>
</instanceState>
<privateDnsName>ip-10-0-0-39.ap-northeast-3.compute.internal</privateDnsName>
<dnsName/>
<reason/>
<amiLaunchIndex>0</amiLaunchIndex>
<productCodes/>
<operator>
<managed>false</managed>
</operator>
<instanceType>t3.micro</instanceType>
<launchTime>2025-04-17T00:01:44.000Z</launchTime>
<placement>
<availabilityZone>ap-northeast-3a</availabilityZone>
<groupName/>
<tenancy>default</tenancy>
</placement>
<monitoring>
<state>disabled</state>
</monitoring>
<subnetId>subnet-05c637e57e3d7b56a</subnetId>
<vpcId>vpc-0dbe445807821e5a8</vpcId>
<privateIpAddress>10.0.0.39</privateIpAddress>
<sourceDestCheck>true</sourceDestCheck>
<groupSet>
<item>
<groupId>sg-035ab51ee395f801e</groupId>
<groupName>apc-kan-test-stack2-SecurityGroupEC2-gLim3KcG9leR</groupName>
</item>
</groupSet>
<architecture>x86_64</architecture>
(省略)
</item>
</instancesSet>
<requesterId>558859346216</requesterId>
</item>
</reservationSet>
</DescribeInstancesResponse>sh-5.2$
注意
実行対象のサービスによっては、パラメータにVersionの指定が必要です。
バージョンの指定が無い場合、古いバージョンのAPIが実行されます。
例えば、EC2ではパラメータにバージョンの指定が無かった場合、古いバージョン (2005-10-05) のAPIが実行されます。
古いバージョンのAPIのため、アクションやパラメータが対応していないものがあります。
※DescribeRouteTablesアクションや、DescribeSecurityGroupsアクションのGroupIdパラメータが対応していませんでした。
sh-5.2$ curl -s "https://ec2.ap-northeast-3.amazonaws.com/?Action=DescribeRouteTables" --aws-sigv4 "aws:amz:ap-northeast-3:ec2" --user "`echo $CREDENTIALS | jq -r '.AccessKeyId + ":" + .SecretAccessKey'`" -H "X-Amz-Security-Token: `echo $CREDENTIALS | jq -r '.Token'`" | xmllint --format -
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Errors>
<Error>
<Code>InvalidAction</Code>
<Message>The action DescribeRouteTables is not valid for this web service.</Message>
</Error>
</Errors>
<RequestID>d1286802-d5fe-4043-b7b6-ba40fee979a3</RequestID>
</Response>
sh-5.2$
sh-5.2$
sh-5.2$ curl -s "https://ec2.ap-northeast-3.amazonaws.com/?Action=DescribeSecurityGroups&GroupId.1=sg-035ab51ee395f801e" --aws-sigv4 "aws:amz:ap-northeast-3:ec2" --user "`echo $CREDENTIALS | jq -r '.AccessKeyId + ":" + .SecretAccessKey'`" -H "X-Amz-Security-Token: `echo $CREDENTIALS | jq -r '.Token'`" | xmllint --format -
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Errors>
<Error>
<Code>UnknownParameter</Code>
<Message>The parameter GroupId is not recognized</Message>
</Error>
</Errors>
<RequestID>0b5aed3a-fa08-4a5e-b8e1-10bfdcfe9248</RequestID>
</Response>
また、実行できたとしても、結果が想定通りではない場合があります。
※DescribeInstancesアクションを実行したところ、取得できる情報が大きく異なりました。
sh-5.2$ curl "https://ec2.ap-northeast-3.amazonaws.com/?Action=DescribeInstances" --aws-sigv4 "aws:amz:ap-northeast-3:ec2" --user "`echo $CREDENTIALS | jq -r '.AccessKeyId + ":" + .SecretAccessKey'`" -H "X-Amz-Security-Token: `echo $CREDENTIALS | jq -r '.Token'`"
<?xml version="1.0" encoding="UTF-8"?>
<DescribeInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2005-10-05/">
<reservationSet>
<item>
<reservationId>r-0dee8c953f7041ef5</reservationId>
<ownerId>(省略)</ownerId>
<groupSet/>
<instancesSet>
<item>
<instanceId>i-08c4bec27b91b32fe</instanceId>
<imageId>ami-08ea1604ee9ff115d</imageId>
<instanceState>
<code>16</code>
<name>running</name>
</instanceState>
<dnsName/>
<reason/>
</item>
</instancesSet>
</item>
<item>
(省略)
</item>
</reservationSet>
</DescribeInstancesResponse>sh-5.2$
最新のAPIバージョンは、各サービスのAPIリファレンスから確認できます。
S3の最新APIバージョンは2006-03-01でしたので、S3のAPIはほとんど (全く?) 更新されていないようです。
バージョン指定無しでS3が操作できたのも、そのあたりが影響しているのではないかと思います。
まとめ
今回はAWS SigV4を使用してS3とEC2を操作してみました。
バージョン指定が必要というところで少し躓きましたが、AWS SigV4でもAWS CLIと同等の操作ができました。
AWS SigV4を使用すれば、AWS CLIがインストールされていない環境でもAWS APIにアクセスできそうですね!
AWS SigV4は古くから存在するので情報も多いですが、この記事が誰かのお役に立てば幸いです。
お知らせ
APCはAWS Advanced Tier Services (アドバンストティアサービスパートナー) 認定を受けております。
その中で私達クラウド事業部はAWSなどのクラウド技術を活用したSI/SESのご支援をしております。
また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。