2

I am attempting to write a Perl script that will run on a Centos 6 host. This script will run a shell command that queries our AWS interface like this:

my $json = `aws ec2 describe-instances`;

This query will return a JSON object but I belive my issue is that it is actually being stored as a string in $output and not actually in a JSON object.

I am trying the following code:

# Get each instance
my $json = `aws ec2 describe-instances`;

# Decode AWS json result
my $decoded = decode_json $json;

# Find reference type
print "Reference type: " . ref $decoded,"\n";

# Loop through each EC2 instance
print $decoded -> {Reservations} . "\n";

When I execute this code I get the following message:

Reference type: HASH
ARRAY(0xa774b0)

Can anyone help me with this? I have been googling and messing with this for over a whole day now :(

Below is an example of the string that is stored in $output although in the real output there would be multiple instances:

{
    "Reservations": [
        {
            "OwnerId": "82XXXXXXX043",
            "ReservationId": "r-0XXXXXXXXXXX",
            "Groups": [],
            "Instances": [
                {
                    "Monitoring": {
                        "State": "XXXXX"
                    },
                    "PublicDnsName": "XXX",
                    "RootDeviceType": "XXXXXXX",
                    "State": {
                        "Code": XXX,
                        "Name": "stopped"
                    },
                    "EbsOptimized": XXXX,
                    "LaunchTime": "XXXXXXXXXX",
                    "PrivateIpAddress": "XXXXXXXXXX",
                    "ProductCodes": [],
                    "VpcId": "XXXXXXXXXX",
                    "StateTransitionReason": "UXXXXXXXXXX",
                    "InstanceId": "XXXXXXXXXX",
                    "ImageId": "XXXXXXXXXX",
                    "PrivateDnsName": "XXXXXXXXXX",
                    "KeyName": "XXXXXXXXXX",
                    "SecurityGroups": [
                        {
                            "GroupName": "XXXXXXXXXX",
                            "GroupId": "XXXXXXXXXX"
                        },
                        {
                            "GroupName": "XXXXXXXXXX",
                            "GroupId": "XXXXXXXXXX"
                        },
                        {
                            "GroupName": "XXXXXXXXXX",
                            "GroupId": "XXXXXXXXXX"
                        }
                    ],
                    "ClientToken": "XXXXXXXXXX",
                    "SubnetId": "XXXXXXXXXX",
                    "InstanceType": "XXXXXXXXXX",
                    "NetworkInterfaces": [
                        {
                            "Status": "XXXXXXXXXX",
                            "MacAddress": "XXXXXXXXXX",
                            "SourceDestCheck": XXXXXXXXXX,
                            "VpcId": "XXXXXXXXXX",
                            "Description": "XXXXXXXXXX",
                            "NetworkInterfaceId": "XXXXXXXXXX",
                            "PrivateIpAddresses": [
                                {
                                    "Primary": XXXXXXXXXX,
                                    "PrivateIpAddress": "XXXXXXXXXX"
                                }
                            ],
                            "Ipv6Addresses": [],
                            "Attachment": {
                                "Status": "XXXXXXXXXX",
                                "DeviceIndex": 01234,
                                "DeleteOnTermination": XXXXXXXXXX,
                                "AttachmentId": "XXXXXXXXXX",
                                "AttachTime": "XXXXXXXXXX"
                            },
                            "Groups": [
                                {
                                    "GroupName": "XXXXXXXXXX",
                                    "GroupId": "XXXXXXXXXX"
                                },
                                {
                                    "GroupName": "XXXXXXXXXX",
                                    "GroupId": "XXXXXXXXXX"
                                },
                                {
                                    "GroupName": "XXXXXXXXXX",
                                    "GroupId": "XXXXXXXXXX"
                                }
                            ],
                            "SubnetId": "XXXXXXXXXX",
                            "OwnerId": "XXXXXXXXXX",
                            "PrivateIpAddress": "XXXXXXXXXX"
                        }
                    ],
                    "SourceDestCheck": XXXXXXXXXX,
                    "Placement": {
                        "Tenancy": "XXXXXXXXXX",
                        "GroupName": "XXXXXXXXXX",
                        "AvailabilityZone": "XXXXXXXXXX"
                    },
                    "Hypervisor": "XXXXXXXXXX",
                    "BlockDeviceMappings": [
                        {
                            "DeviceName": "XXXXXXXXXX",
                            "Ebs": {
                                "Status": "XXXXXXXXXX",
                                "DeleteOnTermination": XXXXXXXXXX,
                                "VolumeId": "XXXXXXXXXX",
                                "AttachTime": "XXXXXXXXXX"
                            }
                        }
                    ],
                    "Architecture": "XXXXXXXXXX",
                    "StateReason": {
                        "Message": "XXXXXXXXXX",
                        "Code": "XXXXXXXXXX"
                    },
                    "IamInstanceProfile": {
                        "Id": "XXXXXXXXXX",
                        "Arn": "XXXXXXXXXX"
                    },
                    "RootDeviceName": "XXXXXXXXXX",
                    "VirtualizationType": "XXXXXXXXXX",
                    "Tags": [
                        {
                            "Value": "XXXXXXXXXX",
                            "Key": "XXXXXXXXXX"
                        },
                        {
                            "Value": "XXXXXXXXXX",
                            "Key": "XXXXXXXXXX"
                        },
                        {
                            "Value": "XXXXXXXXXX",
                            "Key": "XXXXXXXXXX"
                        },
                        {
                            "Value": "XXXXXXXXXX",
                            "Key": "XXXXXXXXXX"
                        },
                        {
                            "Value": "XXXXXXXXXX",
                            "Key": "XXXXXXXXXX"
                        },
                        {
                            "Value": "XXXXXXXXXX",
                            "Key": "XXXXXXXXXX"
                        }
                    ],
                    "AmiLaunchIndex": XXXXXXXXXX
                }
            ]
        }
    ]
}
5
  • your example looks like a hash, not like an array. Commented Apr 25, 2018 at 14:25
  • "my issue is that it is actually being stored as a string in $output and not actually in a JSON object". What do you imagine a "JSON object" to be? JSON is JavaScript Object Notation and is, by definition, a string of text. It is the job of the JSON module to convert between a JSON string and the data structure that it represents. Commented Apr 25, 2018 at 14:25
  • There is no variable $output. Do you mean $json? Commented Apr 25, 2018 at 14:30
  • You need to tell us what you actually want to do with this data. The reference type is not very relevant here. When you call decode_json, you turn the string of JSON into a Perl data structure. The hierarchy inside that structure maps exactly to JSON. In your code you say you Loop through each EC2 instance, but you don't loop. You print the value behind the key Reservations. That's an array reference, and if you print that, it stringifies to ARRAY(0xdeadb33f). That's expected. If you want to turn this back into JSON, you need to tell Perl that. encode_json sounds reasonable. Commented Apr 25, 2018 at 14:53
  • Or use Data::Dumper or Data::Printer to inspect the Perl data structure. Commented Apr 25, 2018 at 14:53

2 Answers 2

3

Your JSON starts with a { so the error is quite correct. You don't have an array reference, you have a hash reference.

Try print ref $decoded,"\n" and it'll tell you what type of reference you have.

Try $decoded -> {Reservations} or just print the whole thing with Data::Dumper:

use Data::Dumper;
print Dumper $decoded;
Sign up to request clarification or add additional context in comments.

3 Comments

So it works then. Problem sorted. Your hash dereference gets you an array. You can iterate the array as you wish. Please don't amend your question to ask something else - that invalidates any answers that you're getting, which are supposed to be for other people to refer to.
I guess I am not sure how to loop through the hash. So $decoded is now an array that I can loop through? I will try that...
No. $decoded -> {Reservations} is an array reference. You can iterate that with for my $reservation ( @{$decoded->{Reservations}} ) { and then you'll find that $reservation is another hash reference
3

You've successfully converted the JSON string into a Perl data structure. Looks like you're falling down because you don't know how to manipulate Perl data structures. Reading the perldsc manual page would probably help there.

I see that $decoded->{Reservations} is an array reference. So you'll be able to walk that array with code like:

foreach my $reservation (@{ $decoded->{Reservations} }) {
  # Do something useful with $reservation
}

Alternatively, you might consider using a library like Paws to handle your AWS interaction.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.