{"id":23444092,"url":"https://github.com/sevagh/goat","last_synced_at":"2025-08-31T22:13:10.329Z","repository":{"id":57561558,"uuid":"90773648","full_name":"sevagh/goat","owner":"sevagh","description":"AWS EBS-EC2 attach utility. UNMAINTAINED, SEE FORK -\u003e","archived":false,"fork":false,"pushed_at":"2023-08-14T22:03:41.000Z","size":16812,"stargazers_count":29,"open_issues_count":0,"forks_count":12,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-25T09:41:57.673Z","etag":null,"topics":["attach-ebs-volumes","aws","ebs-volumes","ec2-instance","eni","raid"],"latest_commit_sha":null,"homepage":"https://github.com/steamhaus/goat","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sevagh.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-09T17:32:51.000Z","updated_at":"2024-10-13T17:01:59.000Z","dependencies_parsed_at":"2024-06-20T03:02:42.267Z","dependency_job_id":"827a4ecf-085e-422c-a670-6de145853455","html_url":"https://github.com/sevagh/goat","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/sevagh/goat","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sevagh%2Fgoat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sevagh%2Fgoat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sevagh%2Fgoat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sevagh%2Fgoat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sevagh","download_url":"https://codeload.github.com/sevagh/goat/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sevagh%2Fgoat/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273047117,"owners_count":25036295,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-31T02:00:09.071Z","response_time":79,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["attach-ebs-volumes","aws","ebs-volumes","ec2-instance","eni","raid"],"created_at":"2024-12-23T18:26:38.154Z","updated_at":"2025-08-31T22:13:10.305Z","avatar_url":"https://github.com/sevagh.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# goat\n\n**N.B.: the active maintenance fork of this project is available at [https://github.com/steamhaus/goat](https://github.com/steamhaus/goat)**\n\n### Attach EBS volumes and ENIs to running EC2 instances\n\n`goat` is a Go program which runs from inside the EC2 instance.\n\nBy setting your tags correctly, `goat` can discover and attach EBS volumes and ENIs. For EBS volumes, it can perform additional actions such as RAID (with mdadm), mkfs, and mount EBS volumes to the EC2 instance where it's running.\n\n### Install and run\n\nGoat is a Go binary that should be able to run on any Linux instance. In the releases tab you can find a zip of the binary, and a `.deb` and `.rpm` package with systemd support. Goat needs `mdadm` to perform RAID (which is a dependency in the deb and rpm).\n\nTo use goat, run it during the launch process of your EC2 instance - you can `systemctl enable goat@TARGET` and `systemctl start goat@TARGET` (where TARGET is one of ebs or eni) in the EC2 user data script. [Full Terraform example here](./terraform-example).\n\n### Usage\n\nIn the most basic case, you should run `goat ebs` or `goat eni`.\n\nFull usage:\n\n```\nUsage: goat [OPTIONS] ebs|eni\n\nOPTIONS\n  -debug\n        Interactive debug prompts\n  -logLevel string\n        Log level (default \"info\")\n  -tagPrefix string\n        Prefix for GOAT related tags (default \"GOAT-IN\")\n  -version\n        Display version and exit\n```\n\nYou can set `-tagPrefix` and `-logLevel` with environment variables (which take precedence):\n\n* `GOAT_LOG_LEVEL`\n* `GOAT_TAG_PREFIX`\n\n### Tags\n\nThese are the tags you need (recall that the `GOAT-IN` prefix is configurable):\n\n| Tag Name             | Description             | Resource type     | Required            | Effect      |\n| :------------------- | :---------------------- | :---------------- | :------------------ | :---------- |\n| GOAT-IN:Prefix       | Logical app name        | EC2, EBS, ENI     | :heavy_check_mark:  | attach      |\n| GOAT-IN:NodeId       | Node id                 | EC2, EBS, ENI     | :heavy_check_mark:  | attach      |\n| GOAT-IN:VolumeName   | Distinct volume name    | EBS               |                     |             |\n| GOAT-IN:VolumeSize   | # of disks in vol group | EBS               |                     | mdadm       |\n| GOAT-IN:RaidLevel    | level of RAID (0 or 1)  | EBS               |                     | mdadm       |\n| GOAT-IN:MountPath    | Linux path to mount vol | EBS               |                     | mount       |\n| GOAT-IN:FsType       | Linux filesystem type   | EBS               |                     | mkfs        |\n\nIf non-required tags are omitted, that step is skipped. The barest case will simply attach the EBS volumes and perform no further actions.\n\nThe filesystem and fstab entries are created with the label `GOAT-{VolumeName}` for convenience. Running `goat` multiple times will result in it detecting the existing label it intended to create and not proceeding.\n\nAside from the `mount` syscall, `goat` shells out to `mdadm`, `blkid`, and `mkfs`. If the mount and RAID steps are performed, the configs will be persisted to `/etc/fstab` and `/etc/mdadm.conf`.\n\nCheck the [Terraform example](./terraform-example) for example tag values.\n\n### Permissions\n\nIt's necessary for the instance to have an IAM Role with _at least_ access to the EBS and ENI resources that it will be attaching - see [here](./terraform-example/iam_role.tf). Your roles can be even more permissive (i.e. full EC2 access) but that comes with its own risks.\n\nUnfortunately, resource-level permissions are [currently not supported](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/ec2-api-permissions.html#ec2-api-unsupported-resource-permissions) for attaching network interfaces. This means that to use `goat@eni`, your instances must have full permissions for __all__ ENIs.\n\n### Example EBS usecase - attaching old disks to a new instance\n\nThe specific use-case that `goat` was developed to solve is the following. Say you have 3 instances with their own respective disks, and you receive a termination notice for instance 1. I want the `goat` workflow to be:\n\n1. Terminate instance 1\n2. Create a new instance with the same GOAT tags (to indicate to `goat` that it's the logical equivalent as the machine it is replacing)\n   1. **No need to modify or manipulate the EBS volumes or their tags**\n4. On boot, everything works magically\n\nAfter `goat` ran on the first fresh run, the EBS volumes got the correct filesystems, labels, and in the case of RAID, `mdadm` metadata on them.\n\nThe event flow on a re-created instance is:\n\n1. Get EC2 metadata on the running instance, create an EC2 client, and search EBS volumes\n2. Attach the volumes it needs based on their tags\n3. Discover that `/dev/disk/by-label` already contains the correct disks\n    1. From `mdadm` magic, after the EBS attachment the RAID array is already detected correctly\n4. Proceed to perform the `fstab` and `mount` phases - skip `mdadm`, `mkfs`\n\n**CAVEAT**: the mdadm metadata will have the hostname of the previous EC2 instance:\n\n```\n[centos@ip-172-31-29-69 ~]$ sudo mdadm --detail --scan --verbose\nARRAY /dev/md127 level=raid0 num-devices=3 metadata=1.2 name=\"ip-172-31-25-105:'GOAT-data'\" UUID=2d08b310:fd13bd21:bc2417a4:56a1ec57\n   devices=/dev/xvdb,/dev/xvdc,/dev/xvdd\n[centos@ip-172-31-29-69 ~]$\n```\n\nTo avoid this, define a good/persistent hostname for the EC2 instance, that you will then re-apply to any instance taking ownership of the previous instance's disks.\n\n### ENI notes\n\nAs mentioned, the only action `goat` will do for ENIs is attaching them. You can try to use [ec2-net-utils](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#ec2-net-utils), a tool available on Amazon Linux AMIs, or [this port to CentOS/systemd](https://github.com/etuttle/ec2-utils), to configure an ENI after `goat` attaches it.\n\nENI attachments take a parameter called [DeviceIndex](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface-attachment.html). Goat isn't smart, and always starts from DeviceIndex `1`. This means that your EC2 instance should have no attached ENIs to use `goat`. If it does, they should be the ones that `goat` was going to attach anyway, not external ENIs that have no `goat` tags.\n\n### Build and develop\n\nThe deb, rpm, and zip are generated from a multi-stage [Dockerfile.build](./Dockerfile.build). Invoke it with `make docker-build`. If you have docker locally, you can use the following command in order to quickly get a development env ready: `make dev-env`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsevagh%2Fgoat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsevagh%2Fgoat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsevagh%2Fgoat/lists"}