다음을 통해 공유


저장소 계정 만들기

 

Create Storage Account 비동기 작업을 Microsoft Azure에서 새 저장소 계정을 만듭니다.

요청

Create Storage Account 요청을 다음과 같이 지정할 수 있습니다. 대체 <subscription-id> 와 프로그램 구독 id입니다.

방법 요청 URI
POST https://management.core.windows.net/<subscription-id>/services/storageservices

관리 서비스에 대한 요청이 안전한지 확인해야 합니다. 추가 세부 정보를 참조 하십시오. 서비스 관리 요청 인증.

URI 매개 변수

없음.

요청 헤더

다음 표에서는 요청 헤더에 대해 설명합니다.

요청 헤더 설명
Content-Type 필수 사항입니다. 이 헤더를 설정 응용 프로그램/x m l.
x-ms-version 필수 사항입니다. 이 요청에 사용할 작업의 버전을 지정합니다. 이 헤더의 값으로 설정 되어 있어야 2011-06-01 이상. 버전 관리 헤더에 대 한 자세한 내용은 참조 서비스 관리 버전 관리.

요청 본문

요청 본문의 형식은 다음과 같습니다.

<?xml version="1.0" encoding="utf-8"?> <CreateStorageServiceInput xmlns="https://schemas.microsoft.com/windowsazure"> <ServiceName>name-of-storage-account</ServiceName> <Description>description-of-storage-account</Description> <Label>base64-encoded-label</Label> <AffinityGroup>name-of-affinity-group</AffinityGroup> <Location>location-of-storage-account</Location> <GeoReplicationEnabled>geo-replication-indicator</GeoReplicationEnabled> <ExtendedProperties> <ExtendedProperty> <Name>property-name</Name> <Value>property-value</Value> </ExtendedProperty> </ExtendedProperties> <SecondaryReadEnabled>secondary-read-indicator</SecondaryReadEnabled> <AccountType>type-of-storage-account</AccountType> </CreateStorageServiceInput>  
  

다음 표에서는 요청 본문의 요소에 대해 설명합니다.

요소 이름 설명
Service Name 필수 사항입니다. Azure 내에서 고유 저장소 계정의 이름입니다. 저장소 계정 이름은 길이가 3~24자 사이여야 하며 숫자 및 소문자만 사용해야 합니다.

이 이름은 DNS 접두사 이름이며 저장소 계정의 Blob, 큐 및 테이블에 액세스하는 데 사용할 수 있습니다.

예: http://ServiceName.blob.core.windows.net/mycontainer/
Label 필수 사항입니다. Base64로 인코딩된 문자열로 지정된 저장소 계정의 레이블입니다. 레이블의 길이는 최대 100자입니다. 저장소 계정을 식별하는 데 추적용으로 사용할 수 있는 레이블입니다.
설명 선택 사항입니다. 저장소 계정에 대한 설명입니다. 설명의 길이는 최대 1024자입니다.
위치 필요한 경우 AffinityGroup 지정 하지 않았습니다. 저장소 계정이 만들어지는 위치입니다.

중 하나만 포함할 수는 위치 또는 AffinityGroup 요소에는 요청 본문 중 하나만 있습니다. 사용 가능한 위치 목록에서 사용 하 여 위치 나열 작업 합니다.
AffinityGroup 필요한 경우 위치 지정 하지 않았습니다. 지정된 구독에 있는 기존 선호도 그룹의 이름입니다.

중 하나만 포함할 수는 위치 또는 AffinityGroup 요소에는 요청 본문 중 하나만 있습니다. 사용 가능한 선호도 그룹을 표시 하려면는 선호도 그룹 나열 작업 합니다.
GeoReplicationEnabled 선택 사항입니다. 지리적 복제가 사용으로 설정된 상태에서 저장소 계정을 만들지 여부를 지정합니다 기본값은 요소가 요청 본문에 포함 되지 않은, true합니다. 경우 설정 true, 저장소 계정에 데이터가 심각한 서비스 중단 발생 시 복원 기능을 사용할 수 있는 둘 이상의 지리적 위치에 복제 됩니다.

 GeoReplicationEnabled 요소는 버전 2012-03-01을 사용 하 여 사용할 수 있는 이상 에서만 및는 2014-06-01 버전은 AccountType 요소로 대체 이후인 경우.
