Connect AWS
This is step 1 of https://18-207-170-166.sslip.io/docs/onboard.md. You will create one IAM role in the person's AWS account that Infrapilot's agent may assume, and submit its ARN. There are no long-lived keys: Infrapilot assumes the role for an hour at a time, and the session credentials exist only inside the workspace's sandbox.
Before you start
aws sts get-caller-identity # which account and identity the CLI is using
aws configure get region # the region the project runs in
Confirm with the person that this is the account and region Pilot should manage. Your own identity needs permission to create IAM roles (iam:CreateRole, iam:PutRolePolicy) and to tag the resources you will hand to Pilot.
1. Get the role documents
curl -s -H "Authorization: Bearer $INFRAPILOT_TOKEN" $INFRAPILOT_URL/api/v1/setup/aws-role > /tmp/infrapilot-role.json
jq '.trust_policy' /tmp/infrapilot-role.json > /tmp/infrapilot-trust.json
jq '.policies.tune' /tmp/infrapilot-role.json > /tmp/infrapilot-tune.json
jq '.policies.build' /tmp/infrapilot-role.json > /tmp/infrapilot-build.json
trust_policylets Infrapilot's principal assume the role, and only with this workspace's external id. Nobody else's workspace can use the role, and neither can Infrapilot without that id.policies.tunelets Pilot read the account (resources by tag, schemas, CloudWatch metrics, CloudTrail events) and change the settings of the services it manages (for example Lambda memory, SQS attributes, DynamoDB capacity, Application Auto Scaling bounds), through the AWS Cloud Control API.
It also allows iam:PassRole, to Lambda only. Changing any setting of a Lambda function through Cloud Control re-submits the function's execution role, and AWS counts that as passing it. To narrow it, replace the statement's Resource with the ARNs of the execution roles of the functions Pilot should tune.
policies.buildadds creating and deleting the resources its blueprints use. Attach it only if the fleet spec will declare workloads for Pilot to build. The IAM permissions in it are limited to roles namedinfrapilot-*.
Show the person the two or three documents and say plainly what they allow before creating anything. If they want a narrower policy (fewer services, or Resource restricted to specific ARNs), edit the files: Pilot simply cannot do what the role does not allow, and it will ask for what it lacks.
2. Create the role
aws iam create-role --role-name InfrapilotAgent \
--assume-role-policy-document file:///tmp/infrapilot-trust.json \
--description "Infrapilot's agent: runs this account's infrastructure within the limits in infrapilot.yaml"
aws iam put-role-policy --role-name InfrapilotAgent --policy-name infrapilot-tune \
--policy-document file:///tmp/infrapilot-tune.json
# only when the spec declares workloads for Pilot to build:
aws iam put-role-policy --role-name InfrapilotAgent --policy-name infrapilot-build \
--policy-document file:///tmp/infrapilot-build.json
aws iam get-role --role-name InfrapilotAgent --query Role.Arn --output text
If a role named InfrapilotAgent already exists from another workspace, use a different name (for example InfrapilotAgent-staging); the name is not significant.
3. Submit the connection
curl -s -X POST $INFRAPILOT_URL/api/v1/setup/cloud \
-H "Authorization: Bearer $INFRAPILOT_TOKEN" -H "Content-Type: application/json" \
-d '{"kind": "aws_role", "role_arn": "arn:aws:iam::<account>:role/InfrapilotAgent", "region": "<region>"}'
Infrapilot assumes the role and runs these checks from the sandbox:
| Check | Needs |
|---|---|
credentials | the trust policy (principal and external id) to be exactly as issued |
cloudformation:DescribeType | resource schemas, used to validate every change before it is sent |
cloudformation:ListResources (Cloud Control) | the Cloud Control API, which IAM authorizes under the cloudformation: prefix |
tag:GetResources | finding the resources you tag |
application-autoscaling:DescribeScalableTargets | knowing which values an AWS autoscaler owns |
cloudwatch:GetMetricData | telemetry |
cloudtrail:LookupEvents | attributing changes made outside Infrapilot |
lambda:GetAccountSettings | account limits Pilot must respect |
IAM is eventually consistent. If credentials fails right after you created the role, wait 15 seconds and submit again.
If connection.kinds in GET /api/v1/setup does not include aws_role, this server has no AWS principal configured. Use the first kind it does list; aws_keys takes {"kind": "aws_keys", "access_key_id", "secret_access_key", "account_id", "region"} for an IAM user with the same two policies. Prefer the role whenever it is offered.
4. Tag what Pilot should adopt
Pilot adopts every resource that carries the fleet's tag. Give each a short logical name too; it is the name the spec's objectives and bounds use.
aws resourcegroupstaggingapi tag-resources \
--resource-arn-list arn:aws:lambda:us-east-1:123456789012:function:checkout-prod \
--tags infrapilot:fleet=shop,infrapilot:name=api
- One call takes up to 20 ARNs. Use the same
infrapilot:fleetvalue asfleetin the spec. - A Lambda function's event source mappings (its SQS or stream triggers) are adopted with the function, named
<function name>-from-<source>unless you tag them with a name. - Application Auto Scaling targets and policies on an adopted DynamoDB table or ECS service are found automatically and adopted as controllers. Do not tag them.
- AWS's tag index lists a newly tagged resource after a minute or two.
POST /api/v1/setup/discovershows what it sees.
What Pilot understands on AWS
curl -s $INFRAPILOT_URL/api/types/aws returns the exact list: each resource type with the metrics an objective can name, its live signals, the properties Pilot tunes, and the workload kinds it can build. In short:
| Service | Type | Objectives usually name |
|---|---|---|
| Lambda | AWS::Lambda::Function | Duration (p99, ms), Throttles, Errors |
| Lambda triggers | AWS::Lambda::EventSourceMapping | (tuned: BatchSize, ScalingConfig.MaximumConcurrency) |
| SQS | AWS::SQS::Queue | backlog (live), ApproximateAgeOfOldestMessage |
| DynamoDB | AWS::DynamoDB::Table | WriteThrottleEvents, ReadThrottleEvents |
| Application Auto Scaling | ...::ScalableTarget, ...::ScalingPolicy | (the controllers Pilot tunes instead of the capacity they own) |
| ECS | AWS::ECS::Service | CPUUtilization, MemoryUtilization |
| Kinesis | AWS::Kinesis::Stream | WriteProvisionedThroughputExceeded |
| RDS | AWS::RDS::DBInstance | CPUUtilization, DatabaseConnections |
Any other type the Cloud Control API supports is still adopted, schema-checked and watched for changes made outside Infrapilot. Pilot changes such a type only when the spec's boundaries.manage is all. An objective can name any CloudWatch metric by adding namespace and dimensions.
Workload kinds Pilot can build on AWS: queue, table, bucket, topic, http-service (a Lambda function behind a function URL) and worker (a Lambda function fed by a queue or stream).
Revoking access
Delete the role (aws iam delete-role-policy for each policy, then aws iam delete-role --role-name InfrapilotAgent). Pilot loses access within the hour at most, and everything it managed keeps running as it was left. Tags can stay or go; they do nothing on their own.