Name 선택 사항입니다. 확장 저장소 계정 속성의 이름을 나타냅니다. 각 확장 속성에는 정의된 이름과 값이 모두 있어야 합니다. 확장 속성 이름/값 쌍은 50개까지 지정할 수 있습니다.

Name 요소의 최대 길이는 64자이고, 영숫자와 밑줄만 포함할 수 있으며, 문자로 시작해야 합니다. Name에 다른 문자를 사용하거나, Name을 문자로 시작하지 않거나, 동일한 저장소 계정에서 소유하고 있는 다른 확장 속성의 이름과 동일한 이름을 입력하면 상태 코드 400(잘못된 요청) 오류가 반환됩니다.

 이름 요소는 버전 2012-03-01을 사용 하 여 사용할 수 있는 이상 에서만.
선택 사항입니다. 확장 저장소 계정 속성의 값을 나타냅니다. 각 확장 속성에는 정의된 이름과 값이 모두 있어야 합니다. 확장 속성 이름/값 쌍은 50개까지 지정할 수 있으며 각 확장 속성 값의 최대 길이는 255자입니다.

  요소는 버전 2012-03-01을 사용 하 여 사용할 수 있는 이상 에서만.
SecondaryReadEnabled 선택 사항입니다. 저장소 계정에 대해 보조 읽기가 설정되어 있음을 나타냅니다.

가능한 값은 다음과 같습니다.

- true
- false

 SecondaryReadEnabled 요소는 버전 2013-11-01을 사용 하 여 사용할 수 있는 이상 에서만 및는 2014-06-01 버전은 AccountType 요소로 대체 이후인 경우.
AccountType 계정이 로컬 중복 저장소, 지역 중복 저장소, 영역 중복 저장소 또는 읽기 권한의 지역 중복 저장소를 지원하는지 여부를 지정합니다.

가능한 값은 다음과 같습니다.

- Standard_LRS
- Standard_ZRS
- Standard_GRS
- Standard_RAGRS
- Premium_LRS

 AccountType 요소는 사용할 버전 2014-06-01 이상 에서만 및 SecondaryReadEnabled 및 GeoReplicationEnabled 요소를 대체 합니다.

 Premium_LRS 요소는만 이상의 버전 2014-10-01을 사용 하 여 사용할 수 있습니다. Note: A Standard_ZRS 계정을 다른 계정 유형으로 나중에 변경할 수 없습니다 및 다른 계정 유형으로 변경할 수 없습니다 Standard_ZRS합니다. 이 Premium_LRS 계정.

응답

응답에는 HTTP 상태 코드, 응답 헤더 집합 및 응답 본문이 포함되어 있습니다.

상태 코드

작업에 성공하면 상태 코드 200(정상)이 반환됩니다. 상태 코드에 대 한 정보를 참조 하십시오. 서비스 관리 상태 및 오류 코드.

응답 헤더

이 작업의 응답에는 다음과 같은 헤더가 포함됩니다. 응답에는 추가 표준 HTTP 헤더가 포함될 수도 있습니다. 모든 표준 헤더를 준수 하는 HTTP/1.1 프로토콜 사양.

응답 헤더 설명
x-ms-request-id 관리 서비스에 대해 수행된 요청을 고유하게 식별하는 값입니다. 비동기 작업을 호출할 수 있습니다 작업 상태 가져오기 작업이 완료 되었는지 여부를 확인 하려면 헤더의 값, 실패 했는지, 또는 아직 진행중에서입니다.

응답 본문

없음.

설명

프로그래밍 방식으로 저장소 계정을 만들 수는 저장소 계정 만들기 구독에서 가능한 한도까지 작업을 합니다. 저장소 계정과 관련 된 제한에 대 한 정보를 참조 하십시오. Azure 구독 및 서비스 제한, 할당량 및 제약 조건.

작업은 요청 ID와 함께 즉시 반환되지만 저장소 계정 만들기 작업은 새 저장소 계정을 프로비전하면 몇 분 정도의 시간이 걸릴 수 있으므로 Azure에서 비동기적으로 수행됩니다. 폴링할 수를 확인 하려면 저장소 계정 만들기 작업이 완료 되었을 때의 작업 상태 가져오기 요청 ID 사용 하 여 작업 이렇게 반환 된 XML 본문이 작업 요소를 포함 하는 상태 요소 값을 갖습니다 InProgress, Failed, 또는 Succeeded, 저장소 계정 만들기의 상태에 따라 합니다. 상태가 될때까지 폴링하면 Failed 또는 Succeeded, 작업 요소에 상태 코드가 포함 됩니다는 StatusCode 요소와 실패 한 작업에 추가 오류 정보가 포함 됩니다는 오류 요소입니다.

정보 Azure 저장소 확장성 및 성능 목표 저장소 요구를 계획 하는 경우에 도움이 될 수 있습니다.

예제

이 예제 콘솔 프로그램 설정 설명, 레이블, 위치 및 지리적 복제 상태를 사용 하 여 새 저장소 계정을 만듭니다는 저장소 계정 만들기 작업을 다음 폴링하는 작업 상태 가져오기 요청에서 반환 된 ID를 사용 하 여 작업의 저장소 계정 만들기 호출이 성공, 실패 하거나 폴링 시간이 초과할 때까지 작업 합니다. 마지막으로 호출 저장소 계정 속성 가져오기 새 저장소 계정에 대 한 속성을 표시 합니다. 에 대 한 값을 설정는 x-ms-version 헤더에는 Version 문자열에 구독 id SubscriptionId, 에 관리 인증서 지문을 Thumbprint, ServiceName로 샘플을 실행 하려면 고유한 저장소 계정 이름으로 설정 합니다.

namespace Microsoft.WindowsAzure.ServiceManagementRESTAPI.Samples { using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Xml; using System.Xml.Linq; public class Program { // Set these constants with your values to run the sample. private const string Version = "2011-12-01"; private const string Thumbprint = "management-certificate-thumbprint"; private const string SubscriptionId = "subscription-identifier"; private const string ServiceName = "unique-storage-account-name"; // This is the common namespace for all Service Management REST API XML data. private static XNamespace wa = "https://schemas.microsoft.com/windowsazure"; /// <summary> /// The operation status values from PollGetOperationStatus. /// </summary> private enum OperationStatus { InProgress, Failed, Succeeded, TimedOut } /// <summary> /// Gets or sets the certificate that matches the Thumbprint value. /// </summary> private static X509Certificate2 Certificate { get; set; } static void Main(string[] args) { try { Certificate = GetStoreCertificate(Thumbprint); // Create the new storage account with the following values: string description = "Description for my example storage account"; string label = "My example storage account label"; string location = "North Central US"; bool? enableGeoReplication = true; string requestId = CreateStorageAccount( ServiceName, description, label, null, location, enableGeoReplication); Console.WriteLine( "Called Create Storage Account operation: requestId {0}", requestId); // Loop on Get Operation Status for result of storage creation OperationResult result = PollGetOperationStatus( requestId, pollIntervalSeconds: 20, timeoutSeconds: 180); switch (result.Status) { case OperationStatus.TimedOut: Console.WriteLine( "Poll of Get Operation Status timed out: " + "Operation {0} is still in progress after {1} seconds.", requestId, (int)result.RunningTime.TotalSeconds); break; case OperationStatus.Failed: Console.WriteLine( "Failed: Operation {0} failed after " + "{1} seconds with status {2} ({3}) - {4}: {5}", requestId, (int)result.RunningTime.TotalSeconds, (int)result.StatusCode, result.StatusCode, result.Code, result.Message); break; case OperationStatus.Succeeded: Console.WriteLine( "Succeeded: Operation {0} completed " + "after {1} seconds with status {2} ({3})", requestId, (int)result.RunningTime.TotalSeconds, (int)result.StatusCode, result.StatusCode); break; } // Display the property values for the new storage account. // Convert the Label property to a readable value for display. XElement updatedProperties = GetStorageAccountProperties(ServiceName); XElement labelElement = updatedProperties.Descendants(wa + "Label").First(); labelElement.Value = labelElement.Value.FromBase64(); Console.WriteLine( "New Storage Account Properties for {0}:{1}{2}", ServiceName, Environment.NewLine, updatedProperties.ToString(SaveOptions.OmitDuplicateNamespaces)); } catch (Exception ex) { Console.WriteLine("Exception caught in Main:"); Console.WriteLine(ex.Message); } Console.Write("Press any key to continue:"); Console.ReadKey(); } /// <summary> /// Calls the Get Storage Account Properties operation in the Service /// Management REST API for the specified subscription and storage account /// name and returns the StorageService XML element from the response. /// </summary> /// <param name="serviceName">The name of the storage account.</param> /// <returns>The StorageService XML element from the response.</returns> private static XElement GetStorageAccountProperties( string serviceName) { string uriFormat = "https://management.core.windows.net/{0}" + "/services/storageservices/{1}"; Uri uri = new Uri(String.Format(uriFormat, SubscriptionId, serviceName)); XDocument responseBody; InvokeRequest(uri, "GET", HttpStatusCode.OK, null, out responseBody); return responseBody.Element(wa + "StorageService"); } /// <summary> /// Calls the Create Storage Account operation in the Service Management /// REST API for the specified subscription, storage account name, /// description, label, location or affinity group, and geo-replication /// enabled setting. /// </summary> /// <param name="serviceName">The name of the storage account to update.</param> /// <param name="description">The new description for the storage account.</param> /// <param name="label">The new label for the storage account.</param> /// <param name="affinityGroup">The affinity group name, or null to use a location.</param> /// <param name="location">The location name, or null to use an affinity group.</param> /// <param name="geoReplicationEnabled">The new geo-replication setting, if applicable. /// This optional parameter defaults to null.</param> /// <returns>The requestId for the operation.</returns> private static string CreateStorageAccount( string serviceName, string description, string label, string affinityGroup, string location, bool? geoReplicationEnabled = null) { string uriFormat = "https://management.core.windows.net/{0}" + "/services/storageservices"; Uri uri = new Uri(String.Format(uriFormat, SubscriptionId)); // Location and Affinity Group are mutually exclusive. // Use the location if it isn't null or empty. XElement locationOrAffinityGroup = String.IsNullOrEmpty(location) ? new XElement(wa + "AffinityGroup", affinityGroup) : new XElement(wa + "Location", location); // Create the request XML document XDocument requestBody = new XDocument( new XDeclaration("1.0", "UTF-8", "no"), new XElement( wa + "CreateStorageServiceInput", new XElement(wa + "ServiceName", serviceName), new XElement(wa + "Description", description), new XElement(wa + "Label", label.ToBase64()), locationOrAffinityGroup)); // Add the GeoReplicationEnabled element if the version supports it. if ((geoReplicationEnabled != null) && (String.CompareOrdinal(Version, "2011-12-01") >= 0)) { requestBody.Element( wa + "CreateStorageServiceInput").Add( new XElement( wa + "GeoReplicationEnabled", geoReplicationEnabled.ToString().ToLowerInvariant())); } XDocument responseBody; return InvokeRequest( uri, "POST", HttpStatusCode.Accepted, requestBody, out responseBody); } /// <summary> /// Calls the Get Operation Status operation in the Service /// Management REST API for the specified subscription and requestId /// and returns the Operation XML element from the response. /// </summary> /// <param name="requestId">The requestId of the operation to track.</param> /// <returns>The Operation XML element from the response.</returns> private static XElement GetOperationStatus( string requestId) { string uriFormat = "https://management.core.windows.net/{0}" + "/operations/{1}"; Uri uri = new Uri(String.Format(uriFormat, SubscriptionId, requestId)); XDocument responseBody; InvokeRequest(uri, "GET", HttpStatusCode.OK, null, out responseBody); return responseBody.Element(wa + "Operation"); } /// <summary> /// The results from PollGetOperationStatus are passed in this struct. /// </summary> private struct OperationResult { // The status: InProgress, Failed, Succeeded, or TimedOut. public OperationStatus Status { get; set; } // The http status code of the requestId operation, if any. public HttpStatusCode StatusCode { get; set; } // The approximate running time for PollGetOperationStatus. public TimeSpan RunningTime { get; set; } // The error code for the failed operation. public string Code { get; set; } // The message for the failed operation. public string Message { get; set; } } /// <summary> /// Polls Get Operation Status for the operation specified by requestId /// every pollIntervalSeconds until timeoutSeconds have passed or the /// operation has returned a Failed or Succeeded status. /// </summary> /// <param name="requestId">The requestId of the operation to get status for.</param> /// <param name="pollIntervalSeconds">The interval between calls to Get Operation Status.</param> /// <param name="timeoutSeconds">The maximum number of seconds to poll.</param> /// <returns>An OperationResult structure with status or error information.</returns> private static OperationResult PollGetOperationStatus( string requestId, int pollIntervalSeconds, int timeoutSeconds) { OperationResult result = new OperationResult(); DateTime beginPollTime = DateTime.UtcNow; TimeSpan pollInterval = new TimeSpan(0, 0, pollIntervalSeconds); DateTime endPollTime = beginPollTime + new TimeSpan(0, 0, timeoutSeconds); bool done = false; while (!done) { XElement operation = GetOperationStatus(requestId); result.RunningTime = DateTime.UtcNow - beginPollTime; try { // Turn the Status string into an OperationStatus value result.Status = (OperationStatus)Enum.Parse( typeof(OperationStatus), operation.Element(wa + "Status").Value); } catch (Exception) { throw new ApplicationException(string.Format( "Get Operation Status {0} returned unexpected status: {1}{2}", requestId, Environment.NewLine, operation.ToString(SaveOptions.OmitDuplicateNamespaces))); } switch (result.Status) { case OperationStatus.InProgress: Console.WriteLine( "In progress for {0} seconds", (int)result.RunningTime.TotalSeconds); Thread.Sleep((int)pollInterval.TotalMilliseconds); break; case OperationStatus.Failed: result.StatusCode = (HttpStatusCode)Convert.ToInt32( operation.Element(wa + "HttpStatusCode").Value); XElement error = operation.Element(wa + "Error"); result.Code = error.Element(wa + "Code").Value; result.Message = error.Element(wa + "Message").Value; done = true; break; case OperationStatus.Succeeded: result.StatusCode = (HttpStatusCode)Convert.ToInt32( operation.Element(wa + "HttpStatusCode").Value); done = true; break; } if (!done && DateTime.UtcNow > endPollTime) { result.Status = OperationStatus.TimedOut; done = true; } } return result; } /// <summary> /// Gets the certificate matching the thumbprint from the local store. /// Throws an ArgumentException if a matching certificate is not found. /// </summary> /// <param name="thumbprint">The thumbprint of the certificate to find.</param> /// <returns>The certificate with the specified thumbprint.</returns> private static X509Certificate2 GetStoreCertificate(string thumbprint) { List<StoreLocation> locations = new List<StoreLocation> { StoreLocation.CurrentUser, StoreLocation.LocalMachine }; foreach (var location in locations) { X509Store store = new X509Store("My", location); try { store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); X509Certificate2Collection certificates = store.Certificates.Find( X509FindType.FindByThumbprint, thumbprint, false); if (certificates.Count == 1) { return certificates[0]; } } finally { store.Close(); } } throw new ArgumentException(string.Format( "A Certificate with thumbprint '{0}' could not be located.", thumbprint)); } /// <summary> /// A helper function to invoke a Service Management REST API operation. /// Throws an ApplicationException on unexpected status code results. /// </summary> /// <param name="uri">The URI of the operation to invoke using a web request.</param> /// <param name="method">The method of the web request, GET, PUT, POST, or DELETE.</param> /// <param name="expectedCode">The expected status code.</param> /// <param name="requestBody">The XML body to send with the web request. Use null to send no request body.</param> /// <param name="responseBody">The XML body returned by the request, if any.</param> /// <returns>The requestId returned by the operation.</returns> private static string InvokeRequest( Uri uri, string method, HttpStatusCode expectedCode, XDocument requestBody, out XDocument responseBody) { responseBody = null; string requestId = String.Empty; HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri); request.Method = method; request.Headers.Add("x-ms-Version", Version); request.ClientCertificates.Add(Certificate); request.ContentType = "application/xml"; if (requestBody != null) { using (Stream requestStream = request.GetRequestStream()) { using (StreamWriter streamWriter = new StreamWriter( requestStream, System.Text.UTF8Encoding.UTF8)) { requestBody.Save(streamWriter, SaveOptions.DisableFormatting); } } } HttpWebResponse response; HttpStatusCode statusCode = HttpStatusCode.Unused; try { response = (HttpWebResponse)request.GetResponse(); } catch (WebException ex) { // GetResponse throws a WebException for 4XX and 5XX status codes response = (HttpWebResponse)ex.Response; } try { statusCode = response.StatusCode; if (response.ContentLength > 0) { using (XmlReader reader = XmlReader.Create(response.GetResponseStream())) { responseBody = XDocument.Load(reader); } } if (response.Headers != null) { requestId = response.Headers["x-ms-request-id"]; } } finally { response.Close(); } if (!statusCode.Equals(expectedCode)) { throw new ApplicationException(string.Format( "Call to {0} returned an error:{1}Status Code: {2} ({3}):{1}{4}", uri.ToString(), Environment.NewLine, (int)statusCode, statusCode, responseBody.ToString(SaveOptions.OmitDuplicateNamespaces))); } return requestId; } } /// <summary> /// Helpful extension methods for converting strings to and from Base-64. /// </summary> public static class StringExtensions { /// <summary> /// Converts a UTF-8 string to a Base-64 version of the string. /// </summary> /// <param name="s">The string to convert to Base-64.</param> /// <returns>The Base-64 converted string.</returns> public static string ToBase64(this string s) { byte[] bytes = System.Text.Encoding.UTF8.GetBytes(s); return Convert.ToBase64String(bytes); } /// <summary> /// Converts a Base-64 encoded string to UTF-8. /// </summary> /// <param name="s">The string to convert from Base-64.</param> /// <returns>The converted UTF-8 string.</returns> public static string FromBase64(this string s) { byte[] bytes = Convert.FromBase64String(s); return System.Text.Encoding.UTF8.GetString(bytes); } } }  
  

이 예제 프로그램을 실행하면 다음과 유사한 콘솔 출력이 생성됩니다.

Called Create Storage Account operation: requestId 8ba8bd9cdc50472892a0b3cd3659b297 In progress for 0 seconds In progress for 20 seconds In progress for 41 seconds In progress for 61 seconds In progress for 82 seconds In progress for 103 seconds Succeeded: Operation 8ba8bd9cdc50472892a0b3cd3659b297 completed after 123 seconds with status 200 (OK) New Storage Account Properties for myexamplestorage1: <StorageService xmlns="https://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <Url>https://management.core.windows.net/01234567-89ab-cdef-0123-456789abcdef/services/storageservices/myexamplestorage1</Url> <ServiceName>myexamplestorage1</ServiceName> <StorageServiceProperties> <Description>Description for my example storage account</Description> <Location>North Central US</Location> <Label>My example storage account label</Label> <Status>Created</Status> <Endpoints> <Endpoint>http://myexamplestorage1.blob.core.windows.net/</Endpoint> <Endpoint>http://myexamplestorage1.queue.core.windows.net/</Endpoint> <Endpoint>http://myexamplestorage1.table.core.windows.net/</Endpoint> </Endpoints> <GeoReplicationEnabled>true</GeoReplicationEnabled> <GeoPrimaryRegion>usnorth</GeoPrimaryRegion> <StatusOfPrimary>Available</StatusOfPrimary> <GeoSecondaryRegion>ussouth</GeoSecondaryRegion> <StatusOfSecondary>Available</StatusOfSecondary> </StorageServiceProperties> </StorageService> Press any key to continue